From de1a8b8c691ecc8be8b9741b6b5b5cd141c8c3da Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 26 Nov 2013 15:45:02 +0000 Subject: [PATCH 001/276] Change the REAL-to-INTEGER casting behavior so that if the REAL value is greater than 9223372036854775807.0 then it is cast to the latest possible integer, 9223372036854775807. This is sensible and the way most platforms work in hardware. The former behavior was that oversize REALs would be cast to the smallest possible integer, -9223372036854775808, which is the way Intel hardware works. FossilOrigin-Name: 6f53fc7106658d44edf63068f9a8522fa5a7688b --- manifest | 22 +++++++++++----------- manifest.uuid | 2 +- src/util.c | 3 +-- src/vdbe.c | 4 +++- src/vdbemem.c | 29 ++++++----------------------- test/autoinc.test | 2 +- test/e_expr.test | 4 ++-- 7 files changed, 25 insertions(+), 41 deletions(-) diff --git a/manifest b/manifest index 62e099e034..435fa42b93 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Better\ssupport\sfor\sUTF-8\spaths\son\sCygwin. -D 2013-11-26T00:28:50.946 +C Change\sthe\sREAL-to-INTEGER\scasting\sbehavior\sso\sthat\sif\sthe\sREAL\svalue\nis\sgreater\sthan\s9223372036854775807.0\sthen\sit\sis\scast\sto\sthe\slatest\npossible\sinteger,\s9223372036854775807.\s\sThis\sis\ssensible\sand\sthe\sway\nmost\splatforms\swork\sin\shardware.\s\sThe\sformer\sbehavior\swas\sthat\soversize\nREALs\swould\sbe\scast\sto\sthe\ssmallest\spossible\sinteger,\s-9223372036854775808,\nwhich\sis\sthe\sway\sIntel\shardware\sworks. +D 2013-11-26T15:45:02.186 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -278,15 +278,15 @@ F src/tokenize.c ec4c1a62b890bf1dbcdb966399e140b904c700a4 F src/trigger.c d84e1f3669e9a217731a14a9d472b1c7b87c87ba F src/update.c c05a0ee658f1a149e0960dfd110f3b8bd846bcb0 F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 -F src/util.c 2fa6c821d28bbdbeec1b2a7b091a281c9ef8f918 +F src/util.c cbe054290f780fcd472b89d701c7404c51ec9684 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c 23d0cfba65b6dadf39a0805d0fba266e8146d678 +F src/vdbe.c 061d30aea5bbe70926236836be259ed217ee65c0 F src/vdbe.h c06f0813f853566457ce9cfb1a4a4bc39a5da644 F src/vdbeInt.h 05fbda0e061dbc4aaa2709a8cccf3515c245b263 F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed F src/vdbeaux.c a880c3c7d7c58543574ff7c96feddc5a1deaeae2 F src/vdbeblob.c 8cd05a5630e6d5563ad017bf82edaf812b28acde -F src/vdbemem.c cd02a6ade205ebe989983b7e3d64a5358b8e5e1f +F src/vdbemem.c af650c2019dc197f062440cdb4650b7204e648bf F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147 F src/vdbetrace.c e7ec40e1999ff3c6414424365d5941178966dcbc F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd @@ -330,7 +330,7 @@ F test/attachmalloc.test 3a4bfca9545bfe906a8d2e622de10fbac5b711b0 F test/auth.test 9bea29041871807d9f289ee679d05d3ed103642f F test/auth2.test c3b415b76c033bedb81292118fb7c01f5f10cbcd F test/auth3.test a4755e6a2a2fea547ffe63c874eb569e60a28eb5 -F test/autoinc.test bd30d372d00045252f6c2e41b5f41455e1975acf +F test/autoinc.test c58912526998a39e11f66b533e23cfabea7f25b7 F test/autoindex1.test d4dfe14001dfcb74cfbd7107f45a79fc1ab6183e F test/autovacuum.test 941892505d2c0f410a0cb5970dfa1c7c4e5f6e74 F test/autovacuum_ioerr2.test 8a367b224183ad801e0e24dcb7d1501f45f244b4 @@ -437,7 +437,7 @@ F test/e_createtable.test 3b453432cd14a12732ee9467597d2274ca37ce36 F test/e_delete.test d5186e2f5478b659f16a2c8b66c09892823e542a F test/e_droptrigger.test 3cd080807622c13e5bbb61fc9a57bd7754da2412 F test/e_dropview.test 0c9f7f60989164a70a67a9d9c26d1083bc808306 -F test/e_expr.test 7d7feeadb555b49476e9ca4a145fcf7c0a81ce34 +F test/e_expr.test 0808bc72c7b2a2fab4291418ecd73f4d09d7d671 F test/e_fkey.test d83a04478bb9c02d2c513518548a69f818869f41 F test/e_fts3.test 5c02288842e4f941896fd44afdef564dd5fc1459 F test/e_insert.test 1e44f84d2abe44d66e4fbf198be4b20e3cc724a0 @@ -1143,7 +1143,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 914e6c9d88828b66e8385c4a264702471faa34cf 484162b6e5a8ad9385fe2eb2a5254d13d7b0bc36 -R 1b8f9bd2dcb67783ed3f85d3422a2824 -U mistachkin -Z f0ab176076e12054e72ef7c2fe54ec51 +P 9954327c0febc0ece46f62e05976330a1b82b48f +R 55fc64123fadbe14b9ab9765d23a7587 +U drh +Z 850b84acf394562818ad72b52ff1802d diff --git a/manifest.uuid b/manifest.uuid index b5dd746957..fa5bbf9cf1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9954327c0febc0ece46f62e05976330a1b82b48f \ No newline at end of file +6f53fc7106658d44edf63068f9a8522fa5a7688b \ No newline at end of file diff --git a/src/util.c b/src/util.c index 50ffd98650..5aa8af68d9 100644 --- a/src/util.c +++ b/src/util.c @@ -512,7 +512,7 @@ int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){ u = u*10 + c - '0'; } if( u>LARGEST_INT64 ){ - *pNum = SMALLEST_INT64; + *pNum = neg ? SMALLEST_INT64 : LARGEST_INT64; }else if( neg ){ *pNum = -(i64)u; }else{ @@ -543,7 +543,6 @@ int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){ /* zNum is exactly 9223372036854775808. Fits if negative. The ** special case 2 overflow if positive */ assert( u-1==LARGEST_INT64 ); - assert( (*pNum)==SMALLEST_INT64 ); return neg ? 0 : 2; } } diff --git a/src/vdbe.c b/src/vdbe.c index f8e95f6399..71e4d673c0 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3514,7 +3514,9 @@ case OP_SeekGt: { /* jump, in3 */ ** point number. */ assert( (pIn3->flags & MEM_Real)!=0 ); - if( iKey==SMALLEST_INT64 && (pIn3->r<(double)iKey || pIn3->r>0) ){ + if( (iKey==SMALLEST_INT64 && pIn3->r<(double)iKey) + || (iKey==LARGEST_INT64 && pIn3->r>(double)iKey) + ){ /* The P3 value is too large in magnitude to be expressed as an ** integer. */ res = 1; diff --git a/src/vdbemem.c b/src/vdbemem.c index a67305f350..0fe7a3bcb4 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -303,15 +303,8 @@ void sqlite3VdbeMemRelease(Mem *p){ /* ** Convert a 64-bit IEEE double into a 64-bit signed integer. -** If the double is too large, return 0x8000000000000000. -** -** Most systems appear to do this simply by assigning -** variables and without the extra range tests. But -** there are reports that windows throws an expection -** if the floating point value is out of range. (See ticket #2880.) -** Because we do not completely understand the problem, we will -** take the conservative approach and always do range tests -** before attempting the conversion. +** If the double is out of range of a 64-bit signed integer then +** return the closest available 64-bit signed integer. */ static i64 doubleToInt64(double r){ #ifdef SQLITE_OMIT_FLOATING_POINT @@ -328,14 +321,10 @@ static i64 doubleToInt64(double r){ static const i64 maxInt = LARGEST_INT64; static const i64 minInt = SMALLEST_INT64; - if( r<(double)minInt ){ - return minInt; - }else if( r>(double)maxInt ){ - /* minInt is correct here - not maxInt. It turns out that assigning - ** a very large positive number to an integer results in a very large - ** negative integer. This makes no sense, but it is what x86 hardware - ** does so for compatibility we will do the same in software. */ + if( r<=(double)minInt ){ return minInt; + }else if( r>=(double)maxInt ){ + return maxInt; }else{ return (i64)r; } @@ -417,17 +406,11 @@ void sqlite3VdbeIntegerAffinity(Mem *pMem){ ** ** The second and third terms in the following conditional enforces ** the second condition under the assumption that addition overflow causes - ** values to wrap around. On x86 hardware, the third term is always - ** true and could be omitted. But we leave it in because other - ** architectures might behave differently. + ** values to wrap around. */ if( pMem->r==(double)pMem->u.i && pMem->u.i>SMALLEST_INT64 -#if defined(__i486__) || defined(__x86_64__) - && ALWAYS(pMem->u.iu.iflags |= MEM_Int; } diff --git a/test/autoinc.test b/test/autoinc.test index 98f6919b03..239600616b 100644 --- a/test/autoinc.test +++ b/test/autoinc.test @@ -216,7 +216,7 @@ do_test autoinc-2.27 { } {t1 1238} do_test autoinc-2.28 { execsql { - UPDATE sqlite_sequence SET seq='12345678901234567890' + UPDATE sqlite_sequence SET seq='-12345678901234567890' WHERE name='t1'; INSERT INTO t1 VALUES(NULL,6); SELECT * FROM t1; diff --git a/test/e_expr.test b/test/e_expr.test index 2018db8a05..eead6a2b93 100644 --- a/test/e_expr.test +++ b/test/e_expr.test @@ -1606,14 +1606,14 @@ do_expr_test e_expr-31.1.4 { CAST(-0.99999 AS INTEGER) } integer 0 # an INTEGER then the result of the cast is the largest negative # integer: -9223372036854775808. # -do_expr_test e_expr-31.2.1 { CAST(2e+50 AS INT) } integer -9223372036854775808 +do_expr_test e_expr-31.2.1 { CAST(2e+50 AS INT) } integer 9223372036854775807 do_expr_test e_expr-31.2.2 { CAST(-2e+50 AS INT) } integer -9223372036854775808 do_expr_test e_expr-31.2.3 { CAST(-9223372036854775809.0 AS INT) } integer -9223372036854775808 do_expr_test e_expr-31.2.4 { CAST(9223372036854775809.0 AS INT) -} integer -9223372036854775808 +} integer 9223372036854775807 # EVIDENCE-OF: R-09295-61337 Casting a TEXT or BLOB value into NUMERIC From dbb3c98ad1eaf5e3ab00757f04a35c6d6e898e11 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 26 Nov 2013 16:20:28 +0000 Subject: [PATCH 002/276] Do not try to run the atof1.test test script on ARM hardware which lacks the "long double" type. FossilOrigin-Name: fafca560f28f526abdf1474c33af94665a65aaf0 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/atof1.test | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 435fa42b93..b4dc5841dc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\sREAL-to-INTEGER\scasting\sbehavior\sso\sthat\sif\sthe\sREAL\svalue\nis\sgreater\sthan\s9223372036854775807.0\sthen\sit\sis\scast\sto\sthe\slatest\npossible\sinteger,\s9223372036854775807.\s\sThis\sis\ssensible\sand\sthe\sway\nmost\splatforms\swork\sin\shardware.\s\sThe\sformer\sbehavior\swas\sthat\soversize\nREALs\swould\sbe\scast\sto\sthe\ssmallest\spossible\sinteger,\s-9223372036854775808,\nwhich\sis\sthe\sway\sIntel\shardware\sworks. -D 2013-11-26T15:45:02.186 +C Do\snot\stry\sto\srun\sthe\satof1.test\stest\sscript\son\sARM\shardware\swhich\slacks\nthe\s"long\sdouble"\stype. +D 2013-11-26T16:20:28.799 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -321,7 +321,7 @@ F test/async2.test c0a9bd20816d7d6a2ceca7b8c03d3d69c28ffb8b F test/async3.test d73a062002376d7edc1fe3edff493edbec1fc2f7 F test/async4.test 1787e3952128aa10238bf39945126de7ca23685a F test/async5.test 383ab533fdb9f7ad228cc99ee66e1acb34cc0dc0 -F test/atof1.test 9bf1d25180a2e05fc12ce3940cc8003033642f68 +F test/atof1.test 08a61df9365c341f334a65f4348897312d8f3db7 F test/attach.test 0d112b7713611fdf0340260192749737135fda5f F test/attach2.test 0ec5defa340363de6cd50fd595046465e9aaba2d F test/attach3.test d89ccfe4fe6e2b5e368d480fcdfe4b496c54cf4e @@ -1143,7 +1143,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 9954327c0febc0ece46f62e05976330a1b82b48f -R 55fc64123fadbe14b9ab9765d23a7587 +P 6f53fc7106658d44edf63068f9a8522fa5a7688b +R 0b6d53f178500662f3ea7da63b0a8b9a U drh -Z 850b84acf394562818ad72b52ff1802d +Z 1b696475d3b2c1907923dd0866112072 diff --git a/manifest.uuid b/manifest.uuid index fa5bbf9cf1..a2f192f5f4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6f53fc7106658d44edf63068f9a8522fa5a7688b \ No newline at end of file +fafca560f28f526abdf1474c33af94665a65aaf0 \ No newline at end of file diff --git a/test/atof1.test b/test/atof1.test index 76eb4273b9..5c04d02290 100644 --- a/test/atof1.test +++ b/test/atof1.test @@ -15,7 +15,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl -if {![info exists __GNUC__]} { +if {![info exists __GNUC__] || [regexp arm $tcl_platform(machine)]} { finish_test return } From 0425f18959aaafb4c1ce703d461acfb7a8ae65d3 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 26 Nov 2013 16:48:04 +0000 Subject: [PATCH 003/276] Change tclsqlite3.c so that it never invokes ctype macros with signed character arguments. FossilOrigin-Name: c07caabf2396c84b2ccb0e9f98ae6279ce41c59d --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/tclsqlite.c | 12 ++++++------ 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index b4dc5841dc..ce7a5e9090 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\stry\sto\srun\sthe\satof1.test\stest\sscript\son\sARM\shardware\swhich\slacks\nthe\s"long\sdouble"\stype. -D 2013-11-26T16:20:28.799 +C Change\stclsqlite3.c\sso\sthat\sit\snever\sinvokes\sctype\smacros\swith\ssigned\ncharacter\sarguments. +D 2013-11-26T16:48:04.270 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -228,7 +228,7 @@ F src/sqliteInt.h 9d586cb37572cd9e0a48242d449c6a69c2e74e72 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e -F src/tclsqlite.c 3b5f3716e320480659239abe887164521c575d83 +F src/tclsqlite.c 651b10698c87bbc3ae5772e2491e3444c5bbf153 F src/test1.c 5757066e503a8ed51313cb3a5d9bcdcced2991a9 F src/test2.c 7355101c085304b90024f2261e056cdff13c6c35 F src/test3.c 1c0e5d6f080b8e33c1ce8b3078e7013fdbcd560c @@ -1143,7 +1143,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 6f53fc7106658d44edf63068f9a8522fa5a7688b -R 0b6d53f178500662f3ea7da63b0a8b9a +P fafca560f28f526abdf1474c33af94665a65aaf0 +R 6dbbdfc524469f7c72c8eb6b873b5729 U drh -Z 1b696475d3b2c1907923dd0866112072 +Z 7b1df47f508bb396c6901395cdb1db93 diff --git a/manifest.uuid b/manifest.uuid index a2f192f5f4..eb8198cac8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fafca560f28f526abdf1474c33af94665a65aaf0 \ No newline at end of file +c07caabf2396c84b2ccb0e9f98ae6279ce41c59d \ No newline at end of file diff --git a/src/tclsqlite.c b/src/tclsqlite.c index b8fdf23c4e..0f57dda6ca 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -424,13 +424,12 @@ static int safeToUseEvalObjv(Tcl_Interp *interp, Tcl_Obj *pCmd){ */ static SqlFunc *findSqlFunc(SqliteDb *pDb, const char *zName){ SqlFunc *p, *pNew; - int i; - pNew = (SqlFunc*)Tcl_Alloc( sizeof(*pNew) + strlen30(zName) + 1 ); + int nName = strlen30(zName); + pNew = (SqlFunc*)Tcl_Alloc( sizeof(*pNew) + nName + 1 ); pNew->zName = (char*)&pNew[1]; - for(i=0; zName[i]; i++){ pNew->zName[i] = tolower(zName[i]); } - pNew->zName[i] = 0; + memcpy(pNew->zName, zName, nName+1); for(p=pDb->pFunc; p; p=p->pNext){ - if( strcmp(p->zName, pNew->zName)==0 ){ + if( sqlite3_stricmp(p->zName, pNew->zName)==0 ){ Tcl_Free((char*)pNew); return p; } @@ -1083,13 +1082,14 @@ static int dbPrepareAndBind( int nSql; /* Length of zSql in bytes */ int nVar; /* Number of variables in statement */ int iParm = 0; /* Next free entry in apParm */ + char c; int i; Tcl_Interp *interp = pDb->interp; *ppPreStmt = 0; /* Trim spaces from the start of zSql and calculate the remaining length. */ - while( isspace(zSql[0]) ){ zSql++; } + while( (c = zSql[0])==' ' || c=='\t' || c=='\r' || c=='\n' ){ zSql++; } nSql = strlen30(zSql); for(pPreStmt = pDb->stmtList; pPreStmt; pPreStmt=pPreStmt->pNext){ From 55fcab39be8186caac6c7d1262a7c943564623bb Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 26 Nov 2013 16:51:13 +0000 Subject: [PATCH 004/276] Fix a possible NULL pointer deference in the wordcount test program. FossilOrigin-Name: 6f91dca0de908dc2b15130a6593a61c3147a409f --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/wordcount.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index ce7a5e9090..d7a8adc696 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\stclsqlite3.c\sso\sthat\sit\snever\sinvokes\sctype\smacros\swith\ssigned\ncharacter\sarguments. -D 2013-11-26T16:48:04.270 +C Fix\sa\spossible\sNULL\spointer\sdeference\sin\sthe\swordcount\stest\sprogram. +D 2013-11-26T16:51:13.426 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -1091,7 +1091,7 @@ F test/without_rowid1.test aaa26da19d543cd8d3d2d0e686dfa255556c15c8 F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99 F test/without_rowid3.test eac3d5c8a1924725b58503a368f2cbd24fd6c8a0 F test/without_rowid4.test 4e08bcbaee0399f35d58b5581881e7a6243d458a -F test/wordcount.c 800b6ab98ac05b7c6343575c45055f72273c9cc2 +F test/wordcount.c 9915e06cb33d8ca8109b8700791afe80d305afda F test/zeroblob.test caaecfb4f908f7bc086ed238668049f96774d688 F test/zerodamage.test 209d7ed441f44cc5299e4ebffbef06fd5aabfefd F tool/build-all-msvc.bat e0917e787df675b020d250d60a00de8abaa4e30a x @@ -1143,7 +1143,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P fafca560f28f526abdf1474c33af94665a65aaf0 -R 6dbbdfc524469f7c72c8eb6b873b5729 +P c07caabf2396c84b2ccb0e9f98ae6279ce41c59d +R d1a47818d75d4c09a9dcb48899bdd6d5 U drh -Z 7b1df47f508bb396c6901395cdb1db93 +Z 42f2f4c4e3d27d9172438c5ee2b1524f diff --git a/manifest.uuid b/manifest.uuid index eb8198cac8..50a66e6b11 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c07caabf2396c84b2ccb0e9f98ae6279ce41c59d \ No newline at end of file +6f91dca0de908dc2b15130a6593a61c3147a409f \ No newline at end of file diff --git a/test/wordcount.c b/test/wordcount.c index b21b4272bc..cf63e983c2 100644 --- a/test/wordcount.c +++ b/test/wordcount.c @@ -116,7 +116,7 @@ static int printResult(void *NotUsed, int nArg, char **azArg, char **azNm){ int i; printf("--"); for(i=0; i Date: Tue, 26 Nov 2013 18:22:59 +0000 Subject: [PATCH 005/276] Reduce the amount of code used to implement OP_SeekGe and similar. FossilOrigin-Name: 8b12a15a2a8139d75f56a099f3f6af844da3ac9c --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbe.c | 52 +++++++++++++++++++++------------------------------ 3 files changed, 29 insertions(+), 39 deletions(-) diff --git a/manifest b/manifest index d7a8adc696..30adfeecf2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\spossible\sNULL\spointer\sdeference\sin\sthe\swordcount\stest\sprogram. -D 2013-11-26T16:51:13.426 +C Reduce\sthe\samount\sof\scode\sused\sto\simplement\sOP_SeekGe\sand\ssimilar. +D 2013-11-26T18:22:59.246 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -280,7 +280,7 @@ F src/update.c c05a0ee658f1a149e0960dfd110f3b8bd846bcb0 F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c cbe054290f780fcd472b89d701c7404c51ec9684 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c 061d30aea5bbe70926236836be259ed217ee65c0 +F src/vdbe.c d9c63f5c5679f6e6c96612264b5674b8020696c4 F src/vdbe.h c06f0813f853566457ce9cfb1a4a4bc39a5da644 F src/vdbeInt.h 05fbda0e061dbc4aaa2709a8cccf3515c245b263 F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed @@ -1143,7 +1143,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P c07caabf2396c84b2ccb0e9f98ae6279ce41c59d -R d1a47818d75d4c09a9dcb48899bdd6d5 -U drh -Z 42f2f4c4e3d27d9172438c5ee2b1524f +P 6f91dca0de908dc2b15130a6593a61c3147a409f +R d3fc734a7145de0774dfe549644c265c +U dan +Z 32a0a7a512d388c26cfa54a9b929b27b diff --git a/manifest.uuid b/manifest.uuid index 50a66e6b11..ffa1d68526 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6f91dca0de908dc2b15130a6593a61c3147a409f \ No newline at end of file +8b12a15a2a8139d75f56a099f3f6af844da3ac9c \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 71e4d673c0..b402a5e6c0 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3510,38 +3510,28 @@ case OP_SeekGt: { /* jump, in3 */ pc = pOp->p2 - 1; break; } - /* If we reach this point, then the P3 value must be a floating - ** point number. */ - assert( (pIn3->flags & MEM_Real)!=0 ); - if( (iKey==SMALLEST_INT64 && pIn3->r<(double)iKey) - || (iKey==LARGEST_INT64 && pIn3->r>(double)iKey) - ){ - /* The P3 value is too large in magnitude to be expressed as an - ** integer. */ - res = 1; - if( pIn3->r<0 ){ - if( oc>=OP_SeekGe ){ assert( oc==OP_SeekGe || oc==OP_SeekGt ); - rc = sqlite3BtreeFirst(pC->pCursor, &res); - if( rc!=SQLITE_OK ) goto abort_due_to_error; - } - }else{ - if( oc<=OP_SeekLe ){ assert( oc==OP_SeekLt || oc==OP_SeekLe ); - rc = sqlite3BtreeLast(pC->pCursor, &res); - if( rc!=SQLITE_OK ) goto abort_due_to_error; - } - } - if( res ){ - pc = pOp->p2 - 1; - } - break; - }else if( oc==OP_SeekLt || oc==OP_SeekGe ){ - /* Use the ceiling() function to convert real->int */ - if( pIn3->r > (double)iKey ) iKey++; - }else{ - /* Use the floor() function to convert real->int */ - assert( oc==OP_SeekLe || oc==OP_SeekGt ); - if( pIn3->r < (double)iKey ) iKey--; + /* If the approximation iKey is larger than the actual real search + ** term, substitute >= for > and < for <=. e.g. if the search term + ** is 4.9 and the integer approximation 5: + ** + ** (x > 4.9) -> (x >= 5) + ** (x <= 4.9) -> (x < 5) + */ + if( pIn3->r<(double)iKey ){ + assert( OP_SeekGe==(OP_SeekGt-1) ); + assert( OP_SeekLt==(OP_SeekLe-1) ); + assert( (OP_SeekLe & 0x0001)==(OP_SeekGt & 0x0001) ); + if( (oc & 0x0001)==(OP_SeekGt & 0x0001) ) oc--; + } + + /* If the approximation iKey is smaller than the actual real search + ** term, substitute <= for < and > for >=. */ + else if( pIn3->r>(double)iKey ){ + assert( OP_SeekLe==(OP_SeekLt+1) ); + assert( OP_SeekGt==(OP_SeekGe+1) ); + assert( (OP_SeekLt & 0x0001)==(OP_SeekGe & 0x0001) ); + if( (oc & 0x0001)==(OP_SeekLt & 0x0001) ) oc++; } } rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)iKey, 0, &res); From 1bcbc6a6d493a2d12d636d47f451eb0575f8e6b0 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 26 Nov 2013 21:18:45 +0000 Subject: [PATCH 006/276] Changing the CAST behavior of REAL values actually changed a documented requirement. So we also have to change the requirement evidence text to match. FossilOrigin-Name: d84aa44e3919e25f9520c5120a35ec21e837a9ea --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/e_expr.test | 8 +++++--- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 30adfeecf2..3c8be252eb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Reduce\sthe\samount\sof\scode\sused\sto\simplement\sOP_SeekGe\sand\ssimilar. -D 2013-11-26T18:22:59.246 +C Changing\sthe\sCAST\sbehavior\sof\sREAL\svalues\sactually\schanged\sa\sdocumented\nrequirement.\s\sSo\swe\salso\shave\sto\schange\sthe\srequirement\sevidence\stext\sto\nmatch. +D 2013-11-26T21:18:45.278 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -437,7 +437,7 @@ F test/e_createtable.test 3b453432cd14a12732ee9467597d2274ca37ce36 F test/e_delete.test d5186e2f5478b659f16a2c8b66c09892823e542a F test/e_droptrigger.test 3cd080807622c13e5bbb61fc9a57bd7754da2412 F test/e_dropview.test 0c9f7f60989164a70a67a9d9c26d1083bc808306 -F test/e_expr.test 0808bc72c7b2a2fab4291418ecd73f4d09d7d671 +F test/e_expr.test 5cc73445ccac0fa6e16ef05ccb42021c8bdd0c0e F test/e_fkey.test d83a04478bb9c02d2c513518548a69f818869f41 F test/e_fts3.test 5c02288842e4f941896fd44afdef564dd5fc1459 F test/e_insert.test 1e44f84d2abe44d66e4fbf198be4b20e3cc724a0 @@ -1143,7 +1143,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 6f91dca0de908dc2b15130a6593a61c3147a409f -R d3fc734a7145de0774dfe549644c265c -U dan -Z 32a0a7a512d388c26cfa54a9b929b27b +P 8b12a15a2a8139d75f56a099f3f6af844da3ac9c +R 1c9b8ea37e158d8aa056f9d55c189c9f +U drh +Z 4aa8d025d1cf631a0e550b5e09b9ad22 diff --git a/manifest.uuid b/manifest.uuid index ffa1d68526..c276139572 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8b12a15a2a8139d75f56a099f3f6af844da3ac9c \ No newline at end of file +d84aa44e3919e25f9520c5120a35ec21e837a9ea \ No newline at end of file diff --git a/test/e_expr.test b/test/e_expr.test index eead6a2b93..0f55cb9ae3 100644 --- a/test/e_expr.test +++ b/test/e_expr.test @@ -1602,9 +1602,11 @@ do_expr_test e_expr-31.1.2 { CAST(1.99999 AS INTEGER) } integer 1 do_expr_test e_expr-31.1.3 { CAST(-1.99999 AS INTEGER) } integer -1 do_expr_test e_expr-31.1.4 { CAST(-0.99999 AS INTEGER) } integer 0 -# EVIDENCE-OF: R-49503-28105 If a REAL is too large to be represented as -# an INTEGER then the result of the cast is the largest negative -# integer: -9223372036854775808. +# EVIDENCE-OF: R-51517-40824 If a REAL is greater than the greatest +# possible signed integer (+9223372036854775807) then the result is the +# greatest possible signed integer and if the REAL is less than the +# least possible signed integer (-9223372036854775808) then the result +# is the least possible signed integer. # do_expr_test e_expr-31.2.1 { CAST(2e+50 AS INT) } integer 9223372036854775807 do_expr_test e_expr-31.2.2 { CAST(-2e+50 AS INT) } integer -9223372036854775808 From 2c7e9bfc5013769d1cd149909b1d687173cefd65 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 26 Nov 2013 22:46:54 +0000 Subject: [PATCH 007/276] Add requirements test cases for determining when an expression is true and when it is false. FossilOrigin-Name: 838654e56304a5788ac384ca506c1938f48af488 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/e_expr.test | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 3c8be252eb..1f5ab57756 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Changing\sthe\sCAST\sbehavior\sof\sREAL\svalues\sactually\schanged\sa\sdocumented\nrequirement.\s\sSo\swe\salso\shave\sto\schange\sthe\srequirement\sevidence\stext\sto\nmatch. -D 2013-11-26T21:18:45.278 +C Add\srequirements\stest\scases\sfor\sdetermining\swhen\san\sexpression\sis\strue\sand\nwhen\sit\sis\sfalse. +D 2013-11-26T22:46:54.424 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -437,7 +437,7 @@ F test/e_createtable.test 3b453432cd14a12732ee9467597d2274ca37ce36 F test/e_delete.test d5186e2f5478b659f16a2c8b66c09892823e542a F test/e_droptrigger.test 3cd080807622c13e5bbb61fc9a57bd7754da2412 F test/e_dropview.test 0c9f7f60989164a70a67a9d9c26d1083bc808306 -F test/e_expr.test 5cc73445ccac0fa6e16ef05ccb42021c8bdd0c0e +F test/e_expr.test a9f7c084ea3648003bcc40dd50861af5d2341fc1 F test/e_fkey.test d83a04478bb9c02d2c513518548a69f818869f41 F test/e_fts3.test 5c02288842e4f941896fd44afdef564dd5fc1459 F test/e_insert.test 1e44f84d2abe44d66e4fbf198be4b20e3cc724a0 @@ -1143,7 +1143,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 8b12a15a2a8139d75f56a099f3f6af844da3ac9c -R 1c9b8ea37e158d8aa056f9d55c189c9f +P d84aa44e3919e25f9520c5120a35ec21e837a9ea +R ceef359da24957280bf0acfc550c26b7 U drh -Z 4aa8d025d1cf631a0e550b5e09b9ad22 +Z 5bb7513aebd7acd760a2df9416ad20ba diff --git a/manifest.uuid b/manifest.uuid index c276139572..05481834be 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d84aa44e3919e25f9520c5120a35ec21e837a9ea \ No newline at end of file +838654e56304a5788ac384ca506c1938f48af488 \ No newline at end of file diff --git a/test/e_expr.test b/test/e_expr.test index 0f55cb9ae3..ea23a22d7f 100644 --- a/test/e_expr.test +++ b/test/e_expr.test @@ -1849,5 +1849,43 @@ foreach {tn expr} { do_expr_test e_expr-36.4.$tn $expr null {} } +# EVIDENCE-OF: R-62477-06476 For example, the values NULL, 0.0, 0, +# 'english' and '0' are all considered to be false. +# +do_execsql_test e_expr-37.1 { + SELECT CASE WHEN NULL THEN 'true' ELSE 'false' END; +} {false} +do_execsql_test e_expr-37.2 { + SELECT CASE WHEN 0.0 THEN 'true' ELSE 'false' END; +} {false} +do_execsql_test e_expr-37.3 { + SELECT CASE WHEN 0 THEN 'true' ELSE 'false' END; +} {false} +do_execsql_test e_expr-37.4 { + SELECT CASE WHEN 'engligh' THEN 'true' ELSE 'false' END; +} {false} +do_execsql_test e_expr-37.5 { + SELECT CASE WHEN '0' THEN 'true' ELSE 'false' END; +} {false} + +# EVIDENCE-OF: R-55532-10108 Values 1, 1.0, 0.1, -0.1 and '1english' are +# considered to be true. +# +do_execsql_test e_expr-37.6 { + SELECT CASE WHEN 1 THEN 'true' ELSE 'false' END; +} {true} +do_execsql_test e_expr-37.7 { + SELECT CASE WHEN 1.0 THEN 'true' ELSE 'false' END; +} {true} +do_execsql_test e_expr-37.8 { + SELECT CASE WHEN 0.1 THEN 'true' ELSE 'false' END; +} {true} +do_execsql_test e_expr-37.9 { + SELECT CASE WHEN -0.1 THEN 'true' ELSE 'false' END; +} {true} +do_execsql_test e_expr-37.10 { + SELECT CASE WHEN '1english' THEN 'true' ELSE 'false' END; +} {true} + finish_test From bbbb0e8053a82fabc371c32b2a95497378a7d72f Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 26 Nov 2013 23:27:07 +0000 Subject: [PATCH 008/276] Make sure the update hook is not invoked for WITHOUT ROWID tables, as the documentation specifies. This bug was found while adding requirements marks, so a few extraneous requirements marks are included in this check-in. FossilOrigin-Name: 0978bac6b8aee229d7a0d148546f50d380d06a06 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/resolve.c | 4 +++- src/vdbe.c | 13 ++----------- test/e_createtable.test | 8 ++++++++ test/hook.test | 16 ++++++++++++++++ 6 files changed, 39 insertions(+), 22 deletions(-) diff --git a/manifest b/manifest index 1f5ab57756..9ce618374e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\srequirements\stest\scases\sfor\sdetermining\swhen\san\sexpression\sis\strue\sand\nwhen\sit\sis\sfalse. -D 2013-11-26T22:46:54.424 +C Make\ssure\sthe\supdate\shook\sis\snot\sinvoked\sfor\sWITHOUT\sROWID\stables,\sas\nthe\sdocumentation\sspecifies.\s\sThis\sbug\swas\sfound\swhile\sadding\srequirements\nmarks,\sso\sa\sfew\sextraneous\srequirements\smarks\sare\sincluded\sin\sthis\ncheck-in. +D 2013-11-26T23:27:07.055 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -217,7 +217,7 @@ F src/pragma.c 5ab7279d132143feb77f773688a24ab05da75fd7 F src/prepare.c 359d1a1e9c9bd4488e4dd3a1aaaf2d2ebb9bb768 F src/printf.c da9119eb31a187a4b99f60aa4a225141c0ebb74b F src/random.c 0b2dbc37fdfbfa6bd455b091dfcef5bdb32dba68 -F src/resolve.c a70e32ae6ccb7b780f2b6d3e9e21837affc25ee5 +F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c d41381d80a22d3a83352aeca274cccf264ac277a F src/shell.c c4d06a9238a515ff4bc86b8626139633c09a00a2 @@ -280,7 +280,7 @@ F src/update.c c05a0ee658f1a149e0960dfd110f3b8bd846bcb0 F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c cbe054290f780fcd472b89d701c7404c51ec9684 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c d9c63f5c5679f6e6c96612264b5674b8020696c4 +F src/vdbe.c c2b3cd6baddb224a2f155e410ca69f74e6efc671 F src/vdbe.h c06f0813f853566457ce9cfb1a4a4bc39a5da644 F src/vdbeInt.h 05fbda0e061dbc4aaa2709a8cccf3515c245b263 F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed @@ -433,7 +433,7 @@ F test/descidx3.test 09ddbe3f5295f482d2f8b687cf6db8bad7acd9a2 F test/diskfull.test 106391384780753ea6896b7b4f005d10e9866b6e F test/distinct.test 44028aaf161a5e80a2f229622b3a174d3b352810 F test/distinctagg.test 1a6ef9c87a58669438fc771450d7a72577417376 -F test/e_createtable.test 3b453432cd14a12732ee9467597d2274ca37ce36 +F test/e_createtable.test a4561b93062e651d6def99c9e6956969dbf3754c F test/e_delete.test d5186e2f5478b659f16a2c8b66c09892823e542a F test/e_droptrigger.test 3cd080807622c13e5bbb61fc9a57bd7754da2412 F test/e_dropview.test 0c9f7f60989164a70a67a9d9c26d1083bc808306 @@ -587,7 +587,7 @@ F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26 F test/fuzzer1.test d4c52aaf3ef923da293a2653cfab33d02f718a36 F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536 F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98 -F test/hook.test 45cb22b940c3cc0af616ba7430f666e245711a48 +F test/hook.test 8b24a1a8a1ddf0883c6824825e7577f2636918dc F test/icu.test 70df4faca133254c042d02ae342c0a141f2663f4 F test/in.test 047c4671328e9032ab95666a67021adbbd36e98e F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75 @@ -1143,7 +1143,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P d84aa44e3919e25f9520c5120a35ec21e837a9ea -R ceef359da24957280bf0acfc550c26b7 +P 838654e56304a5788ac384ca506c1938f48af488 +R e178483a3ba4d2f533907e57553db5a6 U drh -Z 5bb7513aebd7acd760a2df9416ad20ba +Z 51c7e3abc8471c6679ba39e030a2dca2 diff --git a/manifest.uuid b/manifest.uuid index 05481834be..91c5fe5dfd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -838654e56304a5788ac384ca506c1938f48af488 \ No newline at end of file +0978bac6b8aee229d7a0d148546f50d380d06a06 \ No newline at end of file diff --git a/src/resolve.c b/src/resolve.c index 2c0907cc47..b0adb86295 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -352,7 +352,9 @@ static int lookupName( } } if( iCol>=pTab->nCol && sqlite3IsRowid(zCol) && HasRowid(pTab) ){ - iCol = -1; /* IMP: R-44911-55124 */ + /* IMP: R-24309-18625 */ + /* IMP: R-44911-55124 */ + iCol = -1; } if( iColnCol ){ cnt++; diff --git a/src/vdbe.c b/src/vdbe.c index b402a5e6c0..3b27ba144a 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -4109,20 +4109,11 @@ case OP_Delete: { i64 iKey; VdbeCursor *pC; - iKey = 0; assert( pOp->p1>=0 && pOp->p1nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); assert( pC->pCursor!=0 ); /* Only valid for real tables, no pseudotables */ - - /* If the update-hook will be invoked, set iKey to the rowid of the - ** row being deleted. - */ - if( db->xUpdateCallback && pOp->p4.z ){ - assert( pC->isTable ); - assert( pC->rowidIsValid ); /* lastRowid set by previous OP_NotFound */ - iKey = pC->lastRowid; - } + iKey = pC->lastRowid; /* Only used for the update hook */ /* The OP_Delete opcode always follows an OP_NotExists or OP_Last or ** OP_Column on the same table without any intervening operations that @@ -4140,7 +4131,7 @@ case OP_Delete: { pC->cacheStatus = CACHE_STALE; /* Invoke the update-hook if required. */ - if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){ + if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z && pC->isTable ){ const char *zDb = db->aDb[pC->iDb].zName; const char *zTbl = pOp->p4.z; db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, zTbl, iKey); diff --git a/test/e_createtable.test b/test/e_createtable.test index 8b57c73971..1c8ab7d86e 100644 --- a/test/e_createtable.test +++ b/test/e_createtable.test @@ -1654,6 +1654,10 @@ do_execsql_test 4.19.4 { SELECT * FROM t5 } {} # of the special case-independent names "rowid", "oid", or "_rowid_" in # place of a column name. # +# EVIDENCE-OF: R-06726-07466 A column name can be any of the names +# defined in the CREATE TABLE statement or one of the following special +# identifiers: "ROWID", "OID", or "_ROWID_". +# drop_all_tables do_execsql_test 5.1.0 { CREATE TABLE t1(x, y); @@ -1678,6 +1682,10 @@ do_createtable_tests 5.1 { # explicitly declared column and cannot be used to retrieve the integer # rowid value. # +# EVIDENCE-OF: R-44615-33286 The special identifiers only refer to the +# row key if the CREATE TABLE statement does not define a real column +# with the same name. +# do_execsql_test 5.2.0 { CREATE TABLE t2(oid, b); CREATE TABLE t3(a, _rowid_); diff --git a/test/hook.test b/test/hook.test index 6346cc77a7..a186da3aa7 100644 --- a/test/hook.test +++ b/test/hook.test @@ -135,9 +135,11 @@ do_test hook-4.1.1 { } execsql { CREATE TABLE t1(a INTEGER PRIMARY KEY, b); + CREATE TABLE t1w(a INT PRIMARY KEY, b) WITHOUT ROWID; INSERT INTO t1 VALUES(1, 'one'); INSERT INTO t1 VALUES(2, 'two'); INSERT INTO t1 VALUES(3, 'three'); + INSERT INTO t1w SELECT * FROM t1; } db update_hook [list lappend ::update_hook] } {} @@ -159,6 +161,20 @@ do_test hook-4.1.2 { DELETE main t1 4 \ ] +# EVIDENCE-OF: R-61808-14344 The sqlite3_update_hook() interface does +# not fire callbacks for changes to a WITHOUT ROWID table. +# +do_test hook-4.1.2w { + set ::update_hook {} + execsql { + INSERT INTO t1w VALUES(4, 'four'); + DELETE FROM t1w WHERE b = 'two'; + UPDATE t1w SET b = '' WHERE a = 1 OR a = 3; + DELETE FROM t1w WHERE 1; -- Avoid the truncate optimization (for now) + } + set ::update_hook +} {} + ifcapable trigger { # Update hook is not invoked for changes to sqlite_master # From ef1bd970ef1b54abd889af2dbe8a66a900697927 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 27 Nov 2013 00:45:49 +0000 Subject: [PATCH 009/276] Add additional test cases and requirements evidence marks for WITHOUT ROWID. FossilOrigin-Name: b408d788105efd007e3546f45d5dd15a5dc5688d --- manifest | 17 ++-- manifest.uuid | 2 +- test/hook.test | 36 ++++++- test/lastinsert.test | 11 +++ test/rowid.test | 4 +- test/without_rowid5.test | 201 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 259 insertions(+), 12 deletions(-) create mode 100644 test/without_rowid5.test diff --git a/manifest b/manifest index 9ce618374e..b545f7f91a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\sthe\supdate\shook\sis\snot\sinvoked\sfor\sWITHOUT\sROWID\stables,\sas\nthe\sdocumentation\sspecifies.\s\sThis\sbug\swas\sfound\swhile\sadding\srequirements\nmarks,\sso\sa\sfew\sextraneous\srequirements\smarks\sare\sincluded\sin\sthis\ncheck-in. -D 2013-11-26T23:27:07.055 +C Add\sadditional\stest\scases\sand\srequirements\sevidence\smarks\sfor\sWITHOUT\sROWID. +D 2013-11-27T00:45:49.889 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -587,7 +587,7 @@ F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26 F test/fuzzer1.test d4c52aaf3ef923da293a2653cfab33d02f718a36 F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536 F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98 -F test/hook.test 8b24a1a8a1ddf0883c6824825e7577f2636918dc +F test/hook.test 162d7cef7a2d2b04839fe14402934e6a1b79442f F test/icu.test 70df4faca133254c042d02ae342c0a141f2663f4 F test/in.test 047c4671328e9032ab95666a67021adbbd36e98e F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75 @@ -643,7 +643,7 @@ F test/jrnlmode.test 9ee3a78f53d52cca737db69293d15dc41c0cbd36 F test/jrnlmode2.test 81610545a4e6ed239ea8fa661891893385e23a1d F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa F test/keyword1.test a2400977a2e4fde43bf33754c2929fda34dbca05 -F test/lastinsert.test 474d519c68cb79d07ecae56a763aa7f322c72f51 +F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63 F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200 F test/like.test 935fb4f608e3ea126891496a6e99b9468372bf5c F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da @@ -756,7 +756,7 @@ F test/releasetest.tcl 06d289d8255794073a58d2850742f627924545ce F test/resolver01.test 33abf37ff8335e6bf98f2b45a0af3e06996ccd9a F test/rollback.test e9504a009a202c3ed711da2e6879ff60c5a4669c F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81 -F test/rowid.test f777404492adb0e00868fd706a3721328fd3af48 +F test/rowid.test b78b30afb9537a73788ca1233a23a32190a3bb1f F test/rtree.test 0c8d9dd458d6824e59683c19ab2ffa9ef946f798 F test/run-wordcount.sh 891e89c4c2d16e629cd45951d4ed899ad12afc09 F test/savepoint.test 6c53f76dffe5df0dd87646efe3e7aa159c36e07b @@ -1091,6 +1091,7 @@ F test/without_rowid1.test aaa26da19d543cd8d3d2d0e686dfa255556c15c8 F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99 F test/without_rowid3.test eac3d5c8a1924725b58503a368f2cbd24fd6c8a0 F test/without_rowid4.test 4e08bcbaee0399f35d58b5581881e7a6243d458a +F test/without_rowid5.test b4a639a367f04d382d20e8f44fc1be4f2d57d107 F test/wordcount.c 9915e06cb33d8ca8109b8700791afe80d305afda F test/zeroblob.test caaecfb4f908f7bc086ed238668049f96774d688 F test/zerodamage.test 209d7ed441f44cc5299e4ebffbef06fd5aabfefd @@ -1143,7 +1144,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 838654e56304a5788ac384ca506c1938f48af488 -R e178483a3ba4d2f533907e57553db5a6 +P 0978bac6b8aee229d7a0d148546f50d380d06a06 +R c5e238577bf88ba62aaf207d6ba68ed5 U drh -Z 51c7e3abc8471c6679ba39e030a2dca2 +Z 6729df1882fbf26a3a642e6e52bb3ce5 diff --git a/manifest.uuid b/manifest.uuid index 91c5fe5dfd..8320ba30fd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0978bac6b8aee229d7a0d148546f50d380d06a06 \ No newline at end of file +b408d788105efd007e3546f45d5dd15a5dc5688d \ No newline at end of file diff --git a/test/hook.test b/test/hook.test index a186da3aa7..de6fbdd254 100644 --- a/test/hook.test +++ b/test/hook.test @@ -127,23 +127,52 @@ db2 close # depopulation of indices, to make sure the update-hook is not # invoked incorrectly. # +# EVIDENCE-OF: R-21999-45122 The sqlite3_update_hook() interface +# registers a callback function with the database connection identified +# by the first argument to be invoked whenever a row is updated, +# inserted or deleted in a rowid table. # Simple tests -do_test hook-4.1.1 { +do_test hook-4.1.1a { catchsql { DROP TABLE t1; } + unset -nocomplain ::update_hook + set ::update_hook {} + db update_hook [list lappend ::update_hook] + # + # EVIDENCE-OF: R-52223-27275 The update hook is not invoked when + # internal system tables are modified (i.e. sqlite_master and + # sqlite_sequence). + # execsql { CREATE TABLE t1(a INTEGER PRIMARY KEY, b); CREATE TABLE t1w(a INT PRIMARY KEY, b) WITHOUT ROWID; + } + set ::update_hook +} {} +do_test hook-4.1.1b { + execsql { INSERT INTO t1 VALUES(1, 'one'); INSERT INTO t1 VALUES(2, 'two'); INSERT INTO t1 VALUES(3, 'three'); INSERT INTO t1w SELECT * FROM t1; } - db update_hook [list lappend ::update_hook] } {} + +# EVIDENCE-OF: R-15506-57666 The second callback argument is one of +# SQLITE_INSERT, SQLITE_DELETE, or SQLITE_UPDATE, depending on the +# operation that caused the callback to be invoked. +# +# EVIDENCE-OF: R-29213-61195 The third and fourth arguments to the +# callback contain pointers to the database and table name containing +# the affected row. +# +# EVIDENCE-OF: R-30809-57812 The final callback parameter is the rowid +# of the row. +# do_test hook-4.1.2 { + set ::update_hook {} execsql { INSERT INTO t1 VALUES(4, 'four'); DELETE FROM t1 WHERE b = 'two'; @@ -164,6 +193,9 @@ do_test hook-4.1.2 { # EVIDENCE-OF: R-61808-14344 The sqlite3_update_hook() interface does # not fire callbacks for changes to a WITHOUT ROWID table. # +# EVIDENCE-OF: R-33257-44249 The update hook is not invoked when WITHOUT +# ROWID tables are modified. +# do_test hook-4.1.2w { set ::update_hook {} execsql { diff --git a/test/lastinsert.test b/test/lastinsert.test index adeb79860b..c5bc267d1a 100644 --- a/test/lastinsert.test +++ b/test/lastinsert.test @@ -36,6 +36,17 @@ do_test lastinsert-1.1 { } } {0 3} +# EVIDENCE-OF: R-47220-63683 The sqlite3_last_insert_rowid() function +# does not work for WITHOUT ROWID tables. +# +do_test lastinsert-1.1w { + catchsql { + create table t1w (k integer primary key) WITHOUT ROWID; + insert into t1w values (123456); + select last_insert_rowid(); -- returns 3 from above. + } +} {0 3} + # LIRID unchanged after an update on a table do_test lastinsert-1.2 { catchsql { diff --git a/test/rowid.test b/test/rowid.test index 5daf581ea6..6d068d79bb 100644 --- a/test/rowid.test +++ b/test/rowid.test @@ -12,7 +12,9 @@ # focus of this file is testing the magic ROWID column that is # found on all tables. # -# $Id: rowid.test,v 1.21 2009/06/26 15:14:55 drh Exp $ +# EVIDENCE-OF: R-36924-43758 By default, every row in SQLite has a +# special column, usually called the "rowid", that uniquely identifies +# that row within the table. set testdir [file dirname $argv0] source $testdir/tester.tcl diff --git a/test/without_rowid5.test b/test/without_rowid5.test new file mode 100644 index 0000000000..45e047befe --- /dev/null +++ b/test/without_rowid5.test @@ -0,0 +1,201 @@ +# 2013-11-26 +# +# 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. +# +#*********************************************************************** +# +# Requirements testing for WITHOUT ROWID tables. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + + +# EVIDENCE-OF: R-36924-43758 By default, every row in SQLite has a +# special column, usually called the "rowid", that uniquely identifies +# that row within the table. +# +# EVIDENCE-OF: R-32341-39358 However if the phrase "WITHOUT ROWID" is +# added to the end of a CREATE TABLE statement, then the special "rowid" +# column is omitted. +# +do_execsql_test without_rowid5-1.1 { + CREATE TABLE t1(a PRIMARY KEY,b,c); + CREATE TABLE t1w(a PRIMARY KEY,b,c) WITHOUT ROWID; + INSERT INTO t1 VALUES(1565,681,1148),(1429,1190,1619),(425,358,1306); + INSERT INTO t1w SELECT a,b,c FROM t1; + SELECT rowid, _rowid_, oid FROM t1 ORDER BY a DESC; +} {1 1 1 2 2 2 3 3 3} +do_catchsql_test without_rowid5-1.2 { + SELECT rowid FROM t1w; +} {1 {no such column: rowid}} +do_catchsql_test without_rowid5-1.3 { + SELECT _rowid_ FROM t1w; +} {1 {no such column: _rowid_}} +do_catchsql_test without_rowid5-1.4 { + SELECT oid FROM t1w; +} {1 {no such column: oid}} + +# EVIDENCE-OF: R-00217-01605 To create a WITHOUT ROWID table, simply add +# the keywords "WITHOUT ROWID" to the end of the CREATE TABLE statement. +# For example: CREATE TABLE IF NOT EXISTS wordcount( word TEXT PRIMARY +# KEY, cnt INTEGER ) WITHOUT ROWID; +# +do_execsql_test without_rowid5-2.1 { + CREATE TABLE IF NOT EXISTS wordcount( + word TEXT PRIMARY KEY, + cnt INTEGER + ) WITHOUT ROWID; + INSERT INTO wordcount VALUES('one',1); +} {} +do_catchsql_test without_rowid5-2.2 { + SELECT rowid FROM wordcount; +} {1 {no such column: rowid}} + +# EVIDENCE-OF: R-24770-17719 As with all SQL syntax, the case of the +# keywords does not matter. One can write "WITHOUT rowid" or "without +# rowid" or "WiThOuT rOwId" and it will mean the same thing. +# +do_execsql_test without_rowid5-2.3 { + CREATE TABLE IF NOT EXISTS wordcount_b( + word TEXT PRIMARY KEY, + cnt INTEGER + ) WITHOUT rowid; + INSERT INTO wordcount_b VALUES('one',1); +} {} +do_catchsql_test without_rowid5-2.4 { + SELECT rowid FROM wordcount_b; +} {1 {no such column: rowid}} +do_execsql_test without_rowid5-2.5 { + CREATE TABLE IF NOT EXISTS wordcount_c( + word TEXT PRIMARY KEY, + cnt INTEGER + ) without rowid; + INSERT INTO wordcount_c VALUES('one',1); +} {} +do_catchsql_test without_rowid5-2.6 { + SELECT rowid FROM wordcount_c; +} {1 {no such column: rowid}} +do_execsql_test without_rowid5-2.7 { + CREATE TABLE IF NOT EXISTS wordcount_d( + word TEXT PRIMARY KEY, + cnt INTEGER + ) WITHOUT rowid; + INSERT INTO wordcount_d VALUES('one',1); +} {} +do_catchsql_test without_rowid5-2.8 { + SELECT rowid FROM wordcount_d; +} {1 {no such column: rowid}} + +# EVIDENCE-OF: R-01418-51310 However, only "rowid" works as the keyword +# in the CREATE TABLE statement. +# +do_catchsql_test without_rowid5-3.1 { + CREATE TABLE IF NOT EXISTS error1( + word TEXT PRIMARY KEY, + cnt INTEGER + ) WITHOUT _rowid_; +} {1 {unknown table option: _rowid_}} +do_catchsql_test without_rowid5-3.2 { + CREATE TABLE IF NOT EXISTS error2( + word TEXT PRIMARY KEY, + cnt INTEGER + ) WITHOUT oid; +} {1 {unknown table option: oid}} + +# EVIDENCE-OF: R-58033-17334 An error is raised if a CREATE TABLE +# statement with the WITHOUT ROWID clause lacks a PRIMARY KEY. +# +# EVIDENCE-OF: R-63443-09418 Every WITHOUT ROWID table must have a +# PRIMARY KEY. +# +# EVIDENCE-OF: R-27966-31616 An attempt to create a WITHOUT ROWID table +# without a PRIMARY KEY results in an error. +# +do_catchsql_test without_rowid5-4.1 { + CREATE TABLE IF NOT EXISTS error3( + word TEXT UNIQUE, + cnt INTEGER + ) WITHOUT ROWID; +} {1 {PRIMARY KEY missing on table error3}} + +# EVIDENCE-OF: R-48230-36247 The special behaviors associated "INTEGER +# PRIMARY KEY" do not apply on WITHOUT ROWID tables. +# +do_execsql_test without_rowid5-5.1 { + CREATE TABLE ipk(key INTEGER PRIMARY KEY, val TEXT) WITHOUT ROWID; + INSERT INTO ipk VALUES('rival','bonus'); -- ok to insert non-integer key + SELECT * FROM ipk; +} {rival bonus} +do_catchsql_test without_rowid5-5.2 { + INSERT INTO ipk VALUES(NULL,'sample'); -- no automatic generation of keys +} {1 {NOT NULL constraint failed: ipk.key}} + +# EVIDENCE-OF: R-33142-02092 AUTOINCREMENT does not work on WITHOUT +# ROWID tables. +# +# EVIDENCE-OF: R-53084-07740 An error is raised if the "AUTOINCREMENT" +# keyword is used in the CREATE TABLE statement for a WITHOUT ROWID +# table. +# +do_catchsql_test without_rowid5-5.3 { + CREATE TABLE ipk2(key INTEGER PRIMARY KEY AUTOINCREMENT, val TEXT)WITHOUT ROWID; +} {1 {AUTOINCREMENT not allowed on WITHOUT ROWID tables}} + +# EVIDENCE-OF: R-27831-00579 NOT NULL is enforced on every column of the +# PRIMARY KEY in a WITHOUT ROWID table. +# +# EVIDENCE-OF: R-29781-51289 So, ordinary rowid tables in SQLite violate +# the SQL standard and allow NULL values in PRIMARY KEY fields. +# +# EVIDENCE-OF: R-27472-62612 But WITHOUT ROWID tables do follow the +# standard and will throw an error on any attempt to insert a NULL into +# a PRIMARY KEY column. +# +do_execsql_test without_rowid5-5.4 { + CREATE TABLE nn(a, b, c, d, e, PRIMARY KEY(c,a,e)); + CREATE TABLE nnw(a, b, c, d, e, PRIMARY KEY(c,a,e)) WITHOUT ROWID; + INSERT INTO nn VALUES(1,2,3,4,5); + INSERT INTO nnw VALUES(1,2,3,4,5); +} {} +do_execsql_test without_rowid5-5.5 { + INSERT INTO nn VALUES(NULL, 3,4,5,6); + INSERT INTO nn VALUES(3,4,NULL,7,8); + INSERT INTO nn VALUES(4,5,6,7,NULL); + SELECT count(*) FROM nn; +} {4} +do_catchsql_test without_rowid5-5.6 { + INSERT INTO nnw VALUES(NULL, 3,4,5,6); +} {1 {NOT NULL constraint failed: nnw.a}} +do_catchsql_test without_rowid5-5.7 { + INSERT INTO nnw VALUES(3,4,NULL,7,8) +} {1 {NOT NULL constraint failed: nnw.c}} +do_catchsql_test without_rowid5-5.8 { + INSERT INTO nnw VALUES(4,5,6,7,NULL) +} {1 {NOT NULL constraint failed: nnw.e}} +do_execsql_test without_rowid5-5.9 { + SELECT count(*) FROM nnw; +} {1} + +# EVIDENCE-OF: R-12643-30541 The incremental blob I/O mechanism does not +# work for WITHOUT ROWID tables. +# +# EVIDENCE-OF: R-25760-33257 The sqlite3_blob_open() interface will fail +# for a WITHOUT ROWID table. +# +do_execsql_test without_rowid5-6.1 { + CREATE TABLE b1(a INTEGER PRIMARY KEY, b BLOB) WITHOUT ROWID; + INSERT INTO b1 VALUES(1,x'0102030405060708090a0b0c0d0e0f'); +} {} +do_test without_rowid5-6.2 { + set rc [catch {db incrblob b1 b 1} msg] + lappend rc $msg +} {1 {cannot open table without rowid: b1}} + + +finish_test From 21236679d15fd11ebd78b5cbfd7eca66a72f3a29 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 27 Nov 2013 01:23:53 +0000 Subject: [PATCH 010/276] Add additional test cases for skip-scan. FossilOrigin-Name: 1ae4915d4d08ee5ce526c04d1d0cda1078641793 --- manifest | 11 ++-- manifest.uuid | 2 +- test/skipscan2.test | 150 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 157 insertions(+), 6 deletions(-) create mode 100644 test/skipscan2.test diff --git a/manifest b/manifest index b545f7f91a..f3db92f644 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sadditional\stest\scases\sand\srequirements\sevidence\smarks\sfor\sWITHOUT\sROWID. -D 2013-11-27T00:45:49.889 +C Add\sadditional\stest\scases\sfor\sskip-scan. +D 2013-11-27T01:23:53.318 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -808,6 +808,7 @@ F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3 F test/shrink.test 8c70f62b6e8eb4d54533de6d65bd06b1b9a17868 F test/sidedelete.test f0ad71abe6233e3b153100f3b8d679b19a488329 F test/skipscan1.test 6bb4891c2cc5efd5690a9da9e7508e53d4a68e10 +F test/skipscan2.test c1e21a19ec8fa3674e9ccd0475f20ef82c275838 F test/soak.test 0b5b6375c9f4110c828070b826b3b4b0bb65cd5f F test/softheap1.test 40562fe6cac6d9827b7b42b86d45aedf12c15e24 F test/sort.test 0e4456e729e5a92a625907c63dcdedfbe72c5dc5 @@ -1144,7 +1145,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 0978bac6b8aee229d7a0d148546f50d380d06a06 -R c5e238577bf88ba62aaf207d6ba68ed5 +P b408d788105efd007e3546f45d5dd15a5dc5688d +R d4fd41c1f94c9f73ab9606b0e58d8a6b U drh -Z 6729df1882fbf26a3a642e6e52bb3ce5 +Z 5fe0b4019eaac7439aed9d81168a0a2a diff --git a/manifest.uuid b/manifest.uuid index 8320ba30fd..74f91dc909 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b408d788105efd007e3546f45d5dd15a5dc5688d \ No newline at end of file +1ae4915d4d08ee5ce526c04d1d0cda1078641793 \ No newline at end of file diff --git a/test/skipscan2.test b/test/skipscan2.test new file mode 100644 index 0000000000..3858ed5e07 --- /dev/null +++ b/test/skipscan2.test @@ -0,0 +1,150 @@ +# 2013-11-27 +# +# 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 tests of the "skip-scan" query strategy. +# +# The test cases in this file are derived from the description of +# the skip-scan query strategy in the "optoverview.html" document. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +do_execsql_test skipscan2-1.1 { + CREATE TABLE people( + name TEXT PRIMARY KEY, + role TEXT NOT NULL, + height INT NOT NULL, -- in cm + CHECK( role IN ('student','teacher') ) + ); + CREATE INDEX people_idx1 ON people(role, height); +} {} +do_execsql_test skipscan2-1.2 { + INSERT INTO people VALUES('Alice','student',156); + INSERT INTO people VALUES('Bob','student',161); + INSERT INTO people VALUES('Cindy','student',155); + INSERT INTO people VALUES('David','student',181); + INSERT INTO people VALUES('Emily','teacher',158); + INSERT INTO people VALUES('Fred','student',163); + INSERT INTO people VALUES('Ginny','student',169); + INSERT INTO people VALUES('Harold','student',172); + INSERT INTO people VALUES('Imma','student',179); + INSERT INTO people VALUES('Jack','student',181); + INSERT INTO people VALUES('Karen','student',163); + INSERT INTO people VALUES('Logan','student',177); + INSERT INTO people VALUES('Megan','teacher',159); + INSERT INTO people VALUES('Nathan','student',163); + INSERT INTO people VALUES('Olivia','student',161); + INSERT INTO people VALUES('Patrick','teacher',180); + INSERT INTO people VALUES('Quiana','student',182); + INSERT INTO people VALUES('Robert','student',159); + INSERT INTO people VALUES('Sally','student',166); + INSERT INTO people VALUES('Tom','student',171); + INSERT INTO people VALUES('Ursula','student',170); + INSERT INTO people VALUES('Vance','student',179); + INSERT INTO people VALUES('Willma','student',175); + INSERT INTO people VALUES('Xavier','teacher',185); + INSERT INTO people VALUES('Yvonne','student',149); + INSERT INTO people VALUES('Zach','student',170); +} + +# Without ANALYZE, a skip-scan is not used +# +do_execsql_test skipscan2-1.3 { + SELECT name FROM people WHERE height>=180 ORDER BY +name; +} {David Jack Patrick Quiana Xavier} +do_execsql_test skipscan2-1.3eqp { + EXPLAIN QUERY PLAN + SELECT name FROM people WHERE height>=180 ORDER BY +name; +} {~/*INDEX people_idx1 */} + +# Now do an ANALYZE. A skip-scan can be used after ANALYZE. +# +do_execsql_test skipscan2-1.4 { + ANALYZE; + -- We do not have enough people above to actually force the use + -- of a skip-scan. So make a manual adjustment to the stat1 table + -- to make it seem like there are many more. + UPDATE sqlite_stat1 SET stat='10000 5000 20' WHERE idx='people_idx1'; + ANALYZE sqlite_master; +} +db cache flush +do_execsql_test skipscan2-1.5 { + SELECT name FROM people WHERE height>=180 ORDER BY +name; +} {David Jack Patrick Quiana Xavier} +do_execsql_test skipscan2-1.5eqp { + EXPLAIN QUERY PLAN + SELECT name FROM people WHERE height>=180 ORDER BY +name; +} {/*INDEX people_idx1 */} + +# Same answer with other formulations of the same query +# +do_execsql_test skipscan2-1.6 { + SELECT name FROM people + WHERE role IN (SELECT DISTINCT role FROM people) + AND height>=180 ORDER BY +name; +} {David Jack Patrick Quiana Xavier} +do_execsql_test skipscan2-1.7 { + SELECT name FROM people WHERE role='teacher' AND height>=180 + UNION ALL + SELECT name FROM people WHERE role='student' AND height>=180 + ORDER BY 1; +} {David Jack Patrick Quiana Xavier} + +# Repeat using a WITHOUT ROWID table. +# +do_execsql_test skipscan2-2.1 { + CREATE TABLE peoplew( + name TEXT PRIMARY KEY, + role TEXT NOT NULL, + height INT NOT NULL, -- in cm + CHECK( role IN ('student','teacher') ) + ) WITHOUT ROWID; + CREATE INDEX peoplew_idx1 ON peoplew(role, height); + INSERT INTO peoplew(name,role,height) + SELECT name, role, height FROM people; + DROP TABLE people; + SELECT name FROM peoplew WHERE height>=180 ORDER BY +name; +} {David Jack Patrick Quiana Xavier} +do_execsql_test skipscan2-2.2 { + SELECT name FROM peoplew + WHERE role IN (SELECT DISTINCT role FROM peoplew) + AND height>=180 ORDER BY +name; +} {David Jack Patrick Quiana Xavier} +do_execsql_test skipscan2-2.2 { + SELECT name FROM peoplew WHERE role='teacher' AND height>=180 + UNION ALL + SELECT name FROM peoplew WHERE role='student' AND height>=180 + ORDER BY 1; +} {David Jack Patrick Quiana Xavier} + +# Now do an ANALYZE. A skip-scan can be used after ANALYZE. +# +do_execsql_test skipscan2-2.4 { + ANALYZE; + -- We do not have enough people above to actually force the use + -- of a skip-scan. So make a manual adjustment to the stat1 table + -- to make it seem like there are many more. + UPDATE sqlite_stat1 SET stat='10000 5000 20' WHERE idx='peoplew_idx1'; + ANALYZE sqlite_master; +} +db cache flush +do_execsql_test skipscan2-2.5 { + SELECT name FROM peoplew WHERE height>=180 ORDER BY +name; +} {David Jack Patrick Quiana Xavier} +do_execsql_test skipscan2-2.5eqp { + EXPLAIN QUERY PLAN + SELECT name FROM peoplew WHERE height>=180 ORDER BY +name; +} {/*INDEX peoplew_idx1 */} + + + +finish_test From 0f7e08e0e2b57236d1b2d94f20c66971004d6032 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Wed, 27 Nov 2013 03:01:34 +0000 Subject: [PATCH 011/276] Avoid using the GetVersionEx functions if they are considered deprecated. FossilOrigin-Name: 0ea9e4722be10221c99cce5bc48d13c7b34e739f --- manifest | 17 ++++++++++------- manifest.uuid | 2 +- src/os_win.c | 41 +++++++++++++++++++++++++++++++++++------ 3 files changed, 46 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index f3db92f644..16c9cab3ac 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sadditional\stest\scases\sfor\sskip-scan. -D 2013-11-27T01:23:53.318 +C Avoid\susing\sthe\sGetVersionEx\sfunctions\sif\sthey\sare\sconsidered\sdeprecated. +D 2013-11-27T03:01:34.176 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -206,7 +206,7 @@ F src/os.c b4ad71336fd96f97776f75587cd9e8218288f5be F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_unix.c 143624d9eabb3b997c59cf594e0d06c56edd43e9 -F src/os_win.c cb3f26205ea785a63ea5bdc21a9c9f9ae3972d0f +F src/os_win.c 4323dd0bac4f7a7037fc4cf87fb4692d17f0b108 F src/pager.c 2aa4444ffe86e9282d03bc349a4a5e49bd77c0e8 F src/pager.h f094af9f6ececfaa8a1e93876905a4f34233fb0c F src/parse.y acee1a9958539e21263362b194594c5255ad2fca @@ -1145,7 +1145,10 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P b408d788105efd007e3546f45d5dd15a5dc5688d -R d4fd41c1f94c9f73ab9606b0e58d8a6b -U drh -Z 5fe0b4019eaac7439aed9d81168a0a2a +P 1ae4915d4d08ee5ce526c04d1d0cda1078641793 +R 1408bb35546f8304605f0cd70b3a2cef +T *branch * vs2013 +T *sym-vs2013 * +T -sym-trunk * +U mistachkin +Z f9b9e39c0c1855e6c7f8a373135be4dd diff --git a/manifest.uuid b/manifest.uuid index 74f91dc909..ed05f28047 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1ae4915d4d08ee5ce526c04d1d0cda1078641793 \ No newline at end of file +0ea9e4722be10221c99cce5bc48d13c7b34e739f \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index 31c4b69df0..22052a3fe7 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -59,6 +59,34 @@ must be defined." #endif +/* +** Define the required Windows SDK version constants if they are not +** already available. +*/ +#ifndef NTDDI_WIN8 +# define NTDDI_WIN8 0x06020000 +#endif + +#ifndef NTDDI_WINBLUE +# define NTDDI_WINBLUE 0x06030000 +#endif + +/* +** Check if the GetVersionEx[AW] functions should be considered deprecated +** and avoid using them in that case. It should be noted here that if the +** value of the SQLITE_WIN32_GETVERSIONEX pre-processor macro is zero +** (whether via this block or via being manually specified), that implies +** the underlying operating system will always be based on the Windows NT +** Kernel. +*/ +#ifndef SQLITE_WIN32_GETVERSIONEX +# if defined(NTDDI_VERSION) && NTDDI_VERSION >= NTDDI_WINBLUE +# define SQLITE_WIN32_GETVERSIONEX 0 +# else +# define SQLITE_WIN32_GETVERSIONEX 1 +# endif +#endif + /* ** This constant should already be defined (in the "WinDef.h" SDK file). */ @@ -694,7 +722,8 @@ static struct win_syscall { #define osGetTickCount ((DWORD(WINAPI*)(VOID))aSyscall[33].pCurrent) -#if defined(SQLITE_WIN32_HAS_ANSI) +#if defined(SQLITE_WIN32_HAS_ANSI) && defined(SQLITE_WIN32_GETVERSIONEX) && \ + SQLITE_WIN32_GETVERSIONEX { "GetVersionExA", (SYSCALL)GetVersionExA, 0 }, #else { "GetVersionExA", (SYSCALL)0, 0 }, @@ -703,7 +732,8 @@ static struct win_syscall { #define osGetVersionExA ((BOOL(WINAPI*)( \ LPOSVERSIONINFOA))aSyscall[34].pCurrent) -#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) +#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \ + defined(SQLITE_WIN32_GETVERSIONEX) && SQLITE_WIN32_GETVERSIONEX { "GetVersionExW", (SYSCALL)GetVersionExW, 0 }, #else { "GetVersionExW", (SYSCALL)0, 0 }, @@ -1260,11 +1290,10 @@ void sqlite3_win32_sleep(DWORD milliseconds){ ** WinNT/2K/XP so that we will know whether or not we can safely call ** the LockFileEx() API. */ -#ifndef NTDDI_WIN8 -# define NTDDI_WIN8 0x06020000 -#endif -#if SQLITE_OS_WINCE || SQLITE_OS_WINRT || !defined(SQLITE_WIN32_HAS_ANSI) +#if !defined(SQLITE_WIN32_GETVERSIONEX) || !SQLITE_WIN32_GETVERSIONEX +# define osIsNT() (1) +#elif SQLITE_OS_WINCE || SQLITE_OS_WINRT || !defined(SQLITE_WIN32_HAS_ANSI) # define osIsNT() (1) #elif !defined(SQLITE_WIN32_HAS_WIDE) # define osIsNT() (0) From c964c39fb02e9495ae3783f79865aae5df0d487d Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 27 Nov 2013 04:22:27 +0000 Subject: [PATCH 012/276] Lower the threshold for using skip-scan from 50 to 18, based on experiments that show that 18 is the approximate break-even point for a variety of schemas. FossilOrigin-Name: 83c0bb9913838d18ba355033afde6e38b4690842 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 6 ++++-- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 4d6b73bdbd..2854113f03 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\susing\sthe\sGetVersionEx\sfunctions\sif\sthey\sare\sconsidered\sdeprecated. -D 2013-11-27T04:00:32.164 +C Lower\sthe\sthreshold\sfor\susing\sskip-scan\sfrom\s50\sto\s18,\sbased\son\sexperiments\nthat\sshow\sthat\s18\sis\sthe\sapproximate\sbreak-even\spoint\sfor\sa\svariety\sof\nschemas. +D 2013-11-27T04:22:27.199 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -293,7 +293,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c e9e593d5bb798c3e67fc3893dfe7055c9e7d8d74 -F src/where.c e558bfa67009ab7de08a7a1960ae0dd443241cdd +F src/where.c e0a9909a58eee7dcde1d1bd5cf6381b0dbc83389 F src/whereInt.h 96a75c61f1d2b9d4a8e4bb17d89deb0cf7cba358 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1145,7 +1145,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 1ae4915d4d08ee5ce526c04d1d0cda1078641793 0ea9e4722be10221c99cce5bc48d13c7b34e739f -R 1408bb35546f8304605f0cd70b3a2cef -U mistachkin -Z 11a83dbec42d946c53dc2adfcd9de746 +P afdca29966805ed0d49fd61a161eb3a3919b5963 +R 7f77bcc3aede19c7431a578762bf35fa +U drh +Z 4656cf413e484f30bbac5ec324b067a0 diff --git a/manifest.uuid b/manifest.uuid index 5dcbdd9cc3..ad77d07941 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -afdca29966805ed0d49fd61a161eb3a3919b5963 \ No newline at end of file +83c0bb9913838d18ba355033afde6e38b4690842 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 101ca1a7c6..7ec6cfaae7 100644 --- a/src/where.c +++ b/src/where.c @@ -3921,12 +3921,14 @@ static int whereLoopAddBtreeIndex( /* Consider using a skip-scan if there are no WHERE clause constraints ** available for the left-most terms of the index, and if the average - ** number of repeats in the left-most terms is at least 50. + ** number of repeats in the left-most terms is at least 18. The magic + ** number 18 was found by experimentation to be the payoff point where + ** skip-scan become faster than a full-scan. */ if( pTerm==0 && saved_nEq==saved_nSkip && saved_nEq+1nKeyCol - && pProbe->aiRowEst[saved_nEq+1]>50 /* TUNING: Minimum for skip-scan */ + && pProbe->aiRowEst[saved_nEq+1]>=18 /* TUNING: Minimum for skip-scan */ ){ LogEst nIter; pNew->u.btree.nEq++; From ac68ced162f6e29ce1fc0fa15b0c0ef1b67b0c83 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 27 Nov 2013 13:24:18 +0000 Subject: [PATCH 013/276] Make sure the colWidth array is correctly initialized in the ".explain" command of the shell. FossilOrigin-Name: ceebcdcaf1acf409b77b4cc2903b4570001f098a --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 2854113f03..9d807e7a96 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Lower\sthe\sthreshold\sfor\susing\sskip-scan\sfrom\s50\sto\s18,\sbased\son\sexperiments\nthat\sshow\sthat\s18\sis\sthe\sapproximate\sbreak-even\spoint\sfor\sa\svariety\sof\nschemas. -D 2013-11-27T04:22:27.199 +C Make\ssure\sthe\scolWidth\sarray\sis\scorrectly\sinitialized\sin\sthe\s".explain"\ncommand\sof\sthe\sshell. +D 2013-11-27T13:24:18.470 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -220,7 +220,7 @@ F src/random.c 0b2dbc37fdfbfa6bd455b091dfcef5bdb32dba68 F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c d41381d80a22d3a83352aeca274cccf264ac277a -F src/shell.c c4d06a9238a515ff4bc86b8626139633c09a00a2 +F src/shell.c 936a72ff784efff3832cce274a96ed0b036e6758 F src/sqlite.h.in a8328969be639b6cd8d9225ed2a51d9d624fff5f F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc @@ -1145,7 +1145,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P afdca29966805ed0d49fd61a161eb3a3919b5963 -R 7f77bcc3aede19c7431a578762bf35fa +P 83c0bb9913838d18ba355033afde6e38b4690842 +R 67ef9465051c6a15a8474ed69b1e156e U drh -Z 4656cf413e484f30bbac5ec324b067a0 +Z 9742934aff6856eb16d7b29615a17978 diff --git a/manifest.uuid b/manifest.uuid index ad77d07941..1f8d47bbde 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -83c0bb9913838d18ba355033afde6e38b4690842 \ No newline at end of file +ceebcdcaf1acf409b77b4cc2903b4570001f098a \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 1db1e64e7e..480ec5b455 100644 --- a/src/shell.c +++ b/src/shell.c @@ -2096,7 +2096,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){ */ p->mode = MODE_Explain; p->showHeader = 1; - memset(p->colWidth,0,ArraySize(p->colWidth)); + memset(p->colWidth,0,sizeof(p->colWidth)); p->colWidth[0] = 4; /* addr */ p->colWidth[1] = 13; /* opcode */ p->colWidth[2] = 4; /* P1 */ From ce00a8378511791f557b19b35f780c9b7924b3f9 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 27 Nov 2013 13:48:02 +0000 Subject: [PATCH 014/276] Additional test cases for skip-scan. FossilOrigin-Name: ce70803f5e1bfb4dc495d3a0c2ddd5ee6c3a10fe --- manifest | 12 +++++------ manifest.uuid | 2 +- test/skipscan2.test | 52 +++++++++++++++++++++++++++++++++++++++------ 3 files changed, 53 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 9d807e7a96..1f661d4044 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\sthe\scolWidth\sarray\sis\scorrectly\sinitialized\sin\sthe\s".explain"\ncommand\sof\sthe\sshell. -D 2013-11-27T13:24:18.470 +C Additional\stest\scases\sfor\sskip-scan. +D 2013-11-27T13:48:02.795 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -808,7 +808,7 @@ F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3 F test/shrink.test 8c70f62b6e8eb4d54533de6d65bd06b1b9a17868 F test/sidedelete.test f0ad71abe6233e3b153100f3b8d679b19a488329 F test/skipscan1.test 6bb4891c2cc5efd5690a9da9e7508e53d4a68e10 -F test/skipscan2.test c1e21a19ec8fa3674e9ccd0475f20ef82c275838 +F test/skipscan2.test 5a4db0799c338ddbacb154aaa5589c0254b36a8d F test/soak.test 0b5b6375c9f4110c828070b826b3b4b0bb65cd5f F test/softheap1.test 40562fe6cac6d9827b7b42b86d45aedf12c15e24 F test/sort.test 0e4456e729e5a92a625907c63dcdedfbe72c5dc5 @@ -1145,7 +1145,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 83c0bb9913838d18ba355033afde6e38b4690842 -R 67ef9465051c6a15a8474ed69b1e156e +P ceebcdcaf1acf409b77b4cc2903b4570001f098a +R bcfcf6f48c85e4fa706276f8ed169192 U drh -Z 9742934aff6856eb16d7b29615a17978 +Z 88c6067bf128a26cfad7d97b15ea7137 diff --git a/manifest.uuid b/manifest.uuid index 1f8d47bbde..eb9f0afe6d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ceebcdcaf1acf409b77b4cc2903b4570001f098a \ No newline at end of file +ce70803f5e1bfb4dc495d3a0c2ddd5ee6c3a10fe \ No newline at end of file diff --git a/test/skipscan2.test b/test/skipscan2.test index 3858ed5e07..e39b16ed27 100644 --- a/test/skipscan2.test +++ b/test/skipscan2.test @@ -99,6 +99,51 @@ do_execsql_test skipscan2-1.7 { ORDER BY 1; } {David Jack Patrick Quiana Xavier} +# Add 8 more people, bringing the total to 34. Then the number of +# duplicates in the left-column of the index will be 17 and +# skip-scan should not be used after an (unfudged) ANALYZE. +# +do_execsql_test skipscan2-1.8 { + INSERT INTO people VALUES('Angie','student',166); + INSERT INTO people VALUES('Brad','student',176); + INSERT INTO people VALUES('Claire','student',168); + INSERT INTO people VALUES('Donald','student',162); + INSERT INTO people VALUES('Elaine','student',177); + INSERT INTO people VALUES('Frazier','student',159); + INSERT INTO people VALUES('Grace','student',179); + INSERT INTO people VALUES('Horace','student',166); + ANALYZE; + SELECT stat FROM sqlite_stat1 WHERE idx='people_idx1'; +} {{34 17 2}} +db cache flush +do_execsql_test skipscan2-1.9 { + SELECT name FROM people WHERE height>=180 ORDER BY +name; +} {David Jack Patrick Quiana Xavier} +do_execsql_test skipscan2-1.9eqp { + EXPLAIN QUERY PLAN + SELECT name FROM people WHERE height>=180 ORDER BY +name; +} {~/*INDEX people_idx1 */} + +# Add 2 more people, bringing the total to 36. Then the number of +# duplicates in the left-column of the index will be 18 and +# skip-scan will be used after an (unfudged) ANALYZE. +# +do_execsql_test skipscan2-1.10 { + INSERT INTO people VALUES('Ingrad','student',155); + INSERT INTO people VALUES('Jacob','student',179); + ANALYZE; + SELECT stat FROM sqlite_stat1 WHERE idx='people_idx1'; +} {{36 18 2}} +db cache flush +do_execsql_test skipscan2-1.11 { + SELECT name FROM people WHERE height>=180 ORDER BY +name; +} {David Jack Patrick Quiana Xavier} +do_execsql_test skipscan2-1.11eqp { + EXPLAIN QUERY PLAN + SELECT name FROM people WHERE height>=180 ORDER BY +name; +} {/*INDEX people_idx1 */} + + # Repeat using a WITHOUT ROWID table. # do_execsql_test skipscan2-2.1 { @@ -111,7 +156,7 @@ do_execsql_test skipscan2-2.1 { CREATE INDEX peoplew_idx1 ON peoplew(role, height); INSERT INTO peoplew(name,role,height) SELECT name, role, height FROM people; - DROP TABLE people; + ALTER TABLE people RENAME TO old_people; SELECT name FROM peoplew WHERE height>=180 ORDER BY +name; } {David Jack Patrick Quiana Xavier} do_execsql_test skipscan2-2.2 { @@ -130,11 +175,6 @@ do_execsql_test skipscan2-2.2 { # do_execsql_test skipscan2-2.4 { ANALYZE; - -- We do not have enough people above to actually force the use - -- of a skip-scan. So make a manual adjustment to the stat1 table - -- to make it seem like there are many more. - UPDATE sqlite_stat1 SET stat='10000 5000 20' WHERE idx='peoplew_idx1'; - ANALYZE sqlite_master; } db cache flush do_execsql_test skipscan2-2.5 { From dcb5fa06e8f2c05f3f0ffe3b6a876d33ca612c68 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 27 Nov 2013 14:50:51 +0000 Subject: [PATCH 015/276] Fix some harmless compiler warnings in speedtest1.exe. FossilOrigin-Name: c75f561f337a56c14335366ed9990e44bc9fc594 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/speedtest1.c | 8 ++++---- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 1f661d4044..d5cd277511 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Additional\stest\scases\sfor\sskip-scan. -D 2013-11-27T13:48:02.795 +C Fix\ssome\sharmless\scompiler\swarnings\sin\sspeedtest1.exe. +D 2013-11-27T14:50:51.106 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -820,7 +820,7 @@ F test/speed3.test d32043614c08c53eafdc80f33191d5bd9b920523 F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b -F test/speedtest1.c aa08ae8e3591bf5c028be9396a84237640761d8c +F test/speedtest1.c 39921e422974a0330f3efde03797795947e648b2 F test/spellfix.test 8c40b169b104086d8795781f670ba3c786d6d8be F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298 F test/stat.test c8eccfe8fcd3f3cfc864ce22d5b9e803a3c69940 @@ -1145,7 +1145,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P ceebcdcaf1acf409b77b4cc2903b4570001f098a -R bcfcf6f48c85e4fa706276f8ed169192 +P ce70803f5e1bfb4dc495d3a0c2ddd5ee6c3a10fe +R 095247e62fa36b05416c8693f0a2370e U drh -Z 88c6067bf128a26cfad7d97b15ea7137 +Z 29cf28ff7ccc2664a2648cb15c3f491d diff --git a/manifest.uuid b/manifest.uuid index eb9f0afe6d..855d4e4e29 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ce70803f5e1bfb4dc495d3a0c2ddd5ee6c3a10fe \ No newline at end of file +c75f561f337a56c14335366ed9990e44bc9fc594 \ No newline at end of file diff --git a/test/speedtest1.c b/test/speedtest1.c index b15f65cfe9..932943912f 100644 --- a/test/speedtest1.c +++ b/test/speedtest1.c @@ -122,8 +122,8 @@ static int integerValue(const char *zArg){ break; } } - if( v>=2147483648 ) fatal_error("parameter to large - max 2147483648"); - return isNeg? -v : v; + if( v>0x7fffffff ) fatal_error("parameter to large - max 2147483648"); + return (int)(isNeg? -v : v); } /* Return the current wall-clock time, in milliseconds */ @@ -256,8 +256,8 @@ void speedtest1_begin_test(int iTestNum, const char *zTestName, ...){ sqlite3_free(zName); g.nResult = 0; g.iStart = speedtest1_timestamp(); - g.x = 2903710987; - g.y = 1157229256; + g.x = 0xad131d0b; + g.y = 0x44f9eac8; } /* Complete a test case */ From b87875ac4098b3048b3a9c42b8ef60087af2c675 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Wed, 27 Nov 2013 18:00:20 +0000 Subject: [PATCH 016/276] Fix spelling typo in speedtest1.exe. FossilOrigin-Name: ae90300e8e3221c208343e5e0d5e5f2381f38107 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/speedtest1.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index d5cd277511..65efc4bad0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\ssome\sharmless\scompiler\swarnings\sin\sspeedtest1.exe. -D 2013-11-27T14:50:51.106 +C Fix\sspelling\stypo\sin\sspeedtest1.exe. +D 2013-11-27T18:00:20.146 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -820,7 +820,7 @@ F test/speed3.test d32043614c08c53eafdc80f33191d5bd9b920523 F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b -F test/speedtest1.c 39921e422974a0330f3efde03797795947e648b2 +F test/speedtest1.c 184ded13ffe61df44d6e2ac9985b61a6417d5311 F test/spellfix.test 8c40b169b104086d8795781f670ba3c786d6d8be F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298 F test/stat.test c8eccfe8fcd3f3cfc864ce22d5b9e803a3c69940 @@ -1145,7 +1145,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P ce70803f5e1bfb4dc495d3a0c2ddd5ee6c3a10fe -R 095247e62fa36b05416c8693f0a2370e -U drh -Z 29cf28ff7ccc2664a2648cb15c3f491d +P c75f561f337a56c14335366ed9990e44bc9fc594 +R 8fc0b17785407e52a1dbc354b6661932 +U mistachkin +Z 8afea8796306e0cb7f61a719616561e8 diff --git a/manifest.uuid b/manifest.uuid index 855d4e4e29..85d5c872a5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c75f561f337a56c14335366ed9990e44bc9fc594 \ No newline at end of file +ae90300e8e3221c208343e5e0d5e5f2381f38107 \ No newline at end of file diff --git a/test/speedtest1.c b/test/speedtest1.c index 932943912f..ea9ec2e351 100644 --- a/test/speedtest1.c +++ b/test/speedtest1.c @@ -122,7 +122,7 @@ static int integerValue(const char *zArg){ break; } } - if( v>0x7fffffff ) fatal_error("parameter to large - max 2147483648"); + if( v>0x7fffffff ) fatal_error("parameter too large - max 2147483648"); return (int)(isNeg? -v : v); } From 9338642ca6432dcd5e874ef959b7ca2ee0725e4e Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 27 Nov 2013 19:17:49 +0000 Subject: [PATCH 017/276] Update documentation of sqlite3_column() for clarity. Update evidence marks on test cases. FossilOrigin-Name: ec2d47a1db2349d5c9b4fe465506e0e347f77921 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/sqlite.h.in | 16 ++++++++-------- test/e_createtable.test | 2 +- test/e_expr.test | 15 +++++++++------ 5 files changed, 28 insertions(+), 25 deletions(-) diff --git a/manifest b/manifest index 65efc4bad0..c6966974e7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sspelling\stypo\sin\sspeedtest1.exe. -D 2013-11-27T18:00:20.146 +C Update\sdocumentation\sof\ssqlite3_column()\sfor\sclarity.\s\sUpdate\sevidence\smarks\non\stest\scases. +D 2013-11-27T19:17:49.817 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -221,7 +221,7 @@ F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c d41381d80a22d3a83352aeca274cccf264ac277a F src/shell.c 936a72ff784efff3832cce274a96ed0b036e6758 -F src/sqlite.h.in a8328969be639b6cd8d9225ed2a51d9d624fff5f +F src/sqlite.h.in af7f4349f939c40848bdfa217855d0bb88f3a581 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc F src/sqliteInt.h 9d586cb37572cd9e0a48242d449c6a69c2e74e72 @@ -433,11 +433,11 @@ F test/descidx3.test 09ddbe3f5295f482d2f8b687cf6db8bad7acd9a2 F test/diskfull.test 106391384780753ea6896b7b4f005d10e9866b6e F test/distinct.test 44028aaf161a5e80a2f229622b3a174d3b352810 F test/distinctagg.test 1a6ef9c87a58669438fc771450d7a72577417376 -F test/e_createtable.test a4561b93062e651d6def99c9e6956969dbf3754c +F test/e_createtable.test ee95d48664503d40f6cc9ef4a7d03216188e2ada F test/e_delete.test d5186e2f5478b659f16a2c8b66c09892823e542a F test/e_droptrigger.test 3cd080807622c13e5bbb61fc9a57bd7754da2412 F test/e_dropview.test 0c9f7f60989164a70a67a9d9c26d1083bc808306 -F test/e_expr.test a9f7c084ea3648003bcc40dd50861af5d2341fc1 +F test/e_expr.test 5c71d183fbf519a4769fd2e2124afdc70b5b1f42 F test/e_fkey.test d83a04478bb9c02d2c513518548a69f818869f41 F test/e_fts3.test 5c02288842e4f941896fd44afdef564dd5fc1459 F test/e_insert.test 1e44f84d2abe44d66e4fbf198be4b20e3cc724a0 @@ -1145,7 +1145,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P c75f561f337a56c14335366ed9990e44bc9fc594 -R 8fc0b17785407e52a1dbc354b6661932 -U mistachkin -Z 8afea8796306e0cb7f61a719616561e8 +P ae90300e8e3221c208343e5e0d5e5f2381f38107 +R b6ce75ba6132c1ec93bb8b6dc747cf97 +U drh +Z 0aae2730740447c74aeda3d2db2e7487 diff --git a/manifest.uuid b/manifest.uuid index 85d5c872a5..95dfd63b81 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ae90300e8e3221c208343e5e0d5e5f2381f38107 \ No newline at end of file +ec2d47a1db2349d5c9b4fe465506e0e347f77921 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index f5565cf210..228d9cca36 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -3775,19 +3775,19 @@ int sqlite3_data_count(sqlite3_stmt *pStmt); ** ** NULL INTEGER Result is 0 ** NULL FLOAT Result is 0.0 -** NULL TEXT Result is NULL pointer -** NULL BLOB Result is NULL pointer +** NULL TEXT Result is a NULL pointer +** NULL BLOB Result is a NULL pointer ** INTEGER FLOAT Convert from integer to float ** INTEGER TEXT ASCII rendering of the integer ** INTEGER BLOB Same as INTEGER->TEXT -** FLOAT INTEGER Convert from float to integer +** FLOAT INTEGER [CAST] to INTEGER ** FLOAT TEXT ASCII rendering of the float -** FLOAT BLOB Same as FLOAT->TEXT -** TEXT INTEGER Use atoi() -** TEXT FLOAT Use atof() +** FLOAT BLOB [CAST] to BLOB +** TEXT INTEGER [CAST] to INTEGER +** TEXT FLOAT [CAST] to REAL ** TEXT BLOB No change -** BLOB INTEGER Convert to TEXT then use atoi() -** BLOB FLOAT Convert to TEXT then use atof() +** BLOB INTEGER [CAST] to INTEGER +** BLOB FLOAT [CAST] to REAL ** BLOB TEXT Add a zero terminator if needed ** ** )^ diff --git a/test/e_createtable.test b/test/e_createtable.test index 1c8ab7d86e..2cd63280df 100644 --- a/test/e_createtable.test +++ b/test/e_createtable.test @@ -1103,7 +1103,7 @@ do_catchsql_test e_createtable-3.11.5 { # EVIDENCE-OF: R-52382-54248 Each table in SQLite may have at most one # PRIMARY KEY. # -# EVIDENCE-OF: R-62315-57691 An error is rasied if more than one PRIMARY +# EVIDENCE-OF: R-31826-01813 An error is raised if more than one PRIMARY # KEY clause appears in a CREATE TABLE statement. # # To test the two above, show that zero primary keys is Ok, one primary diff --git a/test/e_expr.test b/test/e_expr.test index ea23a22d7f..a743c0c390 100644 --- a/test/e_expr.test +++ b/test/e_expr.test @@ -1407,10 +1407,12 @@ do_test e_expr-26.1.6 { set ::evalcount } {5} #------------------------------------------------------------------------- # Test statements related to CAST expressions. # -# EVIDENCE-OF: R-65079-31758 Application of a CAST expression is -# different to application of a column affinity, as with a CAST -# expression the storage class conversion is forced even if it is lossy -# and irrreversible. +# EVIDENCE-OF: R-20854-17109 A CAST conversion is similar to the +# conversion that takes place when a column affinity is applied to a +# value except that with the CAST operator the conversion always takes +# place even if the conversion lossy and irreversible, whereas column +# affinity only changes the data type of a value if the change is +# lossless and reversible. # do_execsql_test e_expr-27.1.1 { CREATE TABLE t3(a TEXT, b REAL, c INTEGER); @@ -1594,8 +1596,9 @@ do_expr_test e_expr-30.4.1 { CAST('' AS INTEGER) } integer 0 do_expr_test e_expr-30.4.2 { CAST('not a number' AS INTEGER) } integer 0 do_expr_test e_expr-30.4.3 { CAST('XXI' AS INTEGER) } integer 0 -# EVIDENCE-OF: R-00741-38776 A cast of a REAL value into an INTEGER will -# truncate the fractional part of the REAL. +# EVIDENCE-OF: R-02752-50091 A cast of a REAL value into an INTEGER +# results in the integer between the REAL value and zero that is closest +# to the REAL value. # do_expr_test e_expr-31.1.1 { CAST(3.14159 AS INTEGER) } integer 3 do_expr_test e_expr-31.1.2 { CAST(1.99999 AS INTEGER) } integer 1 From 2c77be054aece16f91fea60aeb3df86bf91ab17b Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 27 Nov 2013 21:07:03 +0000 Subject: [PATCH 018/276] Remove unnecessary local variables from sqlite3VdbeExec() in order to reduce stack-space requirements of that routine. FossilOrigin-Name: 81891288d9f281cf2ceb4cd701c0c3231b1bab19 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 5 ++--- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index c6966974e7..2b11db792d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sdocumentation\sof\ssqlite3_column()\sfor\sclarity.\s\sUpdate\sevidence\smarks\non\stest\scases. -D 2013-11-27T19:17:49.817 +C Remove\sunnecessary\slocal\svariables\sfrom\ssqlite3VdbeExec()\sin\sorder\sto\nreduce\sstack-space\srequirements\sof\sthat\sroutine. +D 2013-11-27T21:07:03.594 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -280,7 +280,7 @@ F src/update.c c05a0ee658f1a149e0960dfd110f3b8bd846bcb0 F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c cbe054290f780fcd472b89d701c7404c51ec9684 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c c2b3cd6baddb224a2f155e410ca69f74e6efc671 +F src/vdbe.c 54894fde8dc806d259e015ac7c9680145e725835 F src/vdbe.h c06f0813f853566457ce9cfb1a4a4bc39a5da644 F src/vdbeInt.h 05fbda0e061dbc4aaa2709a8cccf3515c245b263 F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed @@ -1145,7 +1145,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P ae90300e8e3221c208343e5e0d5e5f2381f38107 -R b6ce75ba6132c1ec93bb8b6dc747cf97 +P ec2d47a1db2349d5c9b4fe465506e0e347f77921 +R 7567a16f49e2bdddacaa25bcadbc50b4 U drh -Z 0aae2730740447c74aeda3d2db2e7487 +Z d833492813320be0733490cbebae9751 diff --git a/manifest.uuid b/manifest.uuid index 95dfd63b81..d8103977d6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ec2d47a1db2349d5c9b4fe465506e0e347f77921 \ No newline at end of file +81891288d9f281cf2ceb4cd701c0c3231b1bab19 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 3b27ba144a..8ae4ce484c 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -4132,9 +4132,8 @@ case OP_Delete: { /* Invoke the update-hook if required. */ if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z && pC->isTable ){ - const char *zDb = db->aDb[pC->iDb].zName; - const char *zTbl = pOp->p4.z; - db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, zTbl, iKey); + db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, + db->aDb[pC->iDb].zName, pOp->p4.z, iKey); assert( pC->iDb>=0 ); } if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++; From 19be738b4277865578a01bec776454e95bdbed73 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 28 Nov 2013 06:17:56 +0000 Subject: [PATCH 019/276] Fix a test case in temptrigger.test so that it works in auto-vacuum mode. FossilOrigin-Name: c3b7a0e61f4ad690a56ece1d348a3ef74ab300fe --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/temptrigger.test | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 2b11db792d..46cc742312 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sunnecessary\slocal\svariables\sfrom\ssqlite3VdbeExec()\sin\sorder\sto\nreduce\sstack-space\srequirements\sof\sthat\sroutine. -D 2013-11-27T21:07:03.594 +C Fix\sa\stest\scase\sin\stemptrigger.test\sso\sthat\sit\sworks\sin\sauto-vacuum\smode. +D 2013-11-28T06:17:56.598 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -839,7 +839,7 @@ F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930 F test/tclsqlite.test 37a61c2da7e3bfe3b8c1a2867199f6b860df5d43 F test/tempdb.test 19d0f66e2e3eeffd68661a11c83ba5e6ace9128c F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30 -F test/temptrigger.test 0a48d94222d50e6e50d72ac103606c4f8e7cbb81 +F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1 F test/tester.tcl bce6b929932498383ce92431da6a96432c690bf7 F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5 F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58 @@ -1145,7 +1145,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P ec2d47a1db2349d5c9b4fe465506e0e347f77921 -R 7567a16f49e2bdddacaa25bcadbc50b4 -U drh -Z d833492813320be0733490cbebae9751 +P 81891288d9f281cf2ceb4cd701c0c3231b1bab19 +R e5054da8ef1fdd961404f7ffc7aa7a5a +U dan +Z 17d1dc6a3f28e852709091d44bbd59ab diff --git a/manifest.uuid b/manifest.uuid index d8103977d6..0fdb1c275e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -81891288d9f281cf2ceb4cd701c0c3231b1bab19 \ No newline at end of file +c3b7a0e61f4ad690a56ece1d348a3ef74ab300fe \ No newline at end of file diff --git a/test/temptrigger.test b/test/temptrigger.test index d646b672b9..551c620479 100644 --- a/test/temptrigger.test +++ b/test/temptrigger.test @@ -265,10 +265,10 @@ do_test 6.1 { } {} do_execsql_test 6.2 { - SELECT * FROM aux.sqlite_master; + SELECT type,name,tbl_name,sql FROM aux.sqlite_master; INSERT INTO aux.t1 VALUES(1,2,3); } { - table t1 t1 2 {CREATE TABLE t1(a, b, c)} + table t1 t1 {CREATE TABLE t1(a, b, c)} } do_catchsql_test 6.3 { From 0d4a0cdf1895673aef0cf1f8555e855a843e751c Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 28 Nov 2013 14:14:31 +0000 Subject: [PATCH 020/276] Remove an assert() condition that may not be true if the database file is corrupt. Update a test case in corruptC.test. FossilOrigin-Name: 0bcf75516f59e49536f9e5c5cd542058ab61e2fc --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbeaux.c | 1 - test/corruptC.test | 6 +++++- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 46cc742312..f38386e963 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\stest\scase\sin\stemptrigger.test\sso\sthat\sit\sworks\sin\sauto-vacuum\smode. -D 2013-11-28T06:17:56.598 +C Remove\san\sassert()\scondition\sthat\smay\snot\sbe\strue\sif\sthe\sdatabase\sfile\sis\scorrupt.\sUpdate\sa\stest\scase\sin\scorruptC.test. +D 2013-11-28T14:14:31.361 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -284,7 +284,7 @@ F src/vdbe.c 54894fde8dc806d259e015ac7c9680145e725835 F src/vdbe.h c06f0813f853566457ce9cfb1a4a4bc39a5da644 F src/vdbeInt.h 05fbda0e061dbc4aaa2709a8cccf3515c245b263 F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed -F src/vdbeaux.c a880c3c7d7c58543574ff7c96feddc5a1deaeae2 +F src/vdbeaux.c 91438d61d807e738c876c902bf93911294fa4e9c F src/vdbeblob.c 8cd05a5630e6d5563ad017bf82edaf812b28acde F src/vdbemem.c af650c2019dc197f062440cdb4650b7204e648bf F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147 @@ -401,7 +401,7 @@ F test/corrupt8.test 48eb37ffb9a03bceada62219e2bd4c92f4b0cb75 F test/corrupt9.test 959179e68dc0b7b99f424cf3e0381c86dcdd0112 F test/corruptA.test fafa652aa585753be4f6b62ff0bb250266eaf7ce F test/corruptB.test 20d4a20cbed23958888c3e8995b424a47223d647 -F test/corruptC.test 62a767fe64acb1975f58cc6171192839c783edbb +F test/corruptC.test b497c185822c6042d48e2397bbb61b6afa9145f2 F test/corruptD.test 3b09903a2e2fe07ecafe775fea94177f8a4bb34f F test/corruptE.test d3a3d7e864a95978195741744dda4abfd8286018 F test/corruptF.test 1c7b6f77cf3f237fb7fbb5b61d6c921fd4c7b993 @@ -1145,7 +1145,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 81891288d9f281cf2ceb4cd701c0c3231b1bab19 -R e5054da8ef1fdd961404f7ffc7aa7a5a +P c3b7a0e61f4ad690a56ece1d348a3ef74ab300fe +R 21ad128f70c76813a75560c386843590 U dan -Z 17d1dc6a3f28e852709091d44bbd59ab +Z 0b43b2d8a9067c8c1c1e6108e2a66815 diff --git a/manifest.uuid b/manifest.uuid index 0fdb1c275e..f2b05ea696 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c3b7a0e61f4ad690a56ece1d348a3ef74ab300fe \ No newline at end of file +0bcf75516f59e49536f9e5c5cd542058ab61e2fc \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index e2e3843ffd..1f51e681b5 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -3114,7 +3114,6 @@ int sqlite3VdbeRecordCompare( d1 = szHdr1; assert( pKeyInfo->nField+pKeyInfo->nXField>=pPKey2->nField ); assert( pKeyInfo->aSortOrder!=0 ); - assert( idx1nField ); do{ u32 serial_type1; diff --git a/test/corruptC.test b/test/corruptC.test index 34e81a1be8..bf5c3f3972 100644 --- a/test/corruptC.test +++ b/test/corruptC.test @@ -202,6 +202,10 @@ do_test corruptC-2.8 { } {1 {database disk image is malformed}} # corruption (seed 170434) +# +# UPDATE: Prior to 3.8.2, this used to return SQLITE_CORRUPT. It no longer +# does. That is Ok, the point of these tests is to verify that no buffer +# overruns or overreads can be caused by corrupt databases. do_test corruptC-2.9 { db close forcecopy test.bu test.db @@ -211,7 +215,7 @@ do_test corruptC-2.9 { sqlite3 db test.db catchsql {BEGIN; DELETE FROM t1 WHERE x>13; ROLLBACK;} -} {1 {database disk image is malformed}} +} {0 {}} # corruption (seed 186504) do_test corruptC-2.10 { From 1b4b334abbf67fe23e7ca03f76045625b24c8ef1 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 28 Nov 2013 19:28:00 +0000 Subject: [PATCH 021/276] Update a few test cases to account for the new error message formats. FossilOrigin-Name: 65a5bce3ffb656a43a2e5d2308a4bc67497105de --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- test/fkey_malloc.test | 5 ++++- test/ioerr.test | 2 +- test/trans2.test | 4 ++-- 5 files changed, 16 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index f38386e963..428b7ba491 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sassert()\scondition\sthat\smay\snot\sbe\strue\sif\sthe\sdatabase\sfile\sis\scorrupt.\sUpdate\sa\stest\scase\sin\scorruptC.test. -D 2013-11-28T14:14:31.361 +C Update\sa\sfew\stest\scases\sto\saccount\sfor\sthe\snew\serror\smessage\sformats. +D 2013-11-28T19:28:00.296 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -470,7 +470,7 @@ F test/fkey4.test 86446017011273aad8f9a99c1a65019e7bd9ca9d F test/fkey5.test 8a1fde4e7721ae00b05b3178888833726ca2df8d F test/fkey6.test abb59f866c1b44926fd02d1fdd217d831fe04f48 F test/fkey7.test e31d0e71a41c1d29349a16448d6c420e2c53a8fc -F test/fkey_malloc.test bb74c9cb8f8fceed03b58f8a7ef2df98520bbd51 +F test/fkey_malloc.test 594a7ea1fbab553c036c70813cd8bd9407d63749 F test/format4.test 1f0cac8ff3895e9359ed87e41aaabee982a812eb F test/fts-9fd058691.test 78b887e30ae6816df0e1fed6259de4b5a64ad33c F test/fts1a.test 46090311f85da51bb33bd5ce84f7948359c6d8d7 @@ -624,7 +624,7 @@ F test/intarray.test 066b7d7ac38d25bf96f87f1b017bfc687551cdd4 F test/interrupt.test dfe9a67a94b0b2d8f70545ba1a6cca10780d71cc F test/intpkey.test 7506090fc08e028712a8bf47e5f54111947e3844 F test/io.test 3a7abcef18727cc0f2399e04b0e8903eccae50f8 -F test/ioerr.test 40bb2cfcab63fb6aa7424cd97812a84bc16b5fb8 +F test/ioerr.test 2a24bd6ed5a8b062e64bfe1f6cf94fb25e92210d F test/ioerr2.test 9d71166f8466eda510f1af6137bdabaa82b5408d F test/ioerr3.test d3cec5e1a11ad6d27527d0d38573fbff14c71bdd F test/ioerr4.test f130fe9e71008577b342b8874d52984bd04ede2c @@ -989,7 +989,7 @@ F test/tpch01.test 8f4ac52f62f3e9f6bce0889105aecdf0275e331b F test/trace.test 4b36a41a3e9c7842151af6da5998f5080cdad9e5 F test/trace2.test e7a988fdd982cdec62f1f1f34b0360e6476d01a0 F test/trans.test 6e1b4c6a42dba31bd65f8fa5e61a2708e08ddde6 -F test/trans2.test d5337e61de45e66b1fcbf9db833fa8c82e624b22 +F test/trans2.test 62bd045bfc7a1c14c5ba83ba64d21ade31583f76 F test/trans3.test 373ac5183cc56be69f48ae44090e7f672939f732 F test/transitive1.test 03f532954f46cdf5608f7766bff0b0c52bf2a7cd F test/trigger1.test dc47573ac79ffe0ee3eecaa517d70d8dacbccd03 @@ -1145,7 +1145,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P c3b7a0e61f4ad690a56ece1d348a3ef74ab300fe -R 21ad128f70c76813a75560c386843590 +P 0bcf75516f59e49536f9e5c5cd542058ab61e2fc +R 6e7556e59872b6a951f274edf04e3ab4 U dan -Z 0b43b2d8a9067c8c1c1e6108e2a66815 +Z 028b27b689b89b3e9fc267cb7f1e10e7 diff --git a/manifest.uuid b/manifest.uuid index f2b05ea696..a1bddb66b0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0bcf75516f59e49536f9e5c5cd542058ab61e2fc \ No newline at end of file +65a5bce3ffb656a43a2e5d2308a4bc67497105de \ No newline at end of file diff --git a/test/fkey_malloc.test b/test/fkey_malloc.test index b4b5b4eed7..382e6f67d9 100644 --- a/test/fkey_malloc.test +++ b/test/fkey_malloc.test @@ -69,7 +69,10 @@ proc catch_fk_error {zSql} { if {[string match {*foreign key*} $msg]} { return "" } - if {$msg eq "out of memory" || $msg eq "constraint failed"} { + if {$msg eq "out of memory" + || $msg eq "FOREIGN KEY constraint failed" + || $msg eq "constraint failed" + } { error 1 } error $msg diff --git a/test/ioerr.test b/test/ioerr.test index b237439ea2..e59647fe50 100644 --- a/test/ioerr.test +++ b/test/ioerr.test @@ -258,7 +258,7 @@ do_ioerr_test ioerr-10 -ckrefcount true -tclprep { INSERT INTO t1 SELECT (a+500)%900, 'good string' FROM t1; }} msg - if {$msg != "column a is not unique"} { + if {$msg != "UNIQUE constraint failed: t1.a"} { error $msg } } diff --git a/test/trans2.test b/test/trans2.test index cfd3e67736..36a2f9986b 100644 --- a/test/trans2.test +++ b/test/trans2.test @@ -161,7 +161,7 @@ for {set i 2} {$i<=30} {incr i} { z = CASE WHEN id<$max_rowid THEN zeroblob((random()&65535)%5000 + 1000) END; } - } {1 {t1.z may not be NULL}} + } {1 {NOT NULL constraint failed: t1.z}} do_test trans2-$i.11 { db eval {SELECT md5sum(u1), md5sum(u2) FROM t1 ORDER BY id} } $newres @@ -185,7 +185,7 @@ for {set i 2} {$i<=30} {incr i} { z = CASE WHEN id<$max1 THEN zeroblob((random()&65535)%5000 + 1000) END; } - } {1 {t1.z may not be NULL}} + } {1 {NOT NULL constraint failed: t1.z}} do_test trans2-$i.31 { db eval {SELECT md5sum(u1), md5sum(u2) FROM t1 ORDER BY id} } $origres From 09fe614372b54ba46196ba8387561460919ecfc9 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 29 Nov 2013 15:06:27 +0000 Subject: [PATCH 022/276] Add a new sqlite3_test_control() that indicates that database files are always well-formed. Use this during testing to enable assert() statements that prove conditions that are always true for well-formed databases. FossilOrigin-Name: 15e4f63d1f3cbcd0aa789fd3e460cd6e4d3338f9 --- manifest | 58 +++++++++++++++++++++++----------------------- manifest.uuid | 2 +- src/global.c | 2 +- src/main.c | 13 +++++++++++ src/sqlite.h.in | 3 ++- src/sqliteInt.h | 18 ++++++++++++++ src/test1.c | 33 ++++++++++++++++++++++++++ src/vdbeaux.c | 3 ++- test/corrupt.test | 4 ++++ test/corrupt2.test | 4 ++++ test/corrupt3.test | 4 ++++ test/corrupt4.test | 4 ++++ test/corrupt5.test | 4 ++++ test/corrupt6.test | 4 ++++ test/corrupt7.test | 4 ++++ test/corrupt8.test | 4 ++++ test/corrupt9.test | 4 ++++ test/corruptA.test | 4 ++++ test/corruptB.test | 4 ++++ test/corruptC.test | 4 ++++ test/corruptD.test | 4 ++++ test/corruptE.test | 4 ++++ test/corruptF.test | 4 ++++ test/corruptG.test | 4 ++++ test/tester.tcl | 6 +++++ 25 files changed, 169 insertions(+), 33 deletions(-) diff --git a/manifest b/manifest index 428b7ba491..1aaac60acf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sa\sfew\stest\scases\sto\saccount\sfor\sthe\snew\serror\smessage\sformats. -D 2013-11-28T19:28:00.296 +C Add\sa\snew\ssqlite3_test_control()\sthat\sindicates\sthat\sdatabase\sfiles\sare\nalways\swell-formed.\s\sUse\sthis\sduring\stesting\sto\senable\sassert()\sstatements\nthat\sprove\sconditions\sthat\sare\salways\strue\sfor\swell-formed\sdatabases. +D 2013-11-29T15:06:27.785 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -179,7 +179,7 @@ F src/expr.c 31a2b65339f6c3795d4cfa5e99798cd72f9fdfdf F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 2ab0f5384b70594468ef3ac5c7ed8ca24bfd17d5 F src/func.c ef30d26ae4d79bbc7300c74e77fd117a0ba30235 -F src/global.c 5caf4deab621abb45b4c607aad1bd21c20aac759 +F src/global.c 1d7bb7ea8254ae6a68ed9bfaf65fcb3d1690b486 F src/hash.c ac3470bbf1ca4ae4e306a8ecb0fdf1731810ffe4 F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 @@ -188,7 +188,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b F src/loadext.c 867c7b330b740c6c917af9956b13b81d0a048303 -F src/main.c 441a2e106d0e2913fec47e5f13d5802c742e32bb +F src/main.c 74bdee8f574588868e67c25cd377df7cba80102e F src/malloc.c 543a8eb5508eaf4cadf55a9b503379eba2088128 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c0c990fcaddff810ea277b4fb5d9138603dd5d4b @@ -221,15 +221,15 @@ F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c d41381d80a22d3a83352aeca274cccf264ac277a F src/shell.c 936a72ff784efff3832cce274a96ed0b036e6758 -F src/sqlite.h.in af7f4349f939c40848bdfa217855d0bb88f3a581 +F src/sqlite.h.in baf55c31c4e15a4b626acfeaa792f2aaa566657f F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h 9d586cb37572cd9e0a48242d449c6a69c2e74e72 +F src/sqliteInt.h c26e4cde71fd6dbe34b708f2abd2f6436ce191bf F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e F src/tclsqlite.c 651b10698c87bbc3ae5772e2491e3444c5bbf153 -F src/test1.c 5757066e503a8ed51313cb3a5d9bcdcced2991a9 +F src/test1.c 760e0419705f712d80595f47199568cd7e3b57a4 F src/test2.c 7355101c085304b90024f2261e056cdff13c6c35 F src/test3.c 1c0e5d6f080b8e33c1ce8b3078e7013fdbcd560c F src/test4.c 9b32d22f5f150abe23c1830e2057c4037c45b3df @@ -284,7 +284,7 @@ F src/vdbe.c 54894fde8dc806d259e015ac7c9680145e725835 F src/vdbe.h c06f0813f853566457ce9cfb1a4a4bc39a5da644 F src/vdbeInt.h 05fbda0e061dbc4aaa2709a8cccf3515c245b263 F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed -F src/vdbeaux.c 91438d61d807e738c876c902bf93911294fa4e9c +F src/vdbeaux.c 28a791e1694018f7143c349b154b78237f0ea1fb F src/vdbeblob.c 8cd05a5630e6d5563ad017bf82edaf812b28acde F src/vdbemem.c af650c2019dc197f062440cdb4650b7204e648bf F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147 @@ -390,22 +390,22 @@ F test/conflict.test 841bcf7cabbfca39c577eb8411ea8601843b46a8 F test/conflict2.test 3ed0b6ec3c2cb8acebbc89677ea0e58c01aaa1ff F test/conflict3.test dec0634c0f31dec9a4b01c63063e939f0cd21b6b F test/contrib01.test 2a1cbc0f2f48955d7d073f725765da6fbceda6b4 -F test/corrupt.test 4aabd06cff3fe759e3e658bcc17b71789710665e -F test/corrupt2.test 9c0ab4becd50e9050bc1ebb8675456a4e5587bf0 -F test/corrupt3.test 889d7cdb811800303aa722d7813fe8a4299cf726 -F test/corrupt4.test b963f9e01e0f92d15c76fb0747876fd4b96dc30a -F test/corrupt5.test c23da7bfb20917cc7fdbb13ee25c7cc4e9fffeff -F test/corrupt6.test 4e4161aef1f30b9f34582bb4142334b7f47eacae -F test/corrupt7.test a90caf89c7d7cb7893ea4d92529bd0c129317ee4 -F test/corrupt8.test 48eb37ffb9a03bceada62219e2bd4c92f4b0cb75 -F test/corrupt9.test 959179e68dc0b7b99f424cf3e0381c86dcdd0112 -F test/corruptA.test fafa652aa585753be4f6b62ff0bb250266eaf7ce -F test/corruptB.test 20d4a20cbed23958888c3e8995b424a47223d647 -F test/corruptC.test b497c185822c6042d48e2397bbb61b6afa9145f2 -F test/corruptD.test 3b09903a2e2fe07ecafe775fea94177f8a4bb34f -F test/corruptE.test d3a3d7e864a95978195741744dda4abfd8286018 -F test/corruptF.test 1c7b6f77cf3f237fb7fbb5b61d6c921fd4c7b993 -F test/corruptG.test c67fd860e9e3943bc90b856a3049c9a28827167e +F test/corrupt.test 141c39ea650c1365e85a49e402fa05cb9617fb97 +F test/corrupt2.test f2064e0bf934124cc38868fd8badb8f0dd67b552 +F test/corrupt3.test 4b548d0bbe2933bc81d3f54099a05fc4d28aff18 +F test/corrupt4.test b99652079d542b21f4965f6248703b983e40fe80 +F test/corrupt5.test 8ead52af76006f3286e9396cb41898018ccea107 +F test/corrupt6.test 269548d19427ac554c830763b1c5ea54a0252f80 +F test/corrupt7.test 22cc644c2e76c9804bc844121267aa6f8f7c0ded +F test/corrupt8.test 2399dfe40d2c0c63af86706e30f3e6302a8d0516 +F test/corrupt9.test 730a3db08d4ab9aa43392ea30d9c2b4879cbff85 +F test/corruptA.test 53e56dafd180addcdadb402244b8cb9771d2ba26 +F test/corruptB.test 73a8d6c0b9833697ecf16b63e3c5c05c945b5dec +F test/corruptC.test 02405cf7ed0c1e989060e1aab6d02ffbc3906fbb +F test/corruptD.test b3c205fac7952b1de645ce44bb02335cd9e3e040 +F test/corruptE.test 193b4ca4e927e77c1d5f4f56203ddc998432a7ee +F test/corruptF.test be9fde98e4c93648f1ba52b74e5318edc8f59fe4 +F test/corruptG.test c150f156dace653c00a121ad0f5772a0568c41ba F test/count.test 42a251178e32f617eda33f76236a7f79825a50b5 F test/coveridxscan.test cdb47d01acc4a634a34fd25abe85189e0d0f1e62 F test/crash.test fb9dc4a02dcba30d4aa5c2c226f98b220b2b959f @@ -840,7 +840,7 @@ F test/tclsqlite.test 37a61c2da7e3bfe3b8c1a2867199f6b860df5d43 F test/tempdb.test 19d0f66e2e3eeffd68661a11c83ba5e6ace9128c F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30 F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1 -F test/tester.tcl bce6b929932498383ce92431da6a96432c690bf7 +F test/tester.tcl 2a7cce4abf404557c09323a84a2444b189835d0f F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5 F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58 F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7 @@ -1145,7 +1145,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 0bcf75516f59e49536f9e5c5cd542058ab61e2fc -R 6e7556e59872b6a951f274edf04e3ab4 -U dan -Z 028b27b689b89b3e9fc267cb7f1e10e7 +P 65a5bce3ffb656a43a2e5d2308a4bc67497105de +R e2c54e83c6d9de52db2502c5f23f4d01 +U drh +Z 79de7aa38f99c75e5cc2a8b158cbdc48 diff --git a/manifest.uuid b/manifest.uuid index a1bddb66b0..f6f482e260 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -65a5bce3ffb656a43a2e5d2308a4bc67497105de \ No newline at end of file +15e4f63d1f3cbcd0aa789fd3e460cd6e4d3338f9 \ No newline at end of file diff --git a/src/global.c b/src/global.c index 7b02cf2130..1ee3f6436f 100644 --- a/src/global.c +++ b/src/global.c @@ -148,6 +148,7 @@ SQLITE_WSD struct Sqlite3Config sqlite3Config = { SQLITE_USE_URI, /* bOpenUri */ SQLITE_ALLOW_COVERING_INDEX_SCAN, /* bUseCis */ 0x7ffffffe, /* mxStrlen */ + 0, /* neverCorrupt */ 128, /* szLookaside */ 500, /* nLookaside */ {0,0,0,0,0,0,0,0}, /* m */ @@ -183,7 +184,6 @@ SQLITE_WSD struct Sqlite3Config sqlite3Config = { #endif }; - /* ** Hash table for global functions - functions common to all ** database connections. After initialization, this table is diff --git a/src/main.c b/src/main.c index a6a04b4b4c..69a399f385 100644 --- a/src/main.c +++ b/src/main.c @@ -3296,6 +3296,19 @@ int sqlite3_test_control(int op, ...){ } #endif + /* sqlite3_test_control(SQLITE_TESTCTRL_NEVER_CORRUPT, int); + ** + ** Set or clear a flag that indicates that the database file is always well- + ** formed and never corrupt. This flag is clear by default, indicating that + ** database files might have arbitrary corruption. Setting the flag during + ** testing causes certain assert() statements in the code to be activated + ** that demonstrat invariants on well-formed database files. + */ + case SQLITE_TESTCTRL_NEVER_CORRUPT: { + sqlite3Config.neverCorrupt = va_arg(ap, int); + break; + } + } va_end(ap); #endif /* SQLITE_OMIT_BUILTIN_TEST */ diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 228d9cca36..98c89da322 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -6069,7 +6069,8 @@ int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_SCRATCHMALLOC 17 #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 #define SQLITE_TESTCTRL_EXPLAIN_STMT 19 -#define SQLITE_TESTCTRL_LAST 19 +#define SQLITE_TESTCTRL_NEVER_CORRUPT 20 +#define SQLITE_TESTCTRL_LAST 20 /* ** CAPI3REF: SQLite Runtime Status diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 6373bb75d7..98dabeb4ef 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2538,6 +2538,7 @@ struct Sqlite3Config { int bOpenUri; /* True to interpret filenames as URIs */ int bUseCis; /* Use covering indices for full-scans */ int mxStrlen; /* Maximum string length */ + int neverCorrupt; /* Database is always well-formed */ int szLookaside; /* Default lookaside buffer size */ int nLookaside; /* Default lookaside buffer count */ sqlite3_mem_methods m; /* Low-level memory allocation interface */ @@ -2574,6 +2575,23 @@ struct Sqlite3Config { #endif }; +/* +** This macro is used inside of assert() statements to indicate that +** the assert is only valid on a well-formed database. Instead of: +** +** assert( X ); +** +** One writes: +** +** assert( X || CORRUPTIBLE ); +** +** CORRUPTIBLE is true during normal operation. But for many test cases, +** it is set to false using a sqlite3_test_control(). This enables assert() +** statements to prove things that are always true for well-formed +** databases. +*/ +#define CORRUPTIBLE (sqlite3Config.neverCorrupt==0) + /* ** Context pointer passed down through the tree-walk. */ diff --git a/src/test1.c b/src/test1.c index d8a9e52d21..e0c16e13ae 100644 --- a/src/test1.c +++ b/src/test1.c @@ -5453,6 +5453,37 @@ static int reset_prng_state( return TCL_OK; } +/* +** tclcmd: database_may_be_corrupt +** +** Indicate that database files might be corrupt. In other words, set the normal +** state of operation. +*/ +static int database_may_be_corrupt( + ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ + Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ + int objc, /* Number of arguments */ + Tcl_Obj *CONST objv[] /* Command arguments */ +){ + sqlite3_test_control(SQLITE_TESTCTRL_NEVER_CORRUPT, 0); + return TCL_OK; +} +/* +** tclcmd: database_never_corrupt +** +** Indicate that database files are always well-formed. This enables extra assert() +** statements that test conditions that are always true for well-formed databases. +*/ +static int database_never_corrupt( + ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ + Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ + int objc, /* Number of arguments */ + Tcl_Obj *CONST objv[] /* Command arguments */ +){ + sqlite3_test_control(SQLITE_TESTCTRL_NEVER_CORRUPT, 1); + return TCL_OK; +} + /* ** tclcmd: pcache_stats */ @@ -6331,6 +6362,8 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ { "save_prng_state", save_prng_state, 0 }, { "restore_prng_state", restore_prng_state, 0 }, { "reset_prng_state", reset_prng_state, 0 }, + { "database_never_corrupt", database_never_corrupt, 0}, + { "database_may_be_corrupt", database_may_be_corrupt, 0}, { "optimization_control", optimization_control,0}, #if SQLITE_OS_WIN { "lock_win32_file", win32_file_lock, 0 }, diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 1f51e681b5..85685f3572 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -3112,8 +3112,9 @@ int sqlite3VdbeRecordCompare( idx1 = getVarint32(aKey1, szHdr1); d1 = szHdr1; - assert( pKeyInfo->nField+pKeyInfo->nXField>=pPKey2->nField ); + assert( pKeyInfo->nField+pKeyInfo->nXField>=pPKey2->nField || CORRUPTIBLE ); assert( pKeyInfo->aSortOrder!=0 ); + assert( (idx1<=szHdr1 && inField) || CORRUPTIBLE ); do{ u32 serial_type1; diff --git a/test/corrupt.test b/test/corrupt.test index 09f3c5bd7c..3e49a9ff18 100644 --- a/test/corrupt.test +++ b/test/corrupt.test @@ -25,6 +25,10 @@ source $testdir/tester.tcl # do_not_use_codec +# These tests deal with corrupt database files +# +database_may_be_corrupt + # Construct a large database for testing. # do_test corrupt-1.1 { diff --git a/test/corrupt2.test b/test/corrupt2.test index 744a76ed04..805a6148f0 100644 --- a/test/corrupt2.test +++ b/test/corrupt2.test @@ -23,6 +23,10 @@ source $testdir/tester.tcl # do_not_use_codec +# These tests deal with corrupt database files +# +database_may_be_corrupt + set presql "" catch { set presql "$::G(perm:presql);" } unset -nocomplain ::G(perm:presql) diff --git a/test/corrupt3.test b/test/corrupt3.test index a3827227b7..436a466189 100644 --- a/test/corrupt3.test +++ b/test/corrupt3.test @@ -23,6 +23,10 @@ source $testdir/tester.tcl # do_not_use_codec +# These tests deal with corrupt database files +# +database_may_be_corrupt + # We must have the page_size pragma for these tests to work. # ifcapable !pager_pragmas||direct_read { diff --git a/test/corrupt4.test b/test/corrupt4.test index 19061134f6..24db60fd52 100644 --- a/test/corrupt4.test +++ b/test/corrupt4.test @@ -23,6 +23,10 @@ source $testdir/tester.tcl # do_not_use_codec +# These tests deal with corrupt database files +# +database_may_be_corrupt + # We must have the page_size pragma for these tests to work. # ifcapable !pager_pragmas { diff --git a/test/corrupt5.test b/test/corrupt5.test index dca06e5fec..3f5099630e 100644 --- a/test/corrupt5.test +++ b/test/corrupt5.test @@ -19,6 +19,10 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl +# These tests deal with corrupt database files +# +database_may_be_corrupt + # We must have the page_size pragma for these tests to work. # ifcapable !pager_pragmas { diff --git a/test/corrupt6.test b/test/corrupt6.test index c0dcedf3d9..7d90c4a3ba 100644 --- a/test/corrupt6.test +++ b/test/corrupt6.test @@ -24,6 +24,10 @@ source $testdir/tester.tcl # do_not_use_codec +# These tests deal with corrupt database files +# +database_may_be_corrupt + # We must have the page_size pragma for these tests to work. # ifcapable !pager_pragmas { diff --git a/test/corrupt7.test b/test/corrupt7.test index ad566560f7..db92cf1de9 100644 --- a/test/corrupt7.test +++ b/test/corrupt7.test @@ -24,6 +24,10 @@ source $testdir/tester.tcl # do_not_use_codec +# These tests deal with corrupt database files +# +database_may_be_corrupt + # We must have the page_size pragma for these tests to work. # ifcapable !pager_pragmas { diff --git a/test/corrupt8.test b/test/corrupt8.test index 012beb562e..d7bceba31c 100644 --- a/test/corrupt8.test +++ b/test/corrupt8.test @@ -24,6 +24,10 @@ source $testdir/tester.tcl # do_not_use_codec +# These tests deal with corrupt database files +# +database_may_be_corrupt + # We must have the page_size pragma for these tests to work. # ifcapable !pager_pragmas||!autovacuum { diff --git a/test/corrupt9.test b/test/corrupt9.test index f199452f95..bb37758b17 100644 --- a/test/corrupt9.test +++ b/test/corrupt9.test @@ -24,6 +24,10 @@ source $testdir/tester.tcl # do_not_use_codec +# These tests deal with corrupt database files +# +database_may_be_corrupt + # We must have the page_size pragma for these tests to work. # ifcapable !pager_pragmas { diff --git a/test/corruptA.test b/test/corruptA.test index 8b76d3a201..bb9912bd2b 100644 --- a/test/corruptA.test +++ b/test/corruptA.test @@ -24,6 +24,10 @@ source $testdir/tester.tcl # do_not_use_codec +# These tests deal with corrupt database files +# +database_may_be_corrupt + # Create a database to work with. # diff --git a/test/corruptB.test b/test/corruptB.test index 0ff2d6e9e0..c51cb57680 100644 --- a/test/corruptB.test +++ b/test/corruptB.test @@ -30,6 +30,10 @@ source $testdir/tester.tcl # do_not_use_codec +# These tests deal with corrupt database files +# +database_may_be_corrupt + do_test corruptB-1.1 { execsql { diff --git a/test/corruptC.test b/test/corruptC.test index bf5c3f3972..adf6f44c44 100644 --- a/test/corruptC.test +++ b/test/corruptC.test @@ -27,6 +27,10 @@ source $testdir/tester.tcl # do_not_use_codec +# These tests deal with corrupt database files +# +database_may_be_corrupt + # Construct a compact, dense database for testing. # do_test corruptC-1.1 { diff --git a/test/corruptD.test b/test/corruptD.test index 2423cd428e..63474584c3 100644 --- a/test/corruptD.test +++ b/test/corruptD.test @@ -19,6 +19,10 @@ source $testdir/tester.tcl # do_not_use_codec +# These tests deal with corrupt database files +# +database_may_be_corrupt + #-------------------------------------------------------------------------- # OVERVIEW # diff --git a/test/corruptE.test b/test/corruptE.test index 48292ab2e9..4d5b5db3d6 100644 --- a/test/corruptE.test +++ b/test/corruptE.test @@ -24,6 +24,10 @@ source $testdir/tester.tcl # do_not_use_codec +# These tests deal with corrupt database files +# +database_may_be_corrupt + # Do not run the tests in this file if ENABLE_OVERSIZE_CELL_CHECK is on. # ifcapable oversize_cell_check { diff --git a/test/corruptF.test b/test/corruptF.test index 64c6eb890b..8c4fd84219 100644 --- a/test/corruptF.test +++ b/test/corruptF.test @@ -19,6 +19,10 @@ set testprefix corruptF # do_not_use_codec +# These tests deal with corrupt database files +# +database_may_be_corrupt + proc str {i} { format %08d $i } # Create a 6 page database containing a single table - t1. Table t1 diff --git a/test/corruptG.test b/test/corruptG.test index c34911195c..11253fd12c 100644 --- a/test/corruptG.test +++ b/test/corruptG.test @@ -19,6 +19,10 @@ set testprefix corruptG # do_not_use_codec +# These tests deal with corrupt database files +# +database_may_be_corrupt + # Create a simple database with a single entry. Then corrupt the # header-size varint on the index payload so that it maps into a # negative number. Try to use the database. diff --git a/test/tester.tcl b/test/tester.tcl index c1272210d0..771ca91442 100644 --- a/test/tester.tcl +++ b/test/tester.tcl @@ -1886,5 +1886,11 @@ set AUTOVACUUM $sqlite_options(default_autovacuum) # Make sure the FTS enhanced query syntax is disabled. set sqlite_fts3_enable_parentheses 0 +# During testing, assume that all database files are well-formed. The +# few test cases that deliberately corrupt database files should rescind +# this setting by invoking "database_can_be_corrupt" +# +database_never_corrupt + source $testdir/thread_common.tcl source $testdir/malloc_common.tcl From b202366509ad80878c297bb97e68c15ec6df48e0 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 29 Nov 2013 15:39:36 +0000 Subject: [PATCH 023/276] Change the name of the CORRUPTIBLE macro to CORRUPT_DB. FossilOrigin-Name: f865be10e85a4063394a21827db2d854fc25960c --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/sqliteInt.h | 13 +++++++------ src/vdbeaux.c | 4 ++-- 4 files changed, 17 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index 1aaac60acf..8b8ce60236 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\snew\ssqlite3_test_control()\sthat\sindicates\sthat\sdatabase\sfiles\sare\nalways\swell-formed.\s\sUse\sthis\sduring\stesting\sto\senable\sassert()\sstatements\nthat\sprove\sconditions\sthat\sare\salways\strue\sfor\swell-formed\sdatabases. -D 2013-11-29T15:06:27.785 +C Change\sthe\sname\sof\sthe\sCORRUPTIBLE\smacro\sto\sCORRUPT_DB. +D 2013-11-29T15:39:36.814 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -224,7 +224,7 @@ F src/shell.c 936a72ff784efff3832cce274a96ed0b036e6758 F src/sqlite.h.in baf55c31c4e15a4b626acfeaa792f2aaa566657f F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h c26e4cde71fd6dbe34b708f2abd2f6436ce191bf +F src/sqliteInt.h f3a5d663fe9c6c0b2ee7fc2e20a6204eaea5bc7c F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -284,7 +284,7 @@ F src/vdbe.c 54894fde8dc806d259e015ac7c9680145e725835 F src/vdbe.h c06f0813f853566457ce9cfb1a4a4bc39a5da644 F src/vdbeInt.h 05fbda0e061dbc4aaa2709a8cccf3515c245b263 F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed -F src/vdbeaux.c 28a791e1694018f7143c349b154b78237f0ea1fb +F src/vdbeaux.c 5b58b242afe50f6bae77da1c1e26330af32e51c7 F src/vdbeblob.c 8cd05a5630e6d5563ad017bf82edaf812b28acde F src/vdbemem.c af650c2019dc197f062440cdb4650b7204e648bf F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147 @@ -1145,7 +1145,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 65a5bce3ffb656a43a2e5d2308a4bc67497105de -R e2c54e83c6d9de52db2502c5f23f4d01 +P 15e4f63d1f3cbcd0aa789fd3e460cd6e4d3338f9 +R 962cc490e8fc3a8042a30112d4f3290d U drh -Z 79de7aa38f99c75e5cc2a8b158cbdc48 +Z d6583fce3162aa40a5f7e6ad518960af diff --git a/manifest.uuid b/manifest.uuid index f6f482e260..a0b1398f2f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -15e4f63d1f3cbcd0aa789fd3e460cd6e4d3338f9 \ No newline at end of file +f865be10e85a4063394a21827db2d854fc25960c \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 98dabeb4ef..8bf05a9c8e 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2583,14 +2583,15 @@ struct Sqlite3Config { ** ** One writes: ** -** assert( X || CORRUPTIBLE ); +** assert( X || CORRUPT_DB ); ** -** CORRUPTIBLE is true during normal operation. But for many test cases, -** it is set to false using a sqlite3_test_control(). This enables assert() -** statements to prove things that are always true for well-formed -** databases. +** CORRUPT_DB is true during normal operation. CORRUPT_DB does not indicate +** that the database is definitely corrupt, only that it might be corrupt. +** For most test cases, CORRUPT_DB is set to false using a special +** sqlite3_test_control(). This enables assert() statements to prove +** things that are always true for well-formed databases. */ -#define CORRUPTIBLE (sqlite3Config.neverCorrupt==0) +#define CORRUPT_DB (sqlite3Config.neverCorrupt==0) /* ** Context pointer passed down through the tree-walk. diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 85685f3572..7a672fdf27 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -3112,9 +3112,9 @@ int sqlite3VdbeRecordCompare( idx1 = getVarint32(aKey1, szHdr1); d1 = szHdr1; - assert( pKeyInfo->nField+pKeyInfo->nXField>=pPKey2->nField || CORRUPTIBLE ); + assert( pKeyInfo->nField+pKeyInfo->nXField>=pPKey2->nField || CORRUPT_DB ); assert( pKeyInfo->aSortOrder!=0 ); - assert( (idx1<=szHdr1 && inField) || CORRUPTIBLE ); + assert( (idx1<=szHdr1 && inField) || CORRUPT_DB ); do{ u32 serial_type1; From 094b7587fcade1fc3d33216c410a3d0ba7e0c2f4 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 30 Nov 2013 12:49:28 +0000 Subject: [PATCH 024/276] Detect a corrupt UnpackedRecord and return SQLITE_CORRUPT prior to calling sqlite3BtreeMovetoUnpacked(). FossilOrigin-Name: 55ec474db8935ef36fae30da5d11f5701c60c088 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 4 ++++ 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 8b8ce60236..940dfe0022 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\sname\sof\sthe\sCORRUPTIBLE\smacro\sto\sCORRUPT_DB. -D 2013-11-29T15:39:36.814 +C Detect\sa\scorrupt\sUnpackedRecord\sand\sreturn\sSQLITE_CORRUPT\sprior\sto\scalling\nsqlite3BtreeMovetoUnpacked(). +D 2013-11-30T12:49:28.537 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,7 +166,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 1809a7caa2504233bdddd12f5018422421789537 F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c ec8a4dcac5c1ec1ba9705b8c5a13e62167958317 +F src/btree.c fe6c95c57fd14ed4b3329f4b5bb08132fe7c322d F src/btree.h a61ddebc78c66795a2b93181321a116746302cc9 F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0 F src/build.c 07054d45319953e54a89d726e589a423e9c1c590 @@ -1145,7 +1145,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 15e4f63d1f3cbcd0aa789fd3e460cd6e4d3338f9 -R 962cc490e8fc3a8042a30112d4f3290d +P f865be10e85a4063394a21827db2d854fc25960c +R b4c7c44fd7f9f4c41a202ec1f5d2e636 U drh -Z d6583fce3162aa40a5f7e6ad518960af +Z 430bb09012d5a037af5177ecb970e2fe diff --git a/manifest.uuid b/manifest.uuid index a0b1398f2f..4da7a7d3de 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f865be10e85a4063394a21827db2d854fc25960c \ No newline at end of file +55ec474db8935ef36fae30da5d11f5701c60c088 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 27e7146893..30fdf4256f 100644 --- a/src/btree.c +++ b/src/btree.c @@ -694,6 +694,10 @@ static int btreeMoveto( ); if( pIdxKey==0 ) return SQLITE_NOMEM; sqlite3VdbeRecordUnpack(pCur->pKeyInfo, (int)nKey, pKey, pIdxKey); + if( pIdxKey->nField==0 ){ + sqlite3DbFree(pCur->pKeyInfo->db, pFree); + return SQLITE_CORRUPT_BKPT; + } }else{ pIdxKey = 0; } From a256c1a4b3e362733577d0b151e985b2453ae71f Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 1 Dec 2013 01:18:29 +0000 Subject: [PATCH 025/276] Fix typos in the header comment on the sqlite3Atoi64() routine. FossilOrigin-Name: c85e0c546ea6c6be46deea5c7a716b5fb553c7b4 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/util.c | 8 ++++---- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 940dfe0022..7b389a5499 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Detect\sa\scorrupt\sUnpackedRecord\sand\sreturn\sSQLITE_CORRUPT\sprior\sto\scalling\nsqlite3BtreeMovetoUnpacked(). -D 2013-11-30T12:49:28.537 +C Fix\stypos\sin\sthe\sheader\scomment\son\sthe\ssqlite3Atoi64()\sroutine. +D 2013-12-01T01:18:29.458 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -278,7 +278,7 @@ F src/tokenize.c ec4c1a62b890bf1dbcdb966399e140b904c700a4 F src/trigger.c d84e1f3669e9a217731a14a9d472b1c7b87c87ba F src/update.c c05a0ee658f1a149e0960dfd110f3b8bd846bcb0 F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 -F src/util.c cbe054290f780fcd472b89d701c7404c51ec9684 +F src/util.c c1d47254d805074226eb68bab2327f2559799d88 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 F src/vdbe.c 54894fde8dc806d259e015ac7c9680145e725835 F src/vdbe.h c06f0813f853566457ce9cfb1a4a4bc39a5da644 @@ -1145,7 +1145,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P f865be10e85a4063394a21827db2d854fc25960c -R b4c7c44fd7f9f4c41a202ec1f5d2e636 +P 55ec474db8935ef36fae30da5d11f5701c60c088 +R d4e526e47db9fa86e2dd72e39606971c U drh -Z 430bb09012d5a037af5177ecb970e2fe +Z 5cc45f2d22e4b0c01c22c0dac659e6ce diff --git a/manifest.uuid b/manifest.uuid index 4da7a7d3de..2023f47b7b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -55ec474db8935ef36fae30da5d11f5701c60c088 \ No newline at end of file +c85e0c546ea6c6be46deea5c7a716b5fb553c7b4 \ No newline at end of file diff --git a/src/util.c b/src/util.c index 5aa8af68d9..e59f5238f8 100644 --- a/src/util.c +++ b/src/util.c @@ -465,12 +465,12 @@ static int compare2pow63(const char *zNum, int incr){ ** If the zNum value is representable as a 64-bit twos-complement ** integer, then write that value into *pNum and return 0. ** -** If zNum is exactly 9223372036854665808, return 2. This special -** case is broken out because while 9223372036854665808 cannot be a -** signed 64-bit integer, its negative -9223372036854665808 can be. +** If zNum is exactly 9223372036854775808, return 2. This special +** case is broken out because while 9223372036854775808 cannot be a +** signed 64-bit integer, its negative -9223372036854775808 can be. ** ** If zNum is too big for a 64-bit integer and is not -** 9223372036854665808 or if zNum contains any non-numeric text, +** 9223372036854775808 or if zNum contains any non-numeric text, ** then return 1. ** ** length is the number of bytes in the string (bytes, not characters). From 290ea4053a3b767ce90522386a861a098baddf09 Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 1 Dec 2013 18:10:01 +0000 Subject: [PATCH 026/276] Add some #if SQLITE_VERSION_NUMBER macros to test/speedtest1.c in order to make it compatible with older versions of SQLite so that it can be used for historical speed comparisons. FossilOrigin-Name: a9e1627ae714156cf6bd419e41cf9b79fbbe99a9 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/speedtest1.c | 10 +++++++++- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 7b389a5499..4bc50bd00e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\stypos\sin\sthe\sheader\scomment\son\sthe\ssqlite3Atoi64()\sroutine. -D 2013-12-01T01:18:29.458 +C Add\ssome\s#if\sSQLITE_VERSION_NUMBER\smacros\sto\stest/speedtest1.c\sin\sorder\sto\nmake\sit\scompatible\swith\solder\sversions\sof\sSQLite\sso\sthat\sit\scan\sbe\sused\sfor\nhistorical\sspeed\scomparisons. +D 2013-12-01T18:10:01.701 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -820,7 +820,7 @@ F test/speed3.test d32043614c08c53eafdc80f33191d5bd9b920523 F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b -F test/speedtest1.c 184ded13ffe61df44d6e2ac9985b61a6417d5311 +F test/speedtest1.c aa1ff125bc9c4b8eb55db2e3cbb82ba76794dedf F test/spellfix.test 8c40b169b104086d8795781f670ba3c786d6d8be F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298 F test/stat.test c8eccfe8fcd3f3cfc864ce22d5b9e803a3c69940 @@ -1145,7 +1145,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 55ec474db8935ef36fae30da5d11f5701c60c088 -R d4e526e47db9fa86e2dd72e39606971c +P c85e0c546ea6c6be46deea5c7a716b5fb553c7b4 +R 3cfbbdfa905179d97133dd917fc5f770 U drh -Z 5cc45f2d22e4b0c01c22c0dac659e6ce +Z aec8d6f2ae39d50473657768f7788a16 diff --git a/manifest.uuid b/manifest.uuid index 2023f47b7b..e66ea9881c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c85e0c546ea6c6be46deea5c7a716b5fb553c7b4 \ No newline at end of file +a9e1627ae714156cf6bd419e41cf9b79fbbe99a9 \ No newline at end of file diff --git a/test/speedtest1.c b/test/speedtest1.c index ea9ec2e351..473b3d191e 100644 --- a/test/speedtest1.c +++ b/test/speedtest1.c @@ -79,6 +79,12 @@ static int hexDigitValue(char c){ return -1; } +/* Provide an alternative to sqlite3_stricmp() in older versions of +** SQLite */ +#if SQLITE_VERSION_NUMBER<3007011 +# define sqlite3_stricmp strcmp +#endif + /* ** Interpret zArg as an integer value, possibly with suffixes. */ @@ -131,7 +137,7 @@ sqlite3_int64 speedtest1_timestamp(void){ static sqlite3_vfs *clockVfs = 0; sqlite3_int64 t; if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0); - if( clockVfs->iVersion>=1 && clockVfs->xCurrentTimeInt64!=0 ){ + if( clockVfs->iVersion>=2 && clockVfs->xCurrentTimeInt64!=0 ){ clockVfs->xCurrentTimeInt64(clockVfs, &t); }else{ double r; @@ -898,6 +904,7 @@ int main(int argc, char **argv){ /* Database connection statistics printed after both prepared statements ** have been finalized */ +#if SQLITE_VERSION_NUMBER>=3007009 if( showStats ){ sqlite3_db_status(g.db, SQLITE_DBSTATUS_LOOKASIDE_USED, &iCur, &iHi, 0); printf("-- Lookaside Slots Used: %d (max %d)\n", iCur,iHi); @@ -920,6 +927,7 @@ int main(int argc, char **argv){ sqlite3_db_status(g.db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHi, 0); printf("-- Statement Heap Usage: %d bytes\n", iCur); } +#endif sqlite3_close(g.db); From d79e9c58021a832138e3440810722846b0363cc6 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 2 Dec 2013 01:24:05 +0000 Subject: [PATCH 027/276] Still more #if SQLITE_VERSION_NUMBER macros in test/speedtest1.c to enable compilation against older versions of SQLite. FossilOrigin-Name: 4b20cf4206ac12975ca9c4ec7ef76aa21bbd734d --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/speedtest1.c | 7 ++++++- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 4bc50bd00e..f04576e670 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\ssome\s#if\sSQLITE_VERSION_NUMBER\smacros\sto\stest/speedtest1.c\sin\sorder\sto\nmake\sit\scompatible\swith\solder\sversions\sof\sSQLite\sso\sthat\sit\scan\sbe\sused\sfor\nhistorical\sspeed\scomparisons. -D 2013-12-01T18:10:01.701 +C Still\smore\s#if\sSQLITE_VERSION_NUMBER\smacros\sin\stest/speedtest1.c\sto\senable\ncompilation\sagainst\solder\sversions\sof\sSQLite. +D 2013-12-02T01:24:05.116 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -820,7 +820,7 @@ F test/speed3.test d32043614c08c53eafdc80f33191d5bd9b920523 F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b -F test/speedtest1.c aa1ff125bc9c4b8eb55db2e3cbb82ba76794dedf +F test/speedtest1.c ae9d739b7ffba4d63086e365753c56561815514c F test/spellfix.test 8c40b169b104086d8795781f670ba3c786d6d8be F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298 F test/stat.test c8eccfe8fcd3f3cfc864ce22d5b9e803a3c69940 @@ -1145,7 +1145,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P c85e0c546ea6c6be46deea5c7a716b5fb553c7b4 -R 3cfbbdfa905179d97133dd917fc5f770 +P a9e1627ae714156cf6bd419e41cf9b79fbbe99a9 +R 84934b6097c3af0a8962d3cfd75d2be6 U drh -Z aec8d6f2ae39d50473657768f7788a16 +Z a36aa806db8ddb60dca1807195d9ce52 diff --git a/manifest.uuid b/manifest.uuid index e66ea9881c..a685b51324 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a9e1627ae714156cf6bd419e41cf9b79fbbe99a9 \ No newline at end of file +4b20cf4206ac12975ca9c4ec7ef76aa21bbd734d \ No newline at end of file diff --git a/test/speedtest1.c b/test/speedtest1.c index 473b3d191e..766e80dac6 100644 --- a/test/speedtest1.c +++ b/test/speedtest1.c @@ -137,9 +137,12 @@ sqlite3_int64 speedtest1_timestamp(void){ static sqlite3_vfs *clockVfs = 0; sqlite3_int64 t; if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0); +#if SQLITE_VERSION_NUMBER>=3007000 if( clockVfs->iVersion>=2 && clockVfs->xCurrentTimeInt64!=0 ){ clockVfs->xCurrentTimeInt64(clockVfs, &t); - }else{ + }else +#endif + { double r; clockVfs->xCurrentTime(clockVfs, &r); t = (sqlite3_int64)(r*86400000.0); @@ -936,8 +939,10 @@ int main(int argc, char **argv){ if( showStats ){ sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHi, 0); printf("-- Memory Used (bytes): %d (max %d)\n", iCur,iHi); +#if SQLITE_VERSION_NUMBER>=3007000 sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHi, 0); printf("-- Outstanding Allocations: %d (max %d)\n", iCur,iHi); +#endif sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHi, 0); printf("-- Pcache Overflow Bytes: %d (max %d)\n", iCur,iHi); sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHi, 0); From 2a702db1cf51dc94db0f40e8dd8e8ce60612180c Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 2 Dec 2013 21:25:40 +0000 Subject: [PATCH 028/276] Another #if SQLITE_VERSION_NUMBER macro in speedtest1.c for compatibility with older versions of SQLite. FossilOrigin-Name: bc8eacc7f71413184ef5be1412e51f8fd7174cd1 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/speedtest1.c | 4 +++- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index f04576e670..baeef82ada 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Still\smore\s#if\sSQLITE_VERSION_NUMBER\smacros\sin\stest/speedtest1.c\sto\senable\ncompilation\sagainst\solder\sversions\sof\sSQLite. -D 2013-12-02T01:24:05.116 +C Another\s#if\sSQLITE_VERSION_NUMBER\smacro\sin\sspeedtest1.c\sfor\scompatibility\nwith\solder\sversions\sof\sSQLite. +D 2013-12-02T21:25:40.013 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -820,7 +820,7 @@ F test/speed3.test d32043614c08c53eafdc80f33191d5bd9b920523 F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b -F test/speedtest1.c ae9d739b7ffba4d63086e365753c56561815514c +F test/speedtest1.c 4f1e34b6af9af0b59ca11b57d62c3cd851990fba F test/spellfix.test 8c40b169b104086d8795781f670ba3c786d6d8be F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298 F test/stat.test c8eccfe8fcd3f3cfc864ce22d5b9e803a3c69940 @@ -1145,7 +1145,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P a9e1627ae714156cf6bd419e41cf9b79fbbe99a9 -R 84934b6097c3af0a8962d3cfd75d2be6 +P 4b20cf4206ac12975ca9c4ec7ef76aa21bbd734d +R fc7264469bd7eed8b2c47bd423fccf15 U drh -Z a36aa806db8ddb60dca1807195d9ce52 +Z f0389d08b87706a34ccfa173cc3d5e77 diff --git a/manifest.uuid b/manifest.uuid index a685b51324..c2586c5739 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4b20cf4206ac12975ca9c4ec7ef76aa21bbd734d \ No newline at end of file +bc8eacc7f71413184ef5be1412e51f8fd7174cd1 \ No newline at end of file diff --git a/test/speedtest1.c b/test/speedtest1.c index 766e80dac6..f3e79ec816 100644 --- a/test/speedtest1.c +++ b/test/speedtest1.c @@ -922,9 +922,11 @@ int main(int argc, char **argv){ sqlite3_db_status(g.db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHi, 1); printf("-- Page cache hits: %d\n", iCur); sqlite3_db_status(g.db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHi, 1); - printf("-- Page cache misses: %d\n", iCur); + printf("-- Page cache misses: %d\n", iCur); +#if SQLITE_VERSION_NUMBER>=3007012 sqlite3_db_status(g.db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHi, 1); printf("-- Page cache writes: %d\n", iCur); +#endif sqlite3_db_status(g.db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHi, 0); printf("-- Schema Heap Usage: %d bytes\n", iCur); sqlite3_db_status(g.db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHi, 0); From 47b927d2c3552f0ba4c70b15e564612839708156 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 3 Dec 2013 00:11:40 +0000 Subject: [PATCH 029/276] Fix a harmless compiler warning on MacOS. FossilOrigin-Name: 74328de1d720fb35a97b476034406ca17d35ff5f --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/build.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index baeef82ada..5357d69a75 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Another\s#if\sSQLITE_VERSION_NUMBER\smacro\sin\sspeedtest1.c\sfor\scompatibility\nwith\solder\sversions\sof\sSQLite. -D 2013-12-02T21:25:40.013 +C Fix\sa\sharmless\scompiler\swarning\son\sMacOS. +D 2013-12-03T00:11:40.557 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -169,7 +169,7 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btree.c fe6c95c57fd14ed4b3329f4b5bb08132fe7c322d F src/btree.h a61ddebc78c66795a2b93181321a116746302cc9 F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0 -F src/build.c 07054d45319953e54a89d726e589a423e9c1c590 +F src/build.c 1965c7b596ca6295b7ca59541ad186c57564b8f7 F src/callback.c f99a8957ba2adf369645fac0db09ad8adcf1caa2 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c ea4b7f3623a0fcb1146e7f245d7410033e86859c @@ -1145,7 +1145,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 4b20cf4206ac12975ca9c4ec7ef76aa21bbd734d -R fc7264469bd7eed8b2c47bd423fccf15 +P bc8eacc7f71413184ef5be1412e51f8fd7174cd1 +R 62604634a0764c5c22be734f75dfcb96 U drh -Z f0389d08b87706a34ccfa173cc3d5e77 +Z 14b44bb1d46bbe3c25a7b8e87798f10b diff --git a/manifest.uuid b/manifest.uuid index c2586c5739..cc652f65bb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bc8eacc7f71413184ef5be1412e51f8fd7174cd1 \ No newline at end of file +74328de1d720fb35a97b476034406ca17d35ff5f \ No newline at end of file diff --git a/src/build.c b/src/build.c index 27f026c8dd..fd512358bc 100644 --- a/src/build.c +++ b/src/build.c @@ -2790,7 +2790,7 @@ Index *sqlite3CreateIndex( const Column *pTabCol; /* A column in the table */ int nExtra = 0; /* Space allocated for zExtra[] */ int nExtraCol; /* Number of extra columns needed */ - char *zExtra; /* Extra space after the Index object */ + char *zExtra = 0; /* Extra space after the Index object */ Index *pPk = 0; /* PRIMARY KEY index for WITHOUT ROWID tables */ assert( pParse->nErr==0 ); /* Never called with prior errors */ From d5e4547084ee26b732af07bb8c55d8b5879c5074 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 3 Dec 2013 02:52:11 +0000 Subject: [PATCH 030/276] Change some unreachable test conditions to NEVER(). FossilOrigin-Name: 7d99858bec699dface548c77649dfc50e7fb50d8 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbemem.c | 11 +---------- 3 files changed, 8 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index 5357d69a75..3e498482df 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sharmless\scompiler\swarning\son\sMacOS. -D 2013-12-03T00:11:40.557 +C Change\ssome\sunreachable\stest\sconditions\sto\sNEVER(). +D 2013-12-03T02:52:11.992 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -286,7 +286,7 @@ F src/vdbeInt.h 05fbda0e061dbc4aaa2709a8cccf3515c245b263 F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed F src/vdbeaux.c 5b58b242afe50f6bae77da1c1e26330af32e51c7 F src/vdbeblob.c 8cd05a5630e6d5563ad017bf82edaf812b28acde -F src/vdbemem.c af650c2019dc197f062440cdb4650b7204e648bf +F src/vdbemem.c fed9357c0b79cd707957c28b144f5bf9d7cc6bfc F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147 F src/vdbetrace.c e7ec40e1999ff3c6414424365d5941178966dcbc F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd @@ -1145,7 +1145,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P bc8eacc7f71413184ef5be1412e51f8fd7174cd1 -R 62604634a0764c5c22be734f75dfcb96 +P 74328de1d720fb35a97b476034406ca17d35ff5f +R d881184ebe8e40a91ad03d9c9de08f57 U drh -Z 14b44bb1d46bbe3c25a7b8e87798f10b +Z e99c771249b48673bb69ac05e8b183ed diff --git a/manifest.uuid b/manifest.uuid index cc652f65bb..de214931f3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -74328de1d720fb35a97b476034406ca17d35ff5f \ No newline at end of file +7d99858bec699dface548c77649dfc50e7fb50d8 \ No newline at end of file diff --git a/src/vdbemem.c b/src/vdbemem.c index 0fe7a3bcb4..9604920150 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -1078,16 +1078,7 @@ static int valueFromExpr( return SQLITE_OK; } op = pExpr->op; - - /* op can only be TK_REGISTER if we have compiled with SQLITE_ENABLE_STAT4. - ** The ifdef here is to enable us to achieve 100% branch test coverage even - ** when SQLITE_ENABLE_STAT4 is omitted. - */ -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 - if( op==TK_REGISTER ) op = pExpr->op2; -#else if( NEVER(op==TK_REGISTER) ) op = pExpr->op2; -#endif /* Handle negative integers in a single step. This is needed in the ** case when the value is -9223372036854775808. @@ -1309,7 +1300,7 @@ int sqlite3Stat4ProbeSetValue( *pbOk = 1; } }else if( pExpr->op==TK_VARIABLE - || (pExpr->op==TK_REGISTER && pExpr->op2==TK_VARIABLE) + || NEVER(pExpr->op==TK_REGISTER && pExpr->op2==TK_VARIABLE) ){ Vdbe *v; int iBindVar = pExpr->iColumn; From 89bc021850216b15e350ac0970bd578465a77837 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 3 Dec 2013 09:49:52 +0000 Subject: [PATCH 031/276] Add a "database_may_be_corrupt" directive to test file fuzz3.test. Reformat an assert() statement in vdbeaux.c to make its intent clearer. FossilOrigin-Name: 9d8a0e132163f7adeaabbf6baba119e159addd41 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/vdbeaux.c | 3 ++- test/fuzz3.test | 3 +++ 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 3e498482df..f3c8156695 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\ssome\sunreachable\stest\sconditions\sto\sNEVER(). -D 2013-12-03T02:52:11.992 +C Add\sa\s"database_may_be_corrupt"\sdirective\sto\stest\sfile\sfuzz3.test.\sReformat\san\sassert()\sstatement\sin\svdbeaux.c\sto\smake\sits\sintent\sclearer. +D 2013-12-03T09:49:52.308 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -284,7 +284,7 @@ F src/vdbe.c 54894fde8dc806d259e015ac7c9680145e725835 F src/vdbe.h c06f0813f853566457ce9cfb1a4a4bc39a5da644 F src/vdbeInt.h 05fbda0e061dbc4aaa2709a8cccf3515c245b263 F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed -F src/vdbeaux.c 5b58b242afe50f6bae77da1c1e26330af32e51c7 +F src/vdbeaux.c 09b79d475f5af2b3b5068f639609d88e0ced9d95 F src/vdbeblob.c 8cd05a5630e6d5563ad017bf82edaf812b28acde F src/vdbemem.c fed9357c0b79cd707957c28b144f5bf9d7cc6bfc F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147 @@ -581,7 +581,7 @@ F test/func5.test 1435dd313c0bae70d6af089c97a2a997fc5d0e53 F test/fuzz-oss1.test 4912e528ec9cf2f42134456933659d371c9e0d74 F test/fuzz.test 77fd50afc12847af50fcf1941679d90adebadde6 F test/fuzz2.test 207d0f9d06db3eaf47a6b7bfc835b8e2fc397167 -F test/fuzz3.test aec64345184d1662bd30e6a17851ff659d596dc5 +F test/fuzz3.test efd384b896c647b61a2c1848ba70d42aad60a7b3 F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26 F test/fuzzer1.test d4c52aaf3ef923da293a2653cfab33d02f718a36 @@ -1145,7 +1145,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 74328de1d720fb35a97b476034406ca17d35ff5f -R d881184ebe8e40a91ad03d9c9de08f57 -U drh -Z e99c771249b48673bb69ac05e8b183ed +P 7d99858bec699dface548c77649dfc50e7fb50d8 +R 01634e02d76e60e1c382f3065633e24e +U dan +Z 41f50bc12fef31f82fd848dddcf71f30 diff --git a/manifest.uuid b/manifest.uuid index de214931f3..384618d9eb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7d99858bec699dface548c77649dfc50e7fb50d8 \ No newline at end of file +9d8a0e132163f7adeaabbf6baba119e159addd41 \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 7a672fdf27..5b5d82aed8 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -3114,7 +3114,8 @@ int sqlite3VdbeRecordCompare( d1 = szHdr1; assert( pKeyInfo->nField+pKeyInfo->nXField>=pPKey2->nField || CORRUPT_DB ); assert( pKeyInfo->aSortOrder!=0 ); - assert( (idx1<=szHdr1 && inField) || CORRUPT_DB ); + assert( pKeyInfo->nField>0 ); + assert( idx1<=szHdr1 || CORRUPT_DB ); do{ u32 serial_type1; diff --git a/test/fuzz3.test b/test/fuzz3.test index d0efc5250e..2b21404f43 100644 --- a/test/fuzz3.test +++ b/test/fuzz3.test @@ -18,6 +18,9 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl +# These tests deal with corrupt database files +# +database_may_be_corrupt expr srand(123) From 9a01c16df8c84b1c2a8a3621dae065641a1b27cb Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 3 Dec 2013 10:14:28 +0000 Subject: [PATCH 032/276] Remove an unnecessary branch from the UPDATE logic - one that was also unreachable except following an OOM on x64. FossilOrigin-Name: 72f972771457b8c8d9f859238d6a72b43f41d2c3 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/update.c | 6 +----- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index f3c8156695..1dc797e962 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\s"database_may_be_corrupt"\sdirective\sto\stest\sfile\sfuzz3.test.\sReformat\san\sassert()\sstatement\sin\svdbeaux.c\sto\smake\sits\sintent\sclearer. -D 2013-12-03T09:49:52.308 +C Remove\san\sunnecessary\sbranch\sfrom\sthe\sUPDATE\slogic\s-\sone\sthat\swas\salso\nunreachable\sexcept\sfollowing\san\sOOM\son\sx64. +D 2013-12-03T10:14:28.006 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -276,7 +276,7 @@ F src/test_vfstrace.c 34b544e80ba7fb77be15395a609c669df2e660a2 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/tokenize.c ec4c1a62b890bf1dbcdb966399e140b904c700a4 F src/trigger.c d84e1f3669e9a217731a14a9d472b1c7b87c87ba -F src/update.c c05a0ee658f1a149e0960dfd110f3b8bd846bcb0 +F src/update.c d1c2477dcf14d90999d1935af4efb4806553250b F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c c1d47254d805074226eb68bab2327f2559799d88 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 @@ -1145,7 +1145,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 7d99858bec699dface548c77649dfc50e7fb50d8 -R 01634e02d76e60e1c382f3065633e24e -U dan -Z 41f50bc12fef31f82fd848dddcf71f30 +P 9d8a0e132163f7adeaabbf6baba119e159addd41 +R b80304a65eb00e702388789b1ac9934c +U drh +Z 888bf6726ec80b20bf3ce578518b415f diff --git a/manifest.uuid b/manifest.uuid index 384618d9eb..c5e62f74e7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9d8a0e132163f7adeaabbf6baba119e159addd41 \ No newline at end of file +72f972771457b8c8d9f859238d6a72b43f41d2c3 \ No newline at end of file diff --git a/src/update.c b/src/update.c index f2be6d984c..4459a9fb86 100644 --- a/src/update.c +++ b/src/update.c @@ -579,11 +579,7 @@ void sqlite3Update( sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, 0); } if( bReplace || chngKey ){ - if( sqlite3VdbeCurrentAddr(v)==j1+1 ){ - sqlite3VdbeChangeToNoop(v, j1); - }else{ - sqlite3VdbeJumpHere(v, j1); - } + sqlite3VdbeJumpHere(v, j1); } if( hasFK ){ From 070865da8d535e1dc2588892789e252369359e29 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 3 Dec 2013 10:35:00 +0000 Subject: [PATCH 033/276] Modify test file conflict2.test so that it works with the "inmemory_journal" permutation. FossilOrigin-Name: e4164fd8f75ce1c8d63bec70db7049b68208c12c --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/conflict2.test | 5 +++++ 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 1dc797e962..126265ec88 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunnecessary\sbranch\sfrom\sthe\sUPDATE\slogic\s-\sone\sthat\swas\salso\nunreachable\sexcept\sfollowing\san\sOOM\son\sx64. -D 2013-12-03T10:14:28.006 +C Modify\stest\sfile\sconflict2.test\sso\sthat\sit\sworks\swith\sthe\s"inmemory_journal"\spermutation. +D 2013-12-03T10:35:00.119 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -387,7 +387,7 @@ F test/collateA.test b8218ab90d1fa5c59dcf156efabb1b2599c580d6 F test/colmeta.test 087c42997754b8c648819832241daf724f813322 F test/colname.test 08948a4809d22817e0e5de89c7c0a8bd90cb551b F test/conflict.test 841bcf7cabbfca39c577eb8411ea8601843b46a8 -F test/conflict2.test 3ed0b6ec3c2cb8acebbc89677ea0e58c01aaa1ff +F test/conflict2.test 0d3af4fb534fa1bd020c79960bb56e4d52655f09 F test/conflict3.test dec0634c0f31dec9a4b01c63063e939f0cd21b6b F test/contrib01.test 2a1cbc0f2f48955d7d073f725765da6fbceda6b4 F test/corrupt.test 141c39ea650c1365e85a49e402fa05cb9617fb97 @@ -1145,7 +1145,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 9d8a0e132163f7adeaabbf6baba119e159addd41 -R b80304a65eb00e702388789b1ac9934c -U drh -Z 888bf6726ec80b20bf3ce578518b415f +P 72f972771457b8c8d9f859238d6a72b43f41d2c3 +R 020474fd63af79df89a67b479d50bb6b +U dan +Z 3e14c48cef582c6bdd39cdd39332c46a diff --git a/manifest.uuid b/manifest.uuid index c5e62f74e7..6f20eb8820 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -72f972771457b8c8d9f859238d6a72b43f41d2c3 \ No newline at end of file +e4164fd8f75ce1c8d63bec70db7049b68208c12c \ No newline at end of file diff --git a/test/conflict2.test b/test/conflict2.test index 23fbf9da7c..8419f1a3ff 100644 --- a/test/conflict2.test +++ b/test/conflict2.test @@ -305,6 +305,11 @@ foreach {i conf1 cmd t0 t1 t2 t3 t4} { 15 {} {UPDATE OR ABORT} 1 {1 2 3 4} 1 0 1 16 {} {UPDATE OR ROLLBACK} 1 {1 2 3 4} 0 0 0 } { + + # When using in-memory journals, no temporary files are required for + # statement journals. + if {[permutation] == "inmemory_journal"} { set t4 0 } + if {$t0} {set t1 {UNIQUE constraint failed: t1.a}} if {[info exists TEMP_STORE] && $TEMP_STORE==3} { set t3 0 From 1868cbc78c995d51462781ed21abf2a1a08a73cc Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 3 Dec 2013 17:09:53 +0000 Subject: [PATCH 034/276] Fix a typo in fts3varint.test preventing the valgrind permutation test from running. FossilOrigin-Name: b654a4ec729c86c6e94365fb0d3f83c598d4461a --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/fts3varint.test | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 126265ec88..0472ec5877 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Modify\stest\sfile\sconflict2.test\sso\sthat\sit\sworks\swith\sthe\s"inmemory_journal"\spermutation. -D 2013-12-03T10:35:00.119 +C Fix\sa\stypo\sin\sfts3varint.test\spreventing\sthe\svalgrind\spermutation\stest\sfrom\srunning. +D 2013-12-03T17:09:53.190 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -559,7 +559,7 @@ F test/fts3snippet.test d524af6bcef4714e059ef559113dbdc924cd33d1 F test/fts3sort.test ed34c716a11cc2009a35210e84ad5f9c102362ca F test/fts3tok1.test b10d0a12a0ab5f905cea1200b745de233f37443f F test/fts3tok_err.test 52273cd193b9036282f7bacb43da78c6be87418d -F test/fts3varint.test 23e79002ebebd6fbb1235504f7acb087b0fea741 +F test/fts3varint.test 752c08ed5d32c5d7dc211b056f4ed68a76b7e36e F test/fts4aa.test 0c3152322c7f0b548cc942ad763eaba0da87ccca F test/fts4check.test 66fa274cab2b615f2fb338b257713aba8fad88a8 F test/fts4content.test 2e7252557d6d24afa101d9ba1de710d6140e6d06 @@ -1145,7 +1145,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 72f972771457b8c8d9f859238d6a72b43f41d2c3 -R 020474fd63af79df89a67b479d50bb6b +P e4164fd8f75ce1c8d63bec70db7049b68208c12c +R 5dd75e0d17034f1dfb570f2b50097682 U dan -Z 3e14c48cef582c6bdd39cdd39332c46a +Z 186cdf231e96bcfce0281b587d69f9f7 diff --git a/manifest.uuid b/manifest.uuid index 6f20eb8820..1071089651 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e4164fd8f75ce1c8d63bec70db7049b68208c12c \ No newline at end of file +b654a4ec729c86c6e94365fb0d3f83c598d4461a \ No newline at end of file diff --git a/test/fts3varint.test b/test/fts3varint.test index 229c37bac6..ca0189dbfc 100644 --- a/test/fts3varint.test +++ b/test/fts3varint.test @@ -10,7 +10,7 @@ # $Id: fts3.test,v 1.2 2008/07/23 18:17:32 drh Exp $ set testdir [file dirname $argv0] -source $testdir/permutations.test +source $testdir/tester.tcl set testprefix fts3varint ifcapable !fts3 { From b5f68b0c8c0adb278e0cb9d1655d7855a5717776 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 3 Dec 2013 18:26:56 +0000 Subject: [PATCH 035/276] Fix an alignment problem in the stat3/stat4 code affecting 32-bit platforms. FossilOrigin-Name: 14f9bc79014e5762b88b9f0b98f4d47a8092d127 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbemem.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 0472ec5877..345a88274d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\stypo\sin\sfts3varint.test\spreventing\sthe\svalgrind\spermutation\stest\sfrom\srunning. -D 2013-12-03T17:09:53.190 +C Fix\san\salignment\sproblem\sin\sthe\sstat3/stat4\scode\saffecting\s32-bit\splatforms. +D 2013-12-03T18:26:56.746 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -286,7 +286,7 @@ F src/vdbeInt.h 05fbda0e061dbc4aaa2709a8cccf3515c245b263 F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed F src/vdbeaux.c 09b79d475f5af2b3b5068f639609d88e0ced9d95 F src/vdbeblob.c 8cd05a5630e6d5563ad017bf82edaf812b28acde -F src/vdbemem.c fed9357c0b79cd707957c28b144f5bf9d7cc6bfc +F src/vdbemem.c d9811b08c4cda6f9108b49223aa0d3b07d595eb5 F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147 F src/vdbetrace.c e7ec40e1999ff3c6414424365d5941178966dcbc F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd @@ -1145,7 +1145,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P e4164fd8f75ce1c8d63bec70db7049b68208c12c -R 5dd75e0d17034f1dfb570f2b50097682 +P b654a4ec729c86c6e94365fb0d3f83c598d4461a +R 9b643eb26a4f573bb81c9ce75c7a93ef U dan -Z 186cdf231e96bcfce0281b587d69f9f7 +Z 1aa369240dc90be6769d251ab8ec5acc diff --git a/manifest.uuid b/manifest.uuid index 1071089651..39f7a3f4c0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b654a4ec729c86c6e94365fb0d3f83c598d4461a \ No newline at end of file +14f9bc79014e5762b88b9f0b98f4d47a8092d127 \ No newline at end of file diff --git a/src/vdbemem.c b/src/vdbemem.c index 9604920150..670691c072 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -1016,7 +1016,7 @@ static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){ int i; /* Counter variable */ int nCol = pIdx->nColumn; /* Number of index columns including rowid */ - nByte = sizeof(Mem) * nCol + sizeof(UnpackedRecord); + nByte = sizeof(Mem) * nCol + ROUND8(sizeof(UnpackedRecord)); pRec = (UnpackedRecord*)sqlite3DbMallocZero(db, nByte); if( pRec ){ pRec->pKeyInfo = sqlite3KeyInfoOfIndex(p->pParse, pIdx); @@ -1024,7 +1024,7 @@ static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){ assert( pRec->pKeyInfo->nField+pRec->pKeyInfo->nXField==nCol ); assert( pRec->pKeyInfo->enc==ENC(db) ); pRec->flags = UNPACKED_PREFIX_MATCH; - pRec->aMem = (Mem *)&pRec[1]; + pRec->aMem = (Mem *)((u8*)pRec + ROUND8(sizeof(UnpackedRecord))); for(i=0; iaMem[i].flags = MEM_Null; pRec->aMem[i].type = SQLITE_NULL; From 7190e07fc024aa1e97ed5b4a61011a35b77053fa Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 3 Dec 2013 19:16:06 +0000 Subject: [PATCH 036/276] Fix a possible (and probably harmless) uninitialized variable in STAT3/4. FossilOrigin-Name: 33ad4f91477907b7b3e5808c7ba11aacc9a83ba6 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbemem.c | 6 +----- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 345a88274d..6bff4a4071 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\salignment\sproblem\sin\sthe\sstat3/stat4\scode\saffecting\s32-bit\splatforms. -D 2013-12-03T18:26:56.746 +C Fix\sa\spossible\s(and\sprobably\sharmless)\suninitialized\svariable\sin\sSTAT3/4. +D 2013-12-03T19:16:06.615 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -286,7 +286,7 @@ F src/vdbeInt.h 05fbda0e061dbc4aaa2709a8cccf3515c245b263 F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed F src/vdbeaux.c 09b79d475f5af2b3b5068f639609d88e0ced9d95 F src/vdbeblob.c 8cd05a5630e6d5563ad017bf82edaf812b28acde -F src/vdbemem.c d9811b08c4cda6f9108b49223aa0d3b07d595eb5 +F src/vdbemem.c 20e349d2ca928802fc8f2d42a2cc488fd6981d3f F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147 F src/vdbetrace.c e7ec40e1999ff3c6414424365d5941178966dcbc F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd @@ -1145,7 +1145,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P b654a4ec729c86c6e94365fb0d3f83c598d4461a -R 9b643eb26a4f573bb81c9ce75c7a93ef -U dan -Z 1aa369240dc90be6769d251ab8ec5acc +P 14f9bc79014e5762b88b9f0b98f4d47a8092d127 +R a21a54e67ec7aa45fd701d0774acda83 +U drh +Z 49eaa17223688ae51427734254ac0a7e diff --git a/manifest.uuid b/manifest.uuid index 39f7a3f4c0..30347924f9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -14f9bc79014e5762b88b9f0b98f4d47a8092d127 \ No newline at end of file +33ad4f91477907b7b3e5808c7ba11aacc9a83ba6 \ No newline at end of file diff --git a/src/vdbemem.c b/src/vdbemem.c index 670691c072..51f20d4cc7 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -1297,7 +1297,6 @@ int sqlite3Stat4ProbeSetValue( pVal = valueNew(db, &alloc); if( pVal ){ sqlite3VdbeMemSetNull((Mem*)pVal); - *pbOk = 1; } }else if( pExpr->op==TK_VARIABLE || NEVER(pExpr->op==TK_REGISTER && pExpr->op2==TK_VARIABLE) @@ -1313,16 +1312,13 @@ int sqlite3Stat4ProbeSetValue( sqlite3ValueApplyAffinity(pVal, affinity, ENC(db)); } pVal->db = pParse->db; - *pbOk = 1; sqlite3VdbeMemStoreType((Mem*)pVal); } - }else{ - *pbOk = 0; } }else{ rc = valueFromExpr(db, pExpr, ENC(db), affinity, &pVal, &alloc); - *pbOk = (pVal!=0); } + *pbOk = (pVal!=0); assert( pVal==0 || pVal->db==db ); return rc; From 7f59475fdaac1f487f32cc3604b15a7273b73631 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 3 Dec 2013 19:49:55 +0000 Subject: [PATCH 037/276] Remove a branch in STAT4 logic that is no longer reachable after the previous change. FossilOrigin-Name: eca7d3f1612c7a009a9e4ef89f76f9b7e275d1e6 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/where.c | 3 +-- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 6bff4a4071..aceb0f89c8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\spossible\s(and\sprobably\sharmless)\suninitialized\svariable\sin\sSTAT3/4. -D 2013-12-03T19:16:06.615 +C Remove\sa\sbranch\sin\sSTAT4\slogic\sthat\sis\sno\slonger\sreachable\safter\s\nthe\sprevious\schange. +D 2013-12-03T19:49:55.482 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -293,7 +293,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c e9e593d5bb798c3e67fc3893dfe7055c9e7d8d74 -F src/where.c e0a9909a58eee7dcde1d1bd5cf6381b0dbc83389 +F src/where.c e6a4e713abe6f995495ea53dd6a5e48f88b53883 F src/whereInt.h 96a75c61f1d2b9d4a8e4bb17d89deb0cf7cba358 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1145,7 +1145,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 14f9bc79014e5762b88b9f0b98f4d47a8092d127 -R a21a54e67ec7aa45fd701d0774acda83 +P 33ad4f91477907b7b3e5808c7ba11aacc9a83ba6 +R b9a8385eb7153992ed9d3229f4d58e8a U drh -Z 49eaa17223688ae51427734254ac0a7e +Z 1abf6c68d7a5a613f293f6a4e7a65cb6 diff --git a/manifest.uuid b/manifest.uuid index 30347924f9..33fe443f15 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -33ad4f91477907b7b3e5808c7ba11aacc9a83ba6 \ No newline at end of file +eca7d3f1612c7a009a9e4ef89f76f9b7e275d1e6 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 7ec6cfaae7..7d3ec48dac 100644 --- a/src/where.c +++ b/src/where.c @@ -1905,8 +1905,7 @@ static void whereKeyStats( #ifndef SQLITE_DEBUG UNUSED_PARAMETER( pParse ); #endif - assert( pRec!=0 || pParse->db->mallocFailed ); - if( pRec==0 ) return; + assert( pRec!=0 ); iCol = pRec->nField - 1; assert( pIdx->nSample>0 ); assert( pRec->nField>0 && iColnSampleCol ); From 1fa85a15df681cd1ed0f8f93ebe248a4e92620e4 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Tue, 3 Dec 2013 22:32:48 +0000 Subject: [PATCH 038/276] Add memory subsystem related defines to the compile-time options list. FossilOrigin-Name: 52a44146dd7c5a7662545042045e23deab302c96 --- manifest | 17 ++++++++++------- manifest.uuid | 2 +- src/ctime.c | 6 ++++++ 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index aceb0f89c8..81c7f73bd7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sa\sbranch\sin\sSTAT4\slogic\sthat\sis\sno\slonger\sreachable\safter\s\nthe\sprevious\schange. -D 2013-12-03T19:49:55.482 +C Add\smemory\ssubsystem\srelated\sdefines\sto\sthe\scompile-time\soptions\slist. +D 2013-12-03T22:32:48.485 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -172,7 +172,7 @@ F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0 F src/build.c 1965c7b596ca6295b7ca59541ad186c57564b8f7 F src/callback.c f99a8957ba2adf369645fac0db09ad8adcf1caa2 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac -F src/ctime.c ea4b7f3623a0fcb1146e7f245d7410033e86859c +F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 F src/delete.c b36db1f79ee50eaca979660c9dd36437f5410b93 F src/expr.c 31a2b65339f6c3795d4cfa5e99798cd72f9fdfdf @@ -1145,7 +1145,10 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 33ad4f91477907b7b3e5808c7ba11aacc9a83ba6 -R b9a8385eb7153992ed9d3229f4d58e8a -U drh -Z 1abf6c68d7a5a613f293f6a4e7a65cb6 +P eca7d3f1612c7a009a9e4ef89f76f9b7e275d1e6 +R 532b42dc23159f7eb49f2139c4b28b74 +T *branch * memTests +T *sym-memTests * +T -sym-trunk * +U mistachkin +Z 95952b1fd2b9669de1eabdf9cc1c4e34 diff --git a/manifest.uuid b/manifest.uuid index 33fe443f15..08e424e306 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -eca7d3f1612c7a009a9e4ef89f76f9b7e275d1e6 \ No newline at end of file +52a44146dd7c5a7662545042045e23deab302c96 \ No newline at end of file diff --git a/src/ctime.c b/src/ctime.c index 7c915d58c6..c863cbed50 100644 --- a/src/ctime.c +++ b/src/ctime.c @@ -347,6 +347,9 @@ static const char * const azCompileOpt[] = { #ifdef SQLITE_SOUNDEX "SOUNDEX", #endif +#ifdef SQLITE_SYSTEM_MALLOC + "SYSTEM_MALLOC", +#endif #ifdef SQLITE_TCL "TCL", #endif @@ -362,6 +365,9 @@ static const char * const azCompileOpt[] = { #ifdef SQLITE_USE_ALLOCA "USE_ALLOCA", #endif +#ifdef SQLITE_WIN32_MALLOC + "WIN32_MALLOC", +#endif #ifdef SQLITE_ZERO_MALLOC "ZERO_MALLOC" #endif From 3f9cd2ae75e9d992179ef1de0b00c95e719a764f Mon Sep 17 00:00:00 2001 From: mistachkin Date: Tue, 3 Dec 2013 22:33:35 +0000 Subject: [PATCH 039/276] Fix harmless compiler warnings. FossilOrigin-Name: a12d214ecccc5d3372dbcedc88705b0092363971 --- manifest | 15 ++++++--------- manifest.uuid | 2 +- src/mem5.c | 4 ++-- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 81c7f73bd7..27c9a6e154 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\smemory\ssubsystem\srelated\sdefines\sto\sthe\scompile-time\soptions\slist. -D 2013-12-03T22:32:48.485 +C Fix\sharmless\scompiler\swarnings. +D 2013-12-03T22:33:35.657 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -194,7 +194,7 @@ F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c0c990fcaddff810ea277b4fb5d9138603dd5d4b F src/mem2.c dce31758da87ec2cfa52ba4c5df1aed6e07d8e8f F src/mem3.c 61c9d47b792908c532ca3a62b999cf21795c6534 -F src/mem5.c 2221f7e4619619d2df16fcb8a1da2a165ae56d9d +F src/mem5.c 19d9271cb936742707b6118ed44d779657c7c511 F src/memjournal.c 0683aac6cab6ec2b5374c0db37c0deb2436a3785 F src/mutex.c d3b66a569368015e0fcb1ac15f81c119f504d3bc F src/mutex.h 5bc526e19dccc412b7ff04642f6fdad3fdfdabea @@ -1145,10 +1145,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P eca7d3f1612c7a009a9e4ef89f76f9b7e275d1e6 -R 532b42dc23159f7eb49f2139c4b28b74 -T *branch * memTests -T *sym-memTests * -T -sym-trunk * +P 52a44146dd7c5a7662545042045e23deab302c96 +R 2b3d133e432ced9c3134bb1e5c9a52ed U mistachkin -Z 95952b1fd2b9669de1eabdf9cc1c4e34 +Z c9f1aceb76bb9affc6fd3e7a6bcd7640 diff --git a/manifest.uuid b/manifest.uuid index 08e424e306..f54177f7c8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -52a44146dd7c5a7662545042045e23deab302c96 \ No newline at end of file +a12d214ecccc5d3372dbcedc88705b0092363971 \ No newline at end of file diff --git a/src/mem5.c b/src/mem5.c index 3870e91488..4674ec68f5 100644 --- a/src/mem5.c +++ b/src/mem5.c @@ -202,7 +202,7 @@ static void memsys5Leave(void){ static int memsys5Size(void *p){ int iSize = 0; if( p ){ - int i = ((u8 *)p-mem5.zPool)/mem5.szAtom; + int i = (int)(((u8 *)p-mem5.zPool)/mem5.szAtom); assert( i>=0 && i=0 && iBlock Date: Tue, 3 Dec 2013 23:33:29 +0000 Subject: [PATCH 040/276] Make use of the CC nmake macro even when cross-compiling (with MSVC). FossilOrigin-Name: aae7b30ebd9601882a02fe8cf46fbf0390ec3fac --- Makefile.msc | 2 +- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index 437cb0eac3..34059ea2f3 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -162,7 +162,7 @@ RC = rc.exe !IFDEF NCC NCC = $(NCC:\\=\) !ELSEIF $(XCOMPILE)!=0 -NCC = "$(VCINSTALLDIR)\bin\cl.exe" +NCC = "$(VCINSTALLDIR)\bin\$(CC)" NCC = $(NCC:\\=\) !ELSE NCC = $(CC) diff --git a/manifest b/manifest index 27c9a6e154..ce20ef4e04 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Fix\sharmless\scompiler\swarnings. -D 2013-12-03T22:33:35.657 +C Make\suse\sof\sthe\sCC\snmake\smacro\seven\swhen\scross-compiling\s(with\sMSVC). +D 2013-12-03T23:33:29.475 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 -F Makefile.msc a6247094079f3ef97dcd7a69d0e13ff718c7073e +F Makefile.msc bb1f271c8ee9773489c89be00f3f8ad7ed7ae8e0 F Makefile.vxworks db21ed42a01d5740e656b16f92cb5d8d5e5dd315 F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6 F VERSION 52f7e22bfcec71a462e34194b4ae1671380fde59 @@ -1145,7 +1145,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 52a44146dd7c5a7662545042045e23deab302c96 -R 2b3d133e432ced9c3134bb1e5c9a52ed +P a12d214ecccc5d3372dbcedc88705b0092363971 +R 96895a4eb8660c34d34f5a43c1d0b764 U mistachkin -Z c9f1aceb76bb9affc6fd3e7a6bcd7640 +Z 57ab0c18bcd1f41d722261f64b89de43 diff --git a/manifest.uuid b/manifest.uuid index f54177f7c8..ce4e0f7069 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a12d214ecccc5d3372dbcedc88705b0092363971 \ No newline at end of file +aae7b30ebd9601882a02fe8cf46fbf0390ec3fac \ No newline at end of file From 47676fedf640e2433bde647a6c3343fa2e3a64c0 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 5 Dec 2013 16:41:55 +0000 Subject: [PATCH 041/276] Fix two potential (and apparently harmless) shift overflows discovered by the -fcatch-undefined-behavior option of clang. FossilOrigin-Name: e19eead8c9977ed4f00eac54c5bc7e90db78caa8 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/os_unix.c | 2 +- src/util.c | 4 +++- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index aceb0f89c8..3b88511979 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sa\sbranch\sin\sSTAT4\slogic\sthat\sis\sno\slonger\sreachable\safter\s\nthe\sprevious\schange. -D 2013-12-03T19:49:55.482 +C Fix\stwo\spotential\s(and\sapparently\sharmless)\sshift\soverflows\sdiscovered\sby\nthe\s-fcatch-undefined-behavior\soption\sof\sclang. +D 2013-12-05T16:41:55.583 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -205,7 +205,7 @@ F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30 F src/os.c b4ad71336fd96f97776f75587cd9e8218288f5be F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 -F src/os_unix.c 143624d9eabb3b997c59cf594e0d06c56edd43e9 +F src/os_unix.c f076587029285554a3a65d30d0e71d50cd61f41f F src/os_win.c 4323dd0bac4f7a7037fc4cf87fb4692d17f0b108 F src/pager.c 2aa4444ffe86e9282d03bc349a4a5e49bd77c0e8 F src/pager.h f094af9f6ececfaa8a1e93876905a4f34233fb0c @@ -278,7 +278,7 @@ F src/tokenize.c ec4c1a62b890bf1dbcdb966399e140b904c700a4 F src/trigger.c d84e1f3669e9a217731a14a9d472b1c7b87c87ba F src/update.c d1c2477dcf14d90999d1935af4efb4806553250b F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 -F src/util.c c1d47254d805074226eb68bab2327f2559799d88 +F src/util.c 76ed0519296e3f62e97e57dab1999e34184c8e49 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 F src/vdbe.c 54894fde8dc806d259e015ac7c9680145e725835 F src/vdbe.h c06f0813f853566457ce9cfb1a4a4bc39a5da644 @@ -1145,7 +1145,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 33ad4f91477907b7b3e5808c7ba11aacc9a83ba6 -R b9a8385eb7153992ed9d3229f4d58e8a +P eca7d3f1612c7a009a9e4ef89f76f9b7e275d1e6 +R ba7aebdef816e4dde9f2f30108dfb7a9 U drh -Z 1abf6c68d7a5a613f293f6a4e7a65cb6 +Z d225deef3eea562cd29618981c6f7c47 diff --git a/manifest.uuid b/manifest.uuid index 33fe443f15..7d458eb325 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -eca7d3f1612c7a009a9e4ef89f76f9b7e275d1e6 \ No newline at end of file +e19eead8c9977ed4f00eac54c5bc7e90db78caa8 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 501b1b769d..ab657dc7bd 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -4081,7 +4081,7 @@ static int unixShmSystemLock( #ifdef SQLITE_DEBUG { u16 mask; OSTRACE(("SHM-LOCK ")); - mask = (1<<(ofst+n)) - (1<31 ? 0xffffffff : (1<<(ofst+n)) - (1<=5 ) n -= 2; else if( n>=1 ) n -= 1; - if( x>=3 ) return (n+8)<<(x-3); + if( x>=3 ){ + return x>60 ? (u64)LARGEST_INT64 : (n+8)<<(x-3); + } return (n+8)>>(3-x); } From 6f04b95f02eeb62bcf3901d6d4483bdf68c000ee Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 6 Dec 2013 14:53:30 +0000 Subject: [PATCH 042/276] Version 3.8.2 FossilOrigin-Name: 27392118af4c38c5203a04b8013e1afdb1cebd0d --- manifest | 14 ++++++++------ manifest.uuid | 2 +- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index ac8e7ab09e..264b3fc190 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings\sand\simprove\sthe\sMSVC\smakefile. -D 2013-12-05T17:12:47.544 +C Version\s3.8.2 +D 2013-12-06T14:53:30.888 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -1145,8 +1145,10 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P e19eead8c9977ed4f00eac54c5bc7e90db78caa8 aae7b30ebd9601882a02fe8cf46fbf0390ec3fac +P c632567063d81c4be404ce58cbac0eff7412f565 R 39f74301df16683d1c19ab7ca83b6451 -T +closed aae7b30ebd9601882a02fe8cf46fbf0390ec3fac -U drh -Z b21886c5e68a29fa7489a30bb0f632c3 +T +bgcolor * #d0c0ff +T +sym-release * +T +sym-version-3.8.2 * +U dan +Z bddf39b758268961698f9899546a37dd diff --git a/manifest.uuid b/manifest.uuid index 047c9ce824..5097db9159 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c632567063d81c4be404ce58cbac0eff7412f565 \ No newline at end of file +27392118af4c38c5203a04b8013e1afdb1cebd0d \ No newline at end of file From 1b1f30bb5e9fe8e508c8953f4d29d29cb155a510 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 6 Dec 2013 15:37:35 +0000 Subject: [PATCH 043/276] Add code to detect if the database file is moved or deleted out from under SQLite and return an SQLITE_IOERR_NODB. FossilOrigin-Name: 8759a8e4d83b163e315eff316cf163f6ea42f2bb --- manifest | 27 ++++++++++++++------------- manifest.uuid | 2 +- src/os_win.c | 1 + src/pager.c | 25 +++++++++++++++++++++++++ src/sqlite.h.in | 6 +++++- src/test_vfstrace.c | 5 +++++ test/pager4.test | 33 +++++++++++++++++++++++++++++++++ 7 files changed, 84 insertions(+), 15 deletions(-) create mode 100644 test/pager4.test diff --git a/manifest b/manifest index 264b3fc190..feb65446f1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Version\s3.8.2 -D 2013-12-06T14:53:30.888 +C Add\scode\sto\sdetect\sif\sthe\sdatabase\sfile\sis\smoved\sor\sdeleted\sout\sfrom\sunder\nSQLite\sand\sreturn\san\sSQLITE_IOERR_NODB. +D 2013-12-06T15:37:35.675 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -206,8 +206,8 @@ F src/os.c b4ad71336fd96f97776f75587cd9e8218288f5be F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_unix.c f076587029285554a3a65d30d0e71d50cd61f41f -F src/os_win.c 4323dd0bac4f7a7037fc4cf87fb4692d17f0b108 -F src/pager.c 2aa4444ffe86e9282d03bc349a4a5e49bd77c0e8 +F src/os_win.c f149798adb6f32db835b2c9f9fac83d86015e004 +F src/pager.c 3648e602d484020d10cb514b04ef8f445ed06f30 F src/pager.h f094af9f6ececfaa8a1e93876905a4f34233fb0c F src/parse.y acee1a9958539e21263362b194594c5255ad2fca F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 @@ -221,7 +221,7 @@ F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c d41381d80a22d3a83352aeca274cccf264ac277a F src/shell.c 936a72ff784efff3832cce274a96ed0b036e6758 -F src/sqlite.h.in baf55c31c4e15a4b626acfeaa792f2aaa566657f +F src/sqlite.h.in 4373b4a913ea460d91a9a4a54906ee18b350d573 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc F src/sqliteInt.h f3a5d663fe9c6c0b2ee7fc2e20a6204eaea5bc7c @@ -272,7 +272,7 @@ F src/test_syscall.c 16dbe79fb320fadb5acd7a0a59f49e52ab2d2091 F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa F src/test_thread.c 1e133a40b50e9c035b00174035b846e7eef481cb F src/test_vfs.c e72f555ef7a59080f898fcf1a233deb9eb704ea9 -F src/test_vfstrace.c 34b544e80ba7fb77be15395a609c669df2e660a2 +F src/test_vfstrace.c 21b99a6fe3f4c8be13c0fe83006ee13873154d78 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/tokenize.c ec4c1a62b890bf1dbcdb966399e140b904c700a4 F src/trigger.c d84e1f3669e9a217731a14a9d472b1c7b87c87ba @@ -726,6 +726,7 @@ F test/oserror.test 50417780d0e0d7cd23cf12a8277bb44024765df3 F test/pager1.test 1acbdb14c5952a72dd43129cabdbf69aaa3ed1fa F test/pager2.test 67b8f40ae98112bcdba1f2b2d03ea83266418c71 F test/pager3.test 3856d9c80839be0668efee1b74811b1b7f7fc95f +F test/pager4.test 1848509f0aa83f99d438a2bae02c3fd64dd1afe6 F test/pagerfault.test 7285379906ab2f1108b8e82bbdf2d386cc8ff3ff F test/pagerfault2.test caf4c7facb914fd3b03a17b31ae2b180c8d6ca1f F test/pagerfault3.test 1003fcda009bf48a8e22a516e193b6ef0dd1bbd8 @@ -1145,10 +1146,10 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P c632567063d81c4be404ce58cbac0eff7412f565 -R 39f74301df16683d1c19ab7ca83b6451 -T +bgcolor * #d0c0ff -T +sym-release * -T +sym-version-3.8.2 * -U dan -Z bddf39b758268961698f9899546a37dd +P 27392118af4c38c5203a04b8013e1afdb1cebd0d +R 0833e0746c0a3bdbdf22e2e06343a85a +T *branch * detect-moved-db +T *sym-detect-moved-db * +T -sym-trunk * +U drh +Z 9ba43ea2faea1b2f751f5fd7fd1e8bc8 diff --git a/manifest.uuid b/manifest.uuid index 5097db9159..a2f643fbba 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -27392118af4c38c5203a04b8013e1afdb1cebd0d \ No newline at end of file +8759a8e4d83b163e315eff316cf163f6ea42f2bb \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index 22052a3fe7..56b546fb47 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -3192,6 +3192,7 @@ static int winSectorSize(sqlite3_file *id){ static int winDeviceCharacteristics(sqlite3_file *id){ winFile *p = (winFile*)id; return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN | + SQLITE_IOCAP_UNMOVABLE_WHEN_OPEN | ((p->ctrlFlags & WINFILE_PSOW)?SQLITE_IOCAP_POWERSAFE_OVERWRITE:0); } diff --git a/src/pager.c b/src/pager.c index d675b85821..78cb78ab23 100644 --- a/src/pager.c +++ b/src/pager.c @@ -4797,6 +4797,27 @@ int sqlite3PagerOpen( } +/* Verify that the database file has not be deleted or renamed out from +** under the pager. Return SQLITE_OK if the database is still were it ought +** to be on disk. Return non-zero (SQLITE_IOERR_NODB or some other error +** code from sqlite3OsAccess()) if the database has gone missing. +*/ +static int databaseIsUnmoved(Pager *pPager){ + const int fixedFlags = SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN | + SQLITE_IOCAP_UNMOVABLE_WHEN_OPEN; + int dc; + int x = 0, rc; + + if( pPager->tempFile ) return SQLITE_OK; + if( pPager->dbSize==0 ) return SQLITE_OK; + assert( pPager->zFilename && pPager->zFilename[0] ); + dc = sqlite3OsDeviceCharacteristics(pPager->fd); + if( (dc&fixedFlags)==fixedFlags ) return SQLITE_OK; + rc = sqlite3OsAccess(pPager->pVfs, pPager->zFilename, SQLITE_ACCESS_EXISTS, &x); + if( rc==SQLITE_OK && !x ) rc = SQLITE_IOERR_NODB; + return rc; +} + /* ** This function is called after transitioning from PAGER_UNLOCK to @@ -4970,6 +4991,10 @@ int sqlite3PagerSharedLock(Pager *pPager){ goto failed; } + /* Verify that the database is unmoved and undeleted */ + rc = databaseIsUnmoved(pPager); + if( rc ) goto failed; + /* If a journal file exists, and there is no RESERVED lock on the ** database file, then it either needs to be played back or deleted. */ diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 98c89da322..de6b59b0b7 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -475,6 +475,7 @@ int sqlite3_exec( #define SQLITE_IOERR_MMAP (SQLITE_IOERR | (24<<8)) #define SQLITE_IOERR_GETTEMPPATH (SQLITE_IOERR | (25<<8)) #define SQLITE_IOERR_CONVPATH (SQLITE_IOERR | (26<<8)) +#define SQLITE_IOERR_NODB (SQLITE_IOERR | (27<<8)) #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) #define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8)) @@ -553,7 +554,9 @@ int sqlite3_exec( ** after reboot following a crash or power loss, the only bytes in a ** file that were written at the application level might have changed ** and that adjacent bytes, even bytes within the same sector are -** guaranteed to be unchanged. +** guaranteed to be unchanged. The SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN +** and SQLITE_IOCAP_UNMOVABLE_WHEN_OPEN flags indicate that a file +** cannot be deleted or renamed when open, respectively. */ #define SQLITE_IOCAP_ATOMIC 0x00000001 #define SQLITE_IOCAP_ATOMIC512 0x00000002 @@ -568,6 +571,7 @@ int sqlite3_exec( #define SQLITE_IOCAP_SEQUENTIAL 0x00000400 #define SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN 0x00000800 #define SQLITE_IOCAP_POWERSAFE_OVERWRITE 0x00001000 +#define SQLITE_IOCAP_UNMOVABLE_WHEN_OPEN 0x00002000 /* ** CAPI3REF: File Locking Levels diff --git a/src/test_vfstrace.c b/src/test_vfstrace.c index 0aacc01fe4..8d56cf8946 100644 --- a/src/test_vfstrace.c +++ b/src/test_vfstrace.c @@ -258,6 +258,11 @@ static void vfstrace_print_errcode( case SQLITE_IOERR_SHMOPEN: zVal = "SQLITE_IOERR_SHMOPEN"; break; case SQLITE_IOERR_SHMSIZE: zVal = "SQLITE_IOERR_SHMSIZE"; break; case SQLITE_IOERR_SHMLOCK: zVal = "SQLITE_IOERR_SHMLOCK"; break; + case SQLITE_IOERR_SHMMAP: zVal = "SQLITE_IOERR_SHMMAP"; break; + case SQLITE_IOERR_SEEK: zVal = "SQLITE_IOERR_SEEK"; break; + case SQLITE_IOERR_GETTEMPPATH: zVal = "SQLITE_IOERR_GETTEMPPATH"; break; + case SQLITE_IOERR_CONVPATH: zVal = "SQLITE_IOERR_CONVPATH"; break; + case SQLITE_IOERR_NODB: zVal = "SQLITE_IOERR_NODB"; break; case SQLITE_LOCKED_SHAREDCACHE: zVal = "SQLITE_LOCKED_SHAREDCACHE"; break; case SQLITE_BUSY_RECOVERY: zVal = "SQLITE_BUSY_RECOVERY"; break; case SQLITE_CANTOPEN_NOTEMPDIR: zVal = "SQLITE_CANTOPEN_NOTEMPDIR"; break; diff --git a/test/pager4.test b/test/pager4.test new file mode 100644 index 0000000000..dbe9bf8195 --- /dev/null +++ b/test/pager4.test @@ -0,0 +1,33 @@ +# 2013-12-06 +# +# 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. +# +#*********************************************************************** +# +# Tests for the SQLITE_IOERR_NODB error condition: the database file file +# is unlinked or renamed out from under SQLite. +# + +if {$tcl_platform(platform)!="unix"} return + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +do_execsql_test pager4-1.1 { + CREATE TABLE t1(a,b,c); + INSERT INTO t1 VALUES(673,'stone','philips'); + SELECT * FROM t1; +} {673 stone philips} +file delete -force test-xyz.db +file rename test.db test-xyz.db +do_catchsql_test pager4-1.2 { + SELECT * FROM t1; +} {1 {disk I/O error}} + + +finish_test From 3fee8a63c8bea86450439c3320cb1d5f9050413a Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 6 Dec 2013 17:23:38 +0000 Subject: [PATCH 044/276] Only error out on a database file move when attempting to start a write transaction. Assume read transactions are still safe. And make the error SQLITE_READONLY_DBMOVED instead of SQLITE_IOERR_NODB. FossilOrigin-Name: 28348f2ada98c616241a51aecb70b63e87e6ddbb --- manifest | 21 ++++++++---------- manifest.uuid | 2 +- src/pager.c | 28 ++++++++++++------------ src/sqlite.h.in | 2 +- src/test_vfstrace.c | 2 +- test/pager4.test | 52 ++++++++++++++++++++++++++++++++++++++++++++- 6 files changed, 78 insertions(+), 29 deletions(-) diff --git a/manifest b/manifest index feb65446f1..a5b6b1110c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\scode\sto\sdetect\sif\sthe\sdatabase\sfile\sis\smoved\sor\sdeleted\sout\sfrom\sunder\nSQLite\sand\sreturn\san\sSQLITE_IOERR_NODB. -D 2013-12-06T15:37:35.675 +C Only\serror\sout\son\sa\sdatabase\sfile\smove\swhen\sattempting\sto\sstart\sa\swrite\ntransaction.\s\sAssume\sread\stransactions\sare\sstill\ssafe.\s\sAnd\smake\sthe\serror\nSQLITE_READONLY_DBMOVED\sinstead\sof\sSQLITE_IOERR_NODB. +D 2013-12-06T17:23:38.532 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -207,7 +207,7 @@ F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_unix.c f076587029285554a3a65d30d0e71d50cd61f41f F src/os_win.c f149798adb6f32db835b2c9f9fac83d86015e004 -F src/pager.c 3648e602d484020d10cb514b04ef8f445ed06f30 +F src/pager.c 938874307e1b07a98a181cbab41c5625f2aa1666 F src/pager.h f094af9f6ececfaa8a1e93876905a4f34233fb0c F src/parse.y acee1a9958539e21263362b194594c5255ad2fca F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 @@ -221,7 +221,7 @@ F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c d41381d80a22d3a83352aeca274cccf264ac277a F src/shell.c 936a72ff784efff3832cce274a96ed0b036e6758 -F src/sqlite.h.in 4373b4a913ea460d91a9a4a54906ee18b350d573 +F src/sqlite.h.in 5ae0618d16a393ff8e66d1e373d3670892c2d254 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc F src/sqliteInt.h f3a5d663fe9c6c0b2ee7fc2e20a6204eaea5bc7c @@ -272,7 +272,7 @@ F src/test_syscall.c 16dbe79fb320fadb5acd7a0a59f49e52ab2d2091 F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa F src/test_thread.c 1e133a40b50e9c035b00174035b846e7eef481cb F src/test_vfs.c e72f555ef7a59080f898fcf1a233deb9eb704ea9 -F src/test_vfstrace.c 21b99a6fe3f4c8be13c0fe83006ee13873154d78 +F src/test_vfstrace.c 3a0ab304682fecbceb689e7d9b904211fde11d78 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/tokenize.c ec4c1a62b890bf1dbcdb966399e140b904c700a4 F src/trigger.c d84e1f3669e9a217731a14a9d472b1c7b87c87ba @@ -726,7 +726,7 @@ F test/oserror.test 50417780d0e0d7cd23cf12a8277bb44024765df3 F test/pager1.test 1acbdb14c5952a72dd43129cabdbf69aaa3ed1fa F test/pager2.test 67b8f40ae98112bcdba1f2b2d03ea83266418c71 F test/pager3.test 3856d9c80839be0668efee1b74811b1b7f7fc95f -F test/pager4.test 1848509f0aa83f99d438a2bae02c3fd64dd1afe6 +F test/pager4.test afbffa3f6813bd9bf126eb5e66bc954717f36de5 F test/pagerfault.test 7285379906ab2f1108b8e82bbdf2d386cc8ff3ff F test/pagerfault2.test caf4c7facb914fd3b03a17b31ae2b180c8d6ca1f F test/pagerfault3.test 1003fcda009bf48a8e22a516e193b6ef0dd1bbd8 @@ -1146,10 +1146,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 27392118af4c38c5203a04b8013e1afdb1cebd0d -R 0833e0746c0a3bdbdf22e2e06343a85a -T *branch * detect-moved-db -T *sym-detect-moved-db * -T -sym-trunk * +P 8759a8e4d83b163e315eff316cf163f6ea42f2bb +R 2ad1eaf9a51016580f9868708a4f6a69 U drh -Z 9ba43ea2faea1b2f751f5fd7fd1e8bc8 +Z 59055776a0fdbfce14961d0c6b6be93f diff --git a/manifest.uuid b/manifest.uuid index a2f643fbba..a13ba15e4f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8759a8e4d83b163e315eff316cf163f6ea42f2bb \ No newline at end of file +28348f2ada98c616241a51aecb70b63e87e6ddbb \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 78cb78ab23..5803b2927d 100644 --- a/src/pager.c +++ b/src/pager.c @@ -4799,7 +4799,7 @@ int sqlite3PagerOpen( /* Verify that the database file has not be deleted or renamed out from ** under the pager. Return SQLITE_OK if the database is still were it ought -** to be on disk. Return non-zero (SQLITE_IOERR_NODB or some other error +** to be on disk. Return non-zero (SQLITE_READONLY_DBMOVED or some other error ** code from sqlite3OsAccess()) if the database has gone missing. */ static int databaseIsUnmoved(Pager *pPager){ @@ -4814,7 +4814,7 @@ static int databaseIsUnmoved(Pager *pPager){ dc = sqlite3OsDeviceCharacteristics(pPager->fd); if( (dc&fixedFlags)==fixedFlags ) return SQLITE_OK; rc = sqlite3OsAccess(pPager->pVfs, pPager->zFilename, SQLITE_ACCESS_EXISTS, &x); - if( rc==SQLITE_OK && !x ) rc = SQLITE_IOERR_NODB; + if( rc==SQLITE_OK && !x ) rc = SQLITE_READONLY_DBMOVED; return rc; } @@ -4991,10 +4991,6 @@ int sqlite3PagerSharedLock(Pager *pPager){ goto failed; } - /* Verify that the database is unmoved and undeleted */ - rc = databaseIsUnmoved(pPager); - if( rc ) goto failed; - /* If a journal file exists, and there is no RESERVED lock on the ** database file, then it either needs to be played back or deleted. */ @@ -5498,13 +5494,19 @@ static int pager_open_journal(Pager *pPager){ (SQLITE_OPEN_DELETEONCLOSE|SQLITE_OPEN_TEMP_JOURNAL): (SQLITE_OPEN_MAIN_JOURNAL) ); - #ifdef SQLITE_ENABLE_ATOMIC_WRITE - rc = sqlite3JournalOpen( - pVfs, pPager->zJournal, pPager->jfd, flags, jrnlBufferSize(pPager) - ); - #else - rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, flags, 0); - #endif + + /* Verify that the database still has the same name as it did when + ** it was originally opened. */ + rc = databaseIsUnmoved(pPager); + if( rc==SQLITE_OK ){ +#ifdef SQLITE_ENABLE_ATOMIC_WRITE + rc = sqlite3JournalOpen( + pVfs, pPager->zJournal, pPager->jfd, flags, jrnlBufferSize(pPager) + ); +#else + rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, flags, 0); +#endif + } } assert( rc!=SQLITE_OK || isOpen(pPager->jfd) ); } diff --git a/src/sqlite.h.in b/src/sqlite.h.in index de6b59b0b7..f4692f286a 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -475,7 +475,6 @@ int sqlite3_exec( #define SQLITE_IOERR_MMAP (SQLITE_IOERR | (24<<8)) #define SQLITE_IOERR_GETTEMPPATH (SQLITE_IOERR | (25<<8)) #define SQLITE_IOERR_CONVPATH (SQLITE_IOERR | (26<<8)) -#define SQLITE_IOERR_NODB (SQLITE_IOERR | (27<<8)) #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) #define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8)) @@ -487,6 +486,7 @@ int sqlite3_exec( #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) #define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8)) +#define SQLITE_READONLY_DBMOVED (SQLITE_READONLY | (4<<8)) #define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8)) #define SQLITE_CONSTRAINT_CHECK (SQLITE_CONSTRAINT | (1<<8)) #define SQLITE_CONSTRAINT_COMMITHOOK (SQLITE_CONSTRAINT | (2<<8)) diff --git a/src/test_vfstrace.c b/src/test_vfstrace.c index 8d56cf8946..c1792f116e 100644 --- a/src/test_vfstrace.c +++ b/src/test_vfstrace.c @@ -262,7 +262,7 @@ static void vfstrace_print_errcode( case SQLITE_IOERR_SEEK: zVal = "SQLITE_IOERR_SEEK"; break; case SQLITE_IOERR_GETTEMPPATH: zVal = "SQLITE_IOERR_GETTEMPPATH"; break; case SQLITE_IOERR_CONVPATH: zVal = "SQLITE_IOERR_CONVPATH"; break; - case SQLITE_IOERR_NODB: zVal = "SQLITE_IOERR_NODB"; break; + case SQLITE_READONLY_DBMOVED: zVal = "SQLITE_READONLY_DBMOVED"; break; case SQLITE_LOCKED_SHAREDCACHE: zVal = "SQLITE_LOCKED_SHAREDCACHE"; break; case SQLITE_BUSY_RECOVERY: zVal = "SQLITE_BUSY_RECOVERY"; break; case SQLITE_CANTOPEN_NOTEMPDIR: zVal = "SQLITE_CANTOPEN_NOTEMPDIR"; break; diff --git a/test/pager4.test b/test/pager4.test index dbe9bf8195..e757dbe171 100644 --- a/test/pager4.test +++ b/test/pager4.test @@ -18,16 +18,66 @@ if {$tcl_platform(platform)!="unix"} return set testdir [file dirname $argv0] source $testdir/tester.tcl +# Create a database file for testing +# do_execsql_test pager4-1.1 { CREATE TABLE t1(a,b,c); INSERT INTO t1 VALUES(673,'stone','philips'); SELECT * FROM t1; } {673 stone philips} + +# After renaming the database file while it is open, one can still +# read from the database, but writing returns a READONLY error. +# file delete -force test-xyz.db file rename test.db test-xyz.db do_catchsql_test pager4-1.2 { SELECT * FROM t1; -} {1 {disk I/O error}} +} {0 {673 stone philips}} +do_catchsql_test pager4-1.3 { + UPDATE t1 SET a=537; +} {1 {attempt to write a readonly database}} + +# Changing the name back clears the READONLY error +# +file rename test-xyz.db test.db +do_catchsql_test pager4-1.4 { + SELECT * FROM t1; +} {0 {673 stone philips}} +do_catchsql_test pager4-1.5 { + UPDATE t1 SET a=537; + SELECT * FROM t1; +} {0 {537 stone philips}} + +# We can write to a renamed database if journal_mode=OFF or +# journal_mode=MEMORY. +# +file rename test.db test-xyz.db +do_catchsql_test pager4-1.6 { + PRAGMA journal_mode=OFF; + UPDATE t1 SET a=107; + SELECT * FROM t1; +} {0 {off 107 stone philips}} +do_catchsql_test pager4-1.7 { + PRAGMA journal_mode=MEMORY; + UPDATE t1 SET b='magpie'; + SELECT * FROM t1; +} {0 {memory 107 magpie philips}} + +# Any other journal mode gives a READONLY error +# +do_catchsql_test pager4-1.8 { + PRAGMA journal_mode=DELETE; + UPDATE t1 SET c='jaguar'; +} {1 {attempt to write a readonly database}} +do_catchsql_test pager4-1.9 { + PRAGMA journal_mode=TRUNCATE; + UPDATE t1 SET c='jaguar'; +} {1 {attempt to write a readonly database}} +do_catchsql_test pager4-1.10 { + PRAGMA journal_mode=PERSIST; + UPDATE t1 SET c='jaguar'; +} {1 {attempt to write a readonly database}} finish_test From 091a81b91d600159e6ddb3da3d83915513ab4c7e Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 6 Dec 2013 19:58:32 +0000 Subject: [PATCH 045/276] Add the SQLITE_READONLY_DBMOVED error code to the sqlite3ErrName() function. FossilOrigin-Name: 7789f801d720db5394117e764675cd4bbe6b2da1 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/main.c | 1 + 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index a5b6b1110c..d7e2f42853 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Only\serror\sout\son\sa\sdatabase\sfile\smove\swhen\sattempting\sto\sstart\sa\swrite\ntransaction.\s\sAssume\sread\stransactions\sare\sstill\ssafe.\s\sAnd\smake\sthe\serror\nSQLITE_READONLY_DBMOVED\sinstead\sof\sSQLITE_IOERR_NODB. -D 2013-12-06T17:23:38.532 +C Add\sthe\sSQLITE_READONLY_DBMOVED\serror\scode\sto\sthe\ssqlite3ErrName()\sfunction. +D 2013-12-06T19:58:32.556 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -188,7 +188,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b F src/loadext.c 867c7b330b740c6c917af9956b13b81d0a048303 -F src/main.c 74bdee8f574588868e67c25cd377df7cba80102e +F src/main.c 355fc9ab213b43a4d8a96aadf2a84622e6668f0a F src/malloc.c 543a8eb5508eaf4cadf55a9b503379eba2088128 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c0c990fcaddff810ea277b4fb5d9138603dd5d4b @@ -1146,7 +1146,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 8759a8e4d83b163e315eff316cf163f6ea42f2bb -R 2ad1eaf9a51016580f9868708a4f6a69 -U drh -Z 59055776a0fdbfce14961d0c6b6be93f +P 28348f2ada98c616241a51aecb70b63e87e6ddbb +R 9bc31534cba9a5ca27509c106713cf4f +U mistachkin +Z 53877e3b824403e5e8a560ad04bec5a4 diff --git a/manifest.uuid b/manifest.uuid index a13ba15e4f..37578fbff0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -28348f2ada98c616241a51aecb70b63e87e6ddbb \ No newline at end of file +7789f801d720db5394117e764675cd4bbe6b2da1 \ No newline at end of file diff --git a/src/main.c b/src/main.c index 69a399f385..1ba555fde8 100644 --- a/src/main.c +++ b/src/main.c @@ -1086,6 +1086,7 @@ const char *sqlite3ErrName(int rc){ case SQLITE_READONLY_RECOVERY: zName = "SQLITE_READONLY_RECOVERY"; break; case SQLITE_READONLY_CANTLOCK: zName = "SQLITE_READONLY_CANTLOCK"; break; case SQLITE_READONLY_ROLLBACK: zName = "SQLITE_READONLY_ROLLBACK"; break; + case SQLITE_READONLY_DBMOVED: zName = "SQLITE_READONLY_DBMOVED"; break; case SQLITE_INTERRUPT: zName = "SQLITE_INTERRUPT"; break; case SQLITE_IOERR: zName = "SQLITE_IOERR"; break; case SQLITE_IOERR_READ: zName = "SQLITE_IOERR_READ"; break; From 72b8ef6ce3ee4f91e27c8bd86d5c7228ef4108f0 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 6 Dec 2013 22:44:51 +0000 Subject: [PATCH 046/276] Remove some commented-out code from sqlite3BtreeMovetoUnpacked() to try to make it more readable. FossilOrigin-Name: 2d62d1131f8bbc4e1f8f7aeaf0d91e3237fe3b7c --- manifest | 17 +++++++---------- manifest.uuid | 2 +- src/btree.c | 5 +---- 3 files changed, 9 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 264b3fc190..c9d25efc91 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Version\s3.8.2 -D 2013-12-06T14:53:30.888 +C Remove\ssome\scommented-out\scode\sfrom\ssqlite3BtreeMovetoUnpacked()\sto\stry\sto\smake\nit\smore\sreadable. +D 2013-12-06T22:44:51.968 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,7 +166,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 1809a7caa2504233bdddd12f5018422421789537 F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c fe6c95c57fd14ed4b3329f4b5bb08132fe7c322d +F src/btree.c 1c1228bfeff3142c3d30f37f41c62e1e1456a04b F src/btree.h a61ddebc78c66795a2b93181321a116746302cc9 F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0 F src/build.c 1965c7b596ca6295b7ca59541ad186c57564b8f7 @@ -1145,10 +1145,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P c632567063d81c4be404ce58cbac0eff7412f565 -R 39f74301df16683d1c19ab7ca83b6451 -T +bgcolor * #d0c0ff -T +sym-release * -T +sym-version-3.8.2 * -U dan -Z bddf39b758268961698f9899546a37dd +P 27392118af4c38c5203a04b8013e1afdb1cebd0d +R 37ccd3e8b8d51b4fffcef9ee439c7da2 +U drh +Z b12a0af0516653b272442a79b4596fc8 diff --git a/manifest.uuid b/manifest.uuid index 5097db9159..3816e1f6cf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -27392118af4c38c5203a04b8013e1afdb1cebd0d \ No newline at end of file +2d62d1131f8bbc4e1f8f7aeaf0d91e3237fe3b7c \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 30fdf4256f..e93eeffb36 100644 --- a/src/btree.c +++ b/src/btree.c @@ -4716,9 +4716,7 @@ int sqlite3BtreeMovetoUnpacked( ** 2 bytes of the cell. */ nCell = pCell[0]; - if( nCell<=pPage->max1bytePayload - /* && (pCell+nCell)aDataEnd */ - ){ + if( nCell<=pPage->max1bytePayload ){ /* This branch runs if the record-size field of the cell is a ** single byte varint and the record fits entirely on the main ** b-tree page. */ @@ -4726,7 +4724,6 @@ int sqlite3BtreeMovetoUnpacked( c = sqlite3VdbeRecordCompare(nCell, (void*)&pCell[1], pIdxKey); }else if( !(pCell[1] & 0x80) && (nCell = ((nCell&0x7f)<<7) + pCell[1])<=pPage->maxLocal - /* && (pCell+nCell+2)<=pPage->aDataEnd */ ){ /* The record-size field is a 2 byte varint and the record ** fits entirely on the main b-tree page. */ From b8a9bb4fb93253103e09507e706caab4410a9d72 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 6 Dec 2013 22:45:31 +0000 Subject: [PATCH 047/276] Use memcmp() instead of the BINARY collating function where possible, for a performance boost. FossilOrigin-Name: c5a3a1af3c7bd34886e944a1fef2f6340ded24a0 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/build.c | 5 +++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index c9d25efc91..af9d22779a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\ssome\scommented-out\scode\sfrom\ssqlite3BtreeMovetoUnpacked()\sto\stry\sto\smake\nit\smore\sreadable. -D 2013-12-06T22:44:51.968 +C Use\smemcmp()\sinstead\sof\sthe\sBINARY\scollating\sfunction\swhere\spossible,\sfor\na\sperformance\sboost. +D 2013-12-06T22:45:31.452 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -169,7 +169,7 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btree.c 1c1228bfeff3142c3d30f37f41c62e1e1456a04b F src/btree.h a61ddebc78c66795a2b93181321a116746302cc9 F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0 -F src/build.c 1965c7b596ca6295b7ca59541ad186c57564b8f7 +F src/build.c 9b40580b62916612678bdb69ce0286e39c29a862 F src/callback.c f99a8957ba2adf369645fac0db09ad8adcf1caa2 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd @@ -1145,7 +1145,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 27392118af4c38c5203a04b8013e1afdb1cebd0d -R 37ccd3e8b8d51b4fffcef9ee439c7da2 +P 2d62d1131f8bbc4e1f8f7aeaf0d91e3237fe3b7c +R 64ecaeb699cffb8c7d50ef92ad2b85dd U drh -Z b12a0af0516653b272442a79b4596fc8 +Z 924fa8368d7b3d9057325dee3400f3cb diff --git a/manifest.uuid b/manifest.uuid index 3816e1f6cf..cff17acb92 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2d62d1131f8bbc4e1f8f7aeaf0d91e3237fe3b7c \ No newline at end of file +c5a3a1af3c7bd34886e944a1fef2f6340ded24a0 \ No newline at end of file diff --git a/src/build.c b/src/build.c index fd512358bc..a7d5a29946 100644 --- a/src/build.c +++ b/src/build.c @@ -4183,8 +4183,9 @@ KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){ assert( sqlite3KeyInfoIsWriteable(pKey) ); for(i=0; iazColl[i]; - if( NEVER(zColl==0) ) zColl = "BINARY"; - pKey->aColl[i] = sqlite3LocateCollSeq(pParse, zColl); + assert( zColl!=0 ); + pKey->aColl[i] = strcmp(zColl,"BINARY")==0 ? 0 : + sqlite3LocateCollSeq(pParse, zColl); pKey->aSortOrder[i] = pIdx->aSortOrder[i]; } if( pParse->nErr ){ From 4e8fe3ff910f0a2a3605a0596339b1682736e030 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 6 Dec 2013 23:25:27 +0000 Subject: [PATCH 048/276] Performance optimization to the moveToRoot() subroutine in btree.c. FossilOrigin-Name: b5842a70f8e26456a8f0d39539bc266f097480a4 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 16 ++++++---------- 3 files changed, 13 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index af9d22779a..029d04e994 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Use\smemcmp()\sinstead\sof\sthe\sBINARY\scollating\sfunction\swhere\spossible,\sfor\na\sperformance\sboost. -D 2013-12-06T22:45:31.452 +C Performance\soptimization\sto\sthe\smoveToRoot()\ssubroutine\sin\sbtree.c. +D 2013-12-06T23:25:27.601 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,7 +166,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 1809a7caa2504233bdddd12f5018422421789537 F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c 1c1228bfeff3142c3d30f37f41c62e1e1456a04b +F src/btree.c 4037f58ef3f4459d0b9bb1fc1aee1136277d9ba6 F src/btree.h a61ddebc78c66795a2b93181321a116746302cc9 F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0 F src/build.c 9b40580b62916612678bdb69ce0286e39c29a862 @@ -1145,7 +1145,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 2d62d1131f8bbc4e1f8f7aeaf0d91e3237fe3b7c -R 64ecaeb699cffb8c7d50ef92ad2b85dd +P c5a3a1af3c7bd34886e944a1fef2f6340ded24a0 +R 12065e363c2320b45db52efcb2788f0d U drh -Z 924fa8368d7b3d9057325dee3400f3cb +Z 6564d15f297e6c8ddf25ac421a3f69fc diff --git a/manifest.uuid b/manifest.uuid index cff17acb92..5fac78a151 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c5a3a1af3c7bd34886e944a1fef2f6340ded24a0 \ No newline at end of file +b5842a70f8e26456a8f0d39539bc266f097480a4 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index e93eeffb36..a0b6c6ba24 100644 --- a/src/btree.c +++ b/src/btree.c @@ -4395,8 +4395,6 @@ static void moveToParent(BtCursor *pCur){ static int moveToRoot(BtCursor *pCur){ MemPage *pRoot; int rc = SQLITE_OK; - Btree *p = pCur->pBtree; - BtShared *pBt = p->pBt; assert( cursorHoldsMutex(pCur) ); assert( CURSOR_INVALID < CURSOR_REQUIRESEEK ); @@ -4411,16 +4409,12 @@ static int moveToRoot(BtCursor *pCur){ } if( pCur->iPage>=0 ){ - int i; - for(i=1; i<=pCur->iPage; i++){ - releasePage(pCur->apPage[i]); - } - pCur->iPage = 0; + while( pCur->iPage ) releasePage(pCur->apPage[pCur->iPage--]); }else if( pCur->pgnoRoot==0 ){ pCur->eState = CURSOR_INVALID; return SQLITE_OK; }else{ - rc = getAndInitPage(pBt, pCur->pgnoRoot, &pCur->apPage[0], + rc = getAndInitPage(pCur->pBtree->pBt, pCur->pgnoRoot, &pCur->apPage[0], pCur->wrFlag==0 ? PAGER_GET_READONLY : 0); if( rc!=SQLITE_OK ){ pCur->eState = CURSOR_INVALID; @@ -4453,14 +4447,16 @@ static int moveToRoot(BtCursor *pCur){ pCur->atLast = 0; pCur->validNKey = 0; - if( pRoot->nCell==0 && !pRoot->leaf ){ + if( pRoot->nCell>0 ){ + pCur->eState = CURSOR_VALID; + }else if( !pRoot->leaf ){ Pgno subpage; if( pRoot->pgno!=1 ) return SQLITE_CORRUPT_BKPT; subpage = get4byte(&pRoot->aData[pRoot->hdrOffset+8]); pCur->eState = CURSOR_VALID; rc = moveToChild(pCur, subpage); }else{ - pCur->eState = ((pRoot->nCell>0)?CURSOR_VALID:CURSOR_INVALID); + pCur->eState = CURSOR_INVALID; } return rc; } From b959a017b697e7432a65989ace42d1db92430f93 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 7 Dec 2013 12:29:22 +0000 Subject: [PATCH 049/276] Actually look at i-node numbers to determine whether or not the database file has moved. FossilOrigin-Name: 2b1884dc14f9a04a04eebb3245fbe0daaff399eb --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/os_unix.c | 18 ++++++++++++++---- src/pager.c | 7 ++++--- src/sqlite.h.in | 7 +++++++ test/pager4.test | 25 ++++++++++++++++++------- 6 files changed, 54 insertions(+), 25 deletions(-) diff --git a/manifest b/manifest index d7e2f42853..adb35d7204 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sSQLITE_READONLY_DBMOVED\serror\scode\sto\sthe\ssqlite3ErrName()\sfunction. -D 2013-12-06T19:58:32.556 +C Actually\slook\sat\si-node\snumbers\sto\sdetermine\swhether\sor\snot\sthe\sdatabase\nfile\shas\smoved. +D 2013-12-07T12:29:22.514 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -205,9 +205,9 @@ F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30 F src/os.c b4ad71336fd96f97776f75587cd9e8218288f5be F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 -F src/os_unix.c f076587029285554a3a65d30d0e71d50cd61f41f +F src/os_unix.c 60a7b3b23e6fcf83a50d1e320b280b551724e11f F src/os_win.c f149798adb6f32db835b2c9f9fac83d86015e004 -F src/pager.c 938874307e1b07a98a181cbab41c5625f2aa1666 +F src/pager.c 6aa7d8eca75cac90f90f4c2619fb6c47153756e6 F src/pager.h f094af9f6ececfaa8a1e93876905a4f34233fb0c F src/parse.y acee1a9958539e21263362b194594c5255ad2fca F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 @@ -221,7 +221,7 @@ F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c d41381d80a22d3a83352aeca274cccf264ac277a F src/shell.c 936a72ff784efff3832cce274a96ed0b036e6758 -F src/sqlite.h.in 5ae0618d16a393ff8e66d1e373d3670892c2d254 +F src/sqlite.h.in eea3f417059c203f450ec64acbb19e6201063c0c F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc F src/sqliteInt.h f3a5d663fe9c6c0b2ee7fc2e20a6204eaea5bc7c @@ -726,7 +726,7 @@ F test/oserror.test 50417780d0e0d7cd23cf12a8277bb44024765df3 F test/pager1.test 1acbdb14c5952a72dd43129cabdbf69aaa3ed1fa F test/pager2.test 67b8f40ae98112bcdba1f2b2d03ea83266418c71 F test/pager3.test 3856d9c80839be0668efee1b74811b1b7f7fc95f -F test/pager4.test afbffa3f6813bd9bf126eb5e66bc954717f36de5 +F test/pager4.test b40ecb4cc7dff957ee7916e41ab21d1ed702a642 F test/pagerfault.test 7285379906ab2f1108b8e82bbdf2d386cc8ff3ff F test/pagerfault2.test caf4c7facb914fd3b03a17b31ae2b180c8d6ca1f F test/pagerfault3.test 1003fcda009bf48a8e22a516e193b6ef0dd1bbd8 @@ -1146,7 +1146,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 28348f2ada98c616241a51aecb70b63e87e6ddbb -R 9bc31534cba9a5ca27509c106713cf4f -U mistachkin -Z 53877e3b824403e5e8a560ad04bec5a4 +P 7789f801d720db5394117e764675cd4bbe6b2da1 +R 3bce36f2564839cff6784053e8b7c283 +U drh +Z 80f483ee05b71fc1e6bab9b86a396c28 diff --git a/manifest.uuid b/manifest.uuid index 37578fbff0..b80938c565 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7789f801d720db5394117e764675cd4bbe6b2da1 \ No newline at end of file +2b1884dc14f9a04a04eebb3245fbe0daaff399eb \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index ab657dc7bd..485b32fd90 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -1315,6 +1315,15 @@ static int findInodeInfo( return SQLITE_OK; } +/* +** Return TRUE if pFile has been renamed or unlinked since it was first opened. +*/ +static int fileHasMoved(unixFile *pFile){ + struct stat buf; + return pFile->pInode!=0 && + (osStat(pFile->zPath, &buf)!=0 || buf.st_ino!=pFile->pInode->fileId.ino); +} + /* ** Check a unixFile that is a database. Verify the following: @@ -1349,10 +1358,7 @@ static void verifyDbFile(unixFile *pFile){ pFile->ctrlFlags |= UNIXFILE_WARNED; return; } - if( pFile->pInode!=0 - && ((rc = osStat(pFile->zPath, &buf))!=0 - || buf.st_ino!=pFile->pInode->fileId.ino) - ){ + if( fileHasMoved(pFile) ){ sqlite3_log(SQLITE_WARNING, "file renamed while open: %s", pFile->zPath); pFile->ctrlFlags |= UNIXFILE_WARNED; return; @@ -3801,6 +3807,10 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ } return SQLITE_OK; } + case SQLITE_FCNTL_HAS_MOVED: { + *(int*)pArg = fileHasMoved(pFile); + return SQLITE_OK; + } #if SQLITE_MAX_MMAP_SIZE>0 case SQLITE_FCNTL_MMAP_SIZE: { i64 newLimit = *(i64*)pArg; diff --git a/src/pager.c b/src/pager.c index 5803b2927d..297b7bd534 100644 --- a/src/pager.c +++ b/src/pager.c @@ -4806,15 +4806,16 @@ static int databaseIsUnmoved(Pager *pPager){ const int fixedFlags = SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN | SQLITE_IOCAP_UNMOVABLE_WHEN_OPEN; int dc; - int x = 0, rc; + int bHasMoved = 0; + int rc; if( pPager->tempFile ) return SQLITE_OK; if( pPager->dbSize==0 ) return SQLITE_OK; assert( pPager->zFilename && pPager->zFilename[0] ); dc = sqlite3OsDeviceCharacteristics(pPager->fd); if( (dc&fixedFlags)==fixedFlags ) return SQLITE_OK; - rc = sqlite3OsAccess(pPager->pVfs, pPager->zFilename, SQLITE_ACCESS_EXISTS, &x); - if( rc==SQLITE_OK && !x ) rc = SQLITE_READONLY_DBMOVED; + rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_HAS_MOVED, &bHasMoved); + if( rc==SQLITE_OK && bHasMoved ) rc = SQLITE_READONLY_DBMOVED; return rc; } diff --git a/src/sqlite.h.in b/src/sqlite.h.in index f4692f286a..fb6fa462ec 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -920,6 +920,12 @@ struct sqlite3_io_methods { ** SQLite stack may generate instances of this file control if ** the [SQLITE_USE_FCNTL_TRACE] compile-time option is enabled. ** +**
  • [[SQLITE_FCNTL_HAS_MOVED]] +** The [SQLITE_FCNTL_HAS_MOVED] file control interprets its argument as a +** pointer to an integer and it writes a boolean into that integer depending +** on whether or not the file has been renamed, moved, or deleted since it +** was first opened. +** ** */ #define SQLITE_FCNTL_LOCKSTATE 1 @@ -940,6 +946,7 @@ struct sqlite3_io_methods { #define SQLITE_FCNTL_TEMPFILENAME 16 #define SQLITE_FCNTL_MMAP_SIZE 18 #define SQLITE_FCNTL_TRACE 19 +#define SQLITE_FCNTL_HAS_MOVED 20 /* ** CAPI3REF: Mutex Handle diff --git a/test/pager4.test b/test/pager4.test index e757dbe171..edfd2660c2 100644 --- a/test/pager4.test +++ b/test/pager4.test @@ -38,13 +38,24 @@ do_catchsql_test pager4-1.3 { UPDATE t1 SET a=537; } {1 {attempt to write a readonly database}} +# Creating a different database file with the same name of the original +# is detected and still leaves the database read-only. +# +sqlite3 db2 test.db +db2 eval {CREATE TABLE t2(x,y,z)} +do_catchsql_test pager4-1.4 { + UPDATE t1 SET a=948; +} {1 {attempt to write a readonly database}} + # Changing the name back clears the READONLY error # +db2 close +file delete -force test.db file rename test-xyz.db test.db -do_catchsql_test pager4-1.4 { +do_catchsql_test pager4-1.5 { SELECT * FROM t1; } {0 {673 stone philips}} -do_catchsql_test pager4-1.5 { +do_catchsql_test pager4-1.6 { UPDATE t1 SET a=537; SELECT * FROM t1; } {0 {537 stone philips}} @@ -53,12 +64,12 @@ do_catchsql_test pager4-1.5 { # journal_mode=MEMORY. # file rename test.db test-xyz.db -do_catchsql_test pager4-1.6 { +do_catchsql_test pager4-1.7 { PRAGMA journal_mode=OFF; UPDATE t1 SET a=107; SELECT * FROM t1; } {0 {off 107 stone philips}} -do_catchsql_test pager4-1.7 { +do_catchsql_test pager4-1.8 { PRAGMA journal_mode=MEMORY; UPDATE t1 SET b='magpie'; SELECT * FROM t1; @@ -66,15 +77,15 @@ do_catchsql_test pager4-1.7 { # Any other journal mode gives a READONLY error # -do_catchsql_test pager4-1.8 { +do_catchsql_test pager4-1.9 { PRAGMA journal_mode=DELETE; UPDATE t1 SET c='jaguar'; } {1 {attempt to write a readonly database}} -do_catchsql_test pager4-1.9 { +do_catchsql_test pager4-1.10 { PRAGMA journal_mode=TRUNCATE; UPDATE t1 SET c='jaguar'; } {1 {attempt to write a readonly database}} -do_catchsql_test pager4-1.10 { +do_catchsql_test pager4-1.11 { PRAGMA journal_mode=PERSIST; UPDATE t1 SET c='jaguar'; } {1 {attempt to write a readonly database}} From a9c19f935cf5e653da10ef517611b48107d83fff Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 7 Dec 2013 16:45:05 +0000 Subject: [PATCH 050/276] Back out the new device capability. The determination of whether or not a file has moved is now done strictly using a file-control. FossilOrigin-Name: 9c59f5af7ac4908583fab85d37241f200c40f02d --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/os_win.c | 1 - src/pager.c | 14 ++++++++------ src/sqlite.h.in | 4 +--- 5 files changed, 18 insertions(+), 19 deletions(-) diff --git a/manifest b/manifest index adb35d7204..af17b57a3f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Actually\slook\sat\si-node\snumbers\sto\sdetermine\swhether\sor\snot\sthe\sdatabase\nfile\shas\smoved. -D 2013-12-07T12:29:22.514 +C Back\sout\sthe\snew\sdevice\scapability.\s\sThe\sdetermination\sof\swhether\sor\snot\sa\nfile\shas\smoved\sis\snow\sdone\sstrictly\susing\sa\sfile-control. +D 2013-12-07T16:45:05.762 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -206,8 +206,8 @@ F src/os.c b4ad71336fd96f97776f75587cd9e8218288f5be F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_unix.c 60a7b3b23e6fcf83a50d1e320b280b551724e11f -F src/os_win.c f149798adb6f32db835b2c9f9fac83d86015e004 -F src/pager.c 6aa7d8eca75cac90f90f4c2619fb6c47153756e6 +F src/os_win.c 4323dd0bac4f7a7037fc4cf87fb4692d17f0b108 +F src/pager.c d27dc8aaeac16c90eb0c859c074683bfc4533c41 F src/pager.h f094af9f6ececfaa8a1e93876905a4f34233fb0c F src/parse.y acee1a9958539e21263362b194594c5255ad2fca F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 @@ -221,7 +221,7 @@ F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c d41381d80a22d3a83352aeca274cccf264ac277a F src/shell.c 936a72ff784efff3832cce274a96ed0b036e6758 -F src/sqlite.h.in eea3f417059c203f450ec64acbb19e6201063c0c +F src/sqlite.h.in 125dc0b76f0116f1cd6f13536db52ba981e1c5bd F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc F src/sqliteInt.h f3a5d663fe9c6c0b2ee7fc2e20a6204eaea5bc7c @@ -1146,7 +1146,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 7789f801d720db5394117e764675cd4bbe6b2da1 -R 3bce36f2564839cff6784053e8b7c283 +P 2b1884dc14f9a04a04eebb3245fbe0daaff399eb +R 4150eee10eaa0b472e8e9f4c3fd71eac U drh -Z 80f483ee05b71fc1e6bab9b86a396c28 +Z f90de22ca9080d17b19aebd5c1cb9da5 diff --git a/manifest.uuid b/manifest.uuid index b80938c565..d9c23f55bc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2b1884dc14f9a04a04eebb3245fbe0daaff399eb \ No newline at end of file +9c59f5af7ac4908583fab85d37241f200c40f02d \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index 56b546fb47..22052a3fe7 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -3192,7 +3192,6 @@ static int winSectorSize(sqlite3_file *id){ static int winDeviceCharacteristics(sqlite3_file *id){ winFile *p = (winFile*)id; return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN | - SQLITE_IOCAP_UNMOVABLE_WHEN_OPEN | ((p->ctrlFlags & WINFILE_PSOW)?SQLITE_IOCAP_POWERSAFE_OVERWRITE:0); } diff --git a/src/pager.c b/src/pager.c index 297b7bd534..3138035cd5 100644 --- a/src/pager.c +++ b/src/pager.c @@ -4803,19 +4803,21 @@ int sqlite3PagerOpen( ** code from sqlite3OsAccess()) if the database has gone missing. */ static int databaseIsUnmoved(Pager *pPager){ - const int fixedFlags = SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN | - SQLITE_IOCAP_UNMOVABLE_WHEN_OPEN; - int dc; int bHasMoved = 0; int rc; if( pPager->tempFile ) return SQLITE_OK; if( pPager->dbSize==0 ) return SQLITE_OK; assert( pPager->zFilename && pPager->zFilename[0] ); - dc = sqlite3OsDeviceCharacteristics(pPager->fd); - if( (dc&fixedFlags)==fixedFlags ) return SQLITE_OK; rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_HAS_MOVED, &bHasMoved); - if( rc==SQLITE_OK && bHasMoved ) rc = SQLITE_READONLY_DBMOVED; + if( rc==SQLITE_NOTFOUND ){ + /* If the HAS_MOVED file-control is unimplemented, assume that the file + ** has not been moved. That is the historical behavior of SQLite: prior to + ** version 3.8.3, it never checked */ + rc = SQLITE_OK; + }else if( rc==SQLITE_OK && bHasMoved ){ + rc = SQLITE_READONLY_DBMOVED; + } return rc; } diff --git a/src/sqlite.h.in b/src/sqlite.h.in index fb6fa462ec..1ad181e740 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -555,8 +555,7 @@ int sqlite3_exec( ** file that were written at the application level might have changed ** and that adjacent bytes, even bytes within the same sector are ** guaranteed to be unchanged. The SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN -** and SQLITE_IOCAP_UNMOVABLE_WHEN_OPEN flags indicate that a file -** cannot be deleted or renamed when open, respectively. +** flag indicate that a file cannot be deleted when open. */ #define SQLITE_IOCAP_ATOMIC 0x00000001 #define SQLITE_IOCAP_ATOMIC512 0x00000002 @@ -571,7 +570,6 @@ int sqlite3_exec( #define SQLITE_IOCAP_SEQUENTIAL 0x00000400 #define SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN 0x00000800 #define SQLITE_IOCAP_POWERSAFE_OVERWRITE 0x00001000 -#define SQLITE_IOCAP_UNMOVABLE_WHEN_OPEN 0x00002000 /* ** CAPI3REF: File Locking Levels From 9dcc7cd5276bcf371016b2387881718a591b4064 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 7 Dec 2013 17:01:23 +0000 Subject: [PATCH 051/276] Increase the version number to 3.8.3. FossilOrigin-Name: 23d00f22872a907a8ebf5b80689ff7aa66686a07 --- VERSION | 2 +- configure | 18 +++++++++--------- manifest | 15 +++++++-------- manifest.uuid | 2 +- 4 files changed, 18 insertions(+), 19 deletions(-) diff --git a/VERSION b/VERSION index a08ffae0ca..269aa9c86d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.8.2 +3.8.3 diff --git a/configure b/configure index d4bbd2d9be..2403018bb8 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.62 for sqlite 3.8.2. +# Generated by GNU Autoconf 2.62 for sqlite 3.8.3. # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. @@ -743,8 +743,8 @@ SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='sqlite' PACKAGE_TARNAME='sqlite' -PACKAGE_VERSION='3.8.2' -PACKAGE_STRING='sqlite 3.8.2' +PACKAGE_VERSION='3.8.3' +PACKAGE_STRING='sqlite 3.8.3' PACKAGE_BUGREPORT='' # Factoring default headers for most tests. @@ -1483,7 +1483,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures sqlite 3.8.2 to adapt to many kinds of systems. +\`configure' configures sqlite 3.8.3 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1548,7 +1548,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of sqlite 3.8.2:";; + short | recursive ) echo "Configuration of sqlite 3.8.3:";; esac cat <<\_ACEOF @@ -1664,7 +1664,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -sqlite configure 3.8.2 +sqlite configure 3.8.3 generated by GNU Autoconf 2.62 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -1678,7 +1678,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by sqlite $as_me 3.8.2, which was +It was created by sqlite $as_me 3.8.3, which was generated by GNU Autoconf 2.62. Invocation command line was $ $0 $@ @@ -14021,7 +14021,7 @@ exec 6>&1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by sqlite $as_me 3.8.2, which was +This file was extended by sqlite $as_me 3.8.3, which was generated by GNU Autoconf 2.62. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -14074,7 +14074,7 @@ Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_version="\\ -sqlite config.status 3.8.2 +sqlite config.status 3.8.3 configured by $0, generated by GNU Autoconf 2.62, with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" diff --git a/manifest b/manifest index 9d96e87ef3..7cdbd89e49 100644 --- a/manifest +++ b/manifest @@ -1,12 +1,12 @@ -C At\sthe\sstart\sof\seach\swrite\stransaction,\scheck\sto\ssee\sif\sthe\sdatabase\sfile\shas\nbeen\smoved,\sand\sif\sit\shas\srefuse\sto\sstart\sthe\stransaction,\sreturning\san\nSQLITE_READONLY_DBMOVED\serror\scode. -D 2013-12-07T16:56:09.769 +C Increase\sthe\sversion\snumber\sto\s3.8.3. +D 2013-12-07T17:01:23.631 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.msc bb1f271c8ee9773489c89be00f3f8ad7ed7ae8e0 F Makefile.vxworks db21ed42a01d5740e656b16f92cb5d8d5e5dd315 F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6 -F VERSION 52f7e22bfcec71a462e34194b4ae1671380fde59 +F VERSION 8ed548d87d0a27fd7d7620476f9e25f9fa742d73 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 F addopcodes.awk 87ca612393d0f439550634bd2c156ea9ff6195ae F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 @@ -38,7 +38,7 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63 F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977 F config.h.in 0921066a13130082764ab4ab6456f7b5bebe56de F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55 -F configure f97b17cd80fa428e5df4e70a36ed5b4ed21100c2 x +F configure 1673bc402f8fc95015f72c279adc5a9a668ee237 x F configure.ac 4cf9f60785143fa141b10962ccc885d973792e9a F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/lemon.html 334dbf6621b8fb8790297ec1abf3cfa4621709d1 @@ -1146,8 +1146,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P b5842a70f8e26456a8f0d39539bc266f097480a4 9c59f5af7ac4908583fab85d37241f200c40f02d -R b5502e212abebd79211cbde2351c1e6b -T +closed 9c59f5af7ac4908583fab85d37241f200c40f02d +P 369a23e00644f3ff8b6a2d2ed73b8cb65e9f124b +R 0fdea442d6dfa8b801d4e6d289982778 U drh -Z aeb423432b55400118887674a2a0ba39 +Z 0e445b98f25b8020cec84ec084909f7b diff --git a/manifest.uuid b/manifest.uuid index c01ba35b04..0d9cda82d6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -369a23e00644f3ff8b6a2d2ed73b8cb65e9f124b \ No newline at end of file +23d00f22872a907a8ebf5b80689ff7aa66686a07 \ No newline at end of file From 1e98310a14be3f121afe7e5cd9b1280697b9ccbe Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 8 Dec 2013 19:54:52 +0000 Subject: [PATCH 052/276] Interchange two conditions in an "if" statment in sqlite3PagerAcquire() for very slight (0.06%) overall performance increase. FossilOrigin-Name: fbcc1a3ebb016225c3580181c908a2904cc184a5 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pager.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 7cdbd89e49..872cd35469 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Increase\sthe\sversion\snumber\sto\s3.8.3. -D 2013-12-07T17:01:23.631 +C Interchange\stwo\sconditions\sin\san\s"if"\sstatment\sin\ssqlite3PagerAcquire()\sfor\nvery\sslight\s(0.06%)\soverall\sperformance\sincrease. +D 2013-12-08T19:54:52.040 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -207,7 +207,7 @@ F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_unix.c 60a7b3b23e6fcf83a50d1e320b280b551724e11f F src/os_win.c 4323dd0bac4f7a7037fc4cf87fb4692d17f0b108 -F src/pager.c d27dc8aaeac16c90eb0c859c074683bfc4533c41 +F src/pager.c 061d0b41354a8446256f5d765771e2a026ec8ed2 F src/pager.h f094af9f6ececfaa8a1e93876905a4f34233fb0c F src/parse.y acee1a9958539e21263362b194594c5255ad2fca F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 @@ -1146,7 +1146,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 369a23e00644f3ff8b6a2d2ed73b8cb65e9f124b -R 0fdea442d6dfa8b801d4e6d289982778 +P 23d00f22872a907a8ebf5b80689ff7aa66686a07 +R 8a0ad68f8a597479c8d7ee9e24cd34ea U drh -Z 0e445b98f25b8020cec84ec084909f7b +Z ef2f6bbda3376e1ee20657f75cafac8c diff --git a/manifest.uuid b/manifest.uuid index 0d9cda82d6..300c775222 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -23d00f22872a907a8ebf5b80689ff7aa66686a07 \ No newline at end of file +fbcc1a3ebb016225c3580181c908a2904cc184a5 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 3138035cd5..7f79bd7eca 100644 --- a/src/pager.c +++ b/src/pager.c @@ -5292,7 +5292,7 @@ int sqlite3PagerAcquire( if( rc!=SQLITE_OK ) goto pager_acquire_err; } - if( iFrame==0 && bMmapOk ){ + if( bMmapOk && iFrame==0 ){ void *pData = 0; rc = sqlite3OsFetch(pPager->fd, From 2a242876395de5fd87afe92c6f32b71ef90f02ae Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 8 Dec 2013 22:59:29 +0000 Subject: [PATCH 053/276] Avoid unnecessary calls to sqlite3VarintLen() from the OP_MakeRecord opcode. FossilOrigin-Name: 7a234fc3c5e7970ffe0b8d6ac33c26acb64b5c4d --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 13 +++++++++---- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 872cd35469..19fb8c1241 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Interchange\stwo\sconditions\sin\san\s"if"\sstatment\sin\ssqlite3PagerAcquire()\sfor\nvery\sslight\s(0.06%)\soverall\sperformance\sincrease. -D 2013-12-08T19:54:52.040 +C Avoid\sunnecessary\scalls\sto\ssqlite3VarintLen()\sfrom\sthe\sOP_MakeRecord\sopcode. +D 2013-12-08T22:59:29.482 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -280,7 +280,7 @@ F src/update.c d1c2477dcf14d90999d1935af4efb4806553250b F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c 76ed0519296e3f62e97e57dab1999e34184c8e49 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c 54894fde8dc806d259e015ac7c9680145e725835 +F src/vdbe.c 7f51e9d422aefe6bcbaf7bf680e0d4ca9f6288cb F src/vdbe.h c06f0813f853566457ce9cfb1a4a4bc39a5da644 F src/vdbeInt.h 05fbda0e061dbc4aaa2709a8cccf3515c245b263 F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed @@ -1146,7 +1146,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 23d00f22872a907a8ebf5b80689ff7aa66686a07 -R 8a0ad68f8a597479c8d7ee9e24cd34ea +P fbcc1a3ebb016225c3580181c908a2904cc184a5 +R 09b58c480760cc431d5e01573bf9e4b3 U drh -Z ef2f6bbda3376e1ee20657f75cafac8c +Z 1bf421a053293bdaa5254a0efb062c9a diff --git a/manifest.uuid b/manifest.uuid index 300c775222..d22393ad7f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fbcc1a3ebb016225c3580181c908a2904cc184a5 \ No newline at end of file +7a234fc3c5e7970ffe0b8d6ac33c26acb64b5c4d \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 8ae4ce484c..b0b56c4567 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2608,7 +2608,7 @@ case OP_MakeRecord: { serial_type = sqlite3VdbeSerialType(pRec, file_format); len = sqlite3VdbeSerialTypeLen(serial_type); nData += len; - nHdr += sqlite3VarintLen(serial_type); + nHdr += serial_type<=127 ? 1 : sqlite3VarintLen(serial_type); if( pRec->flags & MEM_Zero ){ /* Only pure zero-filled BLOBs can be input to this Opcode. ** We do not allow blobs with a prefix and a zero-filled tail. */ @@ -2619,9 +2619,14 @@ case OP_MakeRecord: { } /* Add the initial header varint and total the size */ - nHdr += nVarint = sqlite3VarintLen(nHdr); - if( nVarintdb->aLimit[SQLITE_LIMIT_LENGTH] ){ From 59bf00cb54fa87425444013fb732f68be69f71a1 Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 8 Dec 2013 23:33:28 +0000 Subject: [PATCH 054/276] Another simplification to the OP_MakeRecord opcode, making it slightly faster and very slightly smaller. FossilOrigin-Name: f2f5a3ce9d075c4b1ac586c5db3a623d9035402d --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 29 +++++++++++++++++++---------- 3 files changed, 26 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index 19fb8c1241..65c6431388 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sunnecessary\scalls\sto\ssqlite3VarintLen()\sfrom\sthe\sOP_MakeRecord\sopcode. -D 2013-12-08T22:59:29.482 +C Another\ssimplification\sto\sthe\sOP_MakeRecord\sopcode,\smaking\sit\sslightly\nfaster\sand\svery\sslightly\ssmaller. +D 2013-12-08T23:33:28.824 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -280,7 +280,7 @@ F src/update.c d1c2477dcf14d90999d1935af4efb4806553250b F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c 76ed0519296e3f62e97e57dab1999e34184c8e49 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c 7f51e9d422aefe6bcbaf7bf680e0d4ca9f6288cb +F src/vdbe.c 6ccb107de55a34b7676a9eaa0aeb827015723fa4 F src/vdbe.h c06f0813f853566457ce9cfb1a4a4bc39a5da644 F src/vdbeInt.h 05fbda0e061dbc4aaa2709a8cccf3515c245b263 F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed @@ -1146,7 +1146,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P fbcc1a3ebb016225c3580181c908a2904cc184a5 -R 09b58c480760cc431d5e01573bf9e4b3 +P 7a234fc3c5e7970ffe0b8d6ac33c26acb64b5c4d +R 57ac1272f14efea499bd7c6c07bb251b U drh -Z 1bf421a053293bdaa5254a0efb062c9a +Z f1f04177179428a44e2d9de7658a5211 diff --git a/manifest.uuid b/manifest.uuid index d22393ad7f..2faf99014f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7a234fc3c5e7970ffe0b8d6ac33c26acb64b5c4d \ No newline at end of file +f2f5a3ce9d075c4b1ac586c5db3a623d9035402d \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index b0b56c4567..5133591e3c 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2560,7 +2560,8 @@ case OP_MakeRecord: { int nField; /* Number of fields in the record */ char *zAffinity; /* The affinity string for the record */ int file_format; /* File format to use for encoding */ - int i; /* Space used in zNewRecord[] */ + int i; /* Space used in zNewRecord[] header */ + int j; /* Space used in zNewRecord[] content */ int len; /* Length of a field */ /* Assuming the record contains N fields, the record format looks @@ -2597,17 +2598,21 @@ case OP_MakeRecord: { /* Loop through the elements that will make up the record to figure ** out how much space is required for the new record. */ - for(pRec=pData0; pRec<=pLast; pRec++){ + assert( pData0<=pLast ); + pRec = pData0; + do{ assert( memIsValid(pRec) ); if( zAffinity ){ applyAffinity(pRec, zAffinity[pRec-pData0], encoding); } - if( pRec->flags&MEM_Zero && pRec->n>0 ){ + if( (pRec->flags&MEM_Zero)!=0 && pRec->n>0 ){ sqlite3VdbeMemExpandBlob(pRec); } serial_type = sqlite3VdbeSerialType(pRec, file_format); len = sqlite3VdbeSerialTypeLen(serial_type); nData += len; + testcase( serial_type==127 ); + testcase( serial_type==128 ); nHdr += serial_type<=127 ? 1 : sqlite3VarintLen(serial_type); if( pRec->flags & MEM_Zero ){ /* Only pure zero-filled BLOBs can be input to this Opcode. @@ -2616,9 +2621,11 @@ case OP_MakeRecord: { }else if( len ){ nZero = 0; } - } + }while( (++pRec)<=pLast ); /* Add the initial header varint and total the size */ + testcase( nHdr==126 ); + testcase( nHdr==127 ); if( nHdr<=126 ){ /* The common case */ nHdr += 1; @@ -2645,14 +2652,16 @@ case OP_MakeRecord: { /* Write the record */ i = putVarint32(zNewRecord, nHdr); - for(pRec=pData0; pRec<=pLast; pRec++){ + j = nHdr; + assert( pData0<=pLast ); + pRec = pData0; + do{ serial_type = sqlite3VdbeSerialType(pRec, file_format); i += putVarint32(&zNewRecord[i], serial_type); /* serial type */ - } - for(pRec=pData0; pRec<=pLast; pRec++){ /* serial data */ - i += sqlite3VdbeSerialPut(&zNewRecord[i], (int)(nByte-i), pRec,file_format); - } - assert( i==nByte ); + j += sqlite3VdbeSerialPut(&zNewRecord[j], (int)(nByte-j), pRec,file_format); + }while( (++pRec)<=pLast ); + assert( i==nHdr ); + assert( j==nByte ); assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); pOut->n = (int)nByte; From 7599d4aa44a0fec270bc744457d4b3a94927d366 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 9 Dec 2013 00:47:11 +0000 Subject: [PATCH 055/276] Use putVarint32() instead of putVarint() for a quantity that can never exceed 2GiB - 1. FossilOrigin-Name: 6996fb34445adedf463b66ed1f339ee1f27ce6e5 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 65c6431388..d9dba027d2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Another\ssimplification\sto\sthe\sOP_MakeRecord\sopcode,\smaking\sit\sslightly\nfaster\sand\svery\sslightly\ssmaller. -D 2013-12-08T23:33:28.824 +C Use\sputVarint32()\sinstead\sof\sputVarint()\sfor\sa\squantity\sthat\scan\snever\nexceed\s2GiB\s-\s1. +D 2013-12-09T00:47:11.109 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,7 +166,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 1809a7caa2504233bdddd12f5018422421789537 F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c 4037f58ef3f4459d0b9bb1fc1aee1136277d9ba6 +F src/btree.c 6a5f69e455804d4ace172075d284124bc816edde F src/btree.h a61ddebc78c66795a2b93181321a116746302cc9 F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0 F src/build.c 9b40580b62916612678bdb69ce0286e39c29a862 @@ -1146,7 +1146,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 7a234fc3c5e7970ffe0b8d6ac33c26acb64b5c4d -R 57ac1272f14efea499bd7c6c07bb251b +P f2f5a3ce9d075c4b1ac586c5db3a623d9035402d +R bafb04b65bbcbde5a371c6f9a8f01895 U drh -Z f1f04177179428a44e2d9de7658a5211 +Z 59e808481ed95c39c5c7f4147ae52c5f diff --git a/manifest.uuid b/manifest.uuid index 2faf99014f..7df5beacca 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f2f5a3ce9d075c4b1ac586c5db3a623d9035402d \ No newline at end of file +6996fb34445adedf463b66ed1f339ee1f27ce6e5 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index a0b6c6ba24..103093521d 100644 --- a/src/btree.c +++ b/src/btree.c @@ -5543,7 +5543,7 @@ static int fillInCell( nHeader += 4; } if( pPage->hasData ){ - nHeader += putVarint(&pCell[nHeader], nData+nZero); + nHeader += putVarint32(&pCell[nHeader], nData+nZero); }else{ nData = nZero = 0; } From 29f2bad6f0c94564522093a9feb6878fd8d893da Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 9 Dec 2013 01:04:54 +0000 Subject: [PATCH 056/276] Avoid unnecessary no-op calls from getAndInitPage() to btreeInitPage() in the btree.c logic. FossilOrigin-Name: 81f5ae13b2e23daee03151d32515387b7f5ba5e5 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index d9dba027d2..a15d84d948 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Use\sputVarint32()\sinstead\sof\sputVarint()\sfor\sa\squantity\sthat\scan\snever\nexceed\s2GiB\s-\s1. -D 2013-12-09T00:47:11.109 +C Avoid\sunnecessary\sno-op\scalls\sfrom\sgetAndInitPage()\sto\sbtreeInitPage()\s\nin\sthe\sbtree.c\slogic. +D 2013-12-09T01:04:54.208 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,7 +166,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 1809a7caa2504233bdddd12f5018422421789537 F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c 6a5f69e455804d4ace172075d284124bc816edde +F src/btree.c 368d2eaeea81254d5c7bf7e3d6c1737e08e1e10e F src/btree.h a61ddebc78c66795a2b93181321a116746302cc9 F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0 F src/build.c 9b40580b62916612678bdb69ce0286e39c29a862 @@ -1146,7 +1146,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P f2f5a3ce9d075c4b1ac586c5db3a623d9035402d -R bafb04b65bbcbde5a371c6f9a8f01895 +P 6996fb34445adedf463b66ed1f339ee1f27ce6e5 +R a6e3d012f7b111fe3cf762bd37b890b8 U drh -Z 59e808481ed95c39c5c7f4147ae52c5f +Z 69daab0d3610fce7f9ad3f7d6b1dfdc6 diff --git a/manifest.uuid b/manifest.uuid index 7df5beacca..e4ff31ef4a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6996fb34445adedf463b66ed1f339ee1f27ce6e5 \ No newline at end of file +81f5ae13b2e23daee03151d32515387b7f5ba5e5 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 103093521d..7f4e83f5f6 100644 --- a/src/btree.c +++ b/src/btree.c @@ -1652,7 +1652,7 @@ static int getAndInitPage( rc = SQLITE_CORRUPT_BKPT; }else{ rc = btreeGetPage(pBt, pgno, ppPage, bReadonly); - if( rc==SQLITE_OK ){ + if( rc==SQLITE_OK && (*ppPage)->isInit==0 ){ rc = btreeInitPage(*ppPage); if( rc!=SQLITE_OK ){ releasePage(*ppPage); From 9bb7c4ff4ff132ba7bfda7ac27c2fdf617ed64cd Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 9 Dec 2013 01:58:11 +0000 Subject: [PATCH 057/276] Use memmove() rather than a home-made copy loop in dropCell() of btree.c, for a size reduction and performance improvement. FossilOrigin-Name: 78e1706804e88a0dd5dc40bee838a3a504cfa53b --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 8 +------- 3 files changed, 8 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index a15d84d948..ee8f50545e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sunnecessary\sno-op\scalls\sfrom\sgetAndInitPage()\sto\sbtreeInitPage()\s\nin\sthe\sbtree.c\slogic. -D 2013-12-09T01:04:54.208 +C Use\smemmove()\srather\sthan\sa\shome-made\scopy\sloop\sin\sdropCell()\sof\sbtree.c,\nfor\sa\ssize\sreduction\sand\sperformance\simprovement. +D 2013-12-09T01:58:11.109 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,7 +166,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 1809a7caa2504233bdddd12f5018422421789537 F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c 368d2eaeea81254d5c7bf7e3d6c1737e08e1e10e +F src/btree.c ac25a91a1ec94b361b09fdd99253b248ab0bbefc F src/btree.h a61ddebc78c66795a2b93181321a116746302cc9 F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0 F src/build.c 9b40580b62916612678bdb69ce0286e39c29a862 @@ -1146,7 +1146,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 6996fb34445adedf463b66ed1f339ee1f27ce6e5 -R a6e3d012f7b111fe3cf762bd37b890b8 +P 81f5ae13b2e23daee03151d32515387b7f5ba5e5 +R dff255530828faccbaffbe7aa2a8b29a U drh -Z 69daab0d3610fce7f9ad3f7d6b1dfdc6 +Z 8d4fe309cbbd963b83317f42164d5ecb diff --git a/manifest.uuid b/manifest.uuid index e4ff31ef4a..ad3f97d213 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -81f5ae13b2e23daee03151d32515387b7f5ba5e5 \ No newline at end of file +78e1706804e88a0dd5dc40bee838a3a504cfa53b \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 7f4e83f5f6..df53050373 100644 --- a/src/btree.c +++ b/src/btree.c @@ -5671,7 +5671,6 @@ static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){ u32 pc; /* Offset to cell content of cell being deleted */ u8 *data; /* pPage->aData */ u8 *ptr; /* Used to move bytes around within data[] */ - u8 *endPtr; /* End of loop */ int rc; /* The return code */ int hdr; /* Beginning of the header. 0 most pages. 100 page 1 */ @@ -5696,13 +5695,8 @@ static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){ *pRC = rc; return; } - endPtr = &pPage->aCellIdx[2*pPage->nCell - 2]; - assert( (SQLITE_PTR_TO_INT(ptr)&1)==0 ); /* ptr is always 2-byte aligned */ - while( ptrnCell--; + memmove(ptr, ptr+2, 2*(pPage->nCell - idx)); put2byte(&data[hdr+3], pPage->nCell); pPage->nFree += 2; } From 8f518837f952dd40930b9ed3c026c4fd6d7453ac Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 9 Dec 2013 02:32:19 +0000 Subject: [PATCH 058/276] Use memmove() rather than a home-made copy loop in insertCell() too. FossilOrigin-Name: a3d796b1673ca68ced247d63c22ddcfb1f9d56ea --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 11 +---------- 3 files changed, 8 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index ee8f50545e..4c5b561fae 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Use\smemmove()\srather\sthan\sa\shome-made\scopy\sloop\sin\sdropCell()\sof\sbtree.c,\nfor\sa\ssize\sreduction\sand\sperformance\simprovement. -D 2013-12-09T01:58:11.109 +C Use\smemmove()\srather\sthan\sa\shome-made\scopy\sloop\sin\sinsertCell()\stoo. +D 2013-12-09T02:32:19.333 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,7 +166,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 1809a7caa2504233bdddd12f5018422421789537 F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c ac25a91a1ec94b361b09fdd99253b248ab0bbefc +F src/btree.c 432c3e22ff76e8ee1caf57ff88ba9f8af1fcfc30 F src/btree.h a61ddebc78c66795a2b93181321a116746302cc9 F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0 F src/build.c 9b40580b62916612678bdb69ce0286e39c29a862 @@ -1146,7 +1146,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 81f5ae13b2e23daee03151d32515387b7f5ba5e5 -R dff255530828faccbaffbe7aa2a8b29a +P 78e1706804e88a0dd5dc40bee838a3a504cfa53b +R 3d219561bfa9f63d670ef18564ca91c7 U drh -Z 8d4fe309cbbd963b83317f42164d5ecb +Z a11cf025d0d9777faa558f3c1da4ce10 diff --git a/manifest.uuid b/manifest.uuid index ad3f97d213..cf1f8b8cea 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -78e1706804e88a0dd5dc40bee838a3a504cfa53b \ No newline at end of file +a3d796b1673ca68ced247d63c22ddcfb1f9d56ea \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index df53050373..4974d57ee5 100644 --- a/src/btree.c +++ b/src/btree.c @@ -5733,9 +5733,6 @@ static void insertCell( int ins; /* Index in data[] where new cell pointer is inserted */ int cellOffset; /* Address of first cell pointer in data[] */ u8 *data; /* The content of the whole page */ - u8 *ptr; /* Used for moving information around in data[] */ - u8 *endPtr; /* End of the loop */ - int nSkip = (iChild ? 4 : 0); if( *pRC ) return; @@ -5786,13 +5783,7 @@ static void insertCell( if( iChild ){ put4byte(&data[idx], iChild); } - ptr = &data[end]; - endPtr = &data[ins]; - assert( (SQLITE_PTR_TO_INT(ptr)&1)==0 ); /* ptr is always 2-byte aligned */ - while( ptr>endPtr ){ - *(u16*)ptr = *(u16*)&ptr[-2]; - ptr -= 2; - } + memmove(&data[ins+2], &data[ins], end-ins); put2byte(&data[ins], idx); put2byte(&data[pPage->hdrOffset+3], pPage->nCell); #ifndef SQLITE_OMIT_AUTOVACUUM From 7250c547a560edae9cbeb4f1fe666194a91fea3e Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 9 Dec 2013 03:07:21 +0000 Subject: [PATCH 059/276] Avoid unnecessary (no-op) calls to sqlite3DbFree() from sqlite3VdbeMemRelease(). FossilOrigin-Name: 2d6dd7c2eb5a64f8994162b564a99ef0014b7460 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbemem.c | 8 +++++--- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 4c5b561fae..643699b1c1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Use\smemmove()\srather\sthan\sa\shome-made\scopy\sloop\sin\sinsertCell()\stoo. -D 2013-12-09T02:32:19.333 +C Avoid\sunnecessary\s(no-op)\scalls\sto\ssqlite3DbFree()\sfrom\ssqlite3VdbeMemRelease(). +D 2013-12-09T03:07:21.713 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -286,7 +286,7 @@ F src/vdbeInt.h 05fbda0e061dbc4aaa2709a8cccf3515c245b263 F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed F src/vdbeaux.c 09b79d475f5af2b3b5068f639609d88e0ced9d95 F src/vdbeblob.c 8cd05a5630e6d5563ad017bf82edaf812b28acde -F src/vdbemem.c 20e349d2ca928802fc8f2d42a2cc488fd6981d3f +F src/vdbemem.c f12d087d92f57fc302028ac1b45374bf8a454d7e F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147 F src/vdbetrace.c e7ec40e1999ff3c6414424365d5941178966dcbc F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd @@ -1146,7 +1146,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 78e1706804e88a0dd5dc40bee838a3a504cfa53b -R 3d219561bfa9f63d670ef18564ca91c7 +P a3d796b1673ca68ced247d63c22ddcfb1f9d56ea +R 92833625552491c74b69254824111a37 U drh -Z a11cf025d0d9777faa558f3c1da4ce10 +Z 1f5af3845443b6f278035b5de234203a diff --git a/manifest.uuid b/manifest.uuid index cf1f8b8cea..5464ad75ae 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a3d796b1673ca68ced247d63c22ddcfb1f9d56ea \ No newline at end of file +2d6dd7c2eb5a64f8994162b564a99ef0014b7460 \ No newline at end of file diff --git a/src/vdbemem.c b/src/vdbemem.c index 51f20d4cc7..8a3acd5308 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -295,10 +295,12 @@ void sqlite3VdbeMemReleaseExternal(Mem *p){ */ void sqlite3VdbeMemRelease(Mem *p){ VdbeMemRelease(p); - sqlite3DbFree(p->db, p->zMalloc); + if( p->zMalloc ){ + sqlite3DbFree(p->db, p->zMalloc); + p->zMalloc = 0; + } p->z = 0; - p->zMalloc = 0; - p->xDel = 0; + assert( p->xDel==0 ); /* Zeroed by VdbeMemRelease() above */ } /* From 195134c6c3471f193708010244f85c83d440be8e Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 9 Dec 2013 12:24:23 +0000 Subject: [PATCH 060/276] Fix an incorrect test number in the output of the speedtest1.c program. No changes to the test algorithms. FossilOrigin-Name: fbfc075a5a3c9c5c98353f396f9da7f7ec7c1c04 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/speedtest1.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 643699b1c1..eb6e212626 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sunnecessary\s(no-op)\scalls\sto\ssqlite3DbFree()\sfrom\ssqlite3VdbeMemRelease(). -D 2013-12-09T03:07:21.713 +C Fix\san\sincorrect\stest\snumber\sin\sthe\soutput\sof\sthe\sspeedtest1.c\sprogram.\s\sNo\nchanges\sto\sthe\stest\salgorithms. +D 2013-12-09T12:24:23.629 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -821,7 +821,7 @@ F test/speed3.test d32043614c08c53eafdc80f33191d5bd9b920523 F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b -F test/speedtest1.c 4f1e34b6af9af0b59ca11b57d62c3cd851990fba +F test/speedtest1.c bb3a4cc62b6cf29f5bc72c85d2bee5991e207be7 F test/spellfix.test 8c40b169b104086d8795781f670ba3c786d6d8be F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298 F test/stat.test c8eccfe8fcd3f3cfc864ce22d5b9e803a3c69940 @@ -1146,7 +1146,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P a3d796b1673ca68ced247d63c22ddcfb1f9d56ea -R 92833625552491c74b69254824111a37 +P 2d6dd7c2eb5a64f8994162b564a99ef0014b7460 +R 9b7d54400c77029a626c96270fd35702 U drh -Z 1f5af3845443b6f278035b5de234203a +Z a893e863f82f8a1033dbfe922fa06c0b diff --git a/manifest.uuid b/manifest.uuid index 5464ad75ae..7d8b23433a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2d6dd7c2eb5a64f8994162b564a99ef0014b7460 \ No newline at end of file +fbfc075a5a3c9c5c98353f396f9da7f7ec7c1c04 \ No newline at end of file diff --git a/test/speedtest1.c b/test/speedtest1.c index f3e79ec816..0e6b1a99c8 100644 --- a/test/speedtest1.c +++ b/test/speedtest1.c @@ -665,7 +665,7 @@ void testset_main(void){ n = sz/5; - speedtest1_begin_test(290, "%d four-ways joins", n); + speedtest1_begin_test(300, "%d four-ways joins", n); speedtest1_exec("BEGIN"); speedtest1_prepare( "SELECT t1.c FROM t1, t2, t3, t4\n" From a6353a3f64584ac73a11b4afbe5147244a64f8aa Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 9 Dec 2013 19:03:26 +0000 Subject: [PATCH 061/276] Performance optimizations for sqlite3VXPrintf(). FossilOrigin-Name: 9227ad48e1612b32a3a3e9551c49890f93abc0a7 --- manifest | 20 +++++++++---------- manifest.uuid | 2 +- src/btree.c | 2 +- src/build.c | 4 ++-- src/printf.c | 52 +++++++++++++++++++++++++++++++------------------ src/sqliteInt.h | 1 + src/where.c | 4 ++-- 7 files changed, 50 insertions(+), 35 deletions(-) diff --git a/manifest b/manifest index eb6e212626..029bbd9b38 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sincorrect\stest\snumber\sin\sthe\soutput\sof\sthe\sspeedtest1.c\sprogram.\s\sNo\nchanges\sto\sthe\stest\salgorithms. -D 2013-12-09T12:24:23.629 +C Performance\soptimizations\sfor\ssqlite3VXPrintf(). +D 2013-12-09T19:03:26.813 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,10 +166,10 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 1809a7caa2504233bdddd12f5018422421789537 F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c 432c3e22ff76e8ee1caf57ff88ba9f8af1fcfc30 +F src/btree.c 44a44aa21ee24763ddda98d9a41bd85498359ae2 F src/btree.h a61ddebc78c66795a2b93181321a116746302cc9 F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0 -F src/build.c 9b40580b62916612678bdb69ce0286e39c29a862 +F src/build.c 47ef8209e56d840d2b35b8a243c6ee567ad52bda F src/callback.c f99a8957ba2adf369645fac0db09ad8adcf1caa2 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd @@ -215,7 +215,7 @@ F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222 F src/pcache1.c a467393909a4ed7ca9de066d85ba5c5b04a5be63 F src/pragma.c 5ab7279d132143feb77f773688a24ab05da75fd7 F src/prepare.c 359d1a1e9c9bd4488e4dd3a1aaaf2d2ebb9bb768 -F src/printf.c da9119eb31a187a4b99f60aa4a225141c0ebb74b +F src/printf.c aacd7f73018122689dbbe89d85c2e37f737b931f F src/random.c 0b2dbc37fdfbfa6bd455b091dfcef5bdb32dba68 F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 @@ -224,7 +224,7 @@ F src/shell.c 936a72ff784efff3832cce274a96ed0b036e6758 F src/sqlite.h.in 125dc0b76f0116f1cd6f13536db52ba981e1c5bd F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h f3a5d663fe9c6c0b2ee7fc2e20a6204eaea5bc7c +F src/sqliteInt.h c59b756b3aebefdce24ff44c4a7b3c155a3c26ee F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -293,7 +293,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c e9e593d5bb798c3e67fc3893dfe7055c9e7d8d74 -F src/where.c e6a4e713abe6f995495ea53dd6a5e48f88b53883 +F src/where.c b8f3aab1e5843012895b89a183dcdd6cef0708db F src/whereInt.h 96a75c61f1d2b9d4a8e4bb17d89deb0cf7cba358 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1146,7 +1146,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 2d6dd7c2eb5a64f8994162b564a99ef0014b7460 -R 9b7d54400c77029a626c96270fd35702 +P fbfc075a5a3c9c5c98353f396f9da7f7ec7c1c04 +R b8ab7b74939c13b89c303e9a6e5110d1 U drh -Z a893e863f82f8a1033dbfe922fa06c0b +Z 3687c2e0d19ee741a7e8e3f49ed7da21 diff --git a/manifest.uuid b/manifest.uuid index 7d8b23433a..e6e97065a9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fbfc075a5a3c9c5c98353f396f9da7f7ec7c1c04 \ No newline at end of file +9227ad48e1612b32a3a3e9551c49890f93abc0a7 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 4974d57ee5..a03737701e 100644 --- a/src/btree.c +++ b/src/btree.c @@ -7745,7 +7745,7 @@ static void checkAppendMsg( sqlite3StrAccumAppend(&pCheck->errMsg, "\n", 1); } if( zMsg1 ){ - sqlite3StrAccumAppend(&pCheck->errMsg, zMsg1, -1); + sqlite3StrAccumAppendAll(&pCheck->errMsg, zMsg1); } sqlite3VXPrintf(&pCheck->errMsg, 1, zFormat, ap); va_end(ap); diff --git a/src/build.c b/src/build.c index a7d5a29946..c83ce57cfa 100644 --- a/src/build.c +++ b/src/build.c @@ -3989,9 +3989,9 @@ void sqlite3UniqueConstraint( for(j=0; jnKeyCol; j++){ char *zCol = pTab->aCol[pIdx->aiColumn[j]].zName; if( j ) sqlite3StrAccumAppend(&errMsg, ", ", 2); - sqlite3StrAccumAppend(&errMsg, pTab->zName, -1); + sqlite3StrAccumAppendAll(&errMsg, pTab->zName); sqlite3StrAccumAppend(&errMsg, ".", 1); - sqlite3StrAccumAppend(&errMsg, zCol, -1); + sqlite3StrAccumAppendAll(&errMsg, zCol); } zErr = sqlite3StrAccumFinish(&errMsg); sqlite3HaltConstraint(pParse, diff --git a/src/printf.c b/src/printf.c index f9e5c6406d..011eecdfaa 100644 --- a/src/printf.c +++ b/src/printf.c @@ -148,6 +148,14 @@ void sqlite3AppendSpace(StrAccum *pAccum, int N){ } } +/* +** Set the StrAccum object to an error mode. +*/ +void setStrAccumError(StrAccum *p, u8 eError){ + p->accError = eError; + p->nAlloc = 0; +} + /* ** On machines with a small stack size, you can redefine the ** SQLITE_PRINT_BUF_SIZE to be something smaller, if desired. @@ -359,7 +367,7 @@ void sqlite3VXPrintf( nOut = precision + 10; zOut = zExtra = sqlite3Malloc( nOut ); if( zOut==0 ){ - pAccum->accError = STRACCUM_NOMEM; + setStrAccumError(pAccum, STRACCUM_NOMEM); return; } } @@ -471,7 +479,7 @@ void sqlite3VXPrintf( if( MAX(e2,0)+precision+width > etBUFSIZE - 15 ){ bufpt = zExtra = sqlite3Malloc( MAX(e2,0)+precision+width+15 ); if( bufpt==0 ){ - pAccum->accError = STRACCUM_NOMEM; + setStrAccumError(pAccum, STRACCUM_NOMEM); return; } } @@ -606,7 +614,7 @@ void sqlite3VXPrintf( if( n>etBUFSIZE ){ bufpt = zExtra = sqlite3Malloc( n ); if( bufpt==0 ){ - pAccum->accError = STRACCUM_NOMEM; + setStrAccumError(pAccum, STRACCUM_NOMEM); return; } }else{ @@ -641,10 +649,10 @@ void sqlite3VXPrintf( struct SrcList_item *pItem = &pSrc->a[k]; assert( k>=0 && knSrc ); if( pItem->zDatabase ){ - sqlite3StrAccumAppend(pAccum, pItem->zDatabase, -1); + sqlite3StrAccumAppendAll(pAccum, pItem->zDatabase); sqlite3StrAccumAppend(pAccum, ".", 1); } - sqlite3StrAccumAppend(pAccum, pItem->zName, -1); + sqlite3StrAccumAppendAll(pAccum, pItem->zName); length = width = 0; break; } @@ -684,21 +692,19 @@ void sqlite3VXPrintf( */ void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){ assert( z!=0 || N==0 ); - if( p->accError ){ - testcase(p->accError==STRACCUM_TOOBIG); - testcase(p->accError==STRACCUM_NOMEM); - return; - } - assert( p->zText!=0 || p->nChar==0 ); - if( N<=0 ){ - if( N==0 || z[0]==0 ) return; - N = sqlite3Strlen30(z); - } + assert( p->zText!=0 || p->nChar==0 || p->accError ); + assert( N>=0 ); + assert( p->accError==0 || p->nAlloc==0 ); if( p->nChar+N >= p->nAlloc ){ char *zNew; + if( p->accError ){ + testcase(p->accError==STRACCUM_TOOBIG); + testcase(p->accError==STRACCUM_NOMEM); + return; + } if( !p->useMalloc ){ - p->accError = STRACCUM_TOOBIG; N = p->nAlloc - p->nChar - 1; + setStrAccumError(p, STRACCUM_TOOBIG); if( N<=0 ){ return; } @@ -708,7 +714,7 @@ void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){ szNew += N + 1; if( szNew > p->mxAlloc ){ sqlite3StrAccumReset(p); - p->accError = STRACCUM_TOOBIG; + setStrAccumError(p, STRACCUM_TOOBIG); return; }else{ p->nAlloc = (int)szNew; @@ -722,8 +728,8 @@ void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){ if( zOld==0 && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar); p->zText = zNew; }else{ - p->accError = STRACCUM_NOMEM; sqlite3StrAccumReset(p); + setStrAccumError(p, STRACCUM_NOMEM); return; } } @@ -733,6 +739,14 @@ void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){ p->nChar += N; } +/* +** Append the complete text of zero-terminated string z[] to the p string. +*/ +void sqlite3StrAccumAppendAll(StrAccum *p, const char *z){ + return sqlite3StrAccumAppend(p, z, sqlite3Strlen30(z)); +} + + /* ** Finish off a string by making sure it is zero-terminated. ** Return a pointer to the resulting string. Return a NULL @@ -750,7 +764,7 @@ char *sqlite3StrAccumFinish(StrAccum *p){ if( p->zText ){ memcpy(p->zText, p->zBase, p->nChar+1); }else{ - p->accError = STRACCUM_NOMEM; + setStrAccumError(p, STRACCUM_NOMEM); } } } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 8bf05a9c8e..1f10c31cb5 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3222,6 +3222,7 @@ int sqlite3OpenTempDatabase(Parse *); void sqlite3StrAccumInit(StrAccum*, char*, int, int); void sqlite3StrAccumAppend(StrAccum*,const char*,int); +void sqlite3StrAccumAppendAll(StrAccum*,const char*); void sqlite3AppendSpace(StrAccum*,int); char *sqlite3StrAccumFinish(StrAccum*); void sqlite3StrAccumReset(StrAccum*); diff --git a/src/where.c b/src/where.c index 7d3ec48dac..afe664aa02 100644 --- a/src/where.c +++ b/src/where.c @@ -2568,7 +2568,7 @@ static void explainAppendTerm( const char *zOp /* Name of the operator */ ){ if( iTerm ) sqlite3StrAccumAppend(pStr, " AND ", 5); - sqlite3StrAccumAppend(pStr, zColumn, -1); + sqlite3StrAccumAppendAll(pStr, zColumn); sqlite3StrAccumAppend(pStr, zOp, 1); sqlite3StrAccumAppend(pStr, "?", 1); } @@ -2614,7 +2614,7 @@ static char *explainIndexRange(sqlite3 *db, WhereLoop *pLoop, Table *pTab){ }else{ if( i ) sqlite3StrAccumAppend(&txt, " AND ", 5); sqlite3StrAccumAppend(&txt, "ANY(", 4); - sqlite3StrAccumAppend(&txt, z, -1); + sqlite3StrAccumAppendAll(&txt, z); sqlite3StrAccumAppend(&txt, ")", 1); } } From c65faab2e126c0c6c650420f498adf40589ee602 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 9 Dec 2013 19:25:28 +0000 Subject: [PATCH 062/276] Minor performance optimizations in pager.c. FossilOrigin-Name: ba9eef5f5293633d1479e1d877bf338edb2a9471 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pager.c | 14 ++++---------- 3 files changed, 11 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index 029bbd9b38..9713b269fb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\soptimizations\sfor\ssqlite3VXPrintf(). -D 2013-12-09T19:03:26.813 +C Minor\sperformance\soptimizations\sin\spager.c. +D 2013-12-09T19:25:28.392 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -207,7 +207,7 @@ F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_unix.c 60a7b3b23e6fcf83a50d1e320b280b551724e11f F src/os_win.c 4323dd0bac4f7a7037fc4cf87fb4692d17f0b108 -F src/pager.c 061d0b41354a8446256f5d765771e2a026ec8ed2 +F src/pager.c 19203eff37c099271189bf8b378a1143847b92e3 F src/pager.h f094af9f6ececfaa8a1e93876905a4f34233fb0c F src/parse.y acee1a9958539e21263362b194594c5255ad2fca F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 @@ -1146,7 +1146,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P fbfc075a5a3c9c5c98353f396f9da7f7ec7c1c04 -R b8ab7b74939c13b89c303e9a6e5110d1 +P 9227ad48e1612b32a3a3e9551c49890f93abc0a7 +R 2aecb7bab925cdbd0159d9e849c7e955 U drh -Z 3687c2e0d19ee741a7e8e3f49ed7da21 +Z 455daaba8769a2d87fdc74aa6d107f2c diff --git a/manifest.uuid b/manifest.uuid index e6e97065a9..c5695949d4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9227ad48e1612b32a3a3e9551c49890f93abc0a7 \ No newline at end of file +ba9eef5f5293633d1479e1d877bf338edb2a9471 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 7f79bd7eca..8cbb50ce3c 100644 --- a/src/pager.c +++ b/src/pager.c @@ -5643,14 +5643,8 @@ static int pager_write(PgHdr *pPg){ || pPager->eState==PAGER_WRITER_DBMOD ); assert( assert_pager_state(pPager) ); - - /* If an error has been previously detected, report the same error - ** again. This should not happen, but the check provides robustness. */ - if( NEVER(pPager->errCode) ) return pPager->errCode; - - /* Higher-level routines never call this function if database is not - ** writable. But check anyway, just for robustness. */ - if( NEVER(pPager->readOnly) ) return SQLITE_PERM; + assert( pPager->errCode==0 ); + assert( pPager->readOnly==0 ); CHECK_PAGE(pPg); @@ -5779,19 +5773,19 @@ int sqlite3PagerWrite(DbPage *pDbPage){ PgHdr *pPg = pDbPage; Pager *pPager = pPg->pPager; - Pgno nPagePerSector = (pPager->sectorSize/pPager->pageSize); assert( (pPg->flags & PGHDR_MMAP)==0 ); assert( pPager->eState>=PAGER_WRITER_LOCKED ); assert( pPager->eState!=PAGER_ERROR ); assert( assert_pager_state(pPager) ); - if( nPagePerSector>1 ){ + if( pPager->sectorSize > pPager->pageSize ){ Pgno nPageCount; /* Total number of pages in database file */ Pgno pg1; /* First page of the sector pPg is located on. */ int nPage = 0; /* Number of pages starting at pg1 to journal */ int ii; /* Loop counter */ int needSync = 0; /* True if any page has PGHDR_NEED_SYNC */ + Pgno nPagePerSector = (pPager->sectorSize/pPager->pageSize); /* Set the doNotSpill NOSYNC bit to 1. This is because we cannot allow ** a journal header to be written between the pages journaled by From 999cd08aae0e93ac3890f8dcf065a70378d7bb67 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 9 Dec 2013 20:42:03 +0000 Subject: [PATCH 063/276] Modify the way some internal file-controls are invoked. In order to support multi-file transactions in the zipvfs extension. FossilOrigin-Name: 32fb1784af4594161d954343e3787db702000a4d --- manifest | 27 +++++++++++++++------------ manifest.uuid | 2 +- src/backup.c | 2 +- src/pager.c | 24 +++++++++++++++--------- src/pager.h | 2 +- src/sqlite.h.in | 2 ++ src/test6.c | 8 ++++++-- test/tester.tcl | 5 ++++- 8 files changed, 45 insertions(+), 27 deletions(-) diff --git a/manifest b/manifest index eb6e212626..49f2c98b68 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sincorrect\stest\snumber\sin\sthe\soutput\sof\sthe\sspeedtest1.c\sprogram.\s\sNo\nchanges\sto\sthe\stest\salgorithms. -D 2013-12-09T12:24:23.629 +C Modify\sthe\sway\ssome\sinternal\sfile-controls\sare\sinvoked.\sIn\sorder\sto\ssupport\smulti-file\stransactions\sin\sthe\szipvfs\sextension. +D 2013-12-09T20:42:03.163 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -163,7 +163,7 @@ F src/alter.c 2af0330bb1b601af7a7789bf7229675fd772a083 F src/analyze.c 581d5c18ce89c6f45d4dca65914d0de5b4dad41f F src/attach.c 0a17c9364895316ca4f52d06a97a72c0af1ae8b3 F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 -F src/backup.c 1809a7caa2504233bdddd12f5018422421789537 +F src/backup.c 6cb4c4ee1d302621eb18ad93a4216fed387b2568 F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btree.c 432c3e22ff76e8ee1caf57ff88ba9f8af1fcfc30 @@ -207,8 +207,8 @@ F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_unix.c 60a7b3b23e6fcf83a50d1e320b280b551724e11f F src/os_win.c 4323dd0bac4f7a7037fc4cf87fb4692d17f0b108 -F src/pager.c 061d0b41354a8446256f5d765771e2a026ec8ed2 -F src/pager.h f094af9f6ececfaa8a1e93876905a4f34233fb0c +F src/pager.c b28711af0f595414a7017f6993d4e6f90a3d2114 +F src/pager.h 6a790b64a9ea79bc2c849bdefdd39e2344bca94a F src/parse.y acee1a9958539e21263362b194594c5255ad2fca F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222 @@ -221,7 +221,7 @@ F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c d41381d80a22d3a83352aeca274cccf264ac277a F src/shell.c 936a72ff784efff3832cce274a96ed0b036e6758 -F src/sqlite.h.in 125dc0b76f0116f1cd6f13536db52ba981e1c5bd +F src/sqlite.h.in 767b7475655de093182ec3d7b1f66a0cf5f1c390 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc F src/sqliteInt.h f3a5d663fe9c6c0b2ee7fc2e20a6204eaea5bc7c @@ -234,7 +234,7 @@ F src/test2.c 7355101c085304b90024f2261e056cdff13c6c35 F src/test3.c 1c0e5d6f080b8e33c1ce8b3078e7013fdbcd560c F src/test4.c 9b32d22f5f150abe23c1830e2057c4037c45b3df F src/test5.c a6d1ac55ac054d0b2b8f37b5e655b6c92645a013 -F src/test6.c 4f958b71334695e65746d357dac77709732b28db +F src/test6.c 6884dcfb1d04c26083ffb441ab329043967c09e5 F src/test7.c 72b732baa5642f795655ba1126ea032af46ecfd2 F src/test8.c c7aab1d9fbbf54fc33d43b73aa24aa55f9eaf534 F src/test9.c bea1e8cf52aa93695487badedd6e1886c321ea60 @@ -841,7 +841,7 @@ F test/tclsqlite.test 37a61c2da7e3bfe3b8c1a2867199f6b860df5d43 F test/tempdb.test 19d0f66e2e3eeffd68661a11c83ba5e6ace9128c F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30 F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1 -F test/tester.tcl 2a7cce4abf404557c09323a84a2444b189835d0f +F test/tester.tcl 08e9f317afe60d398fa900993503ecaef3295bad F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5 F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58 F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7 @@ -1146,7 +1146,10 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 2d6dd7c2eb5a64f8994162b564a99ef0014b7460 -R 9b7d54400c77029a626c96270fd35702 -U drh -Z a893e863f82f8a1033dbfe922fa06c0b +P fbfc075a5a3c9c5c98353f396f9da7f7ec7c1c04 +R e8a2a861e9953d868791659025627e6a +T *branch * zipvfs-multifile-commit +T *sym-zipvfs-multifile-commit * +T -sym-trunk * +U dan +Z 19770b8e4b3ab930c64ec8e320e02ae3 diff --git a/manifest.uuid b/manifest.uuid index 7d8b23433a..c4279a2bfe 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fbfc075a5a3c9c5c98353f396f9da7f7ec7c1c04 \ No newline at end of file +32fb1784af4594161d954343e3787db702000a4d \ No newline at end of file diff --git a/src/backup.c b/src/backup.c index 1bac821f3f..292f3f456c 100644 --- a/src/backup.c +++ b/src/backup.c @@ -526,7 +526,7 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){ /* Sync the database file to disk. */ if( rc==SQLITE_OK ){ - rc = sqlite3PagerSync(pDestPager); + rc = sqlite3PagerSync(pDestPager, 0); } }else{ sqlite3PagerTruncateImage(pDestPager, nDestTruncate); diff --git a/src/pager.c b/src/pager.c index 7f79bd7eca..3a59ca29e1 100644 --- a/src/pager.c +++ b/src/pager.c @@ -1249,6 +1249,7 @@ static int readMasterJournal(sqlite3_file *pJrnl, char *zMaster, u32 nMaster){ || szJ<16 || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-16, &len)) || len>=nMaster + || len==0 || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-12, &cksum)) || SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, aMagic, 8, szJ-8)) || memcmp(aMagic, aJournalMagic, 8) @@ -2018,6 +2019,11 @@ static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){ rc = pager_truncate(pPager, pPager->dbSize); } + if( rc==SQLITE_OK && bCommit && isOpen(pPager->fd) ){ + rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_COMMIT_PHASETWO, 0); + if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; + } + if( !pPager->exclusiveMode && (!pagerUseWal(pPager) || sqlite3WalExclusiveMode(pPager->pWal, 0)) ){ @@ -2831,7 +2837,7 @@ end_playback: if( rc==SQLITE_OK && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN) ){ - rc = sqlite3PagerSync(pPager); + rc = sqlite3PagerSync(pPager, 0); } if( rc==SQLITE_OK ){ rc = pager_end_transaction(pPager, zMaster[0]!='\0', 0); @@ -6006,17 +6012,17 @@ static int pager_incr_changecounter(Pager *pPager, int isDirectMode){ ** If successful, or if called on a pager for which it is a no-op, this ** function returns SQLITE_OK. Otherwise, an IO error code is returned. */ -int sqlite3PagerSync(Pager *pPager){ +int sqlite3PagerSync(Pager *pPager, const char *zMaster){ int rc = SQLITE_OK; + + if( isOpen(pPager->fd) ){ + void *pArg = (void*)zMaster; + rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SYNC_OMITTED, pArg); + if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; + } if( !pPager->noSync ){ assert( !MEMDB ); rc = sqlite3OsSync(pPager->fd, pPager->syncFlags); - }else if( isOpen(pPager->fd) ){ - assert( !MEMDB ); - rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SYNC_OMITTED, 0); - if( rc==SQLITE_NOTFOUND ){ - rc = SQLITE_OK; - } } return rc; } @@ -6215,7 +6221,7 @@ int sqlite3PagerCommitPhaseOne( /* Finally, sync the database file. */ if( !noSync ){ - rc = sqlite3PagerSync(pPager); + rc = sqlite3PagerSync(pPager, zMaster); } IOTRACE(("DBSYNC %p\n", pPager)) } diff --git a/src/pager.h b/src/pager.h index 7851d28345..55988a8486 100644 --- a/src/pager.h +++ b/src/pager.h @@ -150,7 +150,7 @@ void sqlite3PagerPagecount(Pager*, int*); int sqlite3PagerBegin(Pager*, int exFlag, int); int sqlite3PagerCommitPhaseOne(Pager*,const char *zMaster, int); int sqlite3PagerExclusiveLock(Pager*); -int sqlite3PagerSync(Pager *pPager); +int sqlite3PagerSync(Pager *pPager, const char *zMaster); int sqlite3PagerCommitPhaseTwo(Pager*); int sqlite3PagerRollback(Pager*); int sqlite3PagerOpenSavepoint(Pager *pPager, int n); diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 1ad181e740..9616adcd38 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -946,6 +946,8 @@ struct sqlite3_io_methods { #define SQLITE_FCNTL_TRACE 19 #define SQLITE_FCNTL_HAS_MOVED 20 +#define SQLITE_FCNTL_COMMIT_PHASETWO 21 + /* ** CAPI3REF: Mutex Handle ** diff --git a/src/test6.c b/src/test6.c index 6ea03b0f1c..fb94363c36 100644 --- a/src/test6.c +++ b/src/test6.c @@ -409,13 +409,17 @@ static int cfRead( sqlite_int64 iOfst ){ CrashFile *pCrash = (CrashFile *)pFile; + int nCopy = (int)MIN((i64)iAmt, (pCrash->iSize - iOfst)); + + if( nCopy>0 ){ + memcpy(zBuf, &pCrash->zData[iOfst], nCopy); + } /* Check the file-size to see if this is a short-read */ - if( pCrash->iSize<(iOfst+iAmt) ){ + if( nCopyzData[iOfst], iAmt); return SQLITE_OK; } diff --git a/test/tester.tcl b/test/tester.tcl index 771ca91442..109fb310a9 100644 --- a/test/tester.tcl +++ b/test/tester.tcl @@ -1251,6 +1251,7 @@ proc crashsql {args} { set blocksize "" set crashdelay 1 set prngseed 0 + set opendb { sqlite3 db test.db -vfs crash } set tclbody {} set crashfile "" set dc "" @@ -1262,6 +1263,7 @@ proc crashsql {args} { set z2 [lindex $args [expr $ii+1]] if {$n>1 && [string first $z -delay]==0} {set crashdelay $z2} \ + elseif {$n>1 && [string first $z -opendb]==0} {set opendb $z2} \ elseif {$n>1 && [string first $z -seed]==0} {set prngseed $z2} \ elseif {$n>1 && [string first $z -file]==0} {set crashfile $z2} \ elseif {$n>1 && [string first $z -tclbody]==0} {set tclbody $z2} \ @@ -1283,7 +1285,7 @@ proc crashsql {args} { puts $f "sqlite3_crash_enable 1" puts $f "sqlite3_crashparams $blocksize $dc $crashdelay $cfile" puts $f "sqlite3_test_control_pending_byte $::sqlite_pending_byte" - puts $f "sqlite3 db test.db -vfs crash" + puts $f $opendb # This block sets the cache size of the main database to 10 # pages. This is done in case the build is configured to omit @@ -1291,6 +1293,7 @@ proc crashsql {args} { puts $f {db eval {SELECT * FROM sqlite_master;}} puts $f {set bt [btree_from_db db]} puts $f {btree_set_cache_size $bt 10} + if {$prngseed} { set seed [expr {$prngseed%10007+1}] # puts seed=$seed From 2a8d2261ed2859b08f5423c1d0c3903498f71d9d Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 9 Dec 2013 20:43:22 +0000 Subject: [PATCH 064/276] Simplify the sqlite3BtreeKeyFetch() and sqlite3BtreeDataFetch() interfaces to the storage engine. FossilOrigin-Name: bf97598592ff60fab2a06d8b31b0201200b91684 --- manifest | 12 +++++------ manifest.uuid | 2 +- src/btree.c | 56 +++++++++++---------------------------------------- 3 files changed, 19 insertions(+), 51 deletions(-) diff --git a/manifest b/manifest index 9713b269fb..63d41eac58 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\sperformance\soptimizations\sin\spager.c. -D 2013-12-09T19:25:28.392 +C Simplify\sthe\ssqlite3BtreeKeyFetch()\sand\ssqlite3BtreeDataFetch()\sinterfaces\nto\sthe\sstorage\sengine. +D 2013-12-09T20:43:22.965 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,7 +166,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 1809a7caa2504233bdddd12f5018422421789537 F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c 44a44aa21ee24763ddda98d9a41bd85498359ae2 +F src/btree.c 09285d6ffe7d819b9656ea9b7ecf1ab949a926fb F src/btree.h a61ddebc78c66795a2b93181321a116746302cc9 F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0 F src/build.c 47ef8209e56d840d2b35b8a243c6ee567ad52bda @@ -1146,7 +1146,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 9227ad48e1612b32a3a3e9551c49890f93abc0a7 -R 2aecb7bab925cdbd0159d9e849c7e955 +P ba9eef5f5293633d1479e1d877bf338edb2a9471 +R 11cbe9b8d7b59f7bcb32cf4280072bce U drh -Z 455daaba8769a2d87fdc74aa6d107f2c +Z c873c3f777f880d8ffd5cf3f18630860 diff --git a/manifest.uuid b/manifest.uuid index c5695949d4..4b979d210e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ba9eef5f5293633d1479e1d877bf338edb2a9471 \ No newline at end of file +bf97598592ff60fab2a06d8b31b0201200b91684 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index a03737701e..da1b91940d 100644 --- a/src/btree.c +++ b/src/btree.c @@ -4192,10 +4192,10 @@ int sqlite3BtreeData(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){ /* ** Return a pointer to payload information from the entry that the ** pCur cursor is pointing to. The pointer is to the beginning of -** the key if skipKey==0 and it points to the beginning of data if -** skipKey==1. The number of bytes of available key/data is written -** into *pAmt. If *pAmt==0, then the value returned will not be -** a valid pointer. +** the key if index btrees (pPage->intKey==0) and is the data for +** table btrees (pPage->intKey==1). The number of bytes of available +** key/data is written into *pAmt. If *pAmt==0, then the value +** returned will not be a valid pointer. ** ** This routine is an optimization. It is common for the entire key ** and data to fit on the local page and for there to be no overflow @@ -4208,41 +4208,21 @@ int sqlite3BtreeData(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){ ** page of the database. The data might change or move the next time ** any btree routine is called. */ -static const unsigned char *fetchPayload( +static const void *fetchPayload( BtCursor *pCur, /* Cursor pointing to entry to read from */ - u32 *pAmt, /* Write the number of available bytes here */ - int skipKey /* read beginning at data if this is true */ + u32 *pAmt /* Write the number of available bytes here */ ){ - unsigned char *aPayload; - MemPage *pPage; - u32 nKey; - u32 nLocal; - assert( pCur!=0 && pCur->iPage>=0 && pCur->apPage[pCur->iPage]); assert( pCur->eState==CURSOR_VALID ); + assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); assert( cursorHoldsMutex(pCur) ); - pPage = pCur->apPage[pCur->iPage]; - assert( pCur->aiIdx[pCur->iPage]nCell ); + assert( pCur->aiIdx[pCur->iPage]apPage[pCur->iPage]->nCell ); if( pCur->info.nSize==0 ){ btreeParseCell(pCur->apPage[pCur->iPage], pCur->aiIdx[pCur->iPage], &pCur->info); } - aPayload = pCur->info.pCell; - aPayload += pCur->info.nHeader; - if( pPage->intKey ){ - nKey = 0; - }else{ - nKey = (int)pCur->info.nKey; - } - if( skipKey ){ - aPayload += nKey; - nLocal = pCur->info.nLocal - nKey; - }else{ - nLocal = pCur->info.nLocal; - assert( nLocal<=nKey ); - } - *pAmt = nLocal; - return aPayload; + *pAmt = pCur->info.nLocal; + return (void*)(pCur->info.pCell + pCur->info.nHeader); } @@ -4261,22 +4241,10 @@ static const unsigned char *fetchPayload( ** in the common case where no overflow pages are used. */ const void *sqlite3BtreeKeyFetch(BtCursor *pCur, u32 *pAmt){ - const void *p = 0; - assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); - assert( cursorHoldsMutex(pCur) ); - if( ALWAYS(pCur->eState==CURSOR_VALID) ){ - p = (const void*)fetchPayload(pCur, pAmt, 0); - } - return p; + return fetchPayload(pCur, pAmt); } const void *sqlite3BtreeDataFetch(BtCursor *pCur, u32 *pAmt){ - const void *p = 0; - assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); - assert( cursorHoldsMutex(pCur) ); - if( ALWAYS(pCur->eState==CURSOR_VALID) ){ - p = (const void*)fetchPayload(pCur, pAmt, 1); - } - return p; + return fetchPayload(pCur, pAmt); } From a2a3028d5fd74f5fc4be57ff058cfe8761240c66 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 9 Dec 2013 21:06:46 +0000 Subject: [PATCH 065/276] Reduce the number of times that OP_Column calls sqlite3VdbeMemMakeWriteable(). FossilOrigin-Name: 6b51863553e51334880fb322bdf74e51e35d0e61 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 63d41eac58..60ea04f4fb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplify\sthe\ssqlite3BtreeKeyFetch()\sand\ssqlite3BtreeDataFetch()\sinterfaces\nto\sthe\sstorage\sengine. -D 2013-12-09T20:43:22.965 +C Reduce\sthe\snumber\sof\stimes\sthat\sOP_Column\scalls\ssqlite3VdbeMemMakeWriteable(). +D 2013-12-09T21:06:46.044 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -280,7 +280,7 @@ F src/update.c d1c2477dcf14d90999d1935af4efb4806553250b F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c 76ed0519296e3f62e97e57dab1999e34184c8e49 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c 6ccb107de55a34b7676a9eaa0aeb827015723fa4 +F src/vdbe.c 5338567d17c055b26b9b3d280bdd8aa4e8e13d3f F src/vdbe.h c06f0813f853566457ce9cfb1a4a4bc39a5da644 F src/vdbeInt.h 05fbda0e061dbc4aaa2709a8cccf3515c245b263 F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed @@ -1146,7 +1146,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P ba9eef5f5293633d1479e1d877bf338edb2a9471 -R 11cbe9b8d7b59f7bcb32cf4280072bce +P bf97598592ff60fab2a06d8b31b0201200b91684 +R 30f9bdfbb15779200abce614661249ba U drh -Z c873c3f777f880d8ffd5cf3f18630860 +Z 09a9fc22866f6b8bd3a17a9239808986 diff --git a/manifest.uuid b/manifest.uuid index 4b979d210e..65b1e84f6e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bf97598592ff60fab2a06d8b31b0201200b91684 \ No newline at end of file +6b51863553e51334880fb322bdf74e51e35d0e61 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 5133591e3c..1108a85341 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2496,7 +2496,7 @@ case OP_Column: { pDest->enc = encoding; op_column_out: - rc = sqlite3VdbeMemMakeWriteable(pDest); + Deephemeralize(pDest); op_column_error: UPDATE_MAX_BLOBSIZE(pDest); REGISTER_TRACE(pOp->p3, pDest); From 401387553d0c92b6452b22e4769bdf616c34c7de Mon Sep 17 00:00:00 2001 From: mistachkin Date: Mon, 9 Dec 2013 21:48:49 +0000 Subject: [PATCH 066/276] Correct the VFS name as reported by the file control when explicitly using the 'win32-longpath' VFS. FossilOrigin-Name: c43b59dac1fbb67ec3a9d921005543046ad416ce --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/os_win.c | 2 +- test/win32longpath.test | 16 ++++++++++++---- 4 files changed, 22 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 60ea04f4fb..c03216855d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Reduce\sthe\snumber\sof\stimes\sthat\sOP_Column\scalls\ssqlite3VdbeMemMakeWriteable(). -D 2013-12-09T21:06:46.044 +C Correct\sthe\sVFS\sname\sas\sreported\sby\sthe\sfile\scontrol\swhen\sexplicitly\susing\sthe\s'win32-longpath'\sVFS. +D 2013-12-09T21:48:49.439 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -206,7 +206,7 @@ F src/os.c b4ad71336fd96f97776f75587cd9e8218288f5be F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_unix.c 60a7b3b23e6fcf83a50d1e320b280b551724e11f -F src/os_win.c 4323dd0bac4f7a7037fc4cf87fb4692d17f0b108 +F src/os_win.c 16eac0961603182ffc10c02b39fe830126538e07 F src/pager.c 19203eff37c099271189bf8b378a1143847b92e3 F src/pager.h f094af9f6ececfaa8a1e93876905a4f34233fb0c F src/parse.y acee1a9958539e21263362b194594c5255ad2fca @@ -1088,7 +1088,7 @@ F test/wherelimit.test 5e9fd41e79bb2b2d588ed999d641d9c965619b31 F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c F test/win32lock.test 7a6bd73a5dcdee39b5bb93e92395e1773a194361 -F test/win32longpath.test e2aafc07e6990fe86c69be22a3d1a0e210cd329b +F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d F test/without_rowid1.test aaa26da19d543cd8d3d2d0e686dfa255556c15c8 F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99 F test/without_rowid3.test eac3d5c8a1924725b58503a368f2cbd24fd6c8a0 @@ -1146,7 +1146,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P bf97598592ff60fab2a06d8b31b0201200b91684 -R 30f9bdfbb15779200abce614661249ba -U drh -Z 09a9fc22866f6b8bd3a17a9239808986 +P 6b51863553e51334880fb322bdf74e51e35d0e61 +R 02366bc03c0aa38f7c8d01b5c92fd1d6 +U mistachkin +Z d9c38f842954179c02eb8030f4c6e2c4 diff --git a/manifest.uuid b/manifest.uuid index 65b1e84f6e..de251e1a19 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6b51863553e51334880fb322bdf74e51e35d0e61 \ No newline at end of file +c43b59dac1fbb67ec3a9d921005543046ad416ce \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index 22052a3fe7..faa60569c9 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -3119,7 +3119,7 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){ return SQLITE_OK; } case SQLITE_FCNTL_VFSNAME: { - *(char**)pArg = sqlite3_mprintf("win32"); + *(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName); OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); return SQLITE_OK; } diff --git a/test/win32longpath.test b/test/win32longpath.test index 0a6a8f98e6..9e9ed359c6 100644 --- a/test/win32longpath.test +++ b/test/win32longpath.test @@ -19,11 +19,19 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix win32longpath +do_test 1.0 { + file_control_vfsname db +} win32 + db close set path [file nativename [get_pwd]] sqlite3 db [file join $path test.db] -vfs win32-longpath do_test 1.1 { + file_control_vfsname db +} win32-longpath + +do_test 1.2 { db eval { BEGIN EXCLUSIVE; CREATE TABLE t1(x); @@ -47,13 +55,13 @@ make_win32_dir $longPath(3) set fileName $longPath(3)\\test.db -do_test 1.2 { +do_test 1.3 { list [catch {sqlite3 db2 [string range $fileName 4 end]} msg] $msg } {1 {unable to open database file}} sqlite3 db3 $fileName -vfs win32-longpath -do_test 1.3 { +do_test 1.4 { db3 eval { BEGIN EXCLUSIVE; CREATE TABLE t1(x); @@ -71,13 +79,13 @@ db3 close sqlite3 db3 $fileName -vfs win32-longpath -do_test 1.4 { +do_test 1.5 { db3 eval { PRAGMA journal_mode = WAL; } } {wal} -do_test 1.5 { +do_test 1.6 { db3 eval { BEGIN EXCLUSIVE; INSERT INTO t1 VALUES(9); From 038b7bc4efec2bd7bf30c441164b3d422012453d Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 9 Dec 2013 23:17:22 +0000 Subject: [PATCH 067/276] Simplifications to the OP_MakeRecord opcode and the sqlite3VdbeSerialPut() helper function. FossilOrigin-Name: 7277a769694787e0332d1a4efc02041834661e2a --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/vdbe.c | 28 +++++++++++++--------------- src/vdbeInt.h | 2 +- src/vdbeaux.c | 23 ++++------------------- src/vdbemem.c | 2 +- 6 files changed, 30 insertions(+), 47 deletions(-) diff --git a/manifest b/manifest index c03216855d..6901566020 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Correct\sthe\sVFS\sname\sas\sreported\sby\sthe\sfile\scontrol\swhen\sexplicitly\susing\sthe\s'win32-longpath'\sVFS. -D 2013-12-09T21:48:49.439 +C Simplifications\sto\sthe\sOP_MakeRecord\sopcode\sand\sthe\ssqlite3VdbeSerialPut()\nhelper\sfunction. +D 2013-12-09T23:17:22.886 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -280,13 +280,13 @@ F src/update.c d1c2477dcf14d90999d1935af4efb4806553250b F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c 76ed0519296e3f62e97e57dab1999e34184c8e49 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c 5338567d17c055b26b9b3d280bdd8aa4e8e13d3f +F src/vdbe.c 4bfb1fe75a0ad08646e9b82670691c62699bc5ee F src/vdbe.h c06f0813f853566457ce9cfb1a4a4bc39a5da644 -F src/vdbeInt.h 05fbda0e061dbc4aaa2709a8cccf3515c245b263 +F src/vdbeInt.h 7e38eef8f4bd7141e1638b0eacaebf9bc41b26bc F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed -F src/vdbeaux.c 09b79d475f5af2b3b5068f639609d88e0ced9d95 +F src/vdbeaux.c d64bc2a057e77aef3e2a4bc6670b80f516a36d55 F src/vdbeblob.c 8cd05a5630e6d5563ad017bf82edaf812b28acde -F src/vdbemem.c f12d087d92f57fc302028ac1b45374bf8a454d7e +F src/vdbemem.c 2293b66374f4adf54bbdcd662c05a003318600e1 F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147 F src/vdbetrace.c e7ec40e1999ff3c6414424365d5941178966dcbc F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd @@ -1146,7 +1146,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 6b51863553e51334880fb322bdf74e51e35d0e61 -R 02366bc03c0aa38f7c8d01b5c92fd1d6 -U mistachkin -Z d9c38f842954179c02eb8030f4c6e2c4 +P c43b59dac1fbb67ec3a9d921005543046ad416ce +R c11616a6774c1e84bdec6602d7be1c45 +U drh +Z 4d30567758bc854237be3d93d5ebeaed diff --git a/manifest.uuid b/manifest.uuid index de251e1a19..fae0da29de 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c43b59dac1fbb67ec3a9d921005543046ad416ce \ No newline at end of file +7277a769694787e0332d1a4efc02041834661e2a \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 1108a85341..a0a69e8a5c 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2599,29 +2599,27 @@ case OP_MakeRecord: { ** out how much space is required for the new record. */ assert( pData0<=pLast ); - pRec = pData0; + pRec = pLast; do{ assert( memIsValid(pRec) ); if( zAffinity ){ applyAffinity(pRec, zAffinity[pRec-pData0], encoding); } - if( (pRec->flags&MEM_Zero)!=0 && pRec->n>0 ){ - sqlite3VdbeMemExpandBlob(pRec); - } serial_type = sqlite3VdbeSerialType(pRec, file_format); len = sqlite3VdbeSerialTypeLen(serial_type); + if( pRec->flags & MEM_Zero ){ + if( nData ){ + sqlite3VdbeMemExpandBlob(pRec); + }else{ + nZero += pRec->u.nZero; + len -= pRec->u.nZero; + } + } nData += len; testcase( serial_type==127 ); testcase( serial_type==128 ); nHdr += serial_type<=127 ? 1 : sqlite3VarintLen(serial_type); - if( pRec->flags & MEM_Zero ){ - /* Only pure zero-filled BLOBs can be input to this Opcode. - ** We do not allow blobs with a prefix and a zero-filled tail. */ - nZero += pRec->u.nZero; - }else if( len ){ - nZero = 0; - } - }while( (++pRec)<=pLast ); + }while( (--pRec)>=pData0 ); /* Add the initial header varint and total the size */ testcase( nHdr==126 ); @@ -2635,7 +2633,7 @@ case OP_MakeRecord: { nHdr += nVarint; if( nVarintdb->aLimit[SQLITE_LIMIT_LENGTH] ){ goto too_big; } @@ -2657,8 +2655,8 @@ case OP_MakeRecord: { pRec = pData0; do{ serial_type = sqlite3VdbeSerialType(pRec, file_format); - i += putVarint32(&zNewRecord[i], serial_type); /* serial type */ - j += sqlite3VdbeSerialPut(&zNewRecord[j], (int)(nByte-j), pRec,file_format); + i += putVarint32(&zNewRecord[i], serial_type); /* serial type */ + j += sqlite3VdbeSerialPut(&zNewRecord[j], pRec, file_format); /* content */ }while( (++pRec)<=pLast ); assert( i==nHdr ); assert( j==nByte ); diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 371c4d6dc1..b01af20188 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -389,7 +389,7 @@ void sqlite3VdbePrintOp(FILE*, int, Op*); #endif u32 sqlite3VdbeSerialTypeLen(u32); u32 sqlite3VdbeSerialType(Mem*, int); -u32 sqlite3VdbeSerialPut(unsigned char*, int, Mem*, int); +u32 sqlite3VdbeSerialPut(unsigned char*, Mem*, int); u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*); void sqlite3VdbeDeleteAuxData(Vdbe*, int, int); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 5b5d82aed8..c610de4562 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2827,20 +2827,15 @@ static u64 floatSwap(u64 in){ ** buf. It is assumed that the caller has allocated sufficient space. ** Return the number of bytes written. ** -** nBuf is the amount of space left in buf[]. nBuf must always be -** large enough to hold the entire field. Except, if the field is -** a blob with a zero-filled tail, then buf[] might be just the right -** size to hold everything except for the zero-filled tail. If buf[] -** is only big enough to hold the non-zero prefix, then only write that -** prefix into buf[]. But if buf[] is large enough to hold both the -** prefix and the tail then write the prefix and set the tail to all -** zeros. +** nBuf is the amount of space left in buf[]. The caller is responsible +** for allocating enough space to buf[] to hold the entire field, exclusive +** of the pMem->u.nZero bytes for a MEM_Zero value. ** ** Return the number of bytes actually written into buf[]. The number ** of bytes in the zero-filled tail is included in the return value only ** if those bytes were zeroed in buf[]. */ -u32 sqlite3VdbeSerialPut(u8 *buf, int nBuf, Mem *pMem, int file_format){ +u32 sqlite3VdbeSerialPut(u8 *buf, Mem *pMem, int file_format){ u32 serial_type = sqlite3VdbeSerialType(pMem, file_format); u32 len; @@ -2856,7 +2851,6 @@ u32 sqlite3VdbeSerialPut(u8 *buf, int nBuf, Mem *pMem, int file_format){ v = pMem->u.i; } len = i = sqlite3VdbeSerialTypeLen(serial_type); - assert( len<=(u32)nBuf ); while( i-- ){ buf[i] = (u8)(v&0xFF); v >>= 8; @@ -2868,17 +2862,8 @@ u32 sqlite3VdbeSerialPut(u8 *buf, int nBuf, Mem *pMem, int file_format){ if( serial_type>=12 ){ assert( pMem->n + ((pMem->flags & MEM_Zero)?pMem->u.nZero:0) == (int)sqlite3VdbeSerialTypeLen(serial_type) ); - assert( pMem->n<=nBuf ); len = pMem->n; memcpy(buf, pMem->z, len); - if( pMem->flags & MEM_Zero ){ - len += pMem->u.nZero; - assert( nBuf>=0 ); - if( len > (u32)nBuf ){ - len = (u32)nBuf; - } - memset(&buf[pMem->n], 0, len-pMem->n); - } return len; } diff --git a/src/vdbemem.c b/src/vdbemem.c index 8a3acd5308..451744291f 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -1221,7 +1221,7 @@ static void recordFunc( }else{ aRet[0] = nSerial+1; sqlite3PutVarint(&aRet[1], iSerial); - sqlite3VdbeSerialPut(&aRet[1+nSerial], nVal, argv[0], file_format); + sqlite3VdbeSerialPut(&aRet[1+nSerial], argv[0], file_format); sqlite3_result_blob(context, aRet, nRet, SQLITE_TRANSIENT); sqlite3DbFree(db, aRet); } From a01abc302d98fb65239b7e6d1eda8b9e6b7ed1d5 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 10 Dec 2013 16:27:59 +0000 Subject: [PATCH 068/276] Fix handling of errors returned by the SQLITE_FCNTL_OMIT_SYNCED file-control. FossilOrigin-Name: d9a5f44f4a27336d41e60b6c3791bd018fbbff6f --- manifest | 15 ++++++--------- manifest.uuid | 2 +- src/pager.c | 6 ++++-- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 49f2c98b68..5aed39add3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Modify\sthe\sway\ssome\sinternal\sfile-controls\sare\sinvoked.\sIn\sorder\sto\ssupport\smulti-file\stransactions\sin\sthe\szipvfs\sextension. -D 2013-12-09T20:42:03.163 +C Fix\shandling\sof\serrors\sreturned\sby\sthe\sSQLITE_FCNTL_OMIT_SYNCED\sfile-control. +D 2013-12-10T16:27:59.750 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -207,7 +207,7 @@ F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_unix.c 60a7b3b23e6fcf83a50d1e320b280b551724e11f F src/os_win.c 4323dd0bac4f7a7037fc4cf87fb4692d17f0b108 -F src/pager.c b28711af0f595414a7017f6993d4e6f90a3d2114 +F src/pager.c 994fc67f465f4e9159263aa1489cbe608e17d236 F src/pager.h 6a790b64a9ea79bc2c849bdefdd39e2344bca94a F src/parse.y acee1a9958539e21263362b194594c5255ad2fca F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 @@ -1146,10 +1146,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P fbfc075a5a3c9c5c98353f396f9da7f7ec7c1c04 -R e8a2a861e9953d868791659025627e6a -T *branch * zipvfs-multifile-commit -T *sym-zipvfs-multifile-commit * -T -sym-trunk * +P 32fb1784af4594161d954343e3787db702000a4d +R 821341bcc4c1c23a6ba2875fa8192ed8 U dan -Z 19770b8e4b3ab930c64ec8e320e02ae3 +Z 4f103f173d76892892a97e68b335b863 diff --git a/manifest.uuid b/manifest.uuid index c4279a2bfe..b73efe0768 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -32fb1784af4594161d954343e3787db702000a4d \ No newline at end of file +d9a5f44f4a27336d41e60b6c3791bd018fbbff6f \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 3a59ca29e1..395fe0070a 100644 --- a/src/pager.c +++ b/src/pager.c @@ -6020,7 +6020,7 @@ int sqlite3PagerSync(Pager *pPager, const char *zMaster){ rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SYNC_OMITTED, pArg); if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; } - if( !pPager->noSync ){ + if( rc==SQLITE_OK && !pPager->noSync ){ assert( !MEMDB ); rc = sqlite3OsSync(pPager->fd, pPager->syncFlags); } @@ -6350,7 +6350,9 @@ int sqlite3PagerRollback(Pager *pPager){ assert( pPager->eState==PAGER_READER || rc!=SQLITE_OK ); assert( rc==SQLITE_OK || rc==SQLITE_FULL || rc==SQLITE_CORRUPT - || rc==SQLITE_NOMEM || (rc&0xFF)==SQLITE_IOERR ); + || rc==SQLITE_NOMEM || (rc&0xFF)==SQLITE_IOERR + || rc==SQLITE_CANTOPEN + ); /* If an error occurs during a ROLLBACK, we can no longer trust the pager ** cache. So call pager_error() on the way out to make any error persistent. From 6f68f1640d59118de8086dfad5a8d66b708125c4 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 10 Dec 2013 17:34:53 +0000 Subject: [PATCH 069/276] Use SQLITE_FCNTL_SYNC instead of SQLITE_FCNTL_SYNC_OMITTED. Add documentation in for FCNTL_SYNC and FCNTL_COMMIT_PHASETWO. FossilOrigin-Name: 46231af985a1a872d1dc3418591cbaacb0b7c249 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/pager.c | 2 +- src/sqlite.h.in | 36 +++++++++++++++++++++++++----------- 4 files changed, 34 insertions(+), 20 deletions(-) diff --git a/manifest b/manifest index dd877e2a84..c2e2f5f1bb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\schanges\sfrom\sthe\strunk. -D 2013-12-10T16:35:42.772 +C Use\sSQLITE_FCNTL_SYNC\sinstead\sof\sSQLITE_FCNTL_SYNC_OMITTED.\sAdd\sdocumentation\sin\sfor\sFCNTL_SYNC\sand\sFCNTL_COMMIT_PHASETWO. +D 2013-12-10T17:34:53.300 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -207,7 +207,7 @@ F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_unix.c 60a7b3b23e6fcf83a50d1e320b280b551724e11f F src/os_win.c 16eac0961603182ffc10c02b39fe830126538e07 -F src/pager.c 458c580b63f7f023e9863050f938dcd6eaae026f +F src/pager.c 994b3ee3716c89707952051115d72e0bd877e7b9 F src/pager.h 6a790b64a9ea79bc2c849bdefdd39e2344bca94a F src/parse.y acee1a9958539e21263362b194594c5255ad2fca F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 @@ -221,7 +221,7 @@ F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c d41381d80a22d3a83352aeca274cccf264ac277a F src/shell.c 936a72ff784efff3832cce274a96ed0b036e6758 -F src/sqlite.h.in 767b7475655de093182ec3d7b1f66a0cf5f1c390 +F src/sqlite.h.in 592057b6b3881573c2d516bad30fb20171f16b05 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc F src/sqliteInt.h c59b756b3aebefdce24ff44c4a7b3c155a3c26ee @@ -1146,7 +1146,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P d9a5f44f4a27336d41e60b6c3791bd018fbbff6f 7277a769694787e0332d1a4efc02041834661e2a -R 7fad7524df4e460d9aeda5901ac3e435 +P 3ee736a39d1fc175a297c5fdd0d2e1c5a9b5b18e +R 00ff1143b8ee30f4eb0b986958de8c12 U dan -Z 4d74f8c53424c0d52f5bb5be0f7994e7 +Z 4539dd639fdb6689f35ca693fd45b226 diff --git a/manifest.uuid b/manifest.uuid index 55d9c7de58..5e83f3adb2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3ee736a39d1fc175a297c5fdd0d2e1c5a9b5b18e \ No newline at end of file +46231af985a1a872d1dc3418591cbaacb0b7c249 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 36a3c762a5..d2f16d1be5 100644 --- a/src/pager.c +++ b/src/pager.c @@ -6011,7 +6011,7 @@ int sqlite3PagerSync(Pager *pPager, const char *zMaster){ if( isOpen(pPager->fd) ){ void *pArg = (void*)zMaster; - rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SYNC_OMITTED, pArg); + rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SYNC, pArg); if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; } if( rc==SQLITE_OK && !pPager->noSync ){ diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 9616adcd38..b9f4defed7 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -786,15 +786,29 @@ struct sqlite3_io_methods { ** additional information. ** **
  • [[SQLITE_FCNTL_SYNC_OMITTED]] -** ^(The [SQLITE_FCNTL_SYNC_OMITTED] opcode is generated internally by -** SQLite and sent to all VFSes in place of a call to the xSync method -** when the database connection has [PRAGMA synchronous] set to OFF.)^ -** Some specialized VFSes need this signal in order to operate correctly -** when [PRAGMA synchronous | PRAGMA synchronous=OFF] is set, but most -** VFSes do not need this signal and should silently ignore this opcode. -** Applications should not call [sqlite3_file_control()] with this -** opcode as doing so may disrupt the operation of the specialized VFSes -** that do require it. +** No longer in use. +** +**
  • [[SQLITE_FCNTL_SYNC]] +** The [SQLITE_FCNTL_SYNC] opcode is generated internally by SQLite and +** sent to the VFS immediately before the xSync method is invoked on a +** database file descriptor. Or, if the xSync method is not invoked +** because the user has configured SQLite with +** [PRAGMA synchronous | PRAGMA synchronous=OFF] it is invoked in place +** of the xSync method. In most cases, the pointer argument passed with +** this file-control is NULL. However, if the database file is being synced +** as part of a multi-database commit, the argument points to a nul-terminated +** string containing the transactions master-journal file name. VFSes that +** do not need this signal should silently ignore this opcode. Applications +** should not call [sqlite3_file_control()] with this opcode as doing so may +** disrupt the operation of the specialized VFSes that do require it. +** +**
  • [[SQLITE_FCNTL_COMMIT_PHASETWO]] +** The [SQLITE_FCNTL_COMMIT_PHASETWO] opcode is generated internally by SQLite +** and sent to the VFS after a transaction has been committed immediately +** but before the database is unlocked. VFSes that do not need this signal +** should silently ignore this opcode. Applications should not call +** [sqlite3_file_control()] with this opcode as doing so may disrupt the +** operation of the specialized VFSes that do require it. ** **
  • [[SQLITE_FCNTL_WIN32_AV_RETRY]] ** ^The [SQLITE_FCNTL_WIN32_AV_RETRY] opcode is used to configure automatic @@ -945,8 +959,8 @@ struct sqlite3_io_methods { #define SQLITE_FCNTL_MMAP_SIZE 18 #define SQLITE_FCNTL_TRACE 19 #define SQLITE_FCNTL_HAS_MOVED 20 - -#define SQLITE_FCNTL_COMMIT_PHASETWO 21 +#define SQLITE_FCNTL_SYNC 21 +#define SQLITE_FCNTL_COMMIT_PHASETWO 22 /* ** CAPI3REF: Mutex Handle From b0e7704e9f4bff5ad5213921b9e8c5a5d77698af Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 10 Dec 2013 19:49:00 +0000 Subject: [PATCH 070/276] Simplify and improve the performance of the sqlite3VdbeMemGrow() routine. FossilOrigin-Name: 48ecf18774ba9572d86696c60d87007a619d9f53 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/main.c | 3 ++- src/malloc.c | 7 ++++--- src/vdbemem.c | 46 ++++++++++++++++++++++------------------------ 5 files changed, 37 insertions(+), 37 deletions(-) diff --git a/manifest b/manifest index 6901566020..1bdefb7a11 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplifications\sto\sthe\sOP_MakeRecord\sopcode\sand\sthe\ssqlite3VdbeSerialPut()\nhelper\sfunction. -D 2013-12-09T23:17:22.886 +C Simplify\sand\simprove\sthe\sperformance\sof\sthe\ssqlite3VdbeMemGrow()\sroutine. +D 2013-12-10T19:49:00.802 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -188,8 +188,8 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b F src/loadext.c 867c7b330b740c6c917af9956b13b81d0a048303 -F src/main.c 355fc9ab213b43a4d8a96aadf2a84622e6668f0a -F src/malloc.c 543a8eb5508eaf4cadf55a9b503379eba2088128 +F src/main.c a79c8ca051a914e50d6b221d56801d47835714d8 +F src/malloc.c 0203ebce9152c6a0e5de520140b8ba65187350be F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c0c990fcaddff810ea277b4fb5d9138603dd5d4b F src/mem2.c dce31758da87ec2cfa52ba4c5df1aed6e07d8e8f @@ -286,7 +286,7 @@ F src/vdbeInt.h 7e38eef8f4bd7141e1638b0eacaebf9bc41b26bc F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed F src/vdbeaux.c d64bc2a057e77aef3e2a4bc6670b80f516a36d55 F src/vdbeblob.c 8cd05a5630e6d5563ad017bf82edaf812b28acde -F src/vdbemem.c 2293b66374f4adf54bbdcd662c05a003318600e1 +F src/vdbemem.c a381254caef0d102b091923a309c4c3a06a65393 F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147 F src/vdbetrace.c e7ec40e1999ff3c6414424365d5941178966dcbc F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd @@ -1146,7 +1146,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P c43b59dac1fbb67ec3a9d921005543046ad416ce -R c11616a6774c1e84bdec6602d7be1c45 +P 7277a769694787e0332d1a4efc02041834661e2a +R 3ef0e61f6611b17b108322b8d504b195 U drh -Z 4d30567758bc854237be3d93d5ebeaed +Z 641e108686357e5c2dc6bc5a433b2dd9 diff --git a/manifest.uuid b/manifest.uuid index fae0da29de..fd40777301 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7277a769694787e0332d1a4efc02041834661e2a \ No newline at end of file +48ecf18774ba9572d86696c60d87007a619d9f53 \ No newline at end of file diff --git a/src/main.c b/src/main.c index 1ba555fde8..3e9f4e0171 100644 --- a/src/main.c +++ b/src/main.c @@ -588,7 +588,8 @@ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){ db->lookaside.bEnabled = 1; db->lookaside.bMalloced = pBuf==0 ?1:0; }else{ - db->lookaside.pEnd = 0; + db->lookaside.pStart = db; + db->lookaside.pEnd = db; db->lookaside.bEnabled = 0; db->lookaside.bMalloced = 0; } diff --git a/src/malloc.c b/src/malloc.c index 799f0485d4..9c11d07767 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -433,7 +433,7 @@ void sqlite3ScratchFree(void *p){ */ #ifndef SQLITE_OMIT_LOOKASIDE static int isLookaside(sqlite3 *db, void *p){ - return p && p>=db->lookaside.pStart && plookaside.pEnd; + return p>=db->lookaside.pStart && plookaside.pEnd; } #else #define isLookaside(A,B) 0 @@ -449,8 +449,9 @@ int sqlite3MallocSize(void *p){ return sqlite3GlobalConfig.m.xSize(p); } int sqlite3DbMallocSize(sqlite3 *db, void *p){ - assert( db==0 || sqlite3_mutex_held(db->mutex) ); - if( db && isLookaside(db, p) ){ + assert( db!=0 ); + assert( sqlite3_mutex_held(db->mutex) ); + if( isLookaside(db, p) ){ return db->lookaside.sz; }else{ assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) ); diff --git a/src/vdbemem.c b/src/vdbemem.c index 451744291f..6a0a66ead2 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -59,18 +59,14 @@ int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){ /* ** Make sure pMem->z points to a writable allocation of at least -** n bytes. +** min(n,32) bytes. ** -** If the third argument passed to this function is true, then memory -** cell pMem must contain a string or blob. In this case the content is -** preserved. Otherwise, if the third parameter to this function is false, -** any current string or blob value may be discarded. -** -** This function sets the MEM_Dyn flag and clears any xDel callback. -** It also clears MEM_Ephem and MEM_Static. If the preserve flag is -** not set, Mem.n is zeroed. +** If the bPreserve argument is true, then copy of the content of +** pMem->z into the new allocation. pMem must be either a string or +** blob if bPreserve is true. If bPreserve is false, any prior content +** in pMem->z is discarded. */ -int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve){ +int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){ assert( 1 >= ((pMem->zMalloc && pMem->zMalloc==pMem->z) ? 1 : 0) + (((pMem->flags&MEM_Dyn)&&pMem->xDel) ? 1 : 0) + @@ -79,37 +75,39 @@ int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve){ ); assert( (pMem->flags&MEM_RowSet)==0 ); - /* If the preserve flag is set to true, then the memory cell must already + /* If the bPreserve flag is set to true, then the memory cell must already ** contain a valid string or blob value. */ - assert( preserve==0 || pMem->flags&(MEM_Blob|MEM_Str) ); + assert( bPreserve==0 || pMem->flags&(MEM_Blob|MEM_Str) ); + testcase( bPreserve && pMem->z==0 ); - if( n<32 ) n = 32; - if( sqlite3DbMallocSize(pMem->db, pMem->zMalloc)z==pMem->zMalloc ){ + if( pMem->zMalloc==0 || sqlite3DbMallocSize(pMem->db, pMem->zMalloc)z==pMem->zMalloc ){ pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n); - preserve = 0; + bPreserve = 0; }else{ sqlite3DbFree(pMem->db, pMem->zMalloc); pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, n); } + if( pMem->zMalloc==0 ){ + sqlite3VdbeMemRelease(pMem); + pMem->flags = MEM_Null; + return SQLITE_NOMEM; + } } - if( pMem->z && preserve && pMem->zMalloc && pMem->z!=pMem->zMalloc ){ + if( pMem->z && bPreserve && pMem->z!=pMem->zMalloc ){ memcpy(pMem->zMalloc, pMem->z, pMem->n); } - if( pMem->flags&MEM_Dyn && pMem->xDel ){ + if( (pMem->flags&MEM_Dyn)!=0 && pMem->xDel ){ assert( pMem->xDel!=SQLITE_DYNAMIC ); pMem->xDel((void *)(pMem->z)); } pMem->z = pMem->zMalloc; - if( pMem->z==0 ){ - pMem->flags = MEM_Null; - }else{ - pMem->flags &= ~(MEM_Ephem|MEM_Static); - } + pMem->flags &= ~(MEM_Ephem|MEM_Static); pMem->xDel = 0; - return (pMem->z ? SQLITE_OK : SQLITE_NOMEM); + return SQLITE_OK; } /* From 3e6c060fac1a56a67b130b49a47cc731e13125d0 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 10 Dec 2013 20:53:01 +0000 Subject: [PATCH 071/276] In the OP_MakeRecord opcode, factor out affinity changes into separate loop, for a slight performance advantage. FossilOrigin-Name: 1c6ee9b85f61e5cdb5d9b7815cddf526dc78aaa7 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 14 ++++++++++---- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 1bdefb7a11..28544906b3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplify\sand\simprove\sthe\sperformance\sof\sthe\ssqlite3VdbeMemGrow()\sroutine. -D 2013-12-10T19:49:00.802 +C In\sthe\sOP_MakeRecord\sopcode,\sfactor\sout\saffinity\schanges\sinto\sseparate\sloop,\nfor\sa\sslight\sperformance\sadvantage. +D 2013-12-10T20:53:01.865 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -280,7 +280,7 @@ F src/update.c d1c2477dcf14d90999d1935af4efb4806553250b F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c 76ed0519296e3f62e97e57dab1999e34184c8e49 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c 4bfb1fe75a0ad08646e9b82670691c62699bc5ee +F src/vdbe.c c5b17309048f28ff79e0b65aeb72d365a3a415a1 F src/vdbe.h c06f0813f853566457ce9cfb1a4a4bc39a5da644 F src/vdbeInt.h 7e38eef8f4bd7141e1638b0eacaebf9bc41b26bc F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed @@ -1146,7 +1146,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 7277a769694787e0332d1a4efc02041834661e2a -R 3ef0e61f6611b17b108322b8d504b195 +P 48ecf18774ba9572d86696c60d87007a619d9f53 +R 8c35d8f315102eab592f6f641be2ff5b U drh -Z 641e108686357e5c2dc6bc5a433b2dd9 +Z ddd4b5e4f3e2f25b93fe4a6cd498d64a diff --git a/manifest.uuid b/manifest.uuid index fd40777301..6ce25cfed9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -48ecf18774ba9572d86696c60d87007a619d9f53 \ No newline at end of file +1c6ee9b85f61e5cdb5d9b7815cddf526dc78aaa7 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index a0a69e8a5c..37851802ce 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2595,16 +2595,22 @@ case OP_MakeRecord: { pOut = &aMem[pOp->p3]; memAboutToChange(p, pOut); + /* Apply the requested affinity to all inputs + */ + assert( pData0<=pLast ); + if( zAffinity ){ + pRec = pData0; + do{ + applyAffinity(pRec, *(zAffinity++), encoding); + }while( (++pRec)<=pLast ); + } + /* Loop through the elements that will make up the record to figure ** out how much space is required for the new record. */ - assert( pData0<=pLast ); pRec = pLast; do{ assert( memIsValid(pRec) ); - if( zAffinity ){ - applyAffinity(pRec, zAffinity[pRec-pData0], encoding); - } serial_type = sqlite3VdbeSerialType(pRec, file_format); len = sqlite3VdbeSerialTypeLen(serial_type); if( pRec->flags & MEM_Zero ){ From 024045fe6ee141bb981b882e645f3f83481af12b Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 10 Dec 2013 21:38:08 +0000 Subject: [PATCH 072/276] Avoid unnecessary calls to sqlite3VdbeSerialType() from within sqlite3VdbeSerialPut(). FossilOrigin-Name: 079c04a5013074b68f7d90f1ce8bf8e7092ad8a2 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/vdbe.c | 2 +- src/vdbeInt.h | 2 +- src/vdbeaux.c | 3 +-- src/vdbemem.c | 2 +- 6 files changed, 14 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 28544906b3..73f5c3738b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\sOP_MakeRecord\sopcode,\sfactor\sout\saffinity\schanges\sinto\sseparate\sloop,\nfor\sa\sslight\sperformance\sadvantage. -D 2013-12-10T20:53:01.865 +C Avoid\sunnecessary\scalls\sto\ssqlite3VdbeSerialType()\sfrom\swithin\nsqlite3VdbeSerialPut(). +D 2013-12-10T21:38:08.728 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -280,13 +280,13 @@ F src/update.c d1c2477dcf14d90999d1935af4efb4806553250b F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c 76ed0519296e3f62e97e57dab1999e34184c8e49 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c c5b17309048f28ff79e0b65aeb72d365a3a415a1 +F src/vdbe.c 02fac31f3921b0238d0ca72c90db31eb0c91e358 F src/vdbe.h c06f0813f853566457ce9cfb1a4a4bc39a5da644 -F src/vdbeInt.h 7e38eef8f4bd7141e1638b0eacaebf9bc41b26bc +F src/vdbeInt.h e103e9223787cb11e0de48cefb1cdb9fef18e2e8 F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed -F src/vdbeaux.c d64bc2a057e77aef3e2a4bc6670b80f516a36d55 +F src/vdbeaux.c a66fde9e0ecf1d8b7fe60162d28bb6b95f2f6c30 F src/vdbeblob.c 8cd05a5630e6d5563ad017bf82edaf812b28acde -F src/vdbemem.c a381254caef0d102b091923a309c4c3a06a65393 +F src/vdbemem.c dedc9ee05a9d5f7c4913ee623db8d41bdb24363f F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147 F src/vdbetrace.c e7ec40e1999ff3c6414424365d5941178966dcbc F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd @@ -1146,7 +1146,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 48ecf18774ba9572d86696c60d87007a619d9f53 -R 8c35d8f315102eab592f6f641be2ff5b +P 1c6ee9b85f61e5cdb5d9b7815cddf526dc78aaa7 +R 362b67923e10115892fb8388984a2dc3 U drh -Z ddd4b5e4f3e2f25b93fe4a6cd498d64a +Z 43fa988f600d23d399ec0be485c6471b diff --git a/manifest.uuid b/manifest.uuid index 6ce25cfed9..f11bb639e2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1c6ee9b85f61e5cdb5d9b7815cddf526dc78aaa7 \ No newline at end of file +079c04a5013074b68f7d90f1ce8bf8e7092ad8a2 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 37851802ce..7568048492 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2662,7 +2662,7 @@ case OP_MakeRecord: { do{ serial_type = sqlite3VdbeSerialType(pRec, file_format); i += putVarint32(&zNewRecord[i], serial_type); /* serial type */ - j += sqlite3VdbeSerialPut(&zNewRecord[j], pRec, file_format); /* content */ + j += sqlite3VdbeSerialPut(&zNewRecord[j], pRec, serial_type, file_format); }while( (++pRec)<=pLast ); assert( i==nHdr ); assert( j==nByte ); diff --git a/src/vdbeInt.h b/src/vdbeInt.h index b01af20188..e493e5b85e 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -389,7 +389,7 @@ void sqlite3VdbePrintOp(FILE*, int, Op*); #endif u32 sqlite3VdbeSerialTypeLen(u32); u32 sqlite3VdbeSerialType(Mem*, int); -u32 sqlite3VdbeSerialPut(unsigned char*, Mem*, int); +u32 sqlite3VdbeSerialPut(unsigned char*, Mem*, u32, int); u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*); void sqlite3VdbeDeleteAuxData(Vdbe*, int, int); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index c610de4562..a41b222950 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2835,8 +2835,7 @@ static u64 floatSwap(u64 in){ ** of bytes in the zero-filled tail is included in the return value only ** if those bytes were zeroed in buf[]. */ -u32 sqlite3VdbeSerialPut(u8 *buf, Mem *pMem, int file_format){ - u32 serial_type = sqlite3VdbeSerialType(pMem, file_format); +u32 sqlite3VdbeSerialPut(u8 *buf, Mem *pMem, u32 serial_type, int file_format){ u32 len; /* Integer and Real */ diff --git a/src/vdbemem.c b/src/vdbemem.c index 6a0a66ead2..1d0feb6216 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -1219,7 +1219,7 @@ static void recordFunc( }else{ aRet[0] = nSerial+1; sqlite3PutVarint(&aRet[1], iSerial); - sqlite3VdbeSerialPut(&aRet[1+nSerial], argv[0], file_format); + sqlite3VdbeSerialPut(&aRet[1+nSerial], argv[0], iSerial, file_format); sqlite3_result_blob(context, aRet, nRet, SQLITE_TRANSIENT); sqlite3DbFree(db, aRet); } From 2dc0648a80dae86e6393f58e670336ae8f514485 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 11 Dec 2013 00:59:10 +0000 Subject: [PATCH 073/276] Do not run the tool/vdbe-compress.tcl script that generates the vdbeExecUnion object that reduces the size of the sqlite3VdbeExec() stack frame unless the SQLITE_SMALL_STACK compile-time option is specified as on of the OPTS in the makefile. The vdbeExecUnion object gets in the way of C-compiler optimizer and results in slightly slower code. FossilOrigin-Name: 4d0781473a465b4ab0a307914014f3d2ddd0ce33 --- Makefile.in | 2 +- Makefile.msc | 2 +- main.mk | 2 +- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/vdbe.c | 4 ++++ tool/vdbe-compress.tcl | 12 +++++++++++- 7 files changed, 29 insertions(+), 15 deletions(-) diff --git a/Makefile.in b/Makefile.in index a0217c4343..31e30ffc48 100644 --- a/Makefile.in +++ b/Makefile.in @@ -534,7 +534,7 @@ mptester$(EXE): sqlite3.c $(TOP)/mptest/mptest.c mkdir tsrc cp -f $(SRC) tsrc rm tsrc/sqlite.h.in tsrc/parse.y - $(TCLSH_CMD) $(TOP)/tool/vdbe-compress.tcl vdbe.new + $(TCLSH_CMD) $(TOP)/tool/vdbe-compress.tcl $(OPTS) vdbe.new mv vdbe.new tsrc/vdbe.c touch .target_source diff --git a/Makefile.msc b/Makefile.msc index 34059ea2f3..94cd38d0ae 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -911,7 +911,7 @@ mptester.exe: $(TOP)\mptest\mptest.c libsqlite3.lib $(LIBRESOBJS) sqlite3.h -mkdir tsrc for %i in ($(SRC)) do copy /Y %i tsrc del /Q tsrc\sqlite.h.in tsrc\parse.y - $(TCLSH_CMD) $(TOP)\tool\vdbe-compress.tcl < tsrc\vdbe.c > vdbe.new + $(TCLSH_CMD) $(TOP)\tool\vdbe-compress.tcl $(OPTS) < tsrc\vdbe.c > vdbe.new move vdbe.new tsrc\vdbe.c echo > .target_source diff --git a/main.mk b/main.mk index 41d1743832..a53727c904 100644 --- a/main.mk +++ b/main.mk @@ -402,7 +402,7 @@ target_source: $(SRC) $(TOP)/tool/vdbe-compress.tcl mkdir tsrc cp -f $(SRC) tsrc rm tsrc/sqlite.h.in tsrc/parse.y - tclsh $(TOP)/tool/vdbe-compress.tcl vdbe.new + tclsh $(TOP)/tool/vdbe-compress.tcl $(OPTS) vdbe.new mv vdbe.new tsrc/vdbe.c touch target_source diff --git a/manifest b/manifest index 73f5c3738b..4035017719 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Avoid\sunnecessary\scalls\sto\ssqlite3VdbeSerialType()\sfrom\swithin\nsqlite3VdbeSerialPut(). -D 2013-12-10T21:38:08.728 +C Do\snot\srun\sthe\stool/vdbe-compress.tcl\sscript\sthat\sgenerates\sthe\nvdbeExecUnion\sobject\sthat\sreduces\sthe\ssize\sof\sthe\ssqlite3VdbeExec()\nstack\sframe\sunless\sthe\sSQLITE_SMALL_STACK\scompile-time\soption\sis\nspecified\sas\son\sof\sthe\sOPTS\sin\sthe\smakefile.\s\sThe\svdbeExecUnion\sobject\ngets\sin\sthe\sway\sof\sC-compiler\soptimizer\sand\sresults\sin\sslightly\sslower\scode. +D 2013-12-11T00:59:10.395 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f -F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b +F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 -F Makefile.msc bb1f271c8ee9773489c89be00f3f8ad7ed7ae8e0 +F Makefile.msc 4d4ead6b71d1bf03028fbd61da0ba0ec5e1556e1 F Makefile.vxworks db21ed42a01d5740e656b16f92cb5d8d5e5dd315 F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6 F VERSION 8ed548d87d0a27fd7d7620476f9e25f9fa742d73 @@ -142,7 +142,7 @@ F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt f439556c5ce01ced70987e5ee86549a45165d9ff -F main.mk 82fd90375561d7b66287ae5a8b09e1e027394019 +F main.mk 9f091ea7920f8b15e48c7b6e5b6fb0182577ab2e F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a F mkextu.sh 416f9b7089d80e5590a29692c9d9280a10dbad9f F mkextw.sh d2a981497b404d6498f5ff3e3b1f3816bdfcb338 @@ -280,7 +280,7 @@ F src/update.c d1c2477dcf14d90999d1935af4efb4806553250b F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c 76ed0519296e3f62e97e57dab1999e34184c8e49 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c 02fac31f3921b0238d0ca72c90db31eb0c91e358 +F src/vdbe.c bdc4a981fb14843e09e0a369b6b5b40b54c92489 F src/vdbe.h c06f0813f853566457ce9cfb1a4a4bc39a5da644 F src/vdbeInt.h e103e9223787cb11e0de48cefb1cdb9fef18e2e8 F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed @@ -1142,11 +1142,11 @@ F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43 F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d F tool/symbols.sh fec58532668296d7c7dc48be9c87f75ccdb5814f F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 -F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 +F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 1c6ee9b85f61e5cdb5d9b7815cddf526dc78aaa7 -R 362b67923e10115892fb8388984a2dc3 +P 079c04a5013074b68f7d90f1ce8bf8e7092ad8a2 +R 97669e12d755118ec7d7d468b1255e81 U drh -Z 43fa988f600d23d399ec0be485c6471b +Z 0e355cefa23a2e0a8bf13198eee4bf26 diff --git a/manifest.uuid b/manifest.uuid index f11bb639e2..ced68a138a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -079c04a5013074b68f7d90f1ce8bf8e7092ad8a2 \ No newline at end of file +4d0781473a465b4ab0a307914014f3d2ddd0ce33 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 7568048492..92c3c40fa6 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2694,6 +2694,7 @@ case OP_Count: { /* out2-prerelease */ pCrsr = p->apCsr[pOp->p1]->pCursor; assert( pCrsr ); + nEntry = 0; /* Not needed. Only used to silence a warning. */ rc = sqlite3BtreeCount(pCrsr, &nEntry); pOut->u.i = nEntry; break; @@ -4654,6 +4655,7 @@ case OP_IdxRowid: { /* out2-prerelease */ assert( pC->deferredMoveto==0 ); assert( pC->isTable==0 ); if( !pC->nullRow ){ + rowid = 0; /* Not needed. Only used to silence a warning. */ rc = sqlite3VdbeIdxRowid(db, pCrsr, &rowid); if( rc!=SQLITE_OK ){ goto abort_due_to_error; @@ -4717,6 +4719,7 @@ case OP_IdxGE: { /* jump */ #ifdef SQLITE_DEBUG { int i; for(i=0; iopcode==OP_IdxLT ){ res = -res; @@ -4777,6 +4780,7 @@ case OP_Destroy: { /* out2-prerelease */ iDb = pOp->p3; assert( iCnt==1 ); assert( (p->btreeMask & (((yDbMask)1)<aDb[iDb].pBt, pOp->p1, &iMoved); pOut->flags = MEM_Int; pOut->u.i = iMoved; diff --git a/tool/vdbe-compress.tcl b/tool/vdbe-compress.tcl index 95cc1ebf5a..a349830bcf 100644 --- a/tool/vdbe-compress.tcl +++ b/tool/vdbe-compress.tcl @@ -13,7 +13,7 @@ # Script usage: # # mv vdbe.c vdbe.c.template -# tclsh vdbe-compress.tcl vdbe.c +# tclsh vdbe-compress.tcl $CFLAGS vdbe.c # # Modifications made: # @@ -42,6 +42,16 @@ set unionDef {} ;# C code of the union set afterUnion {} ;# C code after the union set sCtr 0 ;# Context counter +# If the SQLITE_SMALL_STACK compile-time option is missing, then +# this transformation becomes a no-op. +# +if {![regexp {SQLITE_SMALL_STACK} $argv]} { + while {![eof stdin]} { + puts [gets stdin] + } + exit +} + # Read program text up to the spot where the union should be # inserted. # From 53cd96464894a49b22899455f20f76b86aef5acf Mon Sep 17 00:00:00 2001 From: mistachkin Date: Wed, 11 Dec 2013 02:21:19 +0000 Subject: [PATCH 074/276] Fix harmless compiler warning. FossilOrigin-Name: 2525296d919245ebb01077aad541e4ae6eab7940 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/printf.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 4035017719..b7423b983a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\srun\sthe\stool/vdbe-compress.tcl\sscript\sthat\sgenerates\sthe\nvdbeExecUnion\sobject\sthat\sreduces\sthe\ssize\sof\sthe\ssqlite3VdbeExec()\nstack\sframe\sunless\sthe\sSQLITE_SMALL_STACK\scompile-time\soption\sis\nspecified\sas\son\sof\sthe\sOPTS\sin\sthe\smakefile.\s\sThe\svdbeExecUnion\sobject\ngets\sin\sthe\sway\sof\sC-compiler\soptimizer\sand\sresults\sin\sslightly\sslower\scode. -D 2013-12-11T00:59:10.395 +C Fix\sharmless\scompiler\swarning. +D 2013-12-11T02:21:19.102 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -215,7 +215,7 @@ F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222 F src/pcache1.c a467393909a4ed7ca9de066d85ba5c5b04a5be63 F src/pragma.c 5ab7279d132143feb77f773688a24ab05da75fd7 F src/prepare.c 359d1a1e9c9bd4488e4dd3a1aaaf2d2ebb9bb768 -F src/printf.c aacd7f73018122689dbbe89d85c2e37f737b931f +F src/printf.c e2f78b695b8053c23394e9ff79e3364e7308c5e4 F src/random.c 0b2dbc37fdfbfa6bd455b091dfcef5bdb32dba68 F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 @@ -1146,7 +1146,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 079c04a5013074b68f7d90f1ce8bf8e7092ad8a2 -R 97669e12d755118ec7d7d468b1255e81 -U drh -Z 0e355cefa23a2e0a8bf13198eee4bf26 +P 4d0781473a465b4ab0a307914014f3d2ddd0ce33 +R 10ffd50a76f97bbe2373fb173610ea36 +U mistachkin +Z 53d10f2a6e8878035ff79985bd9a3564 diff --git a/manifest.uuid b/manifest.uuid index ced68a138a..522742f674 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4d0781473a465b4ab0a307914014f3d2ddd0ce33 \ No newline at end of file +2525296d919245ebb01077aad541e4ae6eab7940 \ No newline at end of file diff --git a/src/printf.c b/src/printf.c index 011eecdfaa..a3c7462d55 100644 --- a/src/printf.c +++ b/src/printf.c @@ -743,7 +743,7 @@ void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){ ** Append the complete text of zero-terminated string z[] to the p string. */ void sqlite3StrAccumAppendAll(StrAccum *p, const char *z){ - return sqlite3StrAccumAppend(p, z, sqlite3Strlen30(z)); + sqlite3StrAccumAppend(p, z, sqlite3Strlen30(z)); } From a9ab481fca8e4828771c098d8ce77a0efd52684a Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 11 Dec 2013 11:00:44 +0000 Subject: [PATCH 075/276] Fix harmless compiler warnings. FossilOrigin-Name: a7e5fcd66659750eb2f4675082df324e7cf35427 --- manifest | 28 ++++++++++++++-------------- manifest.uuid | 2 +- src/func.c | 4 ++-- src/pager.c | 2 +- src/printf.c | 4 ++-- src/vdbe.c | 5 ++--- src/vdbeInt.h | 2 +- src/vdbeaux.c | 2 +- src/vdbemem.c | 2 +- src/vdbetrace.c | 4 +++- 10 files changed, 28 insertions(+), 27 deletions(-) diff --git a/manifest b/manifest index b7423b983a..d9a2b68c9a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarning. -D 2013-12-11T02:21:19.102 +C Fix\sharmless\scompiler\swarnings. +D 2013-12-11T11:00:44.250 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -178,7 +178,7 @@ F src/delete.c b36db1f79ee50eaca979660c9dd36437f5410b93 F src/expr.c 31a2b65339f6c3795d4cfa5e99798cd72f9fdfdf F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 2ab0f5384b70594468ef3ac5c7ed8ca24bfd17d5 -F src/func.c ef30d26ae4d79bbc7300c74e77fd117a0ba30235 +F src/func.c fed87f35cf4da4a798b726d84abefc209b48d831 F src/global.c 1d7bb7ea8254ae6a68ed9bfaf65fcb3d1690b486 F src/hash.c ac3470bbf1ca4ae4e306a8ecb0fdf1731810ffe4 F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22 @@ -207,7 +207,7 @@ F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_unix.c 60a7b3b23e6fcf83a50d1e320b280b551724e11f F src/os_win.c 16eac0961603182ffc10c02b39fe830126538e07 -F src/pager.c 19203eff37c099271189bf8b378a1143847b92e3 +F src/pager.c 9bca84722e29d141089881937743daf8b5f74a2b F src/pager.h f094af9f6ececfaa8a1e93876905a4f34233fb0c F src/parse.y acee1a9958539e21263362b194594c5255ad2fca F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 @@ -215,7 +215,7 @@ F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222 F src/pcache1.c a467393909a4ed7ca9de066d85ba5c5b04a5be63 F src/pragma.c 5ab7279d132143feb77f773688a24ab05da75fd7 F src/prepare.c 359d1a1e9c9bd4488e4dd3a1aaaf2d2ebb9bb768 -F src/printf.c e2f78b695b8053c23394e9ff79e3364e7308c5e4 +F src/printf.c b2778aa160ef792ba51c9f11b743bfc015b66679 F src/random.c 0b2dbc37fdfbfa6bd455b091dfcef5bdb32dba68 F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 @@ -280,15 +280,15 @@ F src/update.c d1c2477dcf14d90999d1935af4efb4806553250b F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c 76ed0519296e3f62e97e57dab1999e34184c8e49 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c bdc4a981fb14843e09e0a369b6b5b40b54c92489 +F src/vdbe.c 919422843c859a1db08db0c88189912dbf625fc7 F src/vdbe.h c06f0813f853566457ce9cfb1a4a4bc39a5da644 -F src/vdbeInt.h e103e9223787cb11e0de48cefb1cdb9fef18e2e8 +F src/vdbeInt.h a7bc268f844d75be48bb7ae16f77b418fd3c641c F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed -F src/vdbeaux.c a66fde9e0ecf1d8b7fe60162d28bb6b95f2f6c30 +F src/vdbeaux.c 74f3ad068f91d60ff56179a22610e7b0ef71e5d6 F src/vdbeblob.c 8cd05a5630e6d5563ad017bf82edaf812b28acde -F src/vdbemem.c dedc9ee05a9d5f7c4913ee623db8d41bdb24363f +F src/vdbemem.c ac71e169dc056936f7a26ccaa808cd17456ffab1 F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147 -F src/vdbetrace.c e7ec40e1999ff3c6414424365d5941178966dcbc +F src/vdbetrace.c 92c3d4f7a98ff59d44bf8351356ef82072f40517 F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 @@ -1146,7 +1146,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 4d0781473a465b4ab0a307914014f3d2ddd0ce33 -R 10ffd50a76f97bbe2373fb173610ea36 -U mistachkin -Z 53d10f2a6e8878035ff79985bd9a3564 +P 2525296d919245ebb01077aad541e4ae6eab7940 +R 24f899fa4dbed59efbcdd4778a6b73ec +U drh +Z 35945f2f4af25cff5df7e46d8c3b59e8 diff --git a/manifest.uuid b/manifest.uuid index 522742f674..8281671249 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2525296d919245ebb01077aad541e4ae6eab7940 \ No newline at end of file +a7e5fcd66659750eb2f4675082df324e7cf35427 \ No newline at end of file diff --git a/src/func.c b/src/func.c index 46c606ac06..951af97b35 100644 --- a/src/func.c +++ b/src/func.c @@ -1511,11 +1511,11 @@ static void groupConcatStep( zSep = ","; nSep = 1; } - sqlite3StrAccumAppend(pAccum, zSep, nSep); + if( nSep ) sqlite3StrAccumAppend(pAccum, zSep, nSep); } zVal = (char*)sqlite3_value_text(argv[0]); nVal = sqlite3_value_bytes(argv[0]); - sqlite3StrAccumAppend(pAccum, zVal, nVal); + if( nVal ) sqlite3StrAccumAppend(pAccum, zVal, nVal); } } static void groupConcatFinalize(sqlite3_context *context){ diff --git a/src/pager.c b/src/pager.c index 8cbb50ce3c..443a523267 100644 --- a/src/pager.c +++ b/src/pager.c @@ -5779,7 +5779,7 @@ int sqlite3PagerWrite(DbPage *pDbPage){ assert( pPager->eState!=PAGER_ERROR ); assert( assert_pager_state(pPager) ); - if( pPager->sectorSize > pPager->pageSize ){ + if( pPager->sectorSize > (u32)pPager->pageSize ){ Pgno nPageCount; /* Total number of pages in database file */ Pgno pg1; /* First page of the sector pPg is located on. */ int nPage = 0; /* Number of pages starting at pg1 to journal */ diff --git a/src/printf.c b/src/printf.c index a3c7462d55..9be0fc9404 100644 --- a/src/printf.c +++ b/src/printf.c @@ -637,7 +637,7 @@ void sqlite3VXPrintf( } case etTOKEN: { Token *pToken = va_arg(ap, Token*); - if( pToken ){ + if( pToken && pToken->n ){ sqlite3StrAccumAppend(pAccum, (const char*)pToken->z, pToken->n); } length = width = 0; @@ -691,7 +691,7 @@ void sqlite3VXPrintf( ** Append N bytes of text from z to the StrAccum object. */ void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){ - assert( z!=0 || N==0 ); + assert( z!=0 ); assert( p->zText!=0 || p->nChar==0 || p->accError ); assert( N>=0 ); assert( p->accError==0 || p->nAlloc==0 ); diff --git a/src/vdbe.c b/src/vdbe.c index 92c3c40fa6..3361120933 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2662,7 +2662,7 @@ case OP_MakeRecord: { do{ serial_type = sqlite3VdbeSerialType(pRec, file_format); i += putVarint32(&zNewRecord[i], serial_type); /* serial type */ - j += sqlite3VdbeSerialPut(&zNewRecord[j], pRec, serial_type, file_format); + j += sqlite3VdbeSerialPut(&zNewRecord[j], pRec, serial_type); /* content */ }while( (++pRec)<=pLast ); assert( i==nHdr ); assert( j==nByte ); @@ -3715,7 +3715,6 @@ case OP_Found: { /* jump, in3 */ if( pOp->opcode!=OP_NoConflict ) sqlite3_found_count++; #endif - alreadyExists = 0; assert( pOp->p1>=0 && pOp->p1nCursor ); assert( pOp->p4type==P4_INT32 ); pC = p->apCsr[pOp->p1]; @@ -3723,6 +3722,7 @@ case OP_Found: { /* jump, in3 */ pIn3 = &aMem[pOp->p3]; assert( pC->pCursor!=0 ); assert( pC->isTable==0 ); + pFree = 0; /* Not needed. Only used to suppress a compiler warning. */ if( pOp->p4.i>0 ){ r.pKeyInfo = pC->pKeyInfo; r.nField = (u16)pOp->p4.i; @@ -5353,7 +5353,6 @@ case OP_FkIfZero: { /* jump */ ** an integer. */ case OP_MemMax: { /* in2 */ - Mem *pIn1; VdbeFrame *pFrame; if( p->pFrame ){ for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent); diff --git a/src/vdbeInt.h b/src/vdbeInt.h index e493e5b85e..d6d71a3957 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -389,7 +389,7 @@ void sqlite3VdbePrintOp(FILE*, int, Op*); #endif u32 sqlite3VdbeSerialTypeLen(u32); u32 sqlite3VdbeSerialType(Mem*, int); -u32 sqlite3VdbeSerialPut(unsigned char*, Mem*, u32, int); +u32 sqlite3VdbeSerialPut(unsigned char*, Mem*, u32); u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*); void sqlite3VdbeDeleteAuxData(Vdbe*, int, int); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index a41b222950..9e1eb581f0 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2835,7 +2835,7 @@ static u64 floatSwap(u64 in){ ** of bytes in the zero-filled tail is included in the return value only ** if those bytes were zeroed in buf[]. */ -u32 sqlite3VdbeSerialPut(u8 *buf, Mem *pMem, u32 serial_type, int file_format){ +u32 sqlite3VdbeSerialPut(u8 *buf, Mem *pMem, u32 serial_type){ u32 len; /* Integer and Real */ diff --git a/src/vdbemem.c b/src/vdbemem.c index 1d0feb6216..d5901b439a 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -1219,7 +1219,7 @@ static void recordFunc( }else{ aRet[0] = nSerial+1; sqlite3PutVarint(&aRet[1], iSerial); - sqlite3VdbeSerialPut(&aRet[1+nSerial], argv[0], iSerial, file_format); + sqlite3VdbeSerialPut(&aRet[1+nSerial], argv[0], iSerial); sqlite3_result_blob(context, aRet, nRet, SQLITE_TRANSIENT); sqlite3DbFree(db, aRet); } diff --git a/src/vdbetrace.c b/src/vdbetrace.c index 0a767261f0..d79763e9e4 100644 --- a/src/vdbetrace.c +++ b/src/vdbetrace.c @@ -90,9 +90,11 @@ char *sqlite3VdbeExpandSql( if( db->nVdbeExec>1 ){ while( *zRawSql ){ const char *zStart = zRawSql; + int n; while( *(zRawSql++)!='\n' && *zRawSql ); sqlite3StrAccumAppend(&out, "-- ", 3); - sqlite3StrAccumAppend(&out, zStart, (int)(zRawSql-zStart)); + n = (int)(zRawSql - zStart); + if( n ) sqlite3StrAccumAppend(&out, zStart, n); } }else{ while( zRawSql[0] ){ From 1d8b85bed183517991ec87e1df99bce768e4d913 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 11 Dec 2013 11:03:19 +0000 Subject: [PATCH 076/276] Have the crash-test infrastructure code in test6.c read and write the 512-byte block containing the pending-byte lock as normal. Earlier versions did not access this part of the file in order to avoid triggering an assert in os_unix.c. But the assert() has since been removed. And not reading/writing this part of the file causes problems for multiplexor tests. FossilOrigin-Name: fdc3f3fa3de1481860e1e2a819db2d6c4eb05658 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/test6.c | 4 ---- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index c2e2f5f1bb..8b592a7952 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Use\sSQLITE_FCNTL_SYNC\sinstead\sof\sSQLITE_FCNTL_SYNC_OMITTED.\sAdd\sdocumentation\sin\sfor\sFCNTL_SYNC\sand\sFCNTL_COMMIT_PHASETWO. -D 2013-12-10T17:34:53.300 +C Have\sthe\scrash-test\sinfrastructure\scode\sin\stest6.c\sread\sand\swrite\sthe\s512-byte\sblock\scontaining\sthe\spending-byte\slock\sas\snormal.\sEarlier\sversions\sdid\snot\saccess\sthis\spart\sof\sthe\sfile\sin\sorder\sto\savoid\striggering\san\sassert\sin\sos_unix.c.\sBut\sthe\sassert()\shas\ssince\sbeen\sremoved.\sAnd\snot\sreading/writing\sthis\spart\sof\sthe\sfile\scauses\sproblems\sfor\smultiplexor\stests. +D 2013-12-11T11:03:19.250 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -234,7 +234,7 @@ F src/test2.c 7355101c085304b90024f2261e056cdff13c6c35 F src/test3.c 1c0e5d6f080b8e33c1ce8b3078e7013fdbcd560c F src/test4.c 9b32d22f5f150abe23c1830e2057c4037c45b3df F src/test5.c a6d1ac55ac054d0b2b8f37b5e655b6c92645a013 -F src/test6.c 6884dcfb1d04c26083ffb441ab329043967c09e5 +F src/test6.c 0c8fdf2e875ab23bb7fab6dee1a2c4c4ff03f5b0 F src/test7.c 72b732baa5642f795655ba1126ea032af46ecfd2 F src/test8.c c7aab1d9fbbf54fc33d43b73aa24aa55f9eaf534 F src/test9.c bea1e8cf52aa93695487badedd6e1886c321ea60 @@ -1146,7 +1146,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 3ee736a39d1fc175a297c5fdd0d2e1c5a9b5b18e -R 00ff1143b8ee30f4eb0b986958de8c12 +P 46231af985a1a872d1dc3418591cbaacb0b7c249 +R cf82896d56fef77694a1be0de6074b9d U dan -Z 4539dd639fdb6689f35ca693fd45b226 +Z ff5d29c735004d7eb85a84bef2a95faa diff --git a/manifest.uuid b/manifest.uuid index 5e83f3adb2..fe1cfc392c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -46231af985a1a872d1dc3418591cbaacb0b7c249 \ No newline at end of file +fdc3f3fa3de1481860e1e2a819db2d6c4eb05658 \ No newline at end of file diff --git a/src/test6.c b/src/test6.c index fb94363c36..0d0cf2c2f1 100644 --- a/src/test6.c +++ b/src/test6.c @@ -173,9 +173,6 @@ static void *crash_realloc(void *p, int n){ static int writeDbFile(CrashFile *p, u8 *z, i64 iAmt, i64 iOff){ int rc = SQLITE_OK; int iSkip = 0; - if( iOff==PENDING_BYTE && (p->flags&SQLITE_OPEN_MAIN_DB) ){ - iSkip = 512; - } if( (iAmt-iSkip)>0 ){ rc = sqlite3OsWrite(p->pRealFile, &z[iSkip], (int)(iAmt-iSkip), iOff+iSkip); } @@ -643,7 +640,6 @@ static int cfOpen( for(iOff=0; iOffiSize; iOff += 512){ int nRead = (int)(pWrapper->iSize - iOff); if( nRead>512 ) nRead = 512; - if( isDb && iOff==PENDING_BYTE ) continue; rc = sqlite3OsRead(pReal, &pWrapper->zData[iOff], nRead, iOff); } }else{ From 39325bac1bc966b700270943ebb1842fc78d01be Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 11 Dec 2013 12:02:55 +0000 Subject: [PATCH 077/276] Remove an unreachable conditional inserted by the previous check-in. FossilOrigin-Name: 3e1d55f0bd84810a035bd6c54583eb373784a9a3 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbetrace.c | 5 ++--- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index d9a2b68c9a..c1b2794c47 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings. -D 2013-12-11T11:00:44.250 +C Remove\san\sunreachable\sconditional\sinserted\sby\sthe\sprevious\scheck-in. +D 2013-12-11T12:02:55.839 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -288,7 +288,7 @@ F src/vdbeaux.c 74f3ad068f91d60ff56179a22610e7b0ef71e5d6 F src/vdbeblob.c 8cd05a5630e6d5563ad017bf82edaf812b28acde F src/vdbemem.c ac71e169dc056936f7a26ccaa808cd17456ffab1 F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147 -F src/vdbetrace.c 92c3d4f7a98ff59d44bf8351356ef82072f40517 +F src/vdbetrace.c f7eb148eb3b4fa3401b20024630dcb43d322e73c F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 @@ -1146,7 +1146,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 2525296d919245ebb01077aad541e4ae6eab7940 -R 24f899fa4dbed59efbcdd4778a6b73ec +P a7e5fcd66659750eb2f4675082df324e7cf35427 +R 67c3fc3c4877c3d23735c8e7af689974 U drh -Z 35945f2f4af25cff5df7e46d8c3b59e8 +Z 7b01fedab63512666d5da7a3d79c1ff6 diff --git a/manifest.uuid b/manifest.uuid index 8281671249..5f6a386d43 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a7e5fcd66659750eb2f4675082df324e7cf35427 \ No newline at end of file +3e1d55f0bd84810a035bd6c54583eb373784a9a3 \ No newline at end of file diff --git a/src/vdbetrace.c b/src/vdbetrace.c index d79763e9e4..a7ff0a685d 100644 --- a/src/vdbetrace.c +++ b/src/vdbetrace.c @@ -90,11 +90,10 @@ char *sqlite3VdbeExpandSql( if( db->nVdbeExec>1 ){ while( *zRawSql ){ const char *zStart = zRawSql; - int n; while( *(zRawSql++)!='\n' && *zRawSql ); sqlite3StrAccumAppend(&out, "-- ", 3); - n = (int)(zRawSql - zStart); - if( n ) sqlite3StrAccumAppend(&out, zStart, n); + assert( (zRawSql - zStart) > 0 ); + sqlite3StrAccumAppend(&out, zStart, (int)(zRawSql-zStart)); } }else{ while( zRawSql[0] ){ From a81ad1758c7cc9ab8dc8e78ceacc8878db77ef52 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 11 Dec 2013 14:00:04 +0000 Subject: [PATCH 078/276] Fix a bug in the shell ".import" command: Do not end the field when an escaped double-quote occurs at the end of a CRNL line. FossilOrigin-Name: 5e239ecda0f7835ce037b38b04627a574b5854cd --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c | 7 ++++--- test/shell5.test | 19 +++++++++++++++++++ 4 files changed, 31 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index c1b2794c47..058f299285 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunreachable\sconditional\sinserted\sby\sthe\sprevious\scheck-in. -D 2013-12-11T12:02:55.839 +C Fix\sa\sbug\sin\sthe\sshell\s".import"\scommand:\s\sDo\snot\send\sthe\sfield\nwhen\san\sescaped\sdouble-quote\soccurs\sat\sthe\send\sof\sa\sCRNL\sline. +D 2013-12-11T14:00:04.667 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -220,7 +220,7 @@ F src/random.c 0b2dbc37fdfbfa6bd455b091dfcef5bdb32dba68 F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c d41381d80a22d3a83352aeca274cccf264ac277a -F src/shell.c 936a72ff784efff3832cce274a96ed0b036e6758 +F src/shell.c 18924f6ccfa70da98bf9e388bab512c0fd1e792e F src/sqlite.h.in 125dc0b76f0116f1cd6f13536db52ba981e1c5bd F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc @@ -804,7 +804,7 @@ F test/shell1.test e7c0b9ebda25d5e78f0a3ea0dc4e31bb6d8098c0 F test/shell2.test e1d3790f064e50b2f973502f45750012667486df F test/shell3.test 5e8545ec72c4413a0e8d4c6be56496e3c257ca29 F test/shell4.test aa4eef8118b412d1a01477a53426ece169ea86a9 -F test/shell5.test 46c8c18d62732415c4fe084816c13d559831705e +F test/shell5.test cee83b4385f842fec1f2a0bec9ea811f35386edf F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3 F test/shrink.test 8c70f62b6e8eb4d54533de6d65bd06b1b9a17868 F test/sidedelete.test f0ad71abe6233e3b153100f3b8d679b19a488329 @@ -1146,7 +1146,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P a7e5fcd66659750eb2f4675082df324e7cf35427 -R 67c3fc3c4877c3d23735c8e7af689974 +P 3e1d55f0bd84810a035bd6c54583eb373784a9a3 +R 7d1fbc3502ae32ded8a54ca8c1f54c36 U drh -Z 7b01fedab63512666d5da7a3d79c1ff6 +Z 2736aa335da363db578416e90c12bc54 diff --git a/manifest.uuid b/manifest.uuid index 5f6a386d43..c859518640 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3e1d55f0bd84810a035bd6c54583eb373784a9a3 \ No newline at end of file +5e239ecda0f7835ce037b38b04627a574b5854cd \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 480ec5b455..7826fdf204 100644 --- a/src/shell.c +++ b/src/shell.c @@ -1836,7 +1836,7 @@ static void csv_append_char(CSVReader *p, int c){ ** + Report syntax errors on stderr */ static char *csv_read_one_field(CSVReader *p){ - int c, pc; + int c, pc, ppc; int cSep = p->cSeparator; p->n = 0; c = fgetc(p->in); @@ -1847,7 +1847,7 @@ static char *csv_read_one_field(CSVReader *p){ if( c=='"' ){ int startLine = p->nLine; int cQuote = c; - pc = 0; + pc = ppc = 0; while( 1 ){ c = fgetc(p->in); if( c=='\n' ) p->nLine++; @@ -1859,7 +1859,7 @@ static char *csv_read_one_field(CSVReader *p){ } if( (c==cSep && pc==cQuote) || (c=='\n' && pc==cQuote) - || (c=='\n' && pc=='\r' && p->n>=2 && p->z[p->n-2]==cQuote) + || (c=='\n' && pc=='\r' && ppc==cQuote) || (c==EOF && pc==cQuote) ){ do{ p->n--; }while( p->z[p->n]!=cQuote ); @@ -1877,6 +1877,7 @@ static char *csv_read_one_field(CSVReader *p){ break; } csv_append_char(p, c); + ppc = pc; pc = c; } }else{ diff --git a/test/shell5.test b/test/shell5.test index cd3d471031..ce05a303ca 100644 --- a/test/shell5.test +++ b/test/shell5.test @@ -268,4 +268,23 @@ do_test shell5-1.9 { } {1 {} 11 | 2 x 22 | 3 {"} 33 | 4 hello 44 | 5 55 {} | 6 66 x | 7 77 {"} | 8 88 hello | {} 9 99 | x 10 110 | {"} 11 121 | hello 12 132 |} db close +# Import columns containing quoted strings +do_test shell5-1.10 { + set out [open shell5.csv w] + fconfigure $out -translation lf + puts $out {column1,column2,column3,column4} + puts $out "field1,field2,\"x3 \"\"\r\ndata\"\" 3\",field4" + puts $out "x1,x2,\"x3 \"\"\ndata\"\" 3\",x4" + close $out + forcedelete test.db + catchcmd test.db {.mode csv + CREATE TABLE t1(a,b,c,d); +.import shell5.csv t1 + } + sqlite3 db test.db + db eval {SELECT hex(c) FROM t1 ORDER BY rowid} +} {636F6C756D6E33 783320220D0A64617461222033 783320220A64617461222033} + +db close + finish_test From a3cc007df47198f501b2ae02eeafbb64d6ff0097 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 13 Dec 2013 16:23:55 +0000 Subject: [PATCH 079/276] Simplication and optimization of error message handling. FossilOrigin-Name: 9d347f547e7ba9590b0c68edf50a14ad94a2bb92 --- manifest | 27 +++++++++++++-------------- manifest.uuid | 2 +- src/backup.c | 6 +++--- src/main.c | 10 +++------- src/sqliteInt.h | 1 + src/util.c | 23 +++++++++++------------ src/vdbeapi.c | 3 ++- src/vdbeaux.c | 4 ++-- src/vdbemem.c | 3 +++ test/capi3.test | 1 + 10 files changed, 40 insertions(+), 40 deletions(-) diff --git a/manifest b/manifest index c46916bc45..51d6982489 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sSQLITE_FCNTL_SYNC\sand\sSQLITE_FCNTL_COMMIT_PHASETWO\sfile-controls\nand\shave\sthe\spager\scall\sthem\sat\sappropriate\stimes.\s\sThis\sis\sneeded\sin\sorder\nto\senable\sZIPVFS\sto\sdo\smulti-file\satomic\scommits. -D 2013-12-11T15:47:39.590 +C Simplication\sand\soptimization\sof\serror\smessage\shandling. +D 2013-12-13T16:23:55.861 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -163,7 +163,7 @@ F src/alter.c 2af0330bb1b601af7a7789bf7229675fd772a083 F src/analyze.c 581d5c18ce89c6f45d4dca65914d0de5b4dad41f F src/attach.c 0a17c9364895316ca4f52d06a97a72c0af1ae8b3 F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 -F src/backup.c 6cb4c4ee1d302621eb18ad93a4216fed387b2568 +F src/backup.c a729e63cf5cd1829507cb7b8e89f99b95141bb53 F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btree.c 09285d6ffe7d819b9656ea9b7ecf1ab949a926fb @@ -188,7 +188,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b F src/loadext.c 867c7b330b740c6c917af9956b13b81d0a048303 -F src/main.c a79c8ca051a914e50d6b221d56801d47835714d8 +F src/main.c fafd3cd2a6c1211c29b9ef36b4af978ef01279ef F src/malloc.c 0203ebce9152c6a0e5de520140b8ba65187350be F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c0c990fcaddff810ea277b4fb5d9138603dd5d4b @@ -224,7 +224,7 @@ F src/shell.c 18924f6ccfa70da98bf9e388bab512c0fd1e792e F src/sqlite.h.in 592057b6b3881573c2d516bad30fb20171f16b05 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h c59b756b3aebefdce24ff44c4a7b3c155a3c26ee +F src/sqliteInt.h 3c1c14a551b019c94e1addcb67d92dd14a62e058 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -278,15 +278,15 @@ F src/tokenize.c ec4c1a62b890bf1dbcdb966399e140b904c700a4 F src/trigger.c d84e1f3669e9a217731a14a9d472b1c7b87c87ba F src/update.c d1c2477dcf14d90999d1935af4efb4806553250b F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 -F src/util.c 76ed0519296e3f62e97e57dab1999e34184c8e49 +F src/util.c e71f19b272f05c8695cf747b4bac1732685f9e5c F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 F src/vdbe.c 919422843c859a1db08db0c88189912dbf625fc7 F src/vdbe.h c06f0813f853566457ce9cfb1a4a4bc39a5da644 F src/vdbeInt.h a7bc268f844d75be48bb7ae16f77b418fd3c641c -F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed -F src/vdbeaux.c 74f3ad068f91d60ff56179a22610e7b0ef71e5d6 +F src/vdbeapi.c ce4e68ea4842cc6081046f533d088dcf01d247ad +F src/vdbeaux.c a22cbd91b24503b82690cb03324ffec9f4ef63f6 F src/vdbeblob.c 8cd05a5630e6d5563ad017bf82edaf812b28acde -F src/vdbemem.c ac71e169dc056936f7a26ccaa808cd17456ffab1 +F src/vdbemem.c 0e69351b2c6ff7d8b638688c0ae336a26befa6b2 F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147 F src/vdbetrace.c f7eb148eb3b4fa3401b20024630dcb43d322e73c F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd @@ -364,7 +364,7 @@ F test/btreefault.test c2bcb542685eea44621275cfedbd8a13f65201e3 F test/busy.test 76b4887f8b9160ba903c1ac22e8ff406ad6ae2f0 F test/cache.test 13bc046b26210471ca6f2889aceb1ea52dc717de F test/capi2.test 011c16da245fdc0106a2785035de6b242c05e738 -F test/capi3.test 56ab450125ead38846cbae7e5b6a216686c3cffa +F test/capi3.test f5eab498a0927d498e6d75c14567addb995ceccb F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4 F test/capi3c.test 93d24621c9ff84da9da060f30431e0453db1cdb0 F test/capi3d.test 6d0fc0a86d73f42dd19a7d8b7761ab9bc02277d0 @@ -1146,8 +1146,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 5e239ecda0f7835ce037b38b04627a574b5854cd 9ff4dfe1e36b40e386858b03f36cfab8f6806fdd -R 13a0878650f79a2d1e381d073556388e -T +closed 9ff4dfe1e36b40e386858b03f36cfab8f6806fdd +P 552f94d50f08cf11f33205730fde52bc2f06cff6 +R ab0976577ee6877312e7ddd6286ed77d U drh -Z b8733cc6e30d13ae991531254c7c0f0a +Z 888310640adcc5f651502c7cdb27c0d3 diff --git a/manifest.uuid b/manifest.uuid index b6a4ded46b..b1625e6376 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -552f94d50f08cf11f33205730fde52bc2f06cff6 \ No newline at end of file +9d347f547e7ba9590b0c68edf50a14ad94a2bb92 \ No newline at end of file diff --git a/src/backup.c b/src/backup.c index 292f3f456c..4a6bc7493c 100644 --- a/src/backup.c +++ b/src/backup.c @@ -601,10 +601,10 @@ int sqlite3_backup_finish(sqlite3_backup *p){ /* Set the error code of the destination database handle. */ rc = (p->rc==SQLITE_DONE) ? SQLITE_OK : p->rc; - sqlite3Error(p->pDestDb, rc, 0); - - /* Exit the mutexes and free the backup context structure. */ if( p->pDestDb ){ + sqlite3Error(p->pDestDb, rc, 0); + + /* Exit the mutexes and free the backup context structure. */ sqlite3LeaveMutexAndCloseZombie(p->pDestDb); } sqlite3BtreeLeave(p->pSrc); diff --git a/src/main.c b/src/main.c index 3e9f4e0171..09e3bb879f 100644 --- a/src/main.c +++ b/src/main.c @@ -987,9 +987,7 @@ void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){ #endif sqlite3Error(db, SQLITE_OK, 0); /* Deallocates any cached error strings. */ - if( db->pErr ){ - sqlite3ValueFree(db->pErr); - } + sqlite3ValueFree(db->pErr); sqlite3CloseExtensions(db); db->magic = SQLITE_MAGIC_ERROR; @@ -1871,6 +1869,7 @@ const char *sqlite3_errmsg(sqlite3 *db){ if( db->mallocFailed ){ z = sqlite3ErrStr(SQLITE_NOMEM); }else{ + testcase( db->pErr==0 ); z = (char*)sqlite3_value_text(db->pErr); assert( !db->mallocFailed ); if( z==0 ){ @@ -1912,8 +1911,7 @@ const void *sqlite3_errmsg16(sqlite3 *db){ }else{ z = sqlite3_value_text16(db->pErr); if( z==0 ){ - sqlite3ValueSetStr(db->pErr, -1, sqlite3ErrStr(db->errCode), - SQLITE_UTF8, SQLITE_STATIC); + sqlite3Error(db, db->errCode, sqlite3ErrStr(db->errCode)); z = sqlite3_value_text16(db->pErr); } /* A malloc() may have failed within the call to sqlite3_value_text16() @@ -2627,8 +2625,6 @@ static int openDatabase( } #endif - sqlite3Error(db, rc, 0); - /* -DSQLITE_DEFAULT_LOCKING_MODE=1 makes EXCLUSIVE the default locking ** mode. -DSQLITE_DEFAULT_LOCKING_MODE=0 make NORMAL the default locking ** mode. Doing nothing at all also makes NORMAL the default. diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 1f10c31cb5..8e1436efd3 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3157,6 +3157,7 @@ const void *sqlite3ValueText(sqlite3_value*, u8); int sqlite3ValueBytes(sqlite3_value*, u8); void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, void(*)(void*)); +void sqlite3ValueSetNull(sqlite3_value*); void sqlite3ValueFree(sqlite3_value*); sqlite3_value *sqlite3ValueNew(sqlite3 *); char *sqlite3Utf16to8(sqlite3 *, const void*, int, u8); diff --git a/src/util.c b/src/util.c index 9fa2a0fbd8..362a5d8970 100644 --- a/src/util.c +++ b/src/util.c @@ -115,18 +115,17 @@ int sqlite3Strlen30(const char *z){ ** to NULL. */ void sqlite3Error(sqlite3 *db, int err_code, const char *zFormat, ...){ - if( db && (db->pErr || (db->pErr = sqlite3ValueNew(db))!=0) ){ - db->errCode = err_code; - if( zFormat ){ - char *z; - va_list ap; - va_start(ap, zFormat); - z = sqlite3VMPrintf(db, zFormat, ap); - va_end(ap); - sqlite3ValueSetStr(db->pErr, -1, z, SQLITE_UTF8, SQLITE_DYNAMIC); - }else{ - sqlite3ValueSetStr(db->pErr, 0, 0, SQLITE_UTF8, SQLITE_STATIC); - } + assert( db!=0 ); + db->errCode = err_code; + if( zFormat && (db->pErr || (db->pErr = sqlite3ValueNew(db))!=0) ){ + char *z; + va_list ap; + va_start(ap, zFormat); + z = sqlite3VMPrintf(db, zFormat, ap); + va_end(ap); + sqlite3ValueSetStr(db->pErr, -1, z, SQLITE_UTF8, SQLITE_DYNAMIC); + }else if( db->pErr ){ + sqlite3ValueSetNull(db->pErr); } } diff --git a/src/vdbeapi.c b/src/vdbeapi.c index d512562174..ea383dffda 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -486,7 +486,7 @@ int sqlite3_step(sqlite3_stmt *pStmt){ v->doingRerun = 1; assert( v->expired==0 ); } - if( rc2!=SQLITE_OK && ALWAYS(v->isPrepareV2) && ALWAYS(db->pErr) ){ + if( rc2!=SQLITE_OK ){ /* This case occurs after failing to recompile an sql statement. ** The error message from the SQL compiler has already been loaded ** into the database handle. This block copies the error message @@ -496,6 +496,7 @@ int sqlite3_step(sqlite3_stmt *pStmt){ ** sqlite3_errmsg() and sqlite3_errcode(). */ const char *zErr = (const char *)sqlite3_value_text(db->pErr); + assert( zErr!=0 || db->mallocFailed ); sqlite3DbFree(db, v->zErrMsg); if( !db->mallocFailed ){ v->zErrMsg = sqlite3DbStrDup(db, zErr); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 9e1eb581f0..6344c4c8fa 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2420,6 +2420,7 @@ int sqlite3VdbeTransferError(Vdbe *p){ if( p->zErrMsg ){ u8 mallocFailed = db->mallocFailed; sqlite3BeginBenignMalloc(); + if( db->pErr==0 ) db->pErr = sqlite3ValueNew(db); sqlite3ValueSetStr(db->pErr, -1, p->zErrMsg, SQLITE_UTF8, SQLITE_TRANSIENT); sqlite3EndBenignMalloc(); db->mallocFailed = mallocFailed; @@ -2488,8 +2489,7 @@ int sqlite3VdbeReset(Vdbe *p){ ** to sqlite3_step(). For consistency (since sqlite3_step() was ** called), set the database error in this case as well. */ - sqlite3Error(db, p->rc, 0); - sqlite3ValueSetStr(db->pErr, -1, p->zErrMsg, SQLITE_UTF8, SQLITE_TRANSIENT); + sqlite3Error(db, p->rc, p->zErrMsg ? "%s" : 0, p->zErrMsg); sqlite3DbFree(db, p->zErrMsg); p->zErrMsg = 0; } diff --git a/src/vdbemem.c b/src/vdbemem.c index d5901b439a..3beccd92db 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -482,6 +482,9 @@ void sqlite3VdbeMemSetNull(Mem *pMem){ MemSetTypeFlag(pMem, MEM_Null); pMem->type = SQLITE_NULL; } +void sqlite3ValueSetNull(sqlite3_value *p){ + sqlite3VdbeMemSetNull((Mem*)p); +} /* ** Delete any previous value and set the value to be a BLOB of length diff --git a/test/capi3.test b/test/capi3.test index 9d7434d25d..2dbc298fa4 100644 --- a/test/capi3.test +++ b/test/capi3.test @@ -1191,6 +1191,7 @@ do_test capi3-18.2 { sqlite3_reset $STMT sqlite3_errcode db } {SQLITE_SCHEMA} +breakpoint do_test capi3-18.3 { sqlite3_errmsg db } {database schema has changed} From 40f22bed06e6002a73a2049a8bb6abd844f2aaf1 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 13 Dec 2013 16:42:18 +0000 Subject: [PATCH 080/276] Avoid unnecessary calls to sqlite3_free() from within sqlite3VXPrintf(). FossilOrigin-Name: e2a8b280e84c1f8fd6106d9427e1ad6cbcfccd10 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/printf.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 51d6982489..9255f89b3a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplication\sand\soptimization\sof\serror\smessage\shandling. -D 2013-12-13T16:23:55.861 +C Avoid\sunnecessary\scalls\sto\ssqlite3_free()\sfrom\swithin\ssqlite3VXPrintf(). +D 2013-12-13T16:42:18.070 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -215,7 +215,7 @@ F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222 F src/pcache1.c a467393909a4ed7ca9de066d85ba5c5b04a5be63 F src/pragma.c 5ab7279d132143feb77f773688a24ab05da75fd7 F src/prepare.c 359d1a1e9c9bd4488e4dd3a1aaaf2d2ebb9bb768 -F src/printf.c b2778aa160ef792ba51c9f11b743bfc015b66679 +F src/printf.c ba8b28e9d4ce984430e9f33f6ef1c85a1826d1dd F src/random.c 0b2dbc37fdfbfa6bd455b091dfcef5bdb32dba68 F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 @@ -1146,7 +1146,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 552f94d50f08cf11f33205730fde52bc2f06cff6 -R ab0976577ee6877312e7ddd6286ed77d +P 9d347f547e7ba9590b0c68edf50a14ad94a2bb92 +R b5a32784d4c7409fae006d7d9202782e U drh -Z 888310640adcc5f651502c7cdb27c0d3 +Z f8a864e171b1e45dee7c898a5141e356 diff --git a/manifest.uuid b/manifest.uuid index b1625e6376..604bc728a0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9d347f547e7ba9590b0c68edf50a14ad94a2bb92 \ No newline at end of file +e2a8b280e84c1f8fd6106d9427e1ad6cbcfccd10 \ No newline at end of file diff --git a/src/printf.c b/src/printf.c index 9be0fc9404..3279a54f21 100644 --- a/src/printf.c +++ b/src/printf.c @@ -683,7 +683,7 @@ void sqlite3VXPrintf( sqlite3AppendSpace(pAccum, nspace); } } - sqlite3_free(zExtra); + if( zExtra ) sqlite3_free(zExtra); }/* End for loop over the format string */ } /* End of function */ From 5d56dd2867c242e9868def654cddc2a160c77c7f Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 13 Dec 2013 18:50:40 +0000 Subject: [PATCH 081/276] Enhance the pcache1PinPage() routine so that it called much less often and runs much faster in the cases when it is actually called. FossilOrigin-Name: a845779cd31aec3204a6a9c776bd9c9f7d47dd24 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pcache1.c | 53 ++++++++++++++++++++++++++++++--------------------- 3 files changed, 38 insertions(+), 29 deletions(-) diff --git a/manifest b/manifest index 9255f89b3a..89fa59f993 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sunnecessary\scalls\sto\ssqlite3_free()\sfrom\swithin\ssqlite3VXPrintf(). -D 2013-12-13T16:42:18.070 +C Enhance\sthe\spcache1PinPage()\sroutine\sso\sthat\sit\scalled\smuch\sless\soften\sand\nruns\smuch\sfaster\sin\sthe\scases\swhen\sit\sis\sactually\scalled. +D 2013-12-13T18:50:40.859 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -212,7 +212,7 @@ F src/pager.h 6a790b64a9ea79bc2c849bdefdd39e2344bca94a F src/parse.y acee1a9958539e21263362b194594c5255ad2fca F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222 -F src/pcache1.c a467393909a4ed7ca9de066d85ba5c5b04a5be63 +F src/pcache1.c 57fee9a9a617218f5037afbbe49b09da65bde56b F src/pragma.c 5ab7279d132143feb77f773688a24ab05da75fd7 F src/prepare.c 359d1a1e9c9bd4488e4dd3a1aaaf2d2ebb9bb768 F src/printf.c ba8b28e9d4ce984430e9f33f6ef1c85a1826d1dd @@ -1146,7 +1146,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 9d347f547e7ba9590b0c68edf50a14ad94a2bb92 -R b5a32784d4c7409fae006d7d9202782e +P e2a8b280e84c1f8fd6106d9427e1ad6cbcfccd10 +R 47d549dcdf3ed528411247342cb19e3a U drh -Z f8a864e171b1e45dee7c898a5141e356 +Z da9f1c1b1e757ffeeb8c40974d788c01 diff --git a/manifest.uuid b/manifest.uuid index 604bc728a0..18544568b9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e2a8b280e84c1f8fd6106d9427e1ad6cbcfccd10 \ No newline at end of file +a845779cd31aec3204a6a9c776bd9c9f7d47dd24 \ No newline at end of file diff --git a/src/pcache1.c b/src/pcache1.c index df9d877537..f173e23fe3 100644 --- a/src/pcache1.c +++ b/src/pcache1.c @@ -96,6 +96,7 @@ struct PCache1 { struct PgHdr1 { sqlite3_pcache_page page; unsigned int iKey; /* Key value (page number) */ + u8 isPinned; /* Page in use, not on the LRU list */ PgHdr1 *pNext; /* Next in hash table chain */ PCache1 *pCache; /* Cache that currently owns this page */ PgHdr1 *pLruNext; /* Next in LRU list of unpinned pages */ @@ -424,34 +425,32 @@ static int pcache1ResizeHash(PCache1 *p){ ** LRU list, then this function is a no-op. ** ** The PGroup mutex must be held when this function is called. -** -** If pPage is NULL then this routine is a no-op. */ static void pcache1PinPage(PgHdr1 *pPage){ PCache1 *pCache; PGroup *pGroup; - if( pPage==0 ) return; + assert( pPage!=0 ); + assert( pPage->isPinned==0 ); pCache = pPage->pCache; pGroup = pCache->pGroup; + assert( pPage->pLruNext || pPage==pGroup->pLruTail ); + assert( pPage->pLruPrev || pPage==pGroup->pLruHead ); assert( sqlite3_mutex_held(pGroup->mutex) ); - if( pPage->pLruNext || pPage==pGroup->pLruTail ){ - if( pPage->pLruPrev ){ - pPage->pLruPrev->pLruNext = pPage->pLruNext; - } - if( pPage->pLruNext ){ - pPage->pLruNext->pLruPrev = pPage->pLruPrev; - } - if( pGroup->pLruHead==pPage ){ - pGroup->pLruHead = pPage->pLruNext; - } - if( pGroup->pLruTail==pPage ){ - pGroup->pLruTail = pPage->pLruPrev; - } - pPage->pLruNext = 0; - pPage->pLruPrev = 0; - pPage->pCache->nRecyclable--; + if( pPage->pLruPrev ){ + pPage->pLruPrev->pLruNext = pPage->pLruNext; + }else{ + pGroup->pLruHead = pPage->pLruNext; } + if( pPage->pLruNext ){ + pPage->pLruNext->pLruPrev = pPage->pLruPrev; + }else{ + pGroup->pLruTail = pPage->pLruPrev; + } + pPage->pLruNext = 0; + pPage->pLruPrev = 0; + pPage->isPinned = 1; + pCache->nRecyclable--; } @@ -483,6 +482,7 @@ static void pcache1EnforceMaxPage(PGroup *pGroup){ while( pGroup->nCurrentPage>pGroup->nMaxPage && pGroup->pLruTail ){ PgHdr1 *p = pGroup->pLruTail; assert( p->pCache->pGroup==pGroup ); + assert( p->isPinned==0 ); pcache1PinPage(p); pcache1RemoveFromHash(p); pcache1FreePage(p); @@ -510,7 +510,7 @@ static void pcache1TruncateUnsafe( if( pPage->iKey>=iLimit ){ pCache->nPage--; *pp = pPage->pNext; - pcache1PinPage(pPage); + if( !pPage->isPinned ) pcache1PinPage(pPage); pcache1FreePage(pPage); }else{ pp = &pPage->pNext; @@ -733,8 +733,11 @@ static sqlite3_pcache_page *pcache1Fetch( } /* Step 2: Abort if no existing page is found and createFlag is 0 */ - if( pPage || createFlag==0 ){ - pcache1PinPage(pPage); + if( pPage ){ + if( !pPage->isPinned ) pcache1PinPage(pPage); + goto fetch_out; + } + if( createFlag==0 ){ goto fetch_out; } @@ -775,6 +778,7 @@ static sqlite3_pcache_page *pcache1Fetch( )){ PCache1 *pOther; pPage = pGroup->pLruTail; + assert( pPage->isPinned==0 ); pcache1RemoveFromHash(pPage); pcache1PinPage(pPage); pOther = pPage->pCache; @@ -811,6 +815,7 @@ static sqlite3_pcache_page *pcache1Fetch( pPage->pCache = pCache; pPage->pLruPrev = 0; pPage->pLruNext = 0; + pPage->isPinned = 1; *(void **)pPage->page.pExtra = 0; pCache->apHash[h] = pPage; } @@ -846,6 +851,7 @@ static void pcache1Unpin( */ assert( pPage->pLruPrev==0 && pPage->pLruNext==0 ); assert( pGroup->pLruHead!=pPage && pGroup->pLruTail!=pPage ); + assert( pPage->isPinned==1 ); if( reuseUnlikely || pGroup->nCurrentPage>pGroup->nMaxPage ){ pcache1RemoveFromHash(pPage); @@ -861,6 +867,7 @@ static void pcache1Unpin( pGroup->pLruHead = pPage; } pCache->nRecyclable++; + pPage->isPinned = 0; } pcache1LeaveMutex(pCache->pGroup); @@ -987,6 +994,7 @@ int sqlite3PcacheReleaseMemory(int nReq){ #ifdef SQLITE_PCACHE_SEPARATE_HEADER nFree += sqlite3MemSize(p); #endif + assert( p->isPinned==0 ); pcache1PinPage(p); pcache1RemoveFromHash(p); pcache1FreePage(p); @@ -1011,6 +1019,7 @@ void sqlite3PcacheStats( PgHdr1 *p; int nRecyclable = 0; for(p=pcache1.grp.pLruHead; p; p=p->pLruNext){ + assert( p->isPinned==0 ); nRecyclable++; } *pnCurrent = pcache1.grp.nCurrentPage; From da8a330a03671577a982a5f1769d49f4016c1bb9 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 13 Dec 2013 19:35:21 +0000 Subject: [PATCH 082/276] Create and use a new pager interface sqlite3PagerUnrefNotNull() that works just like sqlite3PagerUnref() but guarantees that its argument is not a NULL pointer. FossilOrigin-Name: e00f37e2333cac5b53e17cf764ab56c4fcd5f617 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/btree.c | 3 ++- src/pager.c | 35 +++++++++++++++++++---------------- src/pager.h | 1 + 5 files changed, 31 insertions(+), 26 deletions(-) diff --git a/manifest b/manifest index 89fa59f993..fd21bd9f9c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\spcache1PinPage()\sroutine\sso\sthat\sit\scalled\smuch\sless\soften\sand\nruns\smuch\sfaster\sin\sthe\scases\swhen\sit\sis\sactually\scalled. -D 2013-12-13T18:50:40.859 +C Create\sand\suse\sa\snew\spager\sinterface\ssqlite3PagerUnrefNotNull()\sthat\sworks\njust\slike\ssqlite3PagerUnref()\sbut\sguarantees\sthat\sits\sargument\sis\snot\sa\nNULL\spointer. +D 2013-12-13T19:35:21.600 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,7 +166,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c a729e63cf5cd1829507cb7b8e89f99b95141bb53 F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c 09285d6ffe7d819b9656ea9b7ecf1ab949a926fb +F src/btree.c 11e29ef8cf16a42925fde036bcffbeffd9cc82df F src/btree.h a61ddebc78c66795a2b93181321a116746302cc9 F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0 F src/build.c 47ef8209e56d840d2b35b8a243c6ee567ad52bda @@ -207,8 +207,8 @@ F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_unix.c 60a7b3b23e6fcf83a50d1e320b280b551724e11f F src/os_win.c 16eac0961603182ffc10c02b39fe830126538e07 -F src/pager.c 95a568497d789d5729927fca93fec653c485df45 -F src/pager.h 6a790b64a9ea79bc2c849bdefdd39e2344bca94a +F src/pager.c 4757194b2f1ffd65a5fc45a3df4d38acc41fb7b3 +F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428 F src/parse.y acee1a9958539e21263362b194594c5255ad2fca F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222 @@ -1146,7 +1146,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P e2a8b280e84c1f8fd6106d9427e1ad6cbcfccd10 -R 47d549dcdf3ed528411247342cb19e3a +P a845779cd31aec3204a6a9c776bd9c9f7d47dd24 +R 0519b15291565e2dff816e0cb01e063b U drh -Z da9f1c1b1e757ffeeb8c40974d788c01 +Z 0b683c4f7d4e0f307681d123364409c6 diff --git a/manifest.uuid b/manifest.uuid index 18544568b9..012c3325a0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a845779cd31aec3204a6a9c776bd9c9f7d47dd24 \ No newline at end of file +e00f37e2333cac5b53e17cf764ab56c4fcd5f617 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index da1b91940d..20bed057e1 100644 --- a/src/btree.c +++ b/src/btree.c @@ -1673,10 +1673,11 @@ static void releasePage(MemPage *pPage){ if( pPage ){ assert( pPage->aData ); assert( pPage->pBt ); + assert( pPage->pDbPage!=0 ); assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage ); assert( sqlite3PagerGetData(pPage->pDbPage)==pPage->aData ); assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - sqlite3PagerUnref(pPage->pDbPage); + sqlite3PagerUnrefNotNull(pPage->pDbPage); } } diff --git a/src/pager.c b/src/pager.c index b4988cece7..caa41fe9eb 100644 --- a/src/pager.c +++ b/src/pager.c @@ -1990,7 +1990,7 @@ static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){ PgHdr *p = pager_lookup(pPager, 1); if( p ){ p->pageHash = 0; - sqlite3PagerUnref(p); + sqlite3PagerUnrefNotNull(p); } } #endif @@ -2983,7 +2983,7 @@ static int pagerUndoCallback(void *pCtx, Pgno iPg){ if( rc==SQLITE_OK ){ pPager->xReiniter(pPg); } - sqlite3PagerUnref(pPg); + sqlite3PagerUnrefNotNull(pPg); } } @@ -5439,16 +5439,19 @@ DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno){ ** are released, a rollback occurs and the lock on the database is ** removed. */ -void sqlite3PagerUnref(DbPage *pPg){ - if( pPg ){ - Pager *pPager = pPg->pPager; - if( pPg->flags & PGHDR_MMAP ){ - pagerReleaseMapPage(pPg); - }else{ - sqlite3PcacheRelease(pPg); - } - pagerUnlockIfUnused(pPager); +void sqlite3PagerUnrefNotNull(DbPage *pPg){ + Pager *pPager; + assert( pPg!=0 ); + pPager = pPg->pPager; + if( pPg->flags & PGHDR_MMAP ){ + pagerReleaseMapPage(pPg); + }else{ + sqlite3PcacheRelease(pPg); } + pagerUnlockIfUnused(pPager); +} +void sqlite3PagerUnref(DbPage *pPg){ + if( pPg ) sqlite3PagerUnrefNotNull(pPg); } /* @@ -5830,14 +5833,14 @@ int sqlite3PagerWrite(DbPage *pDbPage){ if( pPage->flags&PGHDR_NEED_SYNC ){ needSync = 1; } - sqlite3PagerUnref(pPage); + sqlite3PagerUnrefNotNull(pPage); } } }else if( (pPage = pager_lookup(pPager, pg))!=0 ){ if( pPage->flags&PGHDR_NEED_SYNC ){ needSync = 1; } - sqlite3PagerUnref(pPage); + sqlite3PagerUnrefNotNull(pPage); } } @@ -5853,7 +5856,7 @@ int sqlite3PagerWrite(DbPage *pDbPage){ PgHdr *pPage = pager_lookup(pPager, pg1+ii); if( pPage ){ pPage->flags |= PGHDR_NEED_SYNC; - sqlite3PagerUnref(pPage); + sqlite3PagerUnrefNotNull(pPage); } } } @@ -6783,7 +6786,7 @@ int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, int isCommit){ if( MEMDB ){ assert( pPgOld ); sqlite3PcacheMove(pPgOld, origPgno); - sqlite3PagerUnref(pPgOld); + sqlite3PagerUnrefNotNull(pPgOld); } if( needSyncPgno ){ @@ -6812,7 +6815,7 @@ int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, int isCommit){ } pPgHdr->flags |= PGHDR_NEED_SYNC; sqlite3PcacheMakeDirty(pPgHdr); - sqlite3PagerUnref(pPgHdr); + sqlite3PagerUnrefNotNull(pPgHdr); } return SQLITE_OK; diff --git a/src/pager.h b/src/pager.h index 55988a8486..c9ca8553b9 100644 --- a/src/pager.h +++ b/src/pager.h @@ -136,6 +136,7 @@ int sqlite3PagerAcquire(Pager *pPager, Pgno pgno, DbPage **ppPage, int clrFlag); DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno); void sqlite3PagerRef(DbPage*); void sqlite3PagerUnref(DbPage*); +void sqlite3PagerUnrefNotNull(DbPage*); /* Operations on page references. */ int sqlite3PagerWrite(DbPage*); From 16f9a81125792f2356b91a7fc966e1943fbbbf5e Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 13 Dec 2013 19:48:04 +0000 Subject: [PATCH 083/276] Reduce the number of calls to the subjRequiresPage() routine inside of pager. FossilOrigin-Name: e50ff39a93a51b5a5be4f0e82a76104b81c9e2a4 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pager.c | 15 ++++++--------- 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index fd21bd9f9c..c110182bd6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Create\sand\suse\sa\snew\spager\sinterface\ssqlite3PagerUnrefNotNull()\sthat\sworks\njust\slike\ssqlite3PagerUnref()\sbut\sguarantees\sthat\sits\sargument\sis\snot\sa\nNULL\spointer. -D 2013-12-13T19:35:21.600 +C Reduce\sthe\snumber\sof\scalls\sto\sthe\ssubjRequiresPage()\sroutine\sinside\sof\spager. +D 2013-12-13T19:48:04.970 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -207,7 +207,7 @@ F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_unix.c 60a7b3b23e6fcf83a50d1e320b280b551724e11f F src/os_win.c 16eac0961603182ffc10c02b39fe830126538e07 -F src/pager.c 4757194b2f1ffd65a5fc45a3df4d38acc41fb7b3 +F src/pager.c 3436cc9cce915e3fbcf9ae26a877816c2e6158f1 F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428 F src/parse.y acee1a9958539e21263362b194594c5255ad2fca F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 @@ -1146,7 +1146,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P a845779cd31aec3204a6a9c776bd9c9f7d47dd24 -R 0519b15291565e2dff816e0cb01e063b +P e00f37e2333cac5b53e17cf764ab56c4fcd5f617 +R f4a7260efd0973fe242850b07fa047a9 U drh -Z 0b683c4f7d4e0f307681d123364409c6 +Z 2c603ffc4b31451da49fbf26e09993c0 diff --git a/manifest.uuid b/manifest.uuid index 012c3325a0..cd03c5e940 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e00f37e2333cac5b53e17cf764ab56c4fcd5f617 \ No newline at end of file +e50ff39a93a51b5a5be4f0e82a76104b81c9e2a4 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index caa41fe9eb..c1675b73e3 100644 --- a/src/pager.c +++ b/src/pager.c @@ -1024,15 +1024,12 @@ static char *print_pager_state(Pager *p){ static int subjRequiresPage(PgHdr *pPg){ Pager *pPager = pPg->pPager; PagerSavepoint *p; - Pgno pgno; + Pgno pgno = pPg->pgno; int i; - if( pPager->nSavepoint ){ - pgno = pPg->pgno; - for(i=0; inSavepoint; i++){ - p = &pPager->aSavepoint[i]; - if( p->nOrig>=pgno && 0==sqlite3BitvecTest(p->pInSavepoint, pgno) ){ - return 1; - } + for(i=0; inSavepoint; i++){ + p = &pPager->aSavepoint[i]; + if( p->nOrig>=pgno && 0==sqlite3BitvecTest(p->pInSavepoint, pgno) ){ + return 1; } } return 0; @@ -5677,7 +5674,7 @@ static int pager_write(PgHdr *pPg){ ** to the journal then we can return right away. */ sqlite3PcacheMakeDirty(pPg); - if( pageInJournal(pPg) && !subjRequiresPage(pPg) ){ + if( pageInJournal(pPg) && (pPager->nSavepoint==0 || !subjRequiresPage(pPg)) ){ assert( !pagerUseWal(pPager) ); }else{ From 5dee6afcac2e58c92d4681c33dcdc092176dc691 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 13 Dec 2013 20:45:50 +0000 Subject: [PATCH 084/276] Performance optimizations in the pager_write() routine of pager.c. FossilOrigin-Name: bc5febef921bd12ca7760e9d07d3be0e67140320 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pager.c | 19 ++++++++++--------- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index c110182bd6..1c9fdc8401 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Reduce\sthe\snumber\sof\scalls\sto\sthe\ssubjRequiresPage()\sroutine\sinside\sof\spager. -D 2013-12-13T19:48:04.970 +C Performance\soptimizations\sin\sthe\spager_write()\sroutine\sof\spager.c. +D 2013-12-13T20:45:50.607 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -207,7 +207,7 @@ F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_unix.c 60a7b3b23e6fcf83a50d1e320b280b551724e11f F src/os_win.c 16eac0961603182ffc10c02b39fe830126538e07 -F src/pager.c 3436cc9cce915e3fbcf9ae26a877816c2e6158f1 +F src/pager.c efa923693e958696eee69b205a20bfbc402c8480 F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428 F src/parse.y acee1a9958539e21263362b194594c5255ad2fca F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 @@ -1146,7 +1146,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P e00f37e2333cac5b53e17cf764ab56c4fcd5f617 -R f4a7260efd0973fe242850b07fa047a9 +P e50ff39a93a51b5a5be4f0e82a76104b81c9e2a4 +R 5bf1150c318417a348672020b2f63094 U drh -Z 2c603ffc4b31451da49fbf26e09993c0 +Z 1b9c31d5f496c5b0319085d207729750 diff --git a/manifest.uuid b/manifest.uuid index cd03c5e940..1ecaf09f41 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e50ff39a93a51b5a5be4f0e82a76104b81c9e2a4 \ No newline at end of file +bc5febef921bd12ca7760e9d07d3be0e67140320 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index c1675b73e3..954ba7f1e5 100644 --- a/src/pager.c +++ b/src/pager.c @@ -1038,8 +1038,8 @@ static int subjRequiresPage(PgHdr *pPg){ /* ** Return true if the page is already in the journal file. */ -static int pageInJournal(PgHdr *pPg){ - return sqlite3BitvecTest(pPg->pPager->pInJournal, pPg->pgno); +static int pageInJournal(Pager *pPager, PgHdr *pPg){ + return sqlite3BitvecTest(pPager->pInJournal, pPg->pgno); } /* @@ -4335,7 +4335,7 @@ static int subjournalPage(PgHdr *pPg){ assert( isOpen(pPager->jfd) || pagerUseWal(pPager) ); assert( isOpen(pPager->sjfd) || pPager->nSubRec==0 ); assert( pagerUseWal(pPager) - || pageInJournal(pPg) + || pageInJournal(pPager, pPg) || pPg->pgno>pPager->dbOrigSize ); rc = openSubJournal(pPager); @@ -5636,9 +5636,9 @@ int sqlite3PagerBegin(Pager *pPager, int exFlag, int subjInMemory){ ** of any open savepoints as appropriate. */ static int pager_write(PgHdr *pPg){ - void *pData = pPg->pData; Pager *pPager = pPg->pPager; int rc = SQLITE_OK; + int inJournal; /* This routine is not called unless a write-transaction has already ** been started. The journal file may or may not be open at this point. @@ -5674,7 +5674,8 @@ static int pager_write(PgHdr *pPg){ ** to the journal then we can return right away. */ sqlite3PcacheMakeDirty(pPg); - if( pageInJournal(pPg) && (pPager->nSavepoint==0 || !subjRequiresPage(pPg)) ){ + inJournal = pageInJournal(pPager, pPg); + if( inJournal && (pPager->nSavepoint==0 || !subjRequiresPage(pPg)) ){ assert( !pagerUseWal(pPager) ); }else{ @@ -5682,7 +5683,7 @@ static int pager_write(PgHdr *pPg){ ** EXCLUSIVE lock on the main database file. Write the current page to ** the transaction journal if it is not there already. */ - if( !pageInJournal(pPg) && !pagerUseWal(pPager) ){ + if( !inJournal && !pagerUseWal(pPager) ){ assert( pagerUseWal(pPager)==0 ); if( pPg->pgno<=pPager->dbOrigSize && isOpen(pPager->jfd) ){ u32 cksum; @@ -5695,7 +5696,7 @@ static int pager_write(PgHdr *pPg){ assert( pPg->pgno!=PAGER_MJ_PGNO(pPager) ); assert( pPager->journalHdr<=pPager->journalOff ); - CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM, pData2); + CODEC2(pPager, pPg->pData, pPg->pgno, 7, return SQLITE_NOMEM, pData2); cksum = pager_cksum(pPager, (u8*)pData2); /* Even if an IO or diskfull error occurs while journalling the @@ -5747,7 +5748,7 @@ static int pager_write(PgHdr *pPg){ ** the statement journal format differs from the standard journal format ** in that it omits the checksums and the header. */ - if( subjRequiresPage(pPg) ){ + if( pPager->nSavepoint>0 && subjRequiresPage(pPg) ){ rc = subjournalPage(pPg); } } @@ -6749,7 +6750,7 @@ int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, int isCommit){ if( (pPg->flags&PGHDR_NEED_SYNC) && !isCommit ){ needSyncPgno = pPg->pgno; assert( pPager->journalMode==PAGER_JOURNALMODE_OFF || - pageInJournal(pPg) || pPg->pgno>pPager->dbOrigSize ); + pageInJournal(pPager, pPg) || pPg->pgno>pPager->dbOrigSize ); assert( pPg->flags&PGHDR_DIRTY ); } From 4a8ee3dfe2afb5f0478b1bcdf94202cdf98a469d Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 14 Dec 2013 13:44:22 +0000 Subject: [PATCH 085/276] Allow the SQLITE_DETERMINISTIC flag to be ORed into the preferred text encoding of application-defined functions, to mark the function as deterministic. FossilOrigin-Name: 5716fc2341ddd8cf64139e7168597f864da4e10b --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/callback.c | 1 - src/main.c | 12 +++++++++--- src/sqlite.h.in | 35 +++++++++++++++++++++++++++-------- src/test1.c | 37 +++++++++++++++++++++++++++++++------ test/func5.test | 36 +++++++++++++++++++++++++++++++++--- 7 files changed, 111 insertions(+), 32 deletions(-) diff --git a/manifest b/manifest index 1c9fdc8401..92e7b53f9f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\soptimizations\sin\sthe\spager_write()\sroutine\sof\spager.c. -D 2013-12-13T20:45:50.607 +C Allow\sthe\sSQLITE_DETERMINISTIC\sflag\sto\sbe\sORed\sinto\sthe\spreferred\stext\sencoding\nof\sapplication-defined\sfunctions,\sto\smark\sthe\sfunction\sas\sdeterministic. +D 2013-12-14T13:44:22.886 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -170,7 +170,7 @@ F src/btree.c 11e29ef8cf16a42925fde036bcffbeffd9cc82df F src/btree.h a61ddebc78c66795a2b93181321a116746302cc9 F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0 F src/build.c 47ef8209e56d840d2b35b8a243c6ee567ad52bda -F src/callback.c f99a8957ba2adf369645fac0db09ad8adcf1caa2 +F src/callback.c 174e3c8656bc29f91d710ab61550d16eea34be98 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 @@ -188,7 +188,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b F src/loadext.c 867c7b330b740c6c917af9956b13b81d0a048303 -F src/main.c fafd3cd2a6c1211c29b9ef36b4af978ef01279ef +F src/main.c 45e08d8ca4808625c4512a14898e9c61553e3d2a F src/malloc.c 0203ebce9152c6a0e5de520140b8ba65187350be F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c0c990fcaddff810ea277b4fb5d9138603dd5d4b @@ -221,7 +221,7 @@ F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c d41381d80a22d3a83352aeca274cccf264ac277a F src/shell.c 18924f6ccfa70da98bf9e388bab512c0fd1e792e -F src/sqlite.h.in 592057b6b3881573c2d516bad30fb20171f16b05 +F src/sqlite.h.in 4ef56464aeaa3785a2c5ca37fb3a0fb229d68b2e F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc F src/sqliteInt.h 3c1c14a551b019c94e1addcb67d92dd14a62e058 @@ -229,7 +229,7 @@ F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e F src/tclsqlite.c 651b10698c87bbc3ae5772e2491e3444c5bbf153 -F src/test1.c 760e0419705f712d80595f47199568cd7e3b57a4 +F src/test1.c 633e5e6a116acf4473b9289240bcceb5320a9d93 F src/test2.c 7355101c085304b90024f2261e056cdff13c6c35 F src/test3.c 1c0e5d6f080b8e33c1ce8b3078e7013fdbcd560c F src/test4.c 9b32d22f5f150abe23c1830e2057c4037c45b3df @@ -577,7 +577,7 @@ F test/func.test 00667bbeac044d007f6f021af1b9f6150f0c7ff8 F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f F test/func3.test dbccee9133cfef1473c59ec07b5f0262b9d72f9a F test/func4.test 6beacdfcb0e18c358e6c2dcacf1b65d1fa80955f -F test/func5.test 1435dd313c0bae70d6af089c97a2a997fc5d0e53 +F test/func5.test cdd224400bc3e48d891827cc913a57051a426fa4 F test/fuzz-oss1.test 4912e528ec9cf2f42134456933659d371c9e0d74 F test/fuzz.test 77fd50afc12847af50fcf1941679d90adebadde6 F test/fuzz2.test 207d0f9d06db3eaf47a6b7bfc835b8e2fc397167 @@ -1146,7 +1146,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P e50ff39a93a51b5a5be4f0e82a76104b81c9e2a4 -R 5bf1150c318417a348672020b2f63094 +P bc5febef921bd12ca7760e9d07d3be0e67140320 +R 08fd6b0f6ffb77c364a2bec4efb57810 U drh -Z 1b9c31d5f496c5b0319085d207729750 +Z d2313ea9b793ebbfa6428f7e8b022d58 diff --git a/manifest.uuid b/manifest.uuid index 1ecaf09f41..0d64591d7b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bc5febef921bd12ca7760e9d07d3be0e67140320 \ No newline at end of file +5716fc2341ddd8cf64139e7168597f864da4e10b \ No newline at end of file diff --git a/src/callback.c b/src/callback.c index 66fa490894..260fe806bb 100644 --- a/src/callback.c +++ b/src/callback.c @@ -357,7 +357,6 @@ FuncDef *sqlite3FindFunction( assert( nArg>=(-2) ); assert( nArg>=(-1) || createFlag==0 ); - assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE ); h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % ArraySize(db->aFunc.a); /* First search for a match amongst the application-defined functions. diff --git a/src/main.c b/src/main.c index 09e3bb879f..32e4dee7f0 100644 --- a/src/main.c +++ b/src/main.c @@ -1370,6 +1370,7 @@ int sqlite3CreateFunc( ){ FuncDef *p; int nName; + int extraFlags; assert( sqlite3_mutex_held(db->mutex) ); if( zFunctionName==0 || @@ -1380,6 +1381,10 @@ int sqlite3CreateFunc( (255<(nName = sqlite3Strlen30( zFunctionName))) ){ return SQLITE_MISUSE_BKPT; } + + assert( SQLITE_FUNC_CONSTANT==SQLITE_DETERMINISTIC ); + extraFlags = enc & SQLITE_DETERMINISTIC; + enc &= (SQLITE_FUNC_ENCMASK|SQLITE_ANY); #ifndef SQLITE_OMIT_UTF16 /* If SQLITE_UTF16 is specified as the encoding type, transform this @@ -1393,10 +1398,10 @@ int sqlite3CreateFunc( enc = SQLITE_UTF16NATIVE; }else if( enc==SQLITE_ANY ){ int rc; - rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF8, + rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF8|extraFlags, pUserData, xFunc, xStep, xFinal, pDestructor); if( rc==SQLITE_OK ){ - rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF16LE, + rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF16LE|extraFlags, pUserData, xFunc, xStep, xFinal, pDestructor); } if( rc!=SQLITE_OK ){ @@ -1439,7 +1444,8 @@ int sqlite3CreateFunc( pDestructor->nRef++; } p->pDestructor = pDestructor; - p->funcFlags &= SQLITE_FUNC_ENCMASK; + p->funcFlags = (p->funcFlags & SQLITE_FUNC_ENCMASK) | extraFlags; + testcase( p->funcFlags & SQLITE_DETERMINISTIC ); p->xFunc = xFunc; p->xStep = xStep; p->xFinalize = xFinal; diff --git a/src/sqlite.h.in b/src/sqlite.h.in index b9f4defed7..7b0e648bfc 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -3977,15 +3977,24 @@ int sqlite3_reset(sqlite3_stmt *pStmt); ** ** ^The fourth parameter, eTextRep, specifies what ** [SQLITE_UTF8 | text encoding] this SQL function prefers for -** its parameters. Every SQL function implementation must be able to work -** with UTF-8, UTF-16le, or UTF-16be. But some implementations may be -** more efficient with one encoding than another. ^An application may -** invoke sqlite3_create_function() or sqlite3_create_function16() multiple -** times with the same function but with different values of eTextRep. +** its parameters. The application should set this parameter to +** [SQLITE_UTF16LE] if the function implementation invokes +** [sqlite3_value_text16le()] on an input, or [SQLITE_UTF16BE] if the +** implementation invokes [sqlite3_value_text16be()] on an input, or +** [SQLITE_UTF16] if [sqlite3_value_text16()] is used, or [SQLITE_UTF8] +** otherwise. ^The same SQL function may be registered multiple times using +** different preferred text encodings, with different implementations for +** each encoding. ** ^When multiple implementations of the same function are available, SQLite ** will pick the one that involves the least amount of data conversion. -** If there is only a single implementation which does not care what text -** encoding is used, then the fourth argument should be [SQLITE_ANY]. +** +** ^The fourth parameter may optionally be ORed with [SQLITE_DETERMINISTIC] +** to signal that the function will always return the same result given +** the same inputs within a single SQL statement. Most SQL functions are +** deterministic. The built-in [random()] SQL function is an example of a +** function that is not deterministic. The SQLite query planner is able to +** perform additional optimizations on deterministic functions, so use +** of the [SQLITE_DETERMINISTIC] flag is recommended where possible. ** ** ^(The fifth parameter is an arbitrary pointer. The implementation of the ** function can gain access to this pointer using [sqlite3_user_data()].)^ @@ -4071,9 +4080,19 @@ int sqlite3_create_function_v2( #define SQLITE_UTF16LE 2 #define SQLITE_UTF16BE 3 #define SQLITE_UTF16 4 /* Use native byte order */ -#define SQLITE_ANY 5 /* sqlite3_create_function only */ +#define SQLITE_ANY 5 /* Deprecated */ #define SQLITE_UTF16_ALIGNED 8 /* sqlite3_create_collation only */ +/* +** CAPI3REF: Function Flags +** +** These constants may be ORed together with the +** [SQLITE_UTF8 | preferred text encoding] as the fourth argument +** to [sqlite3_create_function()], [sqlite3_create_function16()], or +** [sqlite3_create_function_v2()]. +*/ +#define SQLITE_DETERMINISTIC 0x800 + /* ** CAPI3REF: Deprecated Functions ** DEPRECATED diff --git a/src/test1.c b/src/test1.c index e0c16e13ae..a96b298661 100644 --- a/src/test1.c +++ b/src/test1.c @@ -942,9 +942,21 @@ static void ptrChngFunction( sqlite3_result_int(context, p1!=p2); } +/* +** This SQL function returns a different answer each time it is called, even if +** the arguments are the same. +*/ +static void nondeterministicFunction( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + static int cnt = 0; + sqlite3_result_int(context, cnt++); +} /* -** Usage: sqlite_test_create_function DB +** Usage: sqlite3_create_function DB ** ** Call the sqlite3_create_function API on the given database in order ** to create a function named "x_coalesce". This function does the same thing @@ -973,16 +985,16 @@ static int test_create_function( return TCL_ERROR; } if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; - rc = sqlite3_create_function(db, "x_coalesce", -1, SQLITE_ANY, 0, + rc = sqlite3_create_function(db, "x_coalesce", -1, SQLITE_UTF8, 0, t1_ifnullFunc, 0, 0); if( rc==SQLITE_OK ){ - rc = sqlite3_create_function(db, "hex8", 1, SQLITE_ANY, 0, - hex8Func, 0, 0); + rc = sqlite3_create_function(db, "hex8", 1, SQLITE_UTF8 | SQLITE_DETERMINISTIC, + 0, hex8Func, 0, 0); } #ifndef SQLITE_OMIT_UTF16 if( rc==SQLITE_OK ){ - rc = sqlite3_create_function(db, "hex16", 1, SQLITE_ANY, 0, - hex16Func, 0, 0); + rc = sqlite3_create_function(db, "hex16", 1, SQLITE_UTF16 | SQLITE_DETERMINISTIC, + 0, hex16Func, 0, 0); } #endif if( rc==SQLITE_OK ){ @@ -994,6 +1006,19 @@ static int test_create_function( ptrChngFunction, 0, 0); } + /* Functions counter1() and counter2() have the same implementation - they + ** both return an ascending integer with each call. But counter1() is marked + ** as non-deterministic and counter2() is marked as deterministic. + */ + if( rc==SQLITE_OK ){ + rc = sqlite3_create_function(db, "counter1", -1, SQLITE_UTF8, + 0, nondeterministicFunction, 0, 0); + } + if( rc==SQLITE_OK ){ + rc = sqlite3_create_function(db, "counter2", -1, SQLITE_UTF8|SQLITE_DETERMINISTIC, + 0, nondeterministicFunction, 0, 0); + } + #ifndef SQLITE_OMIT_UTF16 /* Use the sqlite3_create_function16() API here. Mainly for fun, but also ** because it is not tested anywhere else. */ diff --git a/test/func5.test b/test/func5.test index 83ecb785db..bfd545b4e3 100644 --- a/test/func5.test +++ b/test/func5.test @@ -9,13 +9,15 @@ # #************************************************************************* # -# Verify that constant string expressions that get factored into initializing -# code are not reused between function parameters and other values in the -# VDBE program, as the function might have changed the encoding. +# Testing of function factoring and the SQLITE_DETERMINISTIC flag. # set testdir [file dirname $argv0] source $testdir/tester.tcl +# Verify that constant string expressions that get factored into initializing +# code are not reused between function parameters and other values in the +# VDBE program, as the function might have changed the encoding. +# do_execsql_test func5-1.1 { PRAGMA encoding=UTF16le; CREATE TABLE t1(x,a,b,c); @@ -30,4 +32,32 @@ do_execsql_test func5-1.2 { SELECT x FROM t1 WHERE a='abcdefg' OR c=instr('abcdefg',b) ORDER BY +x; } {2 4} +# Verify that SQLITE_DETERMINISTIC functions get factored out of the +# evaluation loop whereas non-deterministic functions do not. counter1() +# is marked as non-deterministic and so is not factored out of the loop, +# and it really is non-deterministic, returning a different result each +# time. But counter2() is marked as deterministic, so it does get factored +# out of the loop. counter2() has the same implementation as counter1(), +# returning a different result on each invocation, but because it is +# only invoked once outside of the loop, it appears to return the same +# result multiple times. +# +do_execsql_test func5-2.1 { + CREATE TABLE t2(x,y); + INSERT INTO t2 VALUES(1,2),(3,4),(5,6),(7,8); + SELECT x, y FROM t2 WHERE x+5=5+x ORDER BY +x; +} {1 2 3 4 5 6 7 8} +sqlite3_create_function db +do_execsql_test func5-2.2 { + SELECT x, y FROM t2 + WHERE x+counter1('hello')=counter1('hello')+x + ORDER BY +x; +} {} +do_execsql_test func5-2.3 { + SELECT x, y FROM t2 + WHERE x+counter2('hello')=counter2('hello')+x + ORDER BY +x; +} {1 2 3 4 5 6 7 8} + + finish_test From a5c1416d64b4b857721f085258b6ef1dcaeb6f5b Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 17 Dec 2013 15:03:06 +0000 Subject: [PATCH 086/276] Add the printf() SQL function. FossilOrigin-Name: 6db7052eeefafdbf26b3153bc38600fecfb53ae6 --- manifest | 22 +++++----- manifest.uuid | 2 +- src/func.c | 27 +++++++++++++ src/printf.c | 100 ++++++++++++++++++++++++++++++++++++---------- src/sqliteInt.h | 19 +++++++-- src/vdbetrace.c | 20 ++++++---- test/printf2.test | 56 ++++++++++++++++++++++++++ 7 files changed, 203 insertions(+), 43 deletions(-) create mode 100644 test/printf2.test diff --git a/manifest b/manifest index 92e7b53f9f..04c30af9ed 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Allow\sthe\sSQLITE_DETERMINISTIC\sflag\sto\sbe\sORed\sinto\sthe\spreferred\stext\sencoding\nof\sapplication-defined\sfunctions,\sto\smark\sthe\sfunction\sas\sdeterministic. -D 2013-12-14T13:44:22.886 +C Add\sthe\sprintf()\sSQL\sfunction. +D 2013-12-17T15:03:06.814 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -178,7 +178,7 @@ F src/delete.c b36db1f79ee50eaca979660c9dd36437f5410b93 F src/expr.c 31a2b65339f6c3795d4cfa5e99798cd72f9fdfdf F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 2ab0f5384b70594468ef3ac5c7ed8ca24bfd17d5 -F src/func.c fed87f35cf4da4a798b726d84abefc209b48d831 +F src/func.c 6325ac2ec10833ccf4d5c36d323709221d37ea19 F src/global.c 1d7bb7ea8254ae6a68ed9bfaf65fcb3d1690b486 F src/hash.c ac3470bbf1ca4ae4e306a8ecb0fdf1731810ffe4 F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22 @@ -215,7 +215,7 @@ F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222 F src/pcache1.c 57fee9a9a617218f5037afbbe49b09da65bde56b F src/pragma.c 5ab7279d132143feb77f773688a24ab05da75fd7 F src/prepare.c 359d1a1e9c9bd4488e4dd3a1aaaf2d2ebb9bb768 -F src/printf.c ba8b28e9d4ce984430e9f33f6ef1c85a1826d1dd +F src/printf.c 0c0cb58e43410d6237afe0f2751f265fc62eac59 F src/random.c 0b2dbc37fdfbfa6bd455b091dfcef5bdb32dba68 F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 @@ -224,7 +224,7 @@ F src/shell.c 18924f6ccfa70da98bf9e388bab512c0fd1e792e F src/sqlite.h.in 4ef56464aeaa3785a2c5ca37fb3a0fb229d68b2e F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h 3c1c14a551b019c94e1addcb67d92dd14a62e058 +F src/sqliteInt.h b7e9da87740488671cfe4c70038a8eef3a1d317e F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -288,7 +288,7 @@ F src/vdbeaux.c a22cbd91b24503b82690cb03324ffec9f4ef63f6 F src/vdbeblob.c 8cd05a5630e6d5563ad017bf82edaf812b28acde F src/vdbemem.c 0e69351b2c6ff7d8b638688c0ae336a26befa6b2 F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147 -F src/vdbetrace.c f7eb148eb3b4fa3401b20024630dcb43d322e73c +F src/vdbetrace.c 6f52bc0c51e144b7efdcfb2a8f771167a8816767 F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 @@ -739,6 +739,7 @@ F test/permutations.test af3278cbea3a19e025d5169be8193ff48dc3f862 F test/pragma.test e882183ecd21d064cec5c7aaea174fbd36293429 F test/pragma2.test aea7b3d82c76034a2df2b38a13745172ddc0bc13 F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552 +F test/printf2.test 7b1c2c27826702723ad2b1fcd92bce2ffc9f45f3 F test/progress.test a282973d1d17f08071bc58a77d6b80f2a81c354d F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc F test/queryonly.test 5f653159e0f552f0552d43259890c1089391dcca @@ -1146,7 +1147,10 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P bc5febef921bd12ca7760e9d07d3be0e67140320 -R 08fd6b0f6ffb77c364a2bec4efb57810 +P 5716fc2341ddd8cf64139e7168597f864da4e10b +R 2b8d4659fa3fad9afbe93191f7aa6089 +T *branch * printf-sql-function +T *sym-printf-sql-function * +T -sym-trunk * U drh -Z d2313ea9b793ebbfa6428f7e8b022d58 +Z 77c6ba366806353f9c00efecee393357 diff --git a/manifest.uuid b/manifest.uuid index 0d64591d7b..ce69d4e663 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5716fc2341ddd8cf64139e7168597f864da4e10b \ No newline at end of file +6db7052eeefafdbf26b3153bc38600fecfb53ae6 \ No newline at end of file diff --git a/src/func.c b/src/func.c index 951af97b35..1d6ec9f6ee 100644 --- a/src/func.c +++ b/src/func.c @@ -218,6 +218,32 @@ static void instrFunc( sqlite3_result_int(context, N); } +/* +** Implementation of the printf() function. +*/ +static void printfFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + PrintfArguments x; + StrAccum str; + const char *zFormat; + int n; + + if( argc>=1 && (zFormat = (const char*)sqlite3_value_text(argv[0]))!=0 ){ + x.nArg = argc-1; + x.nUsed = 0; + x.apArg = argv+1; + sqlite3StrAccumInit(&str, 0, 0, SQLITE_MAX_LENGTH); + str.db = sqlite3_context_db_handle(context); + sqlite3XPrintf(&str, SQLITE_PRINTF_SQLFUNC, zFormat, &x); + n = str.nChar; + sqlite3_result_text(context, sqlite3StrAccumFinish(&str), n, + SQLITE_DYNAMIC); + } +} + /* ** Implementation of the substr() function. ** @@ -1648,6 +1674,7 @@ void sqlite3RegisterGlobalFunctions(void){ FUNCTION(instr, 2, 0, 0, instrFunc ), FUNCTION(substr, 2, 0, 0, substrFunc ), FUNCTION(substr, 3, 0, 0, substrFunc ), + FUNCTION(printf, -1, 0, 0, printfFunc ), FUNCTION(unicode, 1, 0, 0, unicodeFunc ), FUNCTION(char, -1, 0, 0, charFunc ), FUNCTION(abs, 1, 0, 0, absFunc ), diff --git a/src/printf.c b/src/printf.c index 3279a54f21..da118818bb 100644 --- a/src/printf.c +++ b/src/printf.c @@ -151,11 +151,28 @@ void sqlite3AppendSpace(StrAccum *pAccum, int N){ /* ** Set the StrAccum object to an error mode. */ -void setStrAccumError(StrAccum *p, u8 eError){ +static void setStrAccumError(StrAccum *p, u8 eError){ p->accError = eError; p->nAlloc = 0; } +/* +** Extra argument values from a PrintfArguments object +*/ +static sqlite3_int64 getIntArg(PrintfArguments *p){ + if( p->nArg<=p->nUsed ) return 0; + return sqlite3_value_int64(p->apArg[p->nUsed++]); +} +static double getDoubleArg(PrintfArguments *p){ + if( p->nArg<=p->nUsed ) return 0.0; + return sqlite3_value_double(p->apArg[p->nUsed++]); +} +static char *getTextArg(PrintfArguments *p){ + if( p->nArg<=p->nUsed ) return 0; + return (char*)sqlite3_value_text(p->apArg[p->nUsed++]); +} + + /* ** On machines with a small stack size, you can redefine the ** SQLITE_PRINT_BUF_SIZE to be something smaller, if desired. @@ -169,10 +186,10 @@ void setStrAccumError(StrAccum *p, u8 eError){ ** Render a string given by "fmt" into the StrAccum object. */ void sqlite3VXPrintf( - StrAccum *pAccum, /* Accumulate results here */ - int useExtended, /* Allow extended %-conversions */ - const char *fmt, /* Format string */ - va_list ap /* arguments */ + StrAccum *pAccum, /* Accumulate results here */ + u32 bFlags, /* SQLITE_PRINTF_* flags */ + const char *fmt, /* Format string */ + va_list ap /* arguments */ ){ int c; /* Next character in the format string */ char *bufpt; /* Pointer to the conversion buffer */ @@ -190,6 +207,8 @@ void sqlite3VXPrintf( etByte flag_longlong; /* True if the "ll" flag is present */ etByte done; /* Loop termination flag */ etByte xtype = 0; /* Conversion paradigm */ + u8 bArgList; /* True for SQLITE_PRINTF_SQLFUNC */ + u8 useIntern; /* Ok to use internal conversions (ex: %T) */ char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */ sqlite_uint64 longvalue; /* Value for integer types */ LONGDOUBLE_TYPE realvalue; /* Value for real types */ @@ -204,9 +223,18 @@ void sqlite3VXPrintf( etByte flag_dp; /* True if decimal point should be shown */ etByte flag_rtz; /* True if trailing zeros should be removed */ #endif + PrintfArguments *pArgList = 0; /* Arguments for SQLITE_PRINTF_SQLFUNC */ char buf[etBUFSIZE]; /* Conversion buffer */ bufpt = 0; + if( bFlags ){ + if( (bArgList = (bFlags & SQLITE_PRINTF_SQLFUNC))!=0 ){ + pArgList = va_arg(ap, PrintfArguments*); + } + useIntern = bFlags & SQLITE_PRINTF_INTERNAL; + }else{ + bArgList = useIntern = 0; + } for(; (c=(*fmt))!=0; ++fmt){ if( c!='%' ){ int amt; @@ -238,7 +266,11 @@ void sqlite3VXPrintf( /* Get the field width */ width = 0; if( c=='*' ){ - width = va_arg(ap,int); + if( bArgList ){ + width = (int)getIntArg(pArgList); + }else{ + width = va_arg(ap,int); + } if( width<0 ){ flag_leftjustify = 1; width = -width; @@ -255,7 +287,11 @@ void sqlite3VXPrintf( precision = 0; c = *++fmt; if( c=='*' ){ - precision = va_arg(ap,int); + if( bArgList ){ + precision = (int)getIntArg(pArgList); + }else{ + precision = va_arg(ap,int); + } if( precision<0 ) precision = -precision; c = *++fmt; }else{ @@ -286,7 +322,7 @@ void sqlite3VXPrintf( for(idx=0; idxflags & FLAG_INTERN)==0 ){ + if( useIntern || (infop->flags & FLAG_INTERN)==0 ){ xtype = infop->type; }else{ return; @@ -326,7 +362,9 @@ void sqlite3VXPrintf( case etRADIX: if( infop->flags & FLAG_SIGNED ){ i64 v; - if( flag_longlong ){ + if( bArgList ){ + v = getIntArg(pArgList); + }else if( flag_longlong ){ v = va_arg(ap,i64); }else if( flag_long ){ v = va_arg(ap,long int); @@ -347,7 +385,9 @@ void sqlite3VXPrintf( else prefix = 0; } }else{ - if( flag_longlong ){ + if( bArgList ){ + longvalue = (u64)getIntArg(pArgList); + }else if( flag_longlong ){ longvalue = va_arg(ap,u64); }else if( flag_long ){ longvalue = va_arg(ap,unsigned long int); @@ -407,7 +447,11 @@ void sqlite3VXPrintf( case etFLOAT: case etEXP: case etGENERIC: - realvalue = va_arg(ap,double); + if( bArgList ){ + realvalue = getDoubleArg(pArgList); + }else{ + realvalue = va_arg(ap,double); + } #ifdef SQLITE_OMIT_FLOATING_POINT length = 0; #else @@ -562,7 +606,7 @@ void sqlite3VXPrintf( #endif /* !defined(SQLITE_OMIT_FLOATING_POINT) */ break; case etSIZE: - *(va_arg(ap,int*)) = pAccum->nChar; + if( !bArgList ) *(va_arg(ap,int*)) = pAccum->nChar; length = width = 0; break; case etPERCENT: @@ -571,7 +615,11 @@ void sqlite3VXPrintf( length = 1; break; case etCHARX: - c = va_arg(ap,int); + if( bArgList ){ + c = (int)getIntArg(pArgList); + }else{ + c = va_arg(ap,int); + } buf[0] = (char)c; if( precision>=0 ){ for(idx=1; idx=0 ){ @@ -602,7 +654,13 @@ void sqlite3VXPrintf( int needQuote; char ch; char q = ((xtype==etSQLESCAPE3)?'"':'\''); /* Quote character */ - char *escarg = va_arg(ap,char*); + char *escarg; + + if( bArgList ){ + escarg = getTextArg(pArgList); + }else{ + escarg = va_arg(ap,char*); + } isnull = escarg==0; if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)"); k = precision; @@ -637,6 +695,7 @@ void sqlite3VXPrintf( } case etTOKEN: { Token *pToken = va_arg(ap, Token*); + assert( bArgList==0 ); if( pToken && pToken->n ){ sqlite3StrAccumAppend(pAccum, (const char*)pToken->z, pToken->n); } @@ -647,6 +706,7 @@ void sqlite3VXPrintf( SrcList *pSrc = va_arg(ap, SrcList*); int k = va_arg(ap, int); struct SrcList_item *pItem = &pSrc->a[k]; + assert( bArgList==0 ); assert( k>=0 && knSrc ); if( pItem->zDatabase ){ sqlite3StrAccumAppendAll(pAccum, pItem->zDatabase); @@ -810,7 +870,7 @@ char *sqlite3VMPrintf(sqlite3 *db, const char *zFormat, va_list ap){ sqlite3StrAccumInit(&acc, zBase, sizeof(zBase), db->aLimit[SQLITE_LIMIT_LENGTH]); acc.db = db; - sqlite3VXPrintf(&acc, 1, zFormat, ap); + sqlite3VXPrintf(&acc, SQLITE_PRINTF_INTERNAL, zFormat, ap); z = sqlite3StrAccumFinish(&acc); if( acc.accError==STRACCUM_NOMEM ){ db->mallocFailed = 1; @@ -966,14 +1026,12 @@ void sqlite3DebugPrintf(const char *zFormat, ...){ } #endif -#ifndef SQLITE_OMIT_TRACE /* ** variable-argument wrapper around sqlite3VXPrintf(). */ -void sqlite3XPrintf(StrAccum *p, const char *zFormat, ...){ +void sqlite3XPrintf(StrAccum *p, u32 bFlags, const char *zFormat, ...){ va_list ap; va_start(ap,zFormat); - sqlite3VXPrintf(p, 1, zFormat, ap); + sqlite3VXPrintf(p, bFlags, zFormat, ap); va_end(ap); } -#endif diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 8e1436efd3..af018edf01 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -742,6 +742,7 @@ typedef struct LookasideSlot LookasideSlot; typedef struct Module Module; typedef struct NameContext NameContext; typedef struct Parse Parse; +typedef struct PrintfArguments PrintfArguments; typedef struct RowSet RowSet; typedef struct Savepoint Savepoint; typedef struct Select Select; @@ -2764,10 +2765,20 @@ void sqlite3StatusSet(int, int); # define sqlite3IsNaN(X) 0 #endif -void sqlite3VXPrintf(StrAccum*, int, const char*, va_list); -#ifndef SQLITE_OMIT_TRACE -void sqlite3XPrintf(StrAccum*, const char*, ...); -#endif +/* +** An instance of the following structure holds information about SQL +** functions arguments that are the parameters to the printf() function. +*/ +struct PrintfArguments { + int nArg; /* Total number of arguments */ + int nUsed; /* Number of arguments used so far */ + sqlite3_value **apArg; /* The argument values */ +}; + +#define SQLITE_PRINTF_INTERNAL 0x01 +#define SQLITE_PRINTF_SQLFUNC 0x02 +void sqlite3VXPrintf(StrAccum*, u32, const char*, va_list); +void sqlite3XPrintf(StrAccum*, u32, const char*, ...); char *sqlite3MPrintf(sqlite3*,const char*, ...); char *sqlite3VMPrintf(sqlite3*,const char*, va_list); char *sqlite3MAppendf(sqlite3*,char*,const char*,...); diff --git a/src/vdbetrace.c b/src/vdbetrace.c index a7ff0a685d..4a39e26521 100644 --- a/src/vdbetrace.c +++ b/src/vdbetrace.c @@ -125,9 +125,9 @@ char *sqlite3VdbeExpandSql( if( pVar->flags & MEM_Null ){ sqlite3StrAccumAppend(&out, "NULL", 4); }else if( pVar->flags & MEM_Int ){ - sqlite3XPrintf(&out, "%lld", pVar->u.i); + sqlite3XPrintf(&out, 0, "%lld", pVar->u.i); }else if( pVar->flags & MEM_Real ){ - sqlite3XPrintf(&out, "%!.15g", pVar->r); + sqlite3XPrintf(&out, 0, "%!.15g", pVar->r); }else if( pVar->flags & MEM_Str ){ int nOut; /* Number of bytes of the string text to include in output */ #ifndef SQLITE_OMIT_UTF16 @@ -148,15 +148,17 @@ char *sqlite3VdbeExpandSql( while( nOutn && (pVar->z[nOut]&0xc0)==0x80 ){ nOut++; } } #endif - sqlite3XPrintf(&out, "'%.*q'", nOut, pVar->z); + sqlite3XPrintf(&out, 0, "'%.*q'", nOut, pVar->z); #ifdef SQLITE_TRACE_SIZE_LIMIT - if( nOutn ) sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-nOut); + if( nOutn ){ + sqlite3XPrintf(&out, 0, "/*+%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); + sqlite3XPrintf(&out, 0, "zeroblob(%d)", pVar->u.nZero); }else{ int nOut; /* Number of bytes of the blob to include in output */ assert( pVar->flags & MEM_Blob ); @@ -166,11 +168,13 @@ char *sqlite3VdbeExpandSql( if( nOut>SQLITE_TRACE_SIZE_LIMIT ) nOut = SQLITE_TRACE_SIZE_LIMIT; #endif for(i=0; iz[i]&0xff); + sqlite3XPrintf(&out, 0, "%02x", pVar->z[i]&0xff); } sqlite3StrAccumAppend(&out, "'", 1); #ifdef SQLITE_TRACE_SIZE_LIMIT - if( nOutn ) sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-nOut); + if( nOutn ){ + sqlite3XPrintf(&out, 0, "/*+%d bytes*/", pVar->n-nOut); + } #endif } } @@ -229,7 +233,7 @@ void sqlite3ExplainPrintf(Vdbe *pVdbe, const char *zFormat, ...){ sqlite3AppendSpace(&p->str, p->aIndent[n-1]); } va_start(ap, zFormat); - sqlite3VXPrintf(&p->str, 1, zFormat, ap); + sqlite3VXPrintf(&p->str, SQLITE_PRINTF_INTERNAL, zFormat, ap); va_end(ap); } } diff --git a/test/printf2.test b/test/printf2.test new file mode 100644 index 0000000000..6a017f152e --- /dev/null +++ b/test/printf2.test @@ -0,0 +1,56 @@ +# 2013-12-17 +# +# 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 printf() SQL function. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +do_execsql_test printf2-1.1 { + SELECT printf(); +} {{}} +do_execsql_test printf2-1.2 { + SELECT printf('hello'); +} {hello} +do_execsql_test printf2-1.3 { + SELECT printf('%d,%d,%d',55,-11,3421); +} {55,-11,3421} +do_execsql_test printf2-1.4 { + SELECT printf('%d,%d,%d',55,'-11',3421); +} {55,-11,3421} +do_execsql_test printf2-1.5 { + SELECT printf('%d,%d,%d,%d',55,'-11',3421); +} {55,-11,3421,0} +do_execsql_test printf2-1.6 { + SELECT printf('%.2f',3.141592653); +} {3.14} +do_execsql_test printf2-1.7 { + SELECT printf('%.*f',2,3.141592653); +} {3.14} +do_execsql_test printf2-1.8 { + SELECT printf('%*.*f',5,2,3.141592653); +} {{ 3.14}} +do_execsql_test printf2-1.9 { + SELECT printf('%d',314159.2653); +} {314159} +do_execsql_test printf2-1.10 { + SELECT printf('%lld',314159.2653); +} {314159} +do_execsql_test printf2-1.11 { + SELECT printf('%lld%n',314159.2653,'hi'); +} {314159} +do_execsql_test printf2-1.12 { + SELECT printf('%.*z',5,'abcdefghijklmnop'); +} {abcde} + + +finish_test From fc6ee9df22a16cba04e51a64aaa571fe8e78dcc1 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 17 Dec 2013 15:58:42 +0000 Subject: [PATCH 087/276] Fix the formatting of %c in the printf() SQL function. FossilOrigin-Name: 3375571a5e267744c19a7c310840256cec57a242 --- manifest | 17 +++++++---------- manifest.uuid | 2 +- src/printf.c | 7 +++++-- test/printf2.test | 3 +++ 4 files changed, 16 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 04c30af9ed..e7519c3fa2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sprintf()\sSQL\sfunction. -D 2013-12-17T15:03:06.814 +C Fix\sthe\sformatting\sof\s%c\sin\sthe\sprintf()\sSQL\sfunction. +D 2013-12-17T15:58:42.950 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -215,7 +215,7 @@ F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222 F src/pcache1.c 57fee9a9a617218f5037afbbe49b09da65bde56b F src/pragma.c 5ab7279d132143feb77f773688a24ab05da75fd7 F src/prepare.c 359d1a1e9c9bd4488e4dd3a1aaaf2d2ebb9bb768 -F src/printf.c 0c0cb58e43410d6237afe0f2751f265fc62eac59 +F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c 0b2dbc37fdfbfa6bd455b091dfcef5bdb32dba68 F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 @@ -739,7 +739,7 @@ F test/permutations.test af3278cbea3a19e025d5169be8193ff48dc3f862 F test/pragma.test e882183ecd21d064cec5c7aaea174fbd36293429 F test/pragma2.test aea7b3d82c76034a2df2b38a13745172ddc0bc13 F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552 -F test/printf2.test 7b1c2c27826702723ad2b1fcd92bce2ffc9f45f3 +F test/printf2.test 2f0978059768bb039d3ee09466bdcd06fc7a6a86 F test/progress.test a282973d1d17f08071bc58a77d6b80f2a81c354d F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc F test/queryonly.test 5f653159e0f552f0552d43259890c1089391dcca @@ -1147,10 +1147,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 5716fc2341ddd8cf64139e7168597f864da4e10b -R 2b8d4659fa3fad9afbe93191f7aa6089 -T *branch * printf-sql-function -T *sym-printf-sql-function * -T -sym-trunk * +P 6db7052eeefafdbf26b3153bc38600fecfb53ae6 +R 2f73ea36e182ebaad881490b3d78bb71 U drh -Z 77c6ba366806353f9c00efecee393357 +Z 671b11d5131d6faea51d8a864c8026f9 diff --git a/manifest.uuid b/manifest.uuid index ce69d4e663..56747e8410 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6db7052eeefafdbf26b3153bc38600fecfb53ae6 \ No newline at end of file +3375571a5e267744c19a7c310840256cec57a242 \ No newline at end of file diff --git a/src/printf.c b/src/printf.c index da118818bb..8cfa542b41 100644 --- a/src/printf.c +++ b/src/printf.c @@ -606,7 +606,9 @@ void sqlite3VXPrintf( #endif /* !defined(SQLITE_OMIT_FLOATING_POINT) */ break; case etSIZE: - if( !bArgList ) *(va_arg(ap,int*)) = pAccum->nChar; + if( !bArgList ){ + *(va_arg(ap,int*)) = pAccum->nChar; + } length = width = 0; break; case etPERCENT: @@ -616,7 +618,8 @@ void sqlite3VXPrintf( break; case etCHARX: if( bArgList ){ - c = (int)getIntArg(pArgList); + bufpt = getTextArg(pArgList); + c = bufpt ? bufpt[0] : 0; }else{ c = va_arg(ap,int); } diff --git a/test/printf2.test b/test/printf2.test index 6a017f152e..15babcf485 100644 --- a/test/printf2.test +++ b/test/printf2.test @@ -51,6 +51,9 @@ do_execsql_test printf2-1.11 { do_execsql_test printf2-1.12 { SELECT printf('%.*z',5,'abcdefghijklmnop'); } {abcde} +do_execsql_test printf2-1.13 { + SELECT printf('%c','abcdefghijklmnop'); +} {a} finish_test From 3a8aec5e132e3166efa51906029fbfd48639a3e5 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 17 Dec 2013 16:32:56 +0000 Subject: [PATCH 088/276] Add evidence marks and additional test cases for the printf() SQL function. FossilOrigin-Name: 93121d3097a43997af3c0de65bd9bd7663845fa2 --- manifest | 13 ++++++------- manifest.uuid | 2 +- test/printf2.test | 44 ++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 49 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 1fb5758b05..ce19a94c13 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sprintf()\sSQL\sfunction. -D 2013-12-17T16:10:57.193 +C Add\sevidence\smarks\sand\sadditional\stest\scases\sfor\sthe\sprintf()\sSQL\sfunction. +D 2013-12-17T16:32:56.710 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -739,7 +739,7 @@ F test/permutations.test af3278cbea3a19e025d5169be8193ff48dc3f862 F test/pragma.test e882183ecd21d064cec5c7aaea174fbd36293429 F test/pragma2.test aea7b3d82c76034a2df2b38a13745172ddc0bc13 F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552 -F test/printf2.test 2f0978059768bb039d3ee09466bdcd06fc7a6a86 +F test/printf2.test 414fcba6d6c10e0a5e58efd213811e5ead4635a0 F test/progress.test a282973d1d17f08071bc58a77d6b80f2a81c354d F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc F test/queryonly.test 5f653159e0f552f0552d43259890c1089391dcca @@ -1147,8 +1147,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 5716fc2341ddd8cf64139e7168597f864da4e10b 3375571a5e267744c19a7c310840256cec57a242 -R 2f73ea36e182ebaad881490b3d78bb71 -T +closed 3375571a5e267744c19a7c310840256cec57a242 +P a1bb62f91a85af0584100c3ad77877a949c30cca +R 69f0b68d0886123f335b52e69a6c748f U drh -Z 3980fde025c24face9a02012ab95cda1 +Z 3ce3ba9d696aa32fcf98b10717e459c0 diff --git a/manifest.uuid b/manifest.uuid index ceab92b6f6..5e71d304d7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a1bb62f91a85af0584100c3ad77877a949c30cca \ No newline at end of file +93121d3097a43997af3c0de65bd9bd7663845fa2 \ No newline at end of file diff --git a/test/printf2.test b/test/printf2.test index 15babcf485..8985d083cf 100644 --- a/test/printf2.test +++ b/test/printf2.test @@ -11,13 +11,23 @@ # This file implements regression tests for SQLite library. The # focus of this file is testing the printf() SQL function. # +# +# EVIDENCE-OF: R-63057-40065 The printf(FORMAT,...) SQL function works +# like the sqlite3_mprintf() C-language function and the printf() +# function from the standard C library. +# set testdir [file dirname $argv0] source $testdir/tester.tcl +# EVIDENCE-OF: R-40086-60101 If the FORMAT argument is missing or NULL +# then the result is NULL. +# do_execsql_test printf2-1.1 { - SELECT printf(); -} {{}} + SELECT quote(printf()), quote(printf(NULL,1,2,3)); +} {NULL NULL} + + do_execsql_test printf2-1.2 { SELECT printf('hello'); } {hello} @@ -48,6 +58,9 @@ do_execsql_test printf2-1.10 { do_execsql_test printf2-1.11 { SELECT printf('%lld%n',314159.2653,'hi'); } {314159} + +# EVIDENCE-OF: R-20555-31089 The %z format is interchangable with %s. +# do_execsql_test printf2-1.12 { SELECT printf('%.*z',5,'abcdefghijklmnop'); } {abcde} @@ -55,5 +68,32 @@ do_execsql_test printf2-1.13 { SELECT printf('%c','abcdefghijklmnop'); } {a} +# EVIDENCE-OF: R-02347-27622 The %n format is silently ignored and does +# not consume an argument. +# +do_execsql_test printf2-2.1 { + CREATE TABLE t1(a,b,c); + INSERT INTO t1 VALUES(1,2,3); + INSERT INTO t1 VALUES(-1,-2,-3); + INSERT INTO t1 VALUES('abc','def','ghi'); + INSERT INTO t1 VALUES(1.5,2.25,3.125); + SELECT printf('(%s)-%n-(%s)',a,b,c) FROM t1 ORDER BY rowid; +} {(1)--(2) (-1)--(-2) (abc)--(def) (1.5)--(2.25)} + +# EVIDENCE-OF: R-56064-04001 The %p format is an alias for %X. +# +do_execsql_test printf2-2.2 { + SELECT printf('%s=(%p)',a,a) FROM t1 ORDER BY a; +} {-1=(FFFFFFFFFFFFFFFF) 1=(1) 1.5=(1) abc=(0)} + +# EVIDENCE-OF: R-29410-53018 If there are too few arguments in the +# argument list, missing arguments are assumed to have a NULL value, +# which is translated into 0 or 0.0 for numeric formats or an empty +# string for %s. +# +do_execsql_test printf2-2.3 { + SELECT printf('%s=(%d/%g/%s)',a) FROM t1 ORDER BY a; +} {-1=(0/0/) 1=(0/0/) 1.5=(0/0/) abc=(0/0/)} + finish_test From 9ac7962acea518754b1f5a7a2748164cdb053b52 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 18 Dec 2013 15:11:47 +0000 Subject: [PATCH 089/276] Show changes to the column cache when PRAGMA vdbe_addoptrace=ON is set. FossilOrigin-Name: 4c6a659c432e4f7c0285f58675a67f967b07bb0d --- manifest | 25 ++++++++++++++----------- manifest.uuid | 2 +- src/expr.c | 15 +++++++++++++++ src/select.c | 2 +- src/vdbe.h | 2 +- src/vdbeInt.h | 3 +++ src/vdbeaux.c | 15 ++++++++++++++- src/vdbeblob.c | 2 +- 8 files changed, 50 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index ce19a94c13..628e69c170 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sevidence\smarks\sand\sadditional\stest\scases\sfor\sthe\sprintf()\sSQL\sfunction. -D 2013-12-17T16:32:56.710 +C Show\schanges\sto\sthe\scolumn\scache\swhen\sPRAGMA\svdbe_addoptrace=ON\sis\sset. +D 2013-12-18T15:11:47.634 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -175,7 +175,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 F src/delete.c b36db1f79ee50eaca979660c9dd36437f5410b93 -F src/expr.c 31a2b65339f6c3795d4cfa5e99798cd72f9fdfdf +F src/expr.c 962c29881bcee9e1d7b556020c1d29dc8bd8b906 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 2ab0f5384b70594468ef3ac5c7ed8ca24bfd17d5 F src/func.c 6325ac2ec10833ccf4d5c36d323709221d37ea19 @@ -219,7 +219,7 @@ F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c 0b2dbc37fdfbfa6bd455b091dfcef5bdb32dba68 F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c d41381d80a22d3a83352aeca274cccf264ac277a +F src/select.c c1cd470c699ad55beb762022b2ea820cdfe12895 F src/shell.c 18924f6ccfa70da98bf9e388bab512c0fd1e792e F src/sqlite.h.in 4ef56464aeaa3785a2c5ca37fb3a0fb229d68b2e F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e @@ -281,11 +281,11 @@ F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c e71f19b272f05c8695cf747b4bac1732685f9e5c F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 F src/vdbe.c 919422843c859a1db08db0c88189912dbf625fc7 -F src/vdbe.h c06f0813f853566457ce9cfb1a4a4bc39a5da644 -F src/vdbeInt.h a7bc268f844d75be48bb7ae16f77b418fd3c641c +F src/vdbe.h c3278ab2b410f17acf61faf91be7bce3fd466e8b +F src/vdbeInt.h 8a4d2d69955570bb74a092c3cdbab04afb554963 F src/vdbeapi.c ce4e68ea4842cc6081046f533d088dcf01d247ad -F src/vdbeaux.c a22cbd91b24503b82690cb03324ffec9f4ef63f6 -F src/vdbeblob.c 8cd05a5630e6d5563ad017bf82edaf812b28acde +F src/vdbeaux.c 70aa77f7db7b9b627bbc44a4546deef8ba56c51b +F src/vdbeblob.c bc40f98f256f0b34116d6a44b114da4a81a15d33 F src/vdbemem.c 0e69351b2c6ff7d8b638688c0ae336a26befa6b2 F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147 F src/vdbetrace.c 6f52bc0c51e144b7efdcfb2a8f771167a8816767 @@ -1147,7 +1147,10 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P a1bb62f91a85af0584100c3ad77877a949c30cca -R 69f0b68d0886123f335b52e69a6c748f +P 93121d3097a43997af3c0de65bd9bd7663845fa2 +R 509cbb701cd3c7ed8d65fb3eb1823d74 +T *branch * column-cache-debug +T *sym-column-cache-debug * +T -sym-trunk * U drh -Z 3ce3ba9d696aa32fcf98b10717e459c0 +Z ece27495bc3ec8587c593a30b1f41a23 diff --git a/manifest.uuid b/manifest.uuid index 5e71d304d7..e92963a40e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -93121d3097a43997af3c0de65bd9bd7663845fa2 \ No newline at end of file +4c6a659c432e4f7c0285f58675a67f967b07bb0d \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 6c8a8cce77..81eb00c968 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2170,6 +2170,11 @@ void sqlite3ExprCacheRemove(Parse *pParse, int iReg, int nReg){ */ void sqlite3ExprCachePush(Parse *pParse){ pParse->iCacheLevel++; +#ifdef SQLITE_DEBUG + if( pParse->db->flags & SQLITE_VdbeAddopTrace ){ + printf("PUSH to %d\n", pParse->iCacheLevel); + } +#endif } /* @@ -2183,6 +2188,11 @@ void sqlite3ExprCachePop(Parse *pParse, int N){ assert( N>0 ); assert( pParse->iCacheLevel>=N ); pParse->iCacheLevel -= N; +#ifdef SQLITE_DEBUG + if( pParse->db->flags & SQLITE_VdbeAddopTrace ){ + printf("POP to %d\n", pParse->iCacheLevel); + } +#endif for(i=0, p=pParse->aColCache; iiReg && p->iLevel>pParse->iCacheLevel ){ cacheEntryClear(pParse, p); @@ -2277,6 +2287,11 @@ void sqlite3ExprCacheClear(Parse *pParse){ int i; struct yColCache *p; +#if SQLITE_DEBUG + if( pParse->db->flags & SQLITE_VdbeAddopTrace ){ + printf("CLEAR\n"); + } +#endif for(i=0, p=pParse->aColCache; iiReg ){ cacheEntryClear(pParse, p); diff --git a/src/select.c b/src/select.c index aa8e54b02f..e0b3bde48e 100644 --- a/src/select.c +++ b/src/select.c @@ -1565,7 +1565,7 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect){ Vdbe *sqlite3GetVdbe(Parse *pParse){ Vdbe *v = pParse->pVdbe; if( v==0 ){ - v = pParse->pVdbe = sqlite3VdbeCreate(pParse->db); + v = pParse->pVdbe = sqlite3VdbeCreate(pParse); #ifndef SQLITE_OMIT_TRACE if( v ){ sqlite3VdbeAddOp0(v, OP_Trace); diff --git a/src/vdbe.h b/src/vdbe.h index 62d9aa2711..51cf60b520 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -160,7 +160,7 @@ typedef struct VdbeOpList VdbeOpList; ** Prototypes for the VDBE interface. See comments on the implementation ** for a description of what each of these routines does. */ -Vdbe *sqlite3VdbeCreate(sqlite3*); +Vdbe *sqlite3VdbeCreate(Parse*); int sqlite3VdbeAddOp0(Vdbe*,int); int sqlite3VdbeAddOp1(Vdbe*,int,int); int sqlite3VdbeAddOp2(Vdbe*,int,int,int); diff --git a/src/vdbeInt.h b/src/vdbeInt.h index d6d71a3957..7b4fad67b0 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -312,6 +312,9 @@ struct Vdbe { Mem **apArg; /* Arguments to currently executing user function */ Mem *aColName; /* Column names to return */ Mem *pResultSet; /* Pointer to an array of results */ +#ifdef SQLITE_DEBUG + Parse *pParse; /* Parsing context used to create this Vdbe */ +#endif int nMem; /* Number of memory locations currently allocated */ int nOp; /* Number of instructions in the program */ int nOpAlloc; /* Number of slots allocated for aOp[] */ diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 6344c4c8fa..068059e594 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -20,7 +20,8 @@ /* ** Create a new virtual database engine. */ -Vdbe *sqlite3VdbeCreate(sqlite3 *db){ +Vdbe *sqlite3VdbeCreate(Parse *pParse){ + sqlite3 *db = pParse->db; Vdbe *p; p = sqlite3DbMallocZero(db, sizeof(Vdbe) ); if( p==0 ) return 0; @@ -32,6 +33,9 @@ Vdbe *sqlite3VdbeCreate(sqlite3 *db){ p->pPrev = 0; db->pVdbe = p; p->magic = VDBE_MAGIC_INIT; +#if SQLITE_DEBUG + p->pParse = pParse; +#endif return p; } @@ -151,6 +155,15 @@ int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){ #endif #ifdef SQLITE_DEBUG if( p->db->flags & SQLITE_VdbeAddopTrace ){ + int jj, kk; + Parse *pParse = p->pParse; + for(jj=kk=0; jjaColCache + jj; + if( x->iLevel>pParse->iCacheLevel || x->iReg==0 ) continue; + printf(" r[%d]={%d:%d}", x->iReg, x->iTable, x->iColumn); + kk++; + } + if( kk ) printf("\n"); sqlite3VdbePrintOp(0, i, &p->aOp[i]); test_addop_breakpoint(); } diff --git a/src/vdbeblob.c b/src/vdbeblob.c index 7859d4a6c5..20841c44f9 100644 --- a/src/vdbeblob.c +++ b/src/vdbeblob.c @@ -255,7 +255,7 @@ int sqlite3_blob_open( } } - pBlob->pStmt = (sqlite3_stmt *)sqlite3VdbeCreate(db); + pBlob->pStmt = (sqlite3_stmt *)sqlite3VdbeCreate(pParse); assert( pBlob->pStmt || db->mallocFailed ); if( pBlob->pStmt ){ Vdbe *v = (Vdbe *)pBlob->pStmt; From 039468ef2d682ecd35f81d6d1e41ec51707ad5e8 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 18 Dec 2013 16:27:48 +0000 Subject: [PATCH 090/276] Remove an unnecessary column-cache flush. Add another test case to the speedtest1.c program to accentuate the benefit of not flushing the cache at that point. FossilOrigin-Name: 97fdfc6b79833011fc0c506fe5e0985c0fb1906c --- manifest | 17 +++++++---------- manifest.uuid | 2 +- src/select.c | 1 - test/speedtest1.c | 10 +++++++++- 4 files changed, 17 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 628e69c170..f61e471ae1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Show\schanges\sto\sthe\scolumn\scache\swhen\sPRAGMA\svdbe_addoptrace=ON\sis\sset. -D 2013-12-18T15:11:47.634 +C Remove\san\sunnecessary\scolumn-cache\sflush.\s\sAdd\sanother\stest\scase\sto\sthe\nspeedtest1.c\sprogram\sto\saccentuate\sthe\sbenefit\sof\snot\sflushing\sthe\scache\sat\nthat\spoint. +D 2013-12-18T16:27:48.409 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -219,7 +219,7 @@ F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c 0b2dbc37fdfbfa6bd455b091dfcef5bdb32dba68 F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c c1cd470c699ad55beb762022b2ea820cdfe12895 +F src/select.c ecb020aa28e030761f6addd0adf5438e938931c1 F src/shell.c 18924f6ccfa70da98bf9e388bab512c0fd1e792e F src/sqlite.h.in 4ef56464aeaa3785a2c5ca37fb3a0fb229d68b2e F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e @@ -822,7 +822,7 @@ F test/speed3.test d32043614c08c53eafdc80f33191d5bd9b920523 F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b -F test/speedtest1.c bb3a4cc62b6cf29f5bc72c85d2bee5991e207be7 +F test/speedtest1.c 47788d552a349241471ad06d239383dadd97164d F test/spellfix.test 8c40b169b104086d8795781f670ba3c786d6d8be F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298 F test/stat.test c8eccfe8fcd3f3cfc864ce22d5b9e803a3c69940 @@ -1147,10 +1147,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 93121d3097a43997af3c0de65bd9bd7663845fa2 -R 509cbb701cd3c7ed8d65fb3eb1823d74 -T *branch * column-cache-debug -T *sym-column-cache-debug * -T -sym-trunk * +P 4c6a659c432e4f7c0285f58675a67f967b07bb0d +R ad4bcfdba61e39f0bb9e7693f91a62e0 U drh -Z ece27495bc3ec8587c593a30b1f41a23 +Z e871bbf1438be1f459e194c32e33e3c1 diff --git a/manifest.uuid b/manifest.uuid index e92963a40e..b451c0355a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4c6a659c432e4f7c0285f58675a67f967b07bb0d \ No newline at end of file +97fdfc6b79833011fc0c506fe5e0985c0fb1906c \ No newline at end of file diff --git a/src/select.c b/src/select.c index e0b3bde48e..c394d1c31b 100644 --- a/src/select.c +++ b/src/select.c @@ -598,7 +598,6 @@ static void selectInnerLoop( /* If the destination is an EXISTS(...) expression, the actual ** values returned by the SELECT are not required. */ - sqlite3ExprCacheClear(pParse); sqlite3ExprCodeExprList(pParse, pEList, regResult, (eDest==SRT_Output)?SQLITE_ECEL_DUP:0); } diff --git a/test/speedtest1.c b/test/speedtest1.c index 0e6b1a99c8..51735de02a 100644 --- a/test/speedtest1.c +++ b/test/speedtest1.c @@ -663,9 +663,17 @@ void testset_main(void){ speedtest1_exec("REPLACE INTO t3(a,b,c) SELECT a,b,c FROM t1"); speedtest1_end_test(); + speedtest1_begin_test(300, "Refill a %d-row table using (b&1)==(a&1)", sz); + speedtest1_exec("DELETE FROM t2;"); + speedtest1_exec( + "INSERT INTO t2(a,b,c) SELECT a,b,c FROM t1 WHERE (b&1)==(a&1);" + "INSERT INTO t2(a,b,c) SELECT a,b,c FROM t1 WHERE (b&1)<>(a&1);" + ); + speedtest1_end_test(); + n = sz/5; - speedtest1_begin_test(300, "%d four-ways joins", n); + speedtest1_begin_test(310, "%d four-ways joins", n); speedtest1_exec("BEGIN"); speedtest1_prepare( "SELECT t1.c FROM t1, t2, t3, t4\n" From 46d03fcbfc6cfcaab7d475cd9c2e3b62b946be47 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 19 Dec 2013 02:23:45 +0000 Subject: [PATCH 091/276] Omit one or more pointless instructions that occur in between OP_NoConflict and OP_Halt. FossilOrigin-Name: 61e2f3575c4a94f9571c28fb2bd19da84b0edceb --- manifest | 13 ++++----- manifest.uuid | 2 +- src/insert.c | 80 ++++++++++++++++++++++++++------------------------- 3 files changed, 48 insertions(+), 47 deletions(-) diff --git a/manifest b/manifest index a1d9fbcef1..8a760c5b7d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunnecessary\scolumn-cache\sflush\soperation.\s\sAdd\scode\sto\strace\sthe\ncolumn\scache\swhen\scompiled\swith\sSQLITE_DEBUG\sand\susing\nPRAGMA\svdbe_addoptrace=ON. -D 2013-12-18T18:44:43.134 +C Omit\sone\sor\smore\spointless\sinstructions\sthat\soccur\sin\sbetween\sOP_NoConflict\nand\sOP_Halt. +D 2013-12-19T02:23:45.916 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -183,7 +183,7 @@ F src/global.c 1d7bb7ea8254ae6a68ed9bfaf65fcb3d1690b486 F src/hash.c ac3470bbf1ca4ae4e306a8ecb0fdf1731810ffe4 F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c 3cf8012325857d162f74389420b14be7976a538d +F src/insert.c d1b3fd53cd8e3f232e47675cf2c3d1b1f4101f2a F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b @@ -1147,8 +1147,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 93121d3097a43997af3c0de65bd9bd7663845fa2 97fdfc6b79833011fc0c506fe5e0985c0fb1906c -R ad4bcfdba61e39f0bb9e7693f91a62e0 -T +closed 97fdfc6b79833011fc0c506fe5e0985c0fb1906c +P 58704ed1f4cd78bb3b0c095ffd1626906a95a413 +R 464abf9a1fd9120477908520316caad2 U drh -Z d67945416ae9c517bb5d46293eed5eb3 +Z 1a25f8b4acb360c6ad6b1c4bc1cd07e9 diff --git a/manifest.uuid b/manifest.uuid index c14fd41eab..6fd6c73113 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -58704ed1f4cd78bb3b0c095ffd1626906a95a413 \ No newline at end of file +61e2f3575c4a94f9571c28fb2bd19da84b0edceb \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index b1a9104f71..fe1f74addb 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1503,47 +1503,49 @@ void sqlite3GenerateConstraintChecks( /* Generate code to handle collisions */ regR = (pIdx==pPk) ? regIdx : sqlite3GetTempRange(pParse, nPkField); - if( HasRowid(pTab) ){ - sqlite3VdbeAddOp2(v, OP_IdxRowid, iThisCur, regR); - /* Conflict only if the rowid of the existing index entry - ** is different from old-rowid */ - if( isUpdate ){ - sqlite3VdbeAddOp3(v, OP_Eq, regR, addrUniqueOk, regOldData); - } - }else{ - int x; - /* Extract the PRIMARY KEY from the end of the index entry and - ** store it in registers regR..regR+nPk-1 */ - if( (isUpdate || onError==OE_Replace) && pIdx!=pPk ){ - for(i=0; inKeyCol; i++){ - x = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[i]); - sqlite3VdbeAddOp3(v, OP_Column, iThisCur, x, regR+i); - VdbeComment((v, "%s.%s", pTab->zName, - pTab->aCol[pPk->aiColumn[i]].zName)); + if( isUpdate || onError==OE_Replace ){ + if( HasRowid(pTab) ){ + sqlite3VdbeAddOp2(v, OP_IdxRowid, iThisCur, regR); + /* Conflict only if the rowid of the existing index entry + ** is different from old-rowid */ + if( isUpdate ){ + sqlite3VdbeAddOp3(v, OP_Eq, regR, addrUniqueOk, regOldData); } - } - if( isUpdate ){ - /* If currently processing the PRIMARY KEY of a WITHOUT ROWID - ** table, only conflict if the new PRIMARY KEY values are actually - ** different from the old. - ** - ** For a UNIQUE index, only conflict if the PRIMARY KEY values - ** of the matched index row are different from the original PRIMARY - ** KEY values of this row before the update. */ - int addrJump = sqlite3VdbeCurrentAddr(v)+pPk->nKeyCol; - int op = OP_Ne; - int regCmp = (pIdx->autoIndex==2 ? regIdx : regR); - - for(i=0; inKeyCol; i++){ - char *p4 = (char*)sqlite3LocateCollSeq(pParse, pPk->azColl[i]); - x = pPk->aiColumn[i]; - if( i==(pPk->nKeyCol-1) ){ - addrJump = addrUniqueOk; - op = OP_Eq; + }else{ + int x; + /* Extract the PRIMARY KEY from the end of the index entry and + ** store it in registers regR..regR+nPk-1 */ + if( (isUpdate || onError==OE_Replace) && pIdx!=pPk ){ + for(i=0; inKeyCol; i++){ + x = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[i]); + sqlite3VdbeAddOp3(v, OP_Column, iThisCur, x, regR+i); + VdbeComment((v, "%s.%s", pTab->zName, + pTab->aCol[pPk->aiColumn[i]].zName)); + } + } + if( isUpdate ){ + /* If currently processing the PRIMARY KEY of a WITHOUT ROWID + ** table, only conflict if the new PRIMARY KEY values are actually + ** different from the old. + ** + ** For a UNIQUE index, only conflict if the PRIMARY KEY values + ** of the matched index row are different from the original PRIMARY + ** KEY values of this row before the update. */ + int addrJump = sqlite3VdbeCurrentAddr(v)+pPk->nKeyCol; + int op = OP_Ne; + int regCmp = (pIdx->autoIndex==2 ? regIdx : regR); + + for(i=0; inKeyCol; i++){ + char *p4 = (char*)sqlite3LocateCollSeq(pParse, pPk->azColl[i]); + x = pPk->aiColumn[i]; + if( i==(pPk->nKeyCol-1) ){ + addrJump = addrUniqueOk; + op = OP_Eq; + } + sqlite3VdbeAddOp4(v, op, + regOldData+1+x, addrJump, regCmp+i, p4, P4_COLLSEQ + ); } - sqlite3VdbeAddOp4(v, op, - regOldData+1+x, addrJump, regCmp+i, p4, P4_COLLSEQ - ); } } } From edfac3456e86de8b242e8129d25da1d55e0f1ac4 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 19 Dec 2013 02:56:01 +0000 Subject: [PATCH 092/276] Omit an unnecessary OP_Null opcode from UPDATE. FossilOrigin-Name: 72d111336c5016e5b5092dfebcd01253266a7685 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/update.c | 6 ++++-- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 8a760c5b7d..9374f21e09 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Omit\sone\sor\smore\spointless\sinstructions\sthat\soccur\sin\sbetween\sOP_NoConflict\nand\sOP_Halt. -D 2013-12-19T02:23:45.916 +C Omit\san\sunnecessary\sOP_Null\sopcode\sfrom\sUPDATE. +D 2013-12-19T02:56:01.711 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -276,7 +276,7 @@ F src/test_vfstrace.c 3a0ab304682fecbceb689e7d9b904211fde11d78 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/tokenize.c ec4c1a62b890bf1dbcdb966399e140b904c700a4 F src/trigger.c d84e1f3669e9a217731a14a9d472b1c7b87c87ba -F src/update.c d1c2477dcf14d90999d1935af4efb4806553250b +F src/update.c 47baf532e3ecec8e4093f92d613384f66785fc2f F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c e71f19b272f05c8695cf747b4bac1732685f9e5c F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 @@ -1147,7 +1147,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 58704ed1f4cd78bb3b0c095ffd1626906a95a413 -R 464abf9a1fd9120477908520316caad2 +P 61e2f3575c4a94f9571c28fb2bd19da84b0edceb +R df16247ba6ed01ab9a8dff3d1c0e5ea9 U drh -Z 1a25f8b4acb360c6ad6b1c4bc1cd07e9 +Z 56ef984ce433e185375b049dfac62028 diff --git a/manifest.uuid b/manifest.uuid index 6fd6c73113..7255723874 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -61e2f3575c4a94f9571c28fb2bd19da84b0edceb \ No newline at end of file +72d111336c5016e5b5092dfebcd01253266a7685 \ No newline at end of file diff --git a/src/update.c b/src/update.c index 4459a9fb86..b7f0363c1a 100644 --- a/src/update.c +++ b/src/update.c @@ -496,10 +496,10 @@ void sqlite3Update( newmask = sqlite3TriggerColmask( pParse, pTrigger, pChanges, 1, TRIGGER_BEFORE, pTab, onError ); - sqlite3VdbeAddOp3(v, OP_Null, 0, regNew, regNew+pTab->nCol-1); + /*sqlite3VdbeAddOp3(v, OP_Null, 0, regNew, regNew+pTab->nCol-1);*/ for(i=0; inCol; i++){ if( i==pTab->iPKey ){ - /*sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i);*/ + sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i); }else{ j = aXRef[i]; if( j>=0 ){ @@ -513,6 +513,8 @@ void sqlite3Update( testcase( i==31 ); testcase( i==32 ); sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, regNew+i); + }else{ + sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i); } } } From a021f121c96a5fe4a1176f30a257b5fe8eb3d2d5 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 19 Dec 2013 14:34:34 +0000 Subject: [PATCH 093/276] Remove an unneeded column-cache flush in aggregate SELECT and an unreachable branch in the INSERT logic. FossilOrigin-Name: ffa092e13b3781677b18418cca40e3dd1e388aed --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/insert.c | 2 +- src/select.c | 1 - 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 9374f21e09..2df9dab23f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Omit\san\sunnecessary\sOP_Null\sopcode\sfrom\sUPDATE. -D 2013-12-19T02:56:01.711 +C Remove\san\sunneeded\scolumn-cache\sflush\sin\saggregate\sSELECT\nand\san\sunreachable\sbranch\sin\sthe\sINSERT\slogic. +D 2013-12-19T14:34:34.832 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -183,7 +183,7 @@ F src/global.c 1d7bb7ea8254ae6a68ed9bfaf65fcb3d1690b486 F src/hash.c ac3470bbf1ca4ae4e306a8ecb0fdf1731810ffe4 F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c d1b3fd53cd8e3f232e47675cf2c3d1b1f4101f2a +F src/insert.c f165ba414eda735b327c8126def0a2428f9138de F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b @@ -219,7 +219,7 @@ F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c 0b2dbc37fdfbfa6bd455b091dfcef5bdb32dba68 F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c ecb020aa28e030761f6addd0adf5438e938931c1 +F src/select.c 9d13850293cf19e5ffee59b231fa372e16ce65a9 F src/shell.c 18924f6ccfa70da98bf9e388bab512c0fd1e792e F src/sqlite.h.in 4ef56464aeaa3785a2c5ca37fb3a0fb229d68b2e F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e @@ -1147,7 +1147,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 61e2f3575c4a94f9571c28fb2bd19da84b0edceb -R df16247ba6ed01ab9a8dff3d1c0e5ea9 +P 72d111336c5016e5b5092dfebcd01253266a7685 +R a48136d424494fa9261ddc391e19f98d U drh -Z 56ef984ce433e185375b049dfac62028 +Z 822c060ba762ff386aec37ff13c59f91 diff --git a/manifest.uuid b/manifest.uuid index 7255723874..33bc14bfb2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -72d111336c5016e5b5092dfebcd01253266a7685 \ No newline at end of file +ffa092e13b3781677b18418cca40e3dd1e388aed \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index fe1f74addb..b3b8444f34 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1515,7 +1515,7 @@ void sqlite3GenerateConstraintChecks( int x; /* Extract the PRIMARY KEY from the end of the index entry and ** store it in registers regR..regR+nPk-1 */ - if( (isUpdate || onError==OE_Replace) && pIdx!=pPk ){ + if( pIdx!=pPk ){ for(i=0; inKeyCol; i++){ x = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[i]); sqlite3VdbeAddOp3(v, OP_Column, iThisCur, x, regR+i); diff --git a/src/select.c b/src/select.c index c394d1c31b..132d546971 100644 --- a/src/select.c +++ b/src/select.c @@ -3875,7 +3875,6 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){ struct AggInfo_col *pC; pAggInfo->directMode = 1; - sqlite3ExprCacheClear(pParse); for(i=0, pF=pAggInfo->aFunc; inFunc; i++, pF++){ int nArg; int addrNext = 0; From f6b1a8e1a58aa577e35224d534b9e2cb5ee8d75b Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 19 Dec 2013 16:26:05 +0000 Subject: [PATCH 094/276] Make sure errors encountered while initializing extensions such as FTS4 get reported out from sqlite3_open(). This fixes a bug introduced by check-in [9d347f547e7ba9]. Also remove lots of forgotten "breakpoint" commands left in test scripts over the years. FossilOrigin-Name: ca3fdfd41961d8d3d1e39d20dc628e8a95dabb2f --- manifest | 50 ++++++++++++++++++++-------------------- manifest.uuid | 2 +- src/main.c | 2 ++ test/attach3.test | 1 - test/capi3.test | 1 - test/collate1.test | 1 - test/exclusive2.test | 1 - test/fts3aa.test | 1 - test/fts3ab.test | 1 - test/fts3ag.test | 1 - test/fts3d.test | 1 - test/fts3near.test | 1 - test/fts3tok1.test | 1 - test/fts4unicode.test | 5 ---- test/mmapfault.test | 1 - test/securedel.test | 1 - test/stat.test | 1 - test/tkt-94c04eaadb.test | 1 - test/vtab_shared.test | 1 - test/wal.test | 1 - test/wal2.test | 1 - test/walfault.test | 1 - 22 files changed, 28 insertions(+), 49 deletions(-) diff --git a/manifest b/manifest index 2df9dab23f..7f912e08b8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunneeded\scolumn-cache\sflush\sin\saggregate\sSELECT\nand\san\sunreachable\sbranch\sin\sthe\sINSERT\slogic. -D 2013-12-19T14:34:34.832 +C Make\ssure\serrors\sencountered\swhile\sinitializing\sextensions\ssuch\sas\sFTS4\nget\sreported\sout\sfrom\ssqlite3_open().\s\sThis\sfixes\sa\sbug\sintroduced\sby\ncheck-in\s[9d347f547e7ba9].\s\sAlso\sremove\slots\sof\sforgotten\s"breakpoint"\ncommands\sleft\sin\stest\sscripts\sover\sthe\syears. +D 2013-12-19T16:26:05.208 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -188,7 +188,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b F src/loadext.c 867c7b330b740c6c917af9956b13b81d0a048303 -F src/main.c 45e08d8ca4808625c4512a14898e9c61553e3d2a +F src/main.c 3f00c4adfb5e5dc35b475dbdd475aba83ccf3d17 F src/malloc.c 0203ebce9152c6a0e5de520140b8ba65187350be F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c0c990fcaddff810ea277b4fb5d9138603dd5d4b @@ -324,7 +324,7 @@ F test/async5.test 383ab533fdb9f7ad228cc99ee66e1acb34cc0dc0 F test/atof1.test 08a61df9365c341f334a65f4348897312d8f3db7 F test/attach.test 0d112b7713611fdf0340260192749737135fda5f F test/attach2.test 0ec5defa340363de6cd50fd595046465e9aaba2d -F test/attach3.test d89ccfe4fe6e2b5e368d480fcdfe4b496c54cf4e +F test/attach3.test 359eb65d00102cdfcef6fa4e81dc1648f8f80b27 F test/attach4.test 53bf502f17647c6d6c5add46dda6bac8b6f4665c F test/attachmalloc.test 3a4bfca9545bfe906a8d2e622de10fbac5b711b0 F test/auth.test 9bea29041871807d9f289ee679d05d3ed103642f @@ -364,7 +364,7 @@ F test/btreefault.test c2bcb542685eea44621275cfedbd8a13f65201e3 F test/busy.test 76b4887f8b9160ba903c1ac22e8ff406ad6ae2f0 F test/cache.test 13bc046b26210471ca6f2889aceb1ea52dc717de F test/capi2.test 011c16da245fdc0106a2785035de6b242c05e738 -F test/capi3.test f5eab498a0927d498e6d75c14567addb995ceccb +F test/capi3.test 56ab450125ead38846cbae7e5b6a216686c3cffa F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4 F test/capi3c.test 93d24621c9ff84da9da060f30431e0453db1cdb0 F test/capi3d.test 6d0fc0a86d73f42dd19a7d8b7761ab9bc02277d0 @@ -374,7 +374,7 @@ F test/check.test 5831ddb6f2c687782eaf2e1a07b6e17f24c4f763 F test/close.test 340bd24cc58b16c6bc01967402755027c37eb815 F test/closure01.test dbb28f1ea9eeaf0a53ec5bc0fed352e479def8c7 F test/coalesce.test cee0dccb9fbd2d494b77234bccf9dc6c6786eb91 -F test/collate1.test b709989e6e6ff6e1d2bd64231c2c1d8146846c9e +F test/collate1.test 73b91005f264b7c403e2d63a6708d150679ac99a F test/collate2.test 9aaa410a00734e48bcb27f3872617d6f69b2a621 F test/collate3.test 79558a286362cb9ed603c6fa543f1cda7f563f0f F test/collate4.test f04d5168685f2eef637ecfa2d4ddf8ec0d600177 @@ -456,7 +456,7 @@ F test/eqp.test 57c6c604c2807fb5531731c5323133453c24afac F test/errmsg.test f31592a594b44ee121371d25ddd5d63497bb3401 F test/eval.test bc269c365ba877554948441e91ad5373f9f91be3 F test/exclusive.test c7ebbc756eacf544c108b15eed64d7d4e5f86b75 -F test/exclusive2.test 881193eccec225cfed9d7f744b65e57f26adee25 +F test/exclusive2.test 32798111aae78a5deec980eee383213f189df308 F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7 F test/exists.test 8f7b27b61c2fbe5822f0a1f899c715d14e416e30 F test/expr.test 67c9fd6f8f829e239dc8b0f4a08a73c08b09196d @@ -509,13 +509,13 @@ F test/fts2r.test b154c30b63061d8725e320fba1a39e2201cadd5e F test/fts2token.test d8070b241a15ff13592a9ae4a8b7c171af6f445a F test/fts3.test 672a040ea57036fb4b6fdc09027c18d7d24ab654 F test/fts3_common.tcl 99cf6659b87c0f74f55963c2aea03b3a7d66ceb0 -F test/fts3aa.test ad272d695095a55c16a5091dbdcce7c5f55da605 -F test/fts3ab.test 09aeaa162aee6513d9ff336b6932211008b9d1f9 +F test/fts3aa.test edd20ddbbc5b6015ab340abf2ca278ae11ec387d +F test/fts3ab.test 7f6cf260ae80dda064023df8e8e503e9a412b91f F test/fts3ac.test 636ed7486043055d4f126a0e385f2d5a82ebbf63 F test/fts3ad.test e40570cb6f74f059129ad48bcef3d7cbc20dda49 F test/fts3ae.test ce32a13b34b0260928e4213b4481acf801533bda F test/fts3af.test d394978c534eabf22dd0837e718b913fd66b499c -F test/fts3ag.test 0b7d303f61ae5d620c4efb5e825713ea34ff9441 +F test/fts3ag.test c003672a215124df7fc6000036d896f498b26b53 F test/fts3ah.test dc9f66c32c296f1bc8bcc4535126bddfeca62894 F test/fts3ai.test 24058fdc6e9e5102c1fd8459591b114b6a85d285 F test/fts3aj.test 0ed71e1dd9b03b843a857dc3eb9b15630e0104fc @@ -535,7 +535,7 @@ F test/fts3conf.test ee8500c86dd58ec075e8831a1e216a79989436de F test/fts3corrupt.test 2710b77983cc7789295ddbffea52c1d3b7506dbb F test/fts3corrupt2.test 6d96efae2f8a6af3eeaf283aba437e6d0e5447ba F test/fts3cov.test e0fb00d8b715ddae4a94c305992dfc3ef70353d7 -F test/fts3d.test bf640d79722b720fa1c81834c48cdaa45d531b1a +F test/fts3d.test c8a193513a269ec4c205ca09645e26e0bc71b860 F test/fts3defer.test 0be4440b73a2e651fc1e472066686d6ada4b9963 F test/fts3defer2.test a3b6cbeabaf28c9398652a4d101ea224d9358479 F test/fts3defer3.test dd53fc13223c6d8264a98244e9b19abd35ed71cd @@ -549,7 +549,7 @@ F test/fts3fault2.test 3198eef2804deea7cac8403e771d9cbcb752d887 F test/fts3first.test dbdedd20914c8d539aa3206c9b34a23775644641 F test/fts3malloc.test b0e4c133b8d61d4f6d112d8110f8320e9e453ef6 F test/fts3matchinfo.test ff423e73faab8fc6d7adeefedf74dd8e2b0b14e0 -F test/fts3near.test 12895557870b0f9af7cc0be81a0171abb2d12f12 +F test/fts3near.test 7e3354d46f155a822b59c0e957fd2a70c1d7e905 F test/fts3prefix.test b36d4f00b128a51e7b386cc013a874246d9d7dc1 F test/fts3prefix2.test e1f0a822ca661dced7f12ce392e14eaf65609dce F test/fts3query.test 4fefd43ff24993bc2c9b2778f2bec0cc7629e7ed @@ -557,7 +557,7 @@ F test/fts3rnd.test 1320d8826a845e38a96e769562bf83d7a92a15d0 F test/fts3shared.test 57e26a801f21027b7530da77db54286a6fe4997e F test/fts3snippet.test d524af6bcef4714e059ef559113dbdc924cd33d1 F test/fts3sort.test ed34c716a11cc2009a35210e84ad5f9c102362ca -F test/fts3tok1.test b10d0a12a0ab5f905cea1200b745de233f37443f +F test/fts3tok1.test c551043de056b0b1582a54e878991f57bad074bc F test/fts3tok_err.test 52273cd193b9036282f7bacb43da78c6be87418d F test/fts3varint.test 752c08ed5d32c5d7dc211b056f4ed68a76b7e36e F test/fts4aa.test 0c3152322c7f0b548cc942ad763eaba0da87ccca @@ -571,7 +571,7 @@ F test/fts4merge2.test 5faa558d1b672f82b847d2a337465fa745e46891 F test/fts4merge3.test aab02a09f50fe6baaddc2e159c3eabc116d45fc7 F test/fts4merge4.test c19c85ca1faa7b6d536832b49c12e1867235f584 F test/fts4noti.test aed33ba44808852dcb24bf70fa132e7bf530f057 -F test/fts4unicode.test e28ba1a14181e709dcdf47455f207adf14c7cfe0 +F test/fts4unicode.test 01ec3fe2a7c3cfff3b4c0581b83caa11b33efa36 F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d F test/func.test 00667bbeac044d007f6f021af1b9f6150f0c7ff8 F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f @@ -703,7 +703,7 @@ F test/misuse.test ba4fb5d1a6101d1c171ea38b3c613d0661c83054 F test/mmap1.test 93d167b328255cbe6679fe1e1a23be1b1197d07b F test/mmap2.test 9d6dd9ddb4ad2379f29cc78f38ce1e63ed418022 F test/mmap3.test c92273e16eb8d23c1d55c9815b446bb72ef0512e -F test/mmapfault.test 97507ee06172df99057dbf1c40294eabd82cbb13 +F test/mmapfault.test d4c9eff9cd8c2dc14bc43e71e042f175b0a26fe3 F test/multiplex.test e08cc7177bd6d85990ee1d71100bb6c684c02256 F test/multiplex2.test 580ca5817c7edbe4cc68fa150609c9473393003a F test/multiplex3.test d228f59eac91839a977eac19f21d053f03e4d101 @@ -773,7 +773,7 @@ F test/schema2.test 906408621ea881fdb496d878b1822572a34e32c5 F test/schema3.test 1bc1008e1f8cb5654b248c55f27249366eb7ed38 F test/schema4.test e6a66e20cc69f0e306667c08be7fda3d11707dc5 F test/schema5.test 29699b4421f183c8f0e88bd28ce7d75d13ea653e -F test/securedel.test 87a2561151af1f1e349071a89fdd77059f50113c +F test/securedel.test 21749c32ccc30f1ea9e4b9f33295a6521ec20fa0 F test/securedel2.test 2d54c28e46eb1fd6902089958b20b1b056c6f1c5 F test/select1.test fc2a61f226a649393664ad54bc5376631801517c F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56 @@ -825,7 +825,7 @@ F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b F test/speedtest1.c 47788d552a349241471ad06d239383dadd97164d F test/spellfix.test 8c40b169b104086d8795781f670ba3c786d6d8be F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298 -F test/stat.test c8eccfe8fcd3f3cfc864ce22d5b9e803a3c69940 +F test/stat.test 76fd746b85459e812a0193410fb599f0531f22de F test/stmt.test 25d64e3dbf9a3ce89558667d7f39d966fe2a71b9 F test/subquery.test 666fdecceac258f5fd84bed09a64e49d9f37edd9 F test/subquery2.test 91e1e364072aeff431d1f9689b15147e421d88c7 @@ -882,7 +882,7 @@ F test/tkt-80e031a00f.test 9a154173461a4dbe2de49cda73963e04842d52f7 F test/tkt-8454a207b9.test c583a9f814a82a2b5ba95207f55001c9f0cd816c F test/tkt-868145d012.test a5f941107ece6a64410ca4755c6329b7eb57a356 F test/tkt-91e2e8ba6f.test 08c4f94ae07696b05c9b822da0b4e5337a2f54c5 -F test/tkt-94c04eaadb.test fa9c71192f7e2ea2d51bf078bc34e8da6088bf71 +F test/tkt-94c04eaadb.test f738c57c7f68ab8be1c054415af7774617cb6223 F test/tkt-9d68c883.test 458f7d82a523d7644b54b497c986378a7d8c8b67 F test/tkt-9f2eb3abac.test 85bc63e749f050e6a61c8f9207f1eee65c9d3395 F test/tkt-a7b7803e.test 159ef554234fa1f9fb318c751b284bd1cf858da4 @@ -1042,9 +1042,9 @@ F test/vtabE.test 7c4693638d7797ce2eda17af74292b97e705cc61 F test/vtabF.test fd5ad376f5a34fe0891df1f3cddb4fe7c3eb077e F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5 F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8 -F test/vtab_shared.test 82f463886e18d7f8395a4b6167c91815efe54839 -F test/wal.test a59d00eaa0901e42b8a2ef21f2a4c972ee1f1bd4 -F test/wal2.test d4b470f13c87f6d8268b004380afa04c3c67cb90 +F test/vtab_shared.test 6acafaae7126c9f49be72c2f57eb8bef3024f1cb +F test/wal.test 40073e54359d43354925b2b700b7eebd5e207285 +F test/wal2.test a8e3963abf6b232cf0b852b09b53665ef34007af F test/wal3.test b22eb662bcbc148c5f6d956eaf94b047f7afe9c0 F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c F test/wal5.test 8f888b50f66b78821e61ed0e233ded5de378224b @@ -1059,7 +1059,7 @@ F test/walcksum.test 9afeb96240296c08c72fc524d199c912cfe34daa F test/walcrash.test 451d79e528add5c42764cea74aa2750754171b25 F test/walcrash2.test a0edab4e5390f03b99a790de89aad15d6ec70b36 F test/walcrash3.test e426aa58122d20f2b9fbe9a507f9eb8cab85b8af -F test/walfault.test 54ad6e849c727f4da463964b9eb8c8e8e155cf82 +F test/walfault.test 1f8389f7709877e9b4cc679033d71d6fe529056b F test/walhook.test ed00a40ba7255da22d6b66433ab61fab16a63483 F test/walmode.test 4022fe03ae6e830583672caa101f046438a0473c F test/walnoshm.test 84ca10c544632a756467336b7c3b864d493ee496 @@ -1147,7 +1147,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 72d111336c5016e5b5092dfebcd01253266a7685 -R a48136d424494fa9261ddc391e19f98d +P ffa092e13b3781677b18418cca40e3dd1e388aed +R 62e1d728cd37281433b32cbd44f4c682 U drh -Z 822c060ba762ff386aec37ff13c59f91 +Z 83a1d9d85b0e444eca37253273a68154 diff --git a/manifest.uuid b/manifest.uuid index 33bc14bfb2..44ff93880e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ffa092e13b3781677b18418cca40e3dd1e388aed \ No newline at end of file +ca3fdfd41961d8d3d1e39d20dc628e8a95dabb2f \ No newline at end of file diff --git a/src/main.c b/src/main.c index 32e4dee7f0..d181d6fa00 100644 --- a/src/main.c +++ b/src/main.c @@ -2641,6 +2641,8 @@ static int openDatabase( SQLITE_DEFAULT_LOCKING_MODE); #endif + if( rc ) sqlite3Error(db, rc, 0); + /* Enable the lookaside-malloc subsystem */ setupLookaside(db, 0, sqlite3GlobalConfig.szLookaside, sqlite3GlobalConfig.nLookaside); diff --git a/test/attach3.test b/test/attach3.test index f861425346..1ac10d97a4 100644 --- a/test/attach3.test +++ b/test/attach3.test @@ -322,7 +322,6 @@ do_test attach3-12.9 { db_list } {main temp {}} do_test attach3-12.10 { -breakpoint execsql { DETACH ? } diff --git a/test/capi3.test b/test/capi3.test index 2dbc298fa4..9d7434d25d 100644 --- a/test/capi3.test +++ b/test/capi3.test @@ -1191,7 +1191,6 @@ do_test capi3-18.2 { sqlite3_reset $STMT sqlite3_errcode db } {SQLITE_SCHEMA} -breakpoint do_test capi3-18.3 { sqlite3_errmsg db } {database schema has changed} diff --git a/test/collate1.test b/test/collate1.test index e9ac93aa30..20854157d3 100644 --- a/test/collate1.test +++ b/test/collate1.test @@ -75,7 +75,6 @@ do_test collate1-1.1 { } } {{} 0x119 0x2D} do_test collate1-1.2 { -breakpoint execsql { SELECT c2 FROM collate1t1 ORDER BY 1 COLLATE hex; } diff --git a/test/exclusive2.test b/test/exclusive2.test index 54203e3d8f..712363e762 100644 --- a/test/exclusive2.test +++ b/test/exclusive2.test @@ -301,7 +301,6 @@ do_test exclusive2-3.3 { readPagerChangeCounter test.db } {4} do_test exclusive2-3.4 { -breakpoint execsql { INSERT INTO t1 VALUES(randstr(200, 200)); } diff --git a/test/fts3aa.test b/test/fts3aa.test index bde38af553..6ff384a0d3 100644 --- a/test/fts3aa.test +++ b/test/fts3aa.test @@ -146,7 +146,6 @@ do_test fts3aa-3.3 { execsql {SELECT rowid FROM t1 WHERE content MATCH '-two one'} } {1 5 9 13 17 21 25 29} -breakpoint do_test fts3aa-4.1 { execsql {SELECT rowid FROM t1 WHERE content MATCH 'one OR two'} } {1 2 3 5 6 7 9 10 11 13 14 15 17 18 19 21 22 23 25 26 27 29 30 31} diff --git a/test/fts3ab.test b/test/fts3ab.test index e1f3bdc9cf..86124f78c4 100644 --- a/test/fts3ab.test +++ b/test/fts3ab.test @@ -115,7 +115,6 @@ for {set i 1} {$i<=15} {incr i} { db eval "INSERT INTO t4(norm,plusone,invert) VALUES([join $vset ,]);" } -breakpoint do_test fts3ab-4.1 { execsql {SELECT rowid FROM t4 WHERE t4 MATCH 'norm:one'} } {1 3 5 7 9 11 13 15} diff --git a/test/fts3ag.test b/test/fts3ag.test index 18ed5ae31f..9b658d19df 100644 --- a/test/fts3ag.test +++ b/test/fts3ag.test @@ -78,7 +78,6 @@ do_test fts3ag-1.10 { # Test that docListOrMerge() correctly handles reaching the end of one # doclist before it reaches the end of the other. do_test fts3ag-1.11 { -breakpoint execsql {SELECT rowid FROM t1 WHERE t1 MATCH 'this OR also'} } {1 2} do_test fts3ag-1.12 { diff --git a/test/fts3d.test b/test/fts3d.test index 1ae992b311..818456bfae 100644 --- a/test/fts3d.test +++ b/test/fts3d.test @@ -253,7 +253,6 @@ check_doclist fts3d-4.4.10 1 0 was {[2 0[1]]} # Optimize should leave the result in the level of the highest-level # prior segment. -breakpoint do_test fts3d-4.5 { execsql { SELECT OPTIMIZE(t1) FROM t1 LIMIT 1; diff --git a/test/fts3near.test b/test/fts3near.test index 9276fa3737..2d9981e535 100644 --- a/test/fts3near.test +++ b/test/fts3near.test @@ -165,7 +165,6 @@ do_test fts3near-3.6 { SELECT offsets(t1) FROM t1 WHERE content MATCH 'three NEAR/0 "two four"' } } {{0 0 8 5 0 1 14 3 0 2 18 4}} -breakpoint do_test fts3near-3.7 { execsql { SELECT offsets(t1) FROM t1 WHERE content MATCH '"two four" NEAR/0 three'} diff --git a/test/fts3tok1.test b/test/fts3tok1.test index 4faed34d12..e6fbbe10a2 100644 --- a/test/fts3tok1.test +++ b/test/fts3tok1.test @@ -90,7 +90,6 @@ do_execsql_test 1.13.1 { INSERT INTO c1(x) VALUES('a b c'); INSERT INTO c1(x) VALUES('d e f'); } -breakpoint do_execsql_test 1.13.2 { SELECT * FROM c1, t1 WHERE input = x AND c1.rowid=t1.rowid; } { diff --git a/test/fts4unicode.test b/test/fts4unicode.test index 8edc2877da..f237119a18 100644 --- a/test/fts4unicode.test +++ b/test/fts4unicode.test @@ -392,7 +392,6 @@ foreach T $tokenizers { #------------------------------------------------------------------------- # Test that the private use ranges are treated as alphanumeric. # -breakpoint foreach {tn1 c} { 1 \ue000 2 \ue001 3 \uf000 4 \uf8fe 5 \uf8ff } { @@ -557,7 +556,3 @@ do_execsql_test 11.1 { } finish_test - - - - diff --git a/test/mmapfault.test b/test/mmapfault.test index 248b5bad08..10c5e258b8 100644 --- a/test/mmapfault.test +++ b/test/mmapfault.test @@ -41,7 +41,6 @@ do_test 1-pre { do_faultsim_test 1 -prep { faultsim_restore_and_reopen db func a_string a_string - breakpoint execsql { PRAGMA mmap_size = 1000000; PRAGMA cache_size = 5; diff --git a/test/securedel.test b/test/securedel.test index 7ff5a628a1..7111e08e71 100644 --- a/test/securedel.test +++ b/test/securedel.test @@ -47,7 +47,6 @@ do_test securedel-1.3 { } } {0 0} do_test securedel-1.4 { -breakpoint db eval { PRAGMA secure_delete=ON; PRAGMA db2.secure_delete; diff --git a/test/stat.test b/test/stat.test index f8d3877e36..f0447e4509 100644 --- a/test/stat.test +++ b/test/stat.test @@ -164,7 +164,6 @@ db close forcedelete test.db sqlite3 db test.db register_dbstat_vtab db -breakpoint do_execsql_test stat-5.1 { PRAGMA auto_vacuum = OFF; CREATE VIRTUAL TABLE temp.stat USING dbstat; diff --git a/test/tkt-94c04eaadb.test b/test/tkt-94c04eaadb.test index 0063de664d..9de8aea28d 100644 --- a/test/tkt-94c04eaadb.test +++ b/test/tkt-94c04eaadb.test @@ -44,7 +44,6 @@ do_test tkt-94c94-2.1 { execsql { CREATE TABLE t2(x, y) } db } {} do_test tkt-94c94-2.2 { -breakpoint execsql { INSERT INTO t2 VALUES(1, 2) } db2 } {} do_test tkt-94c94-2.3 { diff --git a/test/vtab_shared.test b/test/vtab_shared.test index 6a76e2749b..13237a8d20 100644 --- a/test/vtab_shared.test +++ b/test/vtab_shared.test @@ -116,7 +116,6 @@ do_test vtab_shared-1.10 { } {1 {database table is locked: sqlite_master}} do_test vtab_shared-1.11 { -breakpoint execsql { CREATE VIRTUAL TABLE t2 USING echo(t0); CREATE VIRTUAL TABLE t3 USING echo(t0); diff --git a/test/wal.test b/test/wal.test index 7435538678..3a69de54f5 100644 --- a/test/wal.test +++ b/test/wal.test @@ -852,7 +852,6 @@ do_test wal-13.1.2 { sqlite3 db test.db execsql { SELECT * FROM t2 } } {B 2} -breakpoint do_test wal-13.1.3 { db close file exists test.db-wal diff --git a/test/wal2.test b/test/wal2.test index 4371e988b2..b331d5ed10 100644 --- a/test/wal2.test +++ b/test/wal2.test @@ -1279,7 +1279,6 @@ foreach {tn settings restart_sync commit_sync ckpt_sync} { PRAGMA synchronous = [lindex $settings 2]; " {0 wal} -if { $tn==2} breakpoint do_test 15.$tn.2 { set sync(normal) 0 set sync(full) 0 diff --git a/test/walfault.test b/test/walfault.test index 4a9d98afda..4e7064d53b 100644 --- a/test/walfault.test +++ b/test/walfault.test @@ -567,7 +567,6 @@ do_test walfault-14-pre { } {} do_faultsim_test walfault-14 -prep { faultsim_restore_and_reopen - breakpoint execsql { SELECT count(*) FROM abc; PRAGMA locking_mode = exclusive; From 1001ee8819a825d2b6076b7f4e98949deb1aef92 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 19 Dec 2013 17:04:58 +0000 Subject: [PATCH 095/276] Do not inject OOM faults into SQLITE_FCNTL_COMMIT_PHASE_TWO file-control invocations. It causes problems for test scripts. FossilOrigin-Name: 8eb28d23e353139d24a8af78309d39249ab9eaf0 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/os.c | 16 +++++++++++++++- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 7f912e08b8..0859d915c2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\serrors\sencountered\swhile\sinitializing\sextensions\ssuch\sas\sFTS4\nget\sreported\sout\sfrom\ssqlite3_open().\s\sThis\sfixes\sa\sbug\sintroduced\sby\ncheck-in\s[9d347f547e7ba9].\s\sAlso\sremove\slots\sof\sforgotten\s"breakpoint"\ncommands\sleft\sin\stest\sscripts\sover\sthe\syears. -D 2013-12-19T16:26:05.208 +C Do\snot\sinject\sOOM\sfaults\sinto\sSQLITE_FCNTL_COMMIT_PHASE_TWO\sfile-control\sinvocations.\sIt\scauses\sproblems\sfor\stest\sscripts. +D 2013-12-19T17:04:58.210 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -202,7 +202,7 @@ F src/mutex_noop.c 7682796b7d8d39bf1c138248858efcd10c9e1553 F src/mutex_unix.c c3a4e00f96ba068a8dbef34084465979aaf369cc F src/mutex_w32.c 6108c88e1cb38d8fbb3534b170793815cbedbf97 F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30 -F src/os.c b4ad71336fd96f97776f75587cd9e8218288f5be +F src/os.c 1b147e4cf7cc39e618115c14a086aed44bc91ace F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_unix.c 60a7b3b23e6fcf83a50d1e320b280b551724e11f @@ -1147,7 +1147,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P ffa092e13b3781677b18418cca40e3dd1e388aed -R 62e1d728cd37281433b32cbd44f4c682 -U drh -Z 83a1d9d85b0e444eca37253273a68154 +P ca3fdfd41961d8d3d1e39d20dc628e8a95dabb2f +R b2d8ac3bed199d88ddec25ed7c70eec6 +U dan +Z b85edb7cdda29606f3560dec5a14157c diff --git a/manifest.uuid b/manifest.uuid index 44ff93880e..5b8bd821b1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ca3fdfd41961d8d3d1e39d20dc628e8a95dabb2f \ No newline at end of file +8eb28d23e353139d24a8af78309d39249ab9eaf0 \ No newline at end of file diff --git a/src/os.c b/src/os.c index be2ea4cfc0..b6c28a1dc4 100644 --- a/src/os.c +++ b/src/os.c @@ -107,7 +107,21 @@ int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut){ ** routine has no return value since the return value would be meaningless. */ int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){ - DO_OS_MALLOC_TEST(id); +#ifdef SQLITE_TEST + if( op!=SQLITE_FCNTL_COMMIT_PHASETWO ){ + /* Faults are not injected into COMMIT_PHASETWO because, assuming SQLite + ** is using a regular VFS, it is called after the corresponding + ** transaction has been committed. Injecting a fault at this point + ** confuses the test scripts - the COMMIT comand returns SQLITE_NOMEM + ** but the transaction is committed anyway. + ** + ** The core must call OsFileControl() though, not OsFileControlHint(), + ** as if a custom VFS (e.g. zipvfs) returns an error here, it probably + ** means the commit really has failed and an error should be returned + ** to the user. */ + DO_OS_MALLOC_TEST(id); + } +#endif return id->pMethods->xFileControl(id, op, pArg); } void sqlite3OsFileControlHint(sqlite3_file *id, int op, void *pArg){ From 7e61d18eb4dfaae65f151c8bd9ad01cde1e5bb58 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 20 Dec 2013 13:11:45 +0000 Subject: [PATCH 096/276] Simplify the accumulator reset for aggregate query processing so that it uses a single multi-register OP_Null rather than a separate OP_Null for each register. FossilOrigin-Name: 2c7fd9b043f5f3d9d8e22dbefa84a9770ca951d0 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/select.c | 21 ++++++++++++++++----- src/sqliteInt.h | 1 + 4 files changed, 26 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 0859d915c2..5cf3f29245 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\sinject\sOOM\sfaults\sinto\sSQLITE_FCNTL_COMMIT_PHASE_TWO\sfile-control\sinvocations.\sIt\scauses\sproblems\sfor\stest\sscripts. -D 2013-12-19T17:04:58.210 +C Simplify\sthe\saccumulator\sreset\sfor\saggregate\squery\sprocessing\sso\sthat\sit\nuses\sa\ssingle\smulti-register\sOP_Null\srather\sthan\sa\sseparate\sOP_Null\sfor\seach\nregister. +D 2013-12-20T13:11:45.101 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -219,12 +219,12 @@ F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c 0b2dbc37fdfbfa6bd455b091dfcef5bdb32dba68 F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c 9d13850293cf19e5ffee59b231fa372e16ce65a9 +F src/select.c 819bb090c9a348d17f69f136cad2bfa9ee9cbb41 F src/shell.c 18924f6ccfa70da98bf9e388bab512c0fd1e792e F src/sqlite.h.in 4ef56464aeaa3785a2c5ca37fb3a0fb229d68b2e F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h b7e9da87740488671cfe4c70038a8eef3a1d317e +F src/sqliteInt.h d0815177df125e900056e1e692504435e7610793 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -1147,7 +1147,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P ca3fdfd41961d8d3d1e39d20dc628e8a95dabb2f -R b2d8ac3bed199d88ddec25ed7c70eec6 -U dan -Z b85edb7cdda29606f3560dec5a14157c +P 8eb28d23e353139d24a8af78309d39249ab9eaf0 +R 488c9d6501762ac1c5b904ecc4a5a8a0 +U drh +Z c5be2c2c1ecdd01c10eef8b3332d3737 diff --git a/manifest.uuid b/manifest.uuid index 5b8bd821b1..d0d554d6c8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8eb28d23e353139d24a8af78309d39249ab9eaf0 \ No newline at end of file +2c7fd9b043f5f3d9d8e22dbefa84a9770ca951d0 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 132d546971..d075116749 100644 --- a/src/select.c +++ b/src/select.c @@ -3822,14 +3822,23 @@ static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){ Vdbe *v = pParse->pVdbe; int i; struct AggInfo_func *pFunc; - if( pAggInfo->nFunc+pAggInfo->nColumn==0 ){ - return; - } + int nReg = pAggInfo->nFunc + pAggInfo->nColumn; + if( nReg==0 ) return; +#ifdef SQLITE_DEBUG + /* Verify that all AggInfo registers are within the range specified by + ** AggInfo.mnReg..AggInfo.mxReg */ + assert( nReg==pAggInfo->mxReg-pAggInfo->mnReg+1 ); for(i=0; inColumn; i++){ - sqlite3VdbeAddOp2(v, OP_Null, 0, pAggInfo->aCol[i].iMem); + assert( pAggInfo->aCol[i].iMem>=pAggInfo->mnReg + && pAggInfo->aCol[i].iMem<=pAggInfo->mxReg ); } + for(i=0; inFunc; i++){ + assert( pAggInfo->aFunc[i].iMem>=pAggInfo->mnReg + && pAggInfo->aFunc[i].iMem<=pAggInfo->mxReg ); + } +#endif + sqlite3VdbeAddOp3(v, OP_Null, 0, pAggInfo->mnReg, pAggInfo->mxReg); for(pFunc=pAggInfo->aFunc, i=0; inFunc; i++, pFunc++){ - sqlite3VdbeAddOp2(v, OP_Null, 0, pFunc->iMem); if( pFunc->iDistinct>=0 ){ Expr *pE = pFunc->pExpr; assert( !ExprHasProperty(pE, EP_xIsSelect) ); @@ -4407,6 +4416,7 @@ int sqlite3Select( sNC.pParse = pParse; sNC.pSrcList = pTabList; sNC.pAggInfo = &sAggInfo; + sAggInfo.mnReg = pParse->nMem+1; sAggInfo.nSortingColumn = pGroupBy ? pGroupBy->nExpr+1 : 0; sAggInfo.pGroupBy = pGroupBy; sqlite3ExprAnalyzeAggList(&sNC, pEList); @@ -4421,6 +4431,7 @@ int sqlite3Select( sqlite3ExprAnalyzeAggList(&sNC, sAggInfo.aFunc[i].pExpr->x.pList); sNC.ncFlags &= ~NC_InAggFunc; } + sAggInfo.mxReg = pParse->nMem; if( db->mallocFailed ) goto select_end; /* Processing for aggregates with GROUP BY is very different and diff --git a/src/sqliteInt.h b/src/sqliteInt.h index af018edf01..a33ff4d43b 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1688,6 +1688,7 @@ struct AggInfo { int sortingIdx; /* Cursor number of the sorting index */ int sortingIdxPTab; /* Cursor number of pseudo-table */ int nSortingColumn; /* Number of columns in the sorting index */ + int mnReg, mxReg; /* Range of registers allocated for aCol and aFunc */ ExprList *pGroupBy; /* The group by clause */ struct AggInfo_col { /* For each column used in source tables */ Table *pTab; /* Source table */ From aed1819875bbb39fe4c75f329e103183f03c3124 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 20 Dec 2013 14:48:12 +0000 Subject: [PATCH 097/276] Allow any arbitrary expression as the filename in an ATTACH statement, including functions and subqueries. FossilOrigin-Name: df70a1f30393b34146d6b8bf1df5a76aaf362efe --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/attach.c | 4 ---- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 5cf3f29245..2ff177f432 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplify\sthe\saccumulator\sreset\sfor\saggregate\squery\sprocessing\sso\sthat\sit\nuses\sa\ssingle\smulti-register\sOP_Null\srather\sthan\sa\sseparate\sOP_Null\sfor\seach\nregister. -D 2013-12-20T13:11:45.101 +C Allow\sany\sarbitrary\sexpression\sas\sthe\sfilename\sin\san\sATTACH\sstatement,\nincluding\sfunctions\sand\ssubqueries. +D 2013-12-20T14:48:12.779 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -161,7 +161,7 @@ F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c 2af0330bb1b601af7a7789bf7229675fd772a083 F src/analyze.c 581d5c18ce89c6f45d4dca65914d0de5b4dad41f -F src/attach.c 0a17c9364895316ca4f52d06a97a72c0af1ae8b3 +F src/attach.c 3801129015ef59d76bf23c95ef9b0069d18a0c52 F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c a729e63cf5cd1829507cb7b8e89f99b95141bb53 F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb @@ -1147,7 +1147,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 8eb28d23e353139d24a8af78309d39249ab9eaf0 -R 488c9d6501762ac1c5b904ecc4a5a8a0 +P 2c7fd9b043f5f3d9d8e22dbefa84a9770ca951d0 +R d11a12f8bb29004dd6853b4e5004e340 U drh -Z c5be2c2c1ecdd01c10eef8b3332d3737 +Z efe52f7d54c1916342aa04894f1853b2 diff --git a/manifest.uuid b/manifest.uuid index d0d554d6c8..d13944d925 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2c7fd9b043f5f3d9d8e22dbefa84a9770ca951d0 \ No newline at end of file +df70a1f30393b34146d6b8bf1df5a76aaf362efe \ No newline at end of file diff --git a/src/attach.c b/src/attach.c index 223c166482..89050fd9dc 100644 --- a/src/attach.c +++ b/src/attach.c @@ -38,10 +38,6 @@ static int resolveAttachExpr(NameContext *pName, Expr *pExpr) if( pExpr ){ if( pExpr->op!=TK_ID ){ rc = sqlite3ResolveExprNames(pName, pExpr); - if( rc==SQLITE_OK && !sqlite3ExprIsConstant(pExpr) ){ - sqlite3ErrorMsg(pName->pParse, "invalid name: \"%s\"", pExpr->u.zToken); - return SQLITE_ERROR; - } }else{ pExpr->op = TK_STRING; } From 4eded604ea64ac459f46887de90cf3586589da5a Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 20 Dec 2013 15:59:20 +0000 Subject: [PATCH 098/276] Combine adjacent single-register OP_Copy instructions into a single multi-register OP_Copy, where possible. Fix the Synopsis comment for multi-register OP_Copy instructions to show the correct register ranges. FossilOrigin-Name: 2ae22dc0cbed2feca4baf89d02aaace0331971d6 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/expr.c | 12 +++++++++++- src/vdbe.c | 2 +- src/vdbeaux.c | 23 +++++++++++++++++++++-- 5 files changed, 42 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 2ff177f432..e722b985a6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Allow\sany\sarbitrary\sexpression\sas\sthe\sfilename\sin\san\sATTACH\sstatement,\nincluding\sfunctions\sand\ssubqueries. -D 2013-12-20T14:48:12.779 +C Combine\sadjacent\ssingle-register\sOP_Copy\sinstructions\sinto\sa\ssingle\nmulti-register\sOP_Copy,\swhere\spossible.\s\sFix\sthe\sSynopsis\scomment\sfor\nmulti-register\sOP_Copy\sinstructions\sto\sshow\sthe\scorrect\sregister\sranges. +D 2013-12-20T15:59:20.716 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -175,7 +175,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 F src/delete.c b36db1f79ee50eaca979660c9dd36437f5410b93 -F src/expr.c 962c29881bcee9e1d7b556020c1d29dc8bd8b906 +F src/expr.c ffe4bc79c66f711f450a6113fbd1943b9b2380f7 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 2ab0f5384b70594468ef3ac5c7ed8ca24bfd17d5 F src/func.c 6325ac2ec10833ccf4d5c36d323709221d37ea19 @@ -280,11 +280,11 @@ F src/update.c 47baf532e3ecec8e4093f92d613384f66785fc2f F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c e71f19b272f05c8695cf747b4bac1732685f9e5c F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c 919422843c859a1db08db0c88189912dbf625fc7 +F src/vdbe.c 6bcf27a80c3fdffee649f12eae91522718a06a64 F src/vdbe.h c3278ab2b410f17acf61faf91be7bce3fd466e8b F src/vdbeInt.h 8a4d2d69955570bb74a092c3cdbab04afb554963 F src/vdbeapi.c ce4e68ea4842cc6081046f533d088dcf01d247ad -F src/vdbeaux.c 70aa77f7db7b9b627bbc44a4546deef8ba56c51b +F src/vdbeaux.c 6fb0607776fe707a12e1859e66fc94b439966274 F src/vdbeblob.c bc40f98f256f0b34116d6a44b114da4a81a15d33 F src/vdbemem.c 0e69351b2c6ff7d8b638688c0ae336a26befa6b2 F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147 @@ -1147,7 +1147,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 2c7fd9b043f5f3d9d8e22dbefa84a9770ca951d0 -R d11a12f8bb29004dd6853b4e5004e340 +P df70a1f30393b34146d6b8bf1df5a76aaf362efe +R ae7f2b624bd6d9dcdad2f041ed2699ab U drh -Z efe52f7d54c1916342aa04894f1853b2 +Z e4024102bfc5328ec565d390ad91c722 diff --git a/manifest.uuid b/manifest.uuid index d13944d925..c405d4165d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -df70a1f30393b34146d6b8bf1df5a76aaf362efe \ No newline at end of file +2ae22dc0cbed2feca4baf89d02aaace0331971d6 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 81eb00c968..8ee73acb78 100644 --- a/src/expr.c +++ b/src/expr.c @@ -3428,7 +3428,17 @@ int sqlite3ExprCodeExprList( }else{ int inReg = sqlite3ExprCodeTarget(pParse, pExpr, target+i); if( inReg!=target+i ){ - sqlite3VdbeAddOp2(pParse->pVdbe, copyOp, inReg, target+i); + VdbeOp *pOp; + Vdbe *v = pParse->pVdbe; + if( copyOp==OP_Copy + && (pOp=sqlite3VdbeGetOp(v, -1))->opcode==OP_Copy + && pOp->p1+pOp->p3+1==inReg + && pOp->p2+pOp->p3+1==target+i + ){ + pOp->p3++; + }else{ + sqlite3VdbeAddOp2(v, copyOp, inReg, target+i); + } } } } diff --git a/src/vdbe.c b/src/vdbe.c index 3361120933..bbc6d3f7f6 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1111,7 +1111,7 @@ case OP_Move: { } /* Opcode: Copy P1 P2 P3 * * -** Synopsis: r[P2@P3]=r[P1@P3] +** Synopsis: r[P2@P3+1]=r[P1@P3+1] ** ** Make a copy of registers P1..P1+P3 into registers P2..P2+P3. ** diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 068059e594..8e95de70c1 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -885,7 +885,17 @@ static int translateP(char c, const Op *pOp){ } /* -** Compute a string for the "comment" field of a VDBE opcode listing +** Compute a string for the "comment" field of a VDBE opcode listing. +** +** The Synopsis: field in comments in the vdbe.c source file gets converted +** to an extra string that is appended to the sqlite3OpcodeName(). In the +** absence of other comments, this synopsis becomes the comment on the opcode. +** Some translation occurs: +** +** "PX" -> "r[X]" +** "PX@PY" -> "r[X..X+Y-1]" or "r[x]" if y is 0 or 1 +** "PX@PY+1" -> "r[X..X+Y]" or "r[x]" if y is 0 +** "PY..PY" -> "r[X..Y]" or "r[x]" if y<=x */ static int displayComment( const Op *pOp, /* The opcode to be commented */ @@ -919,7 +929,13 @@ static int displayComment( ii += 3; jj += sqlite3Strlen30(zTemp+jj); v2 = translateP(zSynopsis[ii], pOp); - if( v2>1 ) sqlite3_snprintf(nTemp-jj, zTemp+jj, "..%d", v1+v2-1); + if( strncmp(zSynopsis+ii+1,"+1",2)==0 ){ + ii += 2; + v2++; + } + if( v2>1 ){ + sqlite3_snprintf(nTemp-jj, zTemp+jj, "..%d", v1+v2-1); + } }else if( strncmp(zSynopsis+ii+1, "..P3", 4)==0 && pOp->p3==0 ){ ii += 4; } @@ -1151,6 +1167,9 @@ void sqlite3VdbePrintOp(FILE *pOut, int pc, Op *pOp){ #else zCom[0] = 0 #endif + /* NB: The sqlite3OpcodeName() function is implemented by code created + ** by the mkopcodeh.awk and mkopcodec.awk scripts which extract the + ** information from the vdbe.c source text */ fprintf(pOut, zFormat1, pc, sqlite3OpcodeName(pOp->opcode), pOp->p1, pOp->p2, pOp->p3, zP4, pOp->p5, zCom From d42ef839bc175303258114a7db99f9f9e065b690 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 20 Dec 2013 18:44:35 +0000 Subject: [PATCH 099/276] Code simplification in sqlite3GenerateIndexKey() by making use of a subroutine found over in expr.c. FossilOrigin-Name: 0026d3355340d66687a3fd4cbece28811ef1b505 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/delete.c | 12 ++---------- 3 files changed, 9 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index e722b985a6..25a05f6a27 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Combine\sadjacent\ssingle-register\sOP_Copy\sinstructions\sinto\sa\ssingle\nmulti-register\sOP_Copy,\swhere\spossible.\s\sFix\sthe\sSynopsis\scomment\sfor\nmulti-register\sOP_Copy\sinstructions\sto\sshow\sthe\scorrect\sregister\sranges. -D 2013-12-20T15:59:20.716 +C Code\ssimplification\sin\ssqlite3GenerateIndexKey()\sby\smaking\suse\sof\sa\ssubroutine\nfound\sover\sin\sexpr.c. +D 2013-12-20T18:44:35.386 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -174,7 +174,7 @@ F src/callback.c 174e3c8656bc29f91d710ab61550d16eea34be98 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 -F src/delete.c b36db1f79ee50eaca979660c9dd36437f5410b93 +F src/delete.c 821da82527c24496bef0677ed4f61a53b44c27ee F src/expr.c ffe4bc79c66f711f450a6113fbd1943b9b2380f7 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 2ab0f5384b70594468ef3ac5c7ed8ca24bfd17d5 @@ -1147,7 +1147,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P df70a1f30393b34146d6b8bf1df5a76aaf362efe -R ae7f2b624bd6d9dcdad2f041ed2699ab +P 2ae22dc0cbed2feca4baf89d02aaace0331971d6 +R 5c55bdf162e02aeda0ecbd1279176bdc U drh -Z e4024102bfc5328ec565d390ad91c722 +Z da74200164ac95fa24bb1bb84f137616 diff --git a/manifest.uuid b/manifest.uuid index c405d4165d..f0698ae6a2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2ae22dc0cbed2feca4baf89d02aaace0331971d6 \ No newline at end of file +0026d3355340d66687a3fd4cbece28811ef1b505 \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index 5315db9e71..8746cd324a 100644 --- a/src/delete.c +++ b/src/delete.c @@ -768,7 +768,6 @@ int sqlite3GenerateIndexKey( Table *pTab = pIdx->pTable; int regBase; int nCol; - Index *pPk; if( piPartIdxLabel ){ if( pIdx->pPartIdxWhere ){ @@ -782,16 +781,9 @@ int sqlite3GenerateIndexKey( } nCol = (prefixOnly && pIdx->uniqNotNull) ? pIdx->nKeyCol : pIdx->nColumn; regBase = sqlite3GetTempRange(pParse, nCol); - pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab); for(j=0; jaiColumn[j]; - if( pPk ) idx = sqlite3ColumnOfIndex(pPk, idx); - if( idx<0 || idx==pTab->iPKey ){ - sqlite3VdbeAddOp2(v, OP_Rowid, iDataCur, regBase+j); - }else{ - sqlite3VdbeAddOp3(v, OP_Column, iDataCur, idx, regBase+j); - sqlite3ColumnDefault(v, pTab, pIdx->aiColumn[j], -1); - } + sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, pIdx->aiColumn[j], + regBase+j); } if( regOut ){ const char *zAff; From a47941fe428060643a3e23a6d898f857a57a7fe7 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 20 Dec 2013 18:57:44 +0000 Subject: [PATCH 100/276] Fix compiler harmless warnings in tclsqlite.c that appeared with GCC 4.8.x. FossilOrigin-Name: d93ae6833a7fca0672caf902a7b48846e54242cd --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/tclsqlite.c | 9 ++++----- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 25a05f6a27..7338e24330 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Code\ssimplification\sin\ssqlite3GenerateIndexKey()\sby\smaking\suse\sof\sa\ssubroutine\nfound\sover\sin\sexpr.c. -D 2013-12-20T18:44:35.386 +C Fix\scompiler\sharmless\swarnings\sin\stclsqlite.c\sthat\sappeared\swith\sGCC\s4.8.x. +D 2013-12-20T18:57:44.631 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -228,7 +228,7 @@ F src/sqliteInt.h d0815177df125e900056e1e692504435e7610793 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e -F src/tclsqlite.c 651b10698c87bbc3ae5772e2491e3444c5bbf153 +F src/tclsqlite.c c43379f77f90399802b0e215faa71c0adc3a4d2e F src/test1.c 633e5e6a116acf4473b9289240bcceb5320a9d93 F src/test2.c 7355101c085304b90024f2261e056cdff13c6c35 F src/test3.c 1c0e5d6f080b8e33c1ce8b3078e7013fdbcd560c @@ -1147,7 +1147,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 2ae22dc0cbed2feca4baf89d02aaace0331971d6 -R 5c55bdf162e02aeda0ecbd1279176bdc +P 0026d3355340d66687a3fd4cbece28811ef1b505 +R 1e7ba7ea1368145f32bc284eea0efbfc U drh -Z da74200164ac95fa24bb1bb84f137616 +Z b38a5e6618ad563a8f912c35a2908336 diff --git a/manifest.uuid b/manifest.uuid index f0698ae6a2..ab92cc76ab 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0026d3355340d66687a3fd4cbece28811ef1b505 \ No newline at end of file +d93ae6833a7fca0672caf902a7b48846e54242cd \ No newline at end of file diff --git a/src/tclsqlite.c b/src/tclsqlite.c index 0f57dda6ca..e3e5628b17 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -1530,9 +1530,9 @@ static int DbUseNre(void){ */ # define SQLITE_TCL_NRE 0 # define DbUseNre() 0 -# define Tcl_NRAddCallback(a,b,c,d,e,f) 0 +# define Tcl_NRAddCallback(a,b,c,d,e,f) (void)0 # define Tcl_NREvalObj(a,b,c) 0 -# define Tcl_NRCreateCommand(a,b,c,d,e,f) 0 +# define Tcl_NRCreateCommand(a,b,c,d,e,f) (void)0 #endif /* @@ -2770,7 +2770,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ ** or savepoint. */ if( DbUseNre() ){ Tcl_NRAddCallback(interp, DbTransPostCmd, cd, 0, 0, 0); - Tcl_NREvalObj(interp, pScript, 0); + (void)Tcl_NREvalObj(interp, pScript, 0); }else{ rc = DbTransPostCmd(&cd, interp, Tcl_EvalObjEx(interp, pScript, 0)); } @@ -3371,8 +3371,7 @@ static void MD5Final(unsigned char digest[16], MD5Context *ctx){ byteReverse(ctx->in, 14); /* Append length in bits and transform */ - ((uint32 *)ctx->in)[ 14 ] = ctx->bits[0]; - ((uint32 *)ctx->in)[ 15 ] = ctx->bits[1]; + memcpy(ctx->in + 14*4, ctx->bits, 8); MD5Transform(ctx->buf, (uint32 *)ctx->in); byteReverse((unsigned char *)ctx->buf, 4); From ae28d6efc697f98f38f9d53fbb26556c82d86148 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 21 Dec 2013 00:04:37 +0000 Subject: [PATCH 101/276] Add a case to speedtest1.c that demonstrates the need to factor OP_Column operators out of inner loops. FossilOrigin-Name: 69a17336fdf4ae891e815914be8942f7222230c2 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/speedtest1.c | 23 ++++++++++++++++++++++- 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 7338e24330..54ee0ed6bb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\scompiler\sharmless\swarnings\sin\stclsqlite.c\sthat\sappeared\swith\sGCC\s4.8.x. -D 2013-12-20T18:57:44.631 +C Add\sa\scase\sto\sspeedtest1.c\sthat\sdemonstrates\sthe\sneed\sto\sfactor\sOP_Column\noperators\sout\sof\sinner\sloops. +D 2013-12-21T00:04:37.543 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -822,7 +822,7 @@ F test/speed3.test d32043614c08c53eafdc80f33191d5bd9b920523 F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b -F test/speedtest1.c 47788d552a349241471ad06d239383dadd97164d +F test/speedtest1.c 60d9ebc64c036ee7803cc5323ef5204686312f5b F test/spellfix.test 8c40b169b104086d8795781f670ba3c786d6d8be F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298 F test/stat.test 76fd746b85459e812a0193410fb599f0531f22de @@ -1147,7 +1147,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 0026d3355340d66687a3fd4cbece28811ef1b505 -R 1e7ba7ea1368145f32bc284eea0efbfc +P d93ae6833a7fca0672caf902a7b48846e54242cd +R 1bba9a023d69c9c6d571dcfd3bfe83d6 U drh -Z b38a5e6618ad563a8f912c35a2908336 +Z 60543214dfc95183844c1868498ec509 diff --git a/manifest.uuid b/manifest.uuid index ab92cc76ab..d06af4fa26 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d93ae6833a7fca0672caf902a7b48846e54242cd \ No newline at end of file +69a17336fdf4ae891e815914be8942f7222230c2 \ No newline at end of file diff --git a/test/speedtest1.c b/test/speedtest1.c index 51735de02a..6137720ee0 100644 --- a/test/speedtest1.c +++ b/test/speedtest1.c @@ -378,6 +378,19 @@ static void randomFunc( sqlite3_result_int64(context, (sqlite3_int64)speedtest1_random()); } +/* Estimate the square root of an integer */ +static int est_square_root(int x){ + int y0 = x/2; + int y1; + int n; + for(n=0; y0>0 && n<10; n++){ + y1 = (y0 + x/y0)/2; + if( y1==y0 ) break; + y0 = y1; + } + return y0; +} + /* ** The main and default testset */ @@ -692,7 +705,15 @@ void testset_main(void){ speedtest1_exec("COMMIT"); speedtest1_end_test(); - + speedtest1_begin_test(320, "subquery in result set", n); + speedtest1_prepare( + "SELECT sum(a), max(c),\n" + " avg((SELECT a FROM t2 WHERE 5+t2.b=t1.b) AND rowid Date: Sat, 21 Dec 2013 15:46:06 +0000 Subject: [PATCH 102/276] Fix the ".echo on" dot-command of the shell so that it echos comments in addition to SQL statements and dot-commands. Add the --explain option to speedtest1 so that the output can be piped into the command-line shell to show nicely-formated VDBE code for the entire test. FossilOrigin-Name: 96397263f94256e284aae9506de1fc48fea89193 --- manifest | 16 ++++++------- manifest.uuid | 2 +- src/shell.c | 6 ++++- test/shell2.test | 6 +++-- test/speedtest1.c | 60 +++++++++++++++++++++++++++++------------------ 5 files changed, 55 insertions(+), 35 deletions(-) diff --git a/manifest b/manifest index 54ee0ed6bb..d556779ff4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\scase\sto\sspeedtest1.c\sthat\sdemonstrates\sthe\sneed\sto\sfactor\sOP_Column\noperators\sout\sof\sinner\sloops. -D 2013-12-21T00:04:37.543 +C Fix\sthe\s".echo\son"\sdot-command\sof\sthe\sshell\sso\sthat\sit\sechos\scomments\sin\naddition\sto\sSQL\sstatements\sand\sdot-commands.\s\sAdd\sthe\s--explain\soption\nto\sspeedtest1\sso\sthat\sthe\soutput\scan\sbe\spiped\sinto\sthe\scommand-line\sshell\nto\sshow\snicely-formated\sVDBE\scode\sfor\sthe\sentire\stest. +D 2013-12-21T15:46:06.562 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -220,7 +220,7 @@ F src/random.c 0b2dbc37fdfbfa6bd455b091dfcef5bdb32dba68 F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c 819bb090c9a348d17f69f136cad2bfa9ee9cbb41 -F src/shell.c 18924f6ccfa70da98bf9e388bab512c0fd1e792e +F src/shell.c a3541193d5fce37e91dad8ef46a9505aa7c9b344 F src/sqlite.h.in 4ef56464aeaa3785a2c5ca37fb3a0fb229d68b2e F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc @@ -802,7 +802,7 @@ F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5 F test/shared_err.test 0079c05c97d88cfa03989b7c20a8b266983087aa F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304 F test/shell1.test e7c0b9ebda25d5e78f0a3ea0dc4e31bb6d8098c0 -F test/shell2.test e1d3790f064e50b2f973502f45750012667486df +F test/shell2.test c57da3a381c099b02c813ba156298d5c2f5c93a3 F test/shell3.test 5e8545ec72c4413a0e8d4c6be56496e3c257ca29 F test/shell4.test aa4eef8118b412d1a01477a53426ece169ea86a9 F test/shell5.test cee83b4385f842fec1f2a0bec9ea811f35386edf @@ -822,7 +822,7 @@ F test/speed3.test d32043614c08c53eafdc80f33191d5bd9b920523 F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b -F test/speedtest1.c 60d9ebc64c036ee7803cc5323ef5204686312f5b +F test/speedtest1.c 0fb5502e0879e18991e7ecc791b41ba1c7fa74e8 F test/spellfix.test 8c40b169b104086d8795781f670ba3c786d6d8be F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298 F test/stat.test 76fd746b85459e812a0193410fb599f0531f22de @@ -1147,7 +1147,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P d93ae6833a7fca0672caf902a7b48846e54242cd -R 1bba9a023d69c9c6d571dcfd3bfe83d6 +P 69a17336fdf4ae891e815914be8942f7222230c2 +R f8c33eb19f28c61795b29a236555d23d U drh -Z 60543214dfc95183844c1868498ec509 +Z 526508e712c84b42d21bbec0b02b9c9e diff --git a/manifest.uuid b/manifest.uuid index d06af4fa26..b9cf9f2e0b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -69a17336fdf4ae891e815914be8942f7222230c2 \ No newline at end of file +96397263f94256e284aae9506de1fc48fea89193 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 7826fdf204..00cff6a8e5 100644 --- a/src/shell.c +++ b/src/shell.c @@ -3038,7 +3038,10 @@ static int process_input(struct callback_data *p, FILE *in){ seenInterrupt = 0; } lineno++; - if( nSql==0 && _all_whitespace(zLine) ) continue; + if( nSql==0 && _all_whitespace(zLine) ){ + if( p->echoOn ) printf("%s\n", zLine); + continue; + } if( zLine && zLine[0]=='.' && nSql==0 ){ if( p->echoOn ) printf("%s\n", zLine); rc = do_meta_command(zLine, p); @@ -3100,6 +3103,7 @@ static int process_input(struct callback_data *p, FILE *in){ } nSql = 0; }else if( nSql && _all_whitespace(zSql) ){ + if( p->echoOn ) printf("%s\n", zSql); nSql = 0; } } diff --git a/test/shell2.test b/test/shell2.test index f02d788415..def574c76c 100644 --- a/test/shell2.test +++ b/test/shell2.test @@ -155,7 +155,8 @@ SELECT * FROM foo1; 2 SELECT * FROM foo2; 1 -2}} +2 +}} # Test with echo on and headers on using dot command and # multiple commands per line. @@ -192,6 +193,7 @@ a SELECT * FROM foo2; b 1 -2}} +2 +}} finish_test diff --git a/test/speedtest1.c b/test/speedtest1.c index 6137720ee0..57d21b26c4 100644 --- a/test/speedtest1.c +++ b/test/speedtest1.c @@ -9,6 +9,7 @@ static const char zHelp[] = " --autovacuum Enable AUTOVACUUM mode\n" " --cachesize N Set the cache size to N\n" " --exclusive Enable locking_mode=EXCLUSIVE\n" + " --explain Like --sqlonly but with added EXPLAIN keywords\n" " --heap SZ MIN Memory allocator uses SZ bytes & min allocation MIN\n" " --incrvacuum Enable incremenatal vacuum mode\n" " --journalmode M Set the journal_mode to MODE\n" @@ -49,6 +50,7 @@ static struct Global { int bWithoutRowid; /* True for --without-rowid */ int bReprepare; /* True to reprepare the SQL on each rerun */ int bSqlOnly; /* True to print the SQL once only */ + int bExplain; /* Print SQL with EXPLAIN prefix */ int szTest; /* Scale factor for test iterations */ const char *zWR; /* Might be WITHOUT ROWID */ const char *zNN; /* Might be NOT NULL */ @@ -290,6 +292,22 @@ void speedtest1_final(void){ } } +/* Print an SQL statement to standard output */ +static void printSql(const char *zSql){ + int n = (int)strlen(zSql); + while( n>0 && (zSql[n-1]==';' || isspace(zSql[n-1])) ){ n--; } + if( g.bExplain ) printf("EXPLAIN "); + printf("%.*s;\n", n, zSql); + if( g.bExplain + && (sqlite3_strglob("CREATE *", zSql) + || sqlite3_strglob("DROP *", zSql) + || sqlite3_strglob("ALTER *", zSql) + ) + ){ + printf("%.*s;\n", n, zSql); + } +} + /* Run SQL */ void speedtest1_exec(const char *zFormat, ...){ va_list ap; @@ -298,9 +316,7 @@ void speedtest1_exec(const char *zFormat, ...){ zSql = sqlite3_vmprintf(zFormat, ap); va_end(ap); if( g.bSqlOnly ){ - int n = (int)strlen(zSql); - while( n>0 && (zSql[n-1]==';' || isspace(zSql[n-1])) ){ n--; } - printf("%.*s;\n", n, zSql); + printSql(zSql); }else{ char *zErrMsg = 0; int rc = sqlite3_exec(g.db, zSql, 0, 0, &zErrMsg); @@ -318,9 +334,7 @@ void speedtest1_prepare(const char *zFormat, ...){ zSql = sqlite3_vmprintf(zFormat, ap); va_end(ap); if( g.bSqlOnly ){ - int n = (int)strlen(zSql); - while( n>0 && (zSql[n-1]==';' || isspace(zSql[n-1])) ){ n--; } - printf("%.*s;\n", n, zSql); + printSql(zSql); }else{ int rc; if( g.pStmt ) sqlite3_finalize(g.pStmt); @@ -497,15 +511,13 @@ void testset_main(void){ speedtest1_begin_test(150, "CREATE INDEX five times"); - speedtest1_exec( - "BEGIN;\n" - "CREATE UNIQUE INDEX t1b ON t1(b);\n" - "CREATE INDEX t1c ON t1(c);\n" - "CREATE UNIQUE INDEX t2b ON t2(b);\n" - "CREATE INDEX t2c ON t2(c DESC);\n" - "CREATE INDEX t3bc ON t3(b,c);\n" - "COMMIT;\n" - ); + speedtest1_exec("BEGIN;"); + speedtest1_exec("CREATE UNIQUE INDEX t1b ON t1(b);"); + speedtest1_exec("CREATE INDEX t1c ON t1(c);"); + speedtest1_exec("CREATE UNIQUE INDEX t2b ON t2(b);"); + speedtest1_exec("CREATE INDEX t2c ON t2(c DESC);"); + speedtest1_exec("CREATE INDEX t3bc ON t3(b,c);"); + speedtest1_exec("COMMIT;"); speedtest1_end_test(); @@ -579,10 +591,8 @@ void testset_main(void){ n = sz; speedtest1_begin_test(190, "DELETE and REFILL one table", n); - speedtest1_exec( - "DELETE FROM t2;" - "INSERT INTO t2 SELECT * FROM t1;" - ); + speedtest1_exec("DELETE FROM t2;"); + speedtest1_exec("INSERT INTO t2 SELECT * FROM t1;"); speedtest1_end_test(); @@ -678,10 +688,10 @@ void testset_main(void){ speedtest1_begin_test(300, "Refill a %d-row table using (b&1)==(a&1)", sz); speedtest1_exec("DELETE FROM t2;"); - speedtest1_exec( - "INSERT INTO t2(a,b,c) SELECT a,b,c FROM t1 WHERE (b&1)==(a&1);" - "INSERT INTO t2(a,b,c) SELECT a,b,c FROM t1 WHERE (b&1)<>(a&1);" - ); + speedtest1_exec("INSERT INTO t2(a,b,c)\n" + " SELECT a,b,c FROM t1 WHERE (b&1)==(a&1);"); + speedtest1_exec("INSERT INTO t2(a,b,c)\n" + " SELECT a,b,c FROM t1 WHERE (b&1)<>(a&1);"); speedtest1_end_test(); @@ -786,6 +796,9 @@ int main(int argc, char **argv){ cacheSize = integerValue(argv[i]); }else if( strcmp(z,"exclusive")==0 ){ doExclusive = 1; + }else if( strcmp(z,"explain")==0 ){ + g.bSqlOnly = 1; + g.bExplain = 1; }else if( strcmp(z,"heap")==0 ){ if( i>=argc-2 ) fatal_error("missing arguments on %s\n", argv[i]); nHeap = integerValue(argv[i+1]); @@ -925,6 +938,7 @@ int main(int argc, char **argv){ speedtest1_exec("PRAGMA journal_mode=%s", zJMode); } + if( g.bExplain ) printf(".explain\n.echo on\n"); if( strcmp(zTSet,"main")==0 ){ testset_main(); }else if( strcmp(zTSet,"debug1")==0 ){ From c73d0d9dec4aae044a020b88c526a485dcb2ab3b Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 21 Dec 2013 16:06:47 +0000 Subject: [PATCH 103/276] Fix harmless compiler warnings in FTS4. This involved corrupting Martin Porter's beautifully written and elegant stemmer code, making it a little less beautiful and a little less elegant. Today is a sad day. But the warnings from GCC grow increasingly verbose and irksome with each new release and so something had to be done. FossilOrigin-Name: df05679838b571c16a7ab7e135f9564cd2d9647c --- ext/fts3/fts3_porter.c | 74 +++++++++++++++++++++++++----------------- manifest | 12 +++---- manifest.uuid | 2 +- 3 files changed, 52 insertions(+), 36 deletions(-) diff --git a/ext/fts3/fts3_porter.c b/ext/fts3/fts3_porter.c index 579745b85f..db175acdbb 100644 --- a/ext/fts3/fts3_porter.c +++ b/ext/fts3/fts3_porter.c @@ -403,12 +403,14 @@ static void porter_stemmer(const char *zIn, int nIn, char *zOut, int *pnOut){ /* Step 2 */ switch( z[1] ){ case 'a': - stem(&z, "lanoita", "ate", m_gt_0) || - stem(&z, "lanoit", "tion", m_gt_0); + if( !stem(&z, "lanoita", "ate", m_gt_0) ){ + stem(&z, "lanoit", "tion", m_gt_0); + } break; case 'c': - stem(&z, "icne", "ence", m_gt_0) || - stem(&z, "icna", "ance", m_gt_0); + if( !stem(&z, "icne", "ence", m_gt_0) ){ + stem(&z, "icna", "ance", m_gt_0); + } break; case 'e': stem(&z, "rezi", "ize", m_gt_0); @@ -417,43 +419,54 @@ static void porter_stemmer(const char *zIn, int nIn, char *zOut, int *pnOut){ stem(&z, "igol", "log", m_gt_0); break; case 'l': - stem(&z, "ilb", "ble", m_gt_0) || - stem(&z, "illa", "al", m_gt_0) || - stem(&z, "iltne", "ent", m_gt_0) || - stem(&z, "ile", "e", m_gt_0) || - stem(&z, "ilsuo", "ous", m_gt_0); + if( !stem(&z, "ilb", "ble", m_gt_0) + && !stem(&z, "illa", "al", m_gt_0) + && !stem(&z, "iltne", "ent", m_gt_0) + && !stem(&z, "ile", "e", m_gt_0) + ){ + stem(&z, "ilsuo", "ous", m_gt_0); + } break; case 'o': - stem(&z, "noitazi", "ize", m_gt_0) || - stem(&z, "noita", "ate", m_gt_0) || - stem(&z, "rota", "ate", m_gt_0); + if( !stem(&z, "noitazi", "ize", m_gt_0) + && !stem(&z, "noita", "ate", m_gt_0) + ){ + stem(&z, "rota", "ate", m_gt_0); + } break; case 's': - stem(&z, "msila", "al", m_gt_0) || - stem(&z, "ssenevi", "ive", m_gt_0) || - stem(&z, "ssenluf", "ful", m_gt_0) || - stem(&z, "ssensuo", "ous", m_gt_0); + if( !stem(&z, "msila", "al", m_gt_0) + && !stem(&z, "ssenevi", "ive", m_gt_0) + && !stem(&z, "ssenluf", "ful", m_gt_0) + ){ + stem(&z, "ssensuo", "ous", m_gt_0); + } break; case 't': - stem(&z, "itila", "al", m_gt_0) || - stem(&z, "itivi", "ive", m_gt_0) || - stem(&z, "itilib", "ble", m_gt_0); + if( !stem(&z, "itila", "al", m_gt_0) + && !stem(&z, "itivi", "ive", m_gt_0) + ){ + stem(&z, "itilib", "ble", m_gt_0); + } break; } /* Step 3 */ switch( z[0] ){ case 'e': - stem(&z, "etaci", "ic", m_gt_0) || - stem(&z, "evita", "", m_gt_0) || - stem(&z, "ezila", "al", m_gt_0); + if( !stem(&z, "etaci", "ic", m_gt_0) + && !stem(&z, "evita", "", m_gt_0) + ){ + stem(&z, "ezila", "al", m_gt_0); + } break; case 'i': stem(&z, "itici", "ic", m_gt_0); break; case 'l': - stem(&z, "laci", "ic", m_gt_0) || - stem(&z, "luf", "", m_gt_0); + if( !stem(&z, "laci", "ic", m_gt_0) ){ + stem(&z, "luf", "", m_gt_0); + } break; case 's': stem(&z, "ssen", "", m_gt_0); @@ -494,9 +507,11 @@ static void porter_stemmer(const char *zIn, int nIn, char *zOut, int *pnOut){ z += 3; } }else if( z[2]=='e' ){ - stem(&z, "tneme", "", m_gt_1) || - stem(&z, "tnem", "", m_gt_1) || - stem(&z, "tne", "", m_gt_1); + if( !stem(&z, "tneme", "", m_gt_1) + && !stem(&z, "tnem", "", m_gt_1) + ){ + stem(&z, "tne", "", m_gt_1); + } } } break; @@ -515,8 +530,9 @@ static void porter_stemmer(const char *zIn, int nIn, char *zOut, int *pnOut){ } break; case 't': - stem(&z, "eta", "", m_gt_1) || - stem(&z, "iti", "", m_gt_1); + if( !stem(&z, "eta", "", m_gt_1) ){ + stem(&z, "iti", "", m_gt_1); + } break; case 'u': if( z[0]=='s' && z[2]=='o' && m_gt_1(z+3) ){ diff --git a/manifest b/manifest index d556779ff4..4d7a6ae0c8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\s".echo\son"\sdot-command\sof\sthe\sshell\sso\sthat\sit\sechos\scomments\sin\naddition\sto\sSQL\sstatements\sand\sdot-commands.\s\sAdd\sthe\s--explain\soption\nto\sspeedtest1\sso\sthat\sthe\soutput\scan\sbe\spiped\sinto\sthe\scommand-line\sshell\nto\sshow\snicely-formated\sVDBE\scode\sfor\sthe\sentire\stest. -D 2013-12-21T15:46:06.562 +C Fix\sharmless\scompiler\swarnings\sin\sFTS4.\s\sThis\sinvolved\scorrupting\nMartin\sPorter's\sbeautifully\swritten\sand\selegant\sstemmer\scode,\smaking\sit\na\slittle\sless\sbeautiful\sand\sa\slittle\sless\selegant.\s\sToday\sis\sa\ssad\nday.\s\sBut\sthe\swarnings\sfrom\sGCC\sgrow\sincreasingly\sverbose\sand\sirksome\nwith\seach\snew\srelease\sand\sso\ssomething\shad\sto\sbe\sdone. +D 2013-12-21T16:06:47.439 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -86,7 +86,7 @@ F ext/fts3/fts3_expr.c 5165c365cb5a035f5be8bb296f7aa3211d43e4ac F ext/fts3/fts3_hash.c 8dd2d06b66c72c628c2732555a32bc0943114914 F ext/fts3/fts3_hash.h 39cf6874dc239d6b4e30479b1975fe5b22a3caaf F ext/fts3/fts3_icu.c e319e108661147bcca8dd511cd562f33a1ba81b5 -F ext/fts3/fts3_porter.c a465b49fcb8249a755792f87516eff182efa42b3 +F ext/fts3/fts3_porter.c 7f8b4bf5af7c0f20f73b8e87e14fa9298f52e290 F ext/fts3/fts3_snippet.c 51beb5c1498176fd9caccaf1c75b55cb803a985a F ext/fts3/fts3_term.c a521f75132f9a495bdca1bdd45949b3191c52763 F ext/fts3/fts3_test.c 8a3a78c4458b2d7c631fcf4b152a5cd656fa7038 @@ -1147,7 +1147,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 69a17336fdf4ae891e815914be8942f7222230c2 -R f8c33eb19f28c61795b29a236555d23d +P 96397263f94256e284aae9506de1fc48fea89193 +R 38a4e7eb09a43c5c635590012754b8d4 U drh -Z 526508e712c84b42d21bbec0b02b9c9e +Z dfc0154e1251c61263e69daa57fb4f97 diff --git a/manifest.uuid b/manifest.uuid index b9cf9f2e0b..f8cb2fecf0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -96397263f94256e284aae9506de1fc48fea89193 \ No newline at end of file +df05679838b571c16a7ab7e135f9564cd2d9647c \ No newline at end of file From 685e3c481c2910938621ae8522ab596d31ad1393 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 21 Dec 2013 17:07:13 +0000 Subject: [PATCH 104/276] Avoid compiler warnings by only enabling sqlite3ErrName() when SQLITE_TEST is defined. FossilOrigin-Name: 862228e50534a6b89c9498c4db664610db11485e --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/main.c | 3 +-- src/sqliteInt.h | 3 +-- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 4d7a6ae0c8..adef4b0eac 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings\sin\sFTS4.\s\sThis\sinvolved\scorrupting\nMartin\sPorter's\sbeautifully\swritten\sand\selegant\sstemmer\scode,\smaking\sit\na\slittle\sless\sbeautiful\sand\sa\slittle\sless\selegant.\s\sToday\sis\sa\ssad\nday.\s\sBut\sthe\swarnings\sfrom\sGCC\sgrow\sincreasingly\sverbose\sand\sirksome\nwith\seach\snew\srelease\sand\sso\ssomething\shad\sto\sbe\sdone. -D 2013-12-21T16:06:47.439 +C Avoid\scompiler\swarnings\sby\sonly\senabling\ssqlite3ErrName()\swhen\nSQLITE_TEST\sis\sdefined. +D 2013-12-21T17:07:13.208 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -188,7 +188,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b F src/loadext.c 867c7b330b740c6c917af9956b13b81d0a048303 -F src/main.c 3f00c4adfb5e5dc35b475dbdd475aba83ccf3d17 +F src/main.c 5307601c58b6e08153a15846098399a59c166d8d F src/malloc.c 0203ebce9152c6a0e5de520140b8ba65187350be F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c0c990fcaddff810ea277b4fb5d9138603dd5d4b @@ -224,7 +224,7 @@ F src/shell.c a3541193d5fce37e91dad8ef46a9505aa7c9b344 F src/sqlite.h.in 4ef56464aeaa3785a2c5ca37fb3a0fb229d68b2e F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h d0815177df125e900056e1e692504435e7610793 +F src/sqliteInt.h 49c7a1223cbe2323a94b1913ed0b0ce946d83278 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -1147,7 +1147,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 96397263f94256e284aae9506de1fc48fea89193 -R 38a4e7eb09a43c5c635590012754b8d4 +P df05679838b571c16a7ab7e135f9564cd2d9647c +R 4daa825d059abf8b202bf30d8a3dabe0 U drh -Z dfc0154e1251c61263e69daa57fb4f97 +Z 3cf2241a5e425a53db01dda8b63c0d1d diff --git a/manifest.uuid b/manifest.uuid index f8cb2fecf0..9f7e8acbd2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -df05679838b571c16a7ab7e135f9564cd2d9647c \ No newline at end of file +862228e50534a6b89c9498c4db664610db11485e \ No newline at end of file diff --git a/src/main.c b/src/main.c index d181d6fa00..fff1bc42e6 100644 --- a/src/main.c +++ b/src/main.c @@ -1062,8 +1062,7 @@ void sqlite3RollbackAll(sqlite3 *db, int tripCode){ ** Return a static string containing the name corresponding to the error code ** specified in the argument. */ -#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) || \ - defined(SQLITE_DEBUG_OS_TRACE) +#if defined(SQLITE_TEST) const char *sqlite3ErrName(int rc){ const char *zName = 0; int i, origRc = rc; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index a33ff4d43b..ce366dc480 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3138,8 +3138,7 @@ void *sqlite3HexToBlob(sqlite3*, const char *z, int n); u8 sqlite3HexToInt(int h); int sqlite3TwoPartName(Parse *, Token *, Token *, Token **); -#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) || \ - defined(SQLITE_DEBUG_OS_TRACE) +#if defined(SQLITE_TEST) const char *sqlite3ErrName(int); #endif From 25555506df6421bbc11fd388b001307f41f5925b Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 21 Dec 2013 17:14:58 +0000 Subject: [PATCH 105/276] Fix speedtest1.c so that in --explain mode it only outputs non-explain text for DDL statements. FossilOrigin-Name: 2d2b3c4951dc2b8317d5ba8b5cf72b1f4a6668f6 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/speedtest1.c | 8 +++++--- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index adef4b0eac..598056669e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\scompiler\swarnings\sby\sonly\senabling\ssqlite3ErrName()\swhen\nSQLITE_TEST\sis\sdefined. -D 2013-12-21T17:07:13.208 +C Fix\sspeedtest1.c\sso\sthat\sin\s--explain\smode\sit\sonly\soutputs\snon-explain\stext\nfor\sDDL\sstatements. +D 2013-12-21T17:14:58.114 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -822,7 +822,7 @@ F test/speed3.test d32043614c08c53eafdc80f33191d5bd9b920523 F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b -F test/speedtest1.c 0fb5502e0879e18991e7ecc791b41ba1c7fa74e8 +F test/speedtest1.c 7130d2cb6db45baa553a4ab2f715116c71c2d9f4 F test/spellfix.test 8c40b169b104086d8795781f670ba3c786d6d8be F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298 F test/stat.test 76fd746b85459e812a0193410fb599f0531f22de @@ -1147,7 +1147,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P df05679838b571c16a7ab7e135f9564cd2d9647c -R 4daa825d059abf8b202bf30d8a3dabe0 +P 862228e50534a6b89c9498c4db664610db11485e +R 33225661bd52597ad2aaeac8ae83129d U drh -Z 3cf2241a5e425a53db01dda8b63c0d1d +Z dddf4f7b316491b40bac25a13a27215d diff --git a/manifest.uuid b/manifest.uuid index 9f7e8acbd2..ab613f509c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -862228e50534a6b89c9498c4db664610db11485e \ No newline at end of file +2d2b3c4951dc2b8317d5ba8b5cf72b1f4a6668f6 \ No newline at end of file diff --git a/test/speedtest1.c b/test/speedtest1.c index 57d21b26c4..38f891e431 100644 --- a/test/speedtest1.c +++ b/test/speedtest1.c @@ -299,10 +299,12 @@ static void printSql(const char *zSql){ if( g.bExplain ) printf("EXPLAIN "); printf("%.*s;\n", n, zSql); if( g.bExplain - && (sqlite3_strglob("CREATE *", zSql) - || sqlite3_strglob("DROP *", zSql) - || sqlite3_strglob("ALTER *", zSql) +#if SQLITE_VERSION_NUMBER>=3007010 + && ( sqlite3_strglob("CREATE *", zSql)==0 + || sqlite3_strglob("DROP *", zSql)==0 + || sqlite3_strglob("ALTER *", zSql)==0 ) +#endif ){ printf("%.*s;\n", n, zSql); } From 6c1de308f284ace4ec8860d5d2a39ebdc996913b Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 22 Dec 2013 20:44:10 +0000 Subject: [PATCH 106/276] Make sure the WhereLoop.aLTerm[] array is large enough when processing the skip-scan optimization. Fix for ticket [520070ec7fbaac]. FossilOrigin-Name: 46d040591f27be01b1860344f8a268797fe344f4 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 1 + test/skipscan1.test | 22 ++++++++++++++++++++++ 4 files changed, 31 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 598056669e..8c8312dca6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sspeedtest1.c\sso\sthat\sin\s--explain\smode\sit\sonly\soutputs\snon-explain\stext\nfor\sDDL\sstatements. -D 2013-12-21T17:14:58.114 +C Make\ssure\sthe\sWhereLoop.aLTerm[]\sarray\sis\slarge\senough\swhen\sprocessing\nthe\sskip-scan\soptimization.\s\sFix\sfor\sticket\s[520070ec7fbaac]. +D 2013-12-22T20:44:10.723 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -293,7 +293,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c e9e593d5bb798c3e67fc3893dfe7055c9e7d8d74 -F src/where.c b8f3aab1e5843012895b89a183dcdd6cef0708db +F src/where.c 60bc8c5b00e2292c24a42455d022eeeda33a16f1 F src/whereInt.h 96a75c61f1d2b9d4a8e4bb17d89deb0cf7cba358 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -809,7 +809,7 @@ F test/shell5.test cee83b4385f842fec1f2a0bec9ea811f35386edf F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3 F test/shrink.test 8c70f62b6e8eb4d54533de6d65bd06b1b9a17868 F test/sidedelete.test f0ad71abe6233e3b153100f3b8d679b19a488329 -F test/skipscan1.test 6bb4891c2cc5efd5690a9da9e7508e53d4a68e10 +F test/skipscan1.test 8c777ffd9dad6ee6d2568160cb2158f0b5cd9dd2 F test/skipscan2.test 5a4db0799c338ddbacb154aaa5589c0254b36a8d F test/soak.test 0b5b6375c9f4110c828070b826b3b4b0bb65cd5f F test/softheap1.test 40562fe6cac6d9827b7b42b86d45aedf12c15e24 @@ -1147,7 +1147,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 862228e50534a6b89c9498c4db664610db11485e -R 33225661bd52597ad2aaeac8ae83129d +P 2d2b3c4951dc2b8317d5ba8b5cf72b1f4a6668f6 +R 7e8e2aceb29a9b78ef373006c69590e7 U drh -Z dddf4f7b316491b40bac25a13a27215d +Z 57f75659f99699708c34bb9af2294488 diff --git a/manifest.uuid b/manifest.uuid index ab613f509c..899b76fa4e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2d2b3c4951dc2b8317d5ba8b5cf72b1f4a6668f6 \ No newline at end of file +46d040591f27be01b1860344f8a268797fe344f4 \ No newline at end of file diff --git a/src/where.c b/src/where.c index afe664aa02..59028b9921 100644 --- a/src/where.c +++ b/src/where.c @@ -3928,6 +3928,7 @@ static int whereLoopAddBtreeIndex( && saved_nEq==saved_nSkip && saved_nEq+1nKeyCol && pProbe->aiRowEst[saved_nEq+1]>=18 /* TUNING: Minimum for skip-scan */ + && (rc = whereLoopResize(db, pNew, pNew->nLTerm+1))==SQLITE_OK ){ LogEst nIter; pNew->u.btree.nEq++; diff --git a/test/skipscan1.test b/test/skipscan1.test index 622e48fcfa..b9eaf2729b 100644 --- a/test/skipscan1.test +++ b/test/skipscan1.test @@ -187,4 +187,26 @@ do_execsql_test skipscan1-3.2sort { SELECT a,b,c,d,'|' FROM t3 WHERE b=345 ORDER BY a; } {~/*ORDER BY*/} +# Ticket 520070ec7fbaac: Array overrun in the skip-scan optimization +# 2013-12-22 +# +do_execsql_test skipscan1-4.1 { + CREATE TABLE t4(a,b,c,d,e,f,g,h,i); + CREATE INDEX t4all ON t4(a,b,c,d,e,f,g,h); + INSERT INTO t4 VALUES(1,2,3,4,5,6,7,8,9); + ANALYZE; + DELETE FROM sqlite_stat1; + INSERT INTO sqlite_stat1 + VALUES('t4','t4all','655360 163840 40960 10240 2560 640 160 40 10'); + ANALYZE sqlite_master; + SELECT i FROM t4 WHERE a=1; + SELECT i FROM t4 WHERE b=2; + SELECT i FROM t4 WHERE c=3; + SELECT i FROM t4 WHERE d=4; + SELECT i FROM t4 WHERE e=5; + SELECT i FROM t4 WHERE f=6; + SELECT i FROM t4 WHERE g=7; + SELECT i FROM t4 WHERE h=8; +} {9 9 9 9 9 9 9 9} + finish_test From eaf4f523a5e28835fe6dd638f1a968e500037576 Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 22 Dec 2013 22:45:14 +0000 Subject: [PATCH 107/276] Remove a condition that is always in the logic that handles reading default values for columns. FossilOrigin-Name: 895af097e71749f423b63ece17c5a4b4dfcd164d --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/update.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 8c8312dca6..4e35cbf529 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\sthe\sWhereLoop.aLTerm[]\sarray\sis\slarge\senough\swhen\sprocessing\nthe\sskip-scan\soptimization.\s\sFix\sfor\sticket\s[520070ec7fbaac]. -D 2013-12-22T20:44:10.723 +C Remove\sa\scondition\sthat\sis\salways\sin\sthe\slogic\sthat\shandles\sreading\ndefault\svalues\sfor\scolumns. +D 2013-12-22T22:45:14.083 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -276,7 +276,7 @@ F src/test_vfstrace.c 3a0ab304682fecbceb689e7d9b904211fde11d78 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/tokenize.c ec4c1a62b890bf1dbcdb966399e140b904c700a4 F src/trigger.c d84e1f3669e9a217731a14a9d472b1c7b87c87ba -F src/update.c 47baf532e3ecec8e4093f92d613384f66785fc2f +F src/update.c c2706a6eb232a96345c35b7e1e75a188e26812bb F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c e71f19b272f05c8695cf747b4bac1732685f9e5c F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 @@ -1147,7 +1147,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 2d2b3c4951dc2b8317d5ba8b5cf72b1f4a6668f6 -R 7e8e2aceb29a9b78ef373006c69590e7 +P 46d040591f27be01b1860344f8a268797fe344f4 +R bad123e1d8507f7c1555170369546428 U drh -Z 57f75659f99699708c34bb9af2294488 +Z 0c66906b8c25c31efd308428f5c19196 diff --git a/manifest.uuid b/manifest.uuid index 899b76fa4e..8fca22d7fb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -46d040591f27be01b1860344f8a268797fe344f4 \ No newline at end of file +895af097e71749f423b63ece17c5a4b4dfcd164d \ No newline at end of file diff --git a/src/update.c b/src/update.c index b7f0363c1a..d62d0d3245 100644 --- a/src/update.c +++ b/src/update.c @@ -72,7 +72,7 @@ void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){ sqlite3VdbeChangeP4(v, -1, (const char *)pValue, P4_MEM); } #ifndef SQLITE_OMIT_FLOATING_POINT - if( iReg>=0 && pTab->aCol[i].affinity==SQLITE_AFF_REAL ){ + if( pTab->aCol[i].affinity==SQLITE_AFF_REAL ){ sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg); } #endif From 58c960816f2a54e15631871d20daca2ddb9d2e00 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 23 Dec 2013 11:33:32 +0000 Subject: [PATCH 108/276] Remove a stray tab character. FossilOrigin-Name: 25b8a1c9ba77df3b7c78cbce922cb593d661696d --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 4e35cbf529..cfc44fed4f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sa\scondition\sthat\sis\salways\sin\sthe\slogic\sthat\shandles\sreading\ndefault\svalues\sfor\scolumns. -D 2013-12-22T22:45:14.083 +C Remove\sa\sstray\stab\scharacter. +D 2013-12-23T11:33:32.196 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -280,7 +280,7 @@ F src/update.c c2706a6eb232a96345c35b7e1e75a188e26812bb F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c e71f19b272f05c8695cf747b4bac1732685f9e5c F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c 6bcf27a80c3fdffee649f12eae91522718a06a64 +F src/vdbe.c b110887e415b5d2af58c2374c4dfdcf774c5d46c F src/vdbe.h c3278ab2b410f17acf61faf91be7bce3fd466e8b F src/vdbeInt.h 8a4d2d69955570bb74a092c3cdbab04afb554963 F src/vdbeapi.c ce4e68ea4842cc6081046f533d088dcf01d247ad @@ -1147,7 +1147,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 46d040591f27be01b1860344f8a268797fe344f4 -R bad123e1d8507f7c1555170369546428 +P 895af097e71749f423b63ece17c5a4b4dfcd164d +R edca4657a892a426dbd4ee6318480a5d U drh -Z 0c66906b8c25c31efd308428f5c19196 +Z a6e6f91b61427f170fce17908ed5a512 diff --git a/manifest.uuid b/manifest.uuid index 8fca22d7fb..d403ad35b8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -895af097e71749f423b63ece17c5a4b4dfcd164d \ No newline at end of file +25b8a1c9ba77df3b7c78cbce922cb593d661696d \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index bbc6d3f7f6..286bc45ba3 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2454,7 +2454,7 @@ case OP_Column: { VdbeMemRelease(pDest); sqlite3VdbeSerialGet(pC->aRow+aOffset[p2], aType[p2], pDest); }else{ - /* This branch happens only when content is on overflow pages */ + /* This branch happens only when content is on overflow pages */ t = aType[p2]; if( ((pOp->p5 & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG))!=0 && ((t>=12 && (t&1)==0) || (pOp->p5 & OPFLAG_TYPEOFARG)!=0)) From 73d5b8f5502c3c6428cf3ba559ff906a21be716a Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 23 Dec 2013 19:09:07 +0000 Subject: [PATCH 109/276] Move elements of the Vdbe object that are only used during statement preparation out into the Parse object. FossilOrigin-Name: c289a253c0c053ac8fc344efe138262c327d8096 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/prepare.c | 6 +++++- src/sqliteInt.h | 3 +++ src/vdbeInt.h | 7 +------ src/vdbeaux.c | 44 +++++++++++++++++++++++++------------------- 6 files changed, 44 insertions(+), 36 deletions(-) diff --git a/manifest b/manifest index cfc44fed4f..1efd07ffd6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sa\sstray\stab\scharacter. -D 2013-12-23T11:33:32.196 +C Move\selements\sof\sthe\sVdbe\sobject\sthat\sare\sonly\sused\sduring\sstatement\npreparation\sout\sinto\sthe\sParse\sobject. +D 2013-12-23T19:09:07.173 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -214,7 +214,7 @@ F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222 F src/pcache1.c 57fee9a9a617218f5037afbbe49b09da65bde56b F src/pragma.c 5ab7279d132143feb77f773688a24ab05da75fd7 -F src/prepare.c 359d1a1e9c9bd4488e4dd3a1aaaf2d2ebb9bb768 +F src/prepare.c 677521ab7132615a8a26107a1d1c3132f44ae337 F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c 0b2dbc37fdfbfa6bd455b091dfcef5bdb32dba68 F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 @@ -224,7 +224,7 @@ F src/shell.c a3541193d5fce37e91dad8ef46a9505aa7c9b344 F src/sqlite.h.in 4ef56464aeaa3785a2c5ca37fb3a0fb229d68b2e F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h 49c7a1223cbe2323a94b1913ed0b0ce946d83278 +F src/sqliteInt.h fdb8c1e4bc5424ad82a9394a845781abf0d7d849 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -282,9 +282,9 @@ F src/util.c e71f19b272f05c8695cf747b4bac1732685f9e5c F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 F src/vdbe.c b110887e415b5d2af58c2374c4dfdcf774c5d46c F src/vdbe.h c3278ab2b410f17acf61faf91be7bce3fd466e8b -F src/vdbeInt.h 8a4d2d69955570bb74a092c3cdbab04afb554963 +F src/vdbeInt.h 42db251e9f863401ff847b90d5fe1614c89a6a56 F src/vdbeapi.c ce4e68ea4842cc6081046f533d088dcf01d247ad -F src/vdbeaux.c 6fb0607776fe707a12e1859e66fc94b439966274 +F src/vdbeaux.c bc6799db8795cd1480f2cab6cb22acf47e3e640f F src/vdbeblob.c bc40f98f256f0b34116d6a44b114da4a81a15d33 F src/vdbemem.c 0e69351b2c6ff7d8b638688c0ae336a26befa6b2 F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147 @@ -1147,7 +1147,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 895af097e71749f423b63ece17c5a4b4dfcd164d -R edca4657a892a426dbd4ee6318480a5d +P 25b8a1c9ba77df3b7c78cbce922cb593d661696d +R d5977954dd1c2aa7ce7a7105c092a6e6 U drh -Z a6e6f91b61427f170fce17908ed5a512 +Z 0801871ae5fea7f25834aba0df14ec53 diff --git a/manifest.uuid b/manifest.uuid index d403ad35b8..3d041c730a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -25b8a1c9ba77df3b7c78cbce922cb593d661696d \ No newline at end of file +c289a253c0c053ac8fc344efe138262c327d8096 \ No newline at end of file diff --git a/src/prepare.c b/src/prepare.c index 7ea7f3bd68..c7ba53a1f5 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -528,7 +528,11 @@ int sqlite3SchemaToIndex(sqlite3 *db, Schema *pSchema){ ** Free all memory allocations in the pParse object */ void sqlite3ParserReset(Parse *pParse){ - if( pParse ) sqlite3ExprListDelete(pParse->db, pParse->pConstExpr); + if( pParse ){ + sqlite3 *db = pParse->db; + sqlite3DbFree(db, pParse->aLabel); + sqlite3ExprListDelete(db, pParse->pConstExpr); + } } /* diff --git a/src/sqliteInt.h b/src/sqliteInt.h index ce366dc480..e7dc69cc73 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2290,6 +2290,9 @@ struct Parse { int nMem; /* Number of memory cells used so far */ int nSet; /* Number of sets used so far */ int nOnce; /* Number of OP_Once instructions so far */ + int nOpAlloc; /* Number of slots allocated for Vdbe.aOp[] */ + int nLabel; /* Number of labels used */ + int *aLabel; /* Space to hold the labels */ int ckBase; /* Base register of data during check constraints */ int iPartIdxTab; /* Table corresponding to a partial index */ int iCacheLevel; /* ColCache valid when aColCache[].iLevel<=iCacheLevel */ diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 7b4fad67b0..c4fa26cc05 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -312,15 +312,9 @@ struct Vdbe { Mem **apArg; /* Arguments to currently executing user function */ Mem *aColName; /* Column names to return */ Mem *pResultSet; /* Pointer to an array of results */ -#ifdef SQLITE_DEBUG Parse *pParse; /* Parsing context used to create this Vdbe */ -#endif int nMem; /* Number of memory locations currently allocated */ int nOp; /* Number of instructions in the program */ - int nOpAlloc; /* Number of slots allocated for aOp[] */ - int nLabel; /* Number of labels used */ - int *aLabel; /* Space to hold the labels */ - u16 nResColumn; /* Number of columns in one row of the result set */ int nCursor; /* Number of slots in apCsr[] */ u32 magic; /* Magic number for sanity checking */ char *zErrMsg; /* Error message written here */ @@ -333,6 +327,7 @@ struct Vdbe { u32 cacheCtr; /* VdbeCursor row cache generation counter */ int pc; /* The program counter */ int rc; /* Value to return */ + u16 nResColumn; /* Number of columns in one row of the result set */ u8 errorAction; /* Recovery action to do in case of an error */ u8 minWriteFileFormat; /* Minimum file format for writable database files */ bft explain:2; /* True if EXPLAIN present on SQL command */ diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 8e95de70c1..d917e8540e 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -33,9 +33,10 @@ Vdbe *sqlite3VdbeCreate(Parse *pParse){ p->pPrev = 0; db->pVdbe = p; p->magic = VDBE_MAGIC_INIT; -#if SQLITE_DEBUG p->pParse = pParse; -#endif + assert( pParse->aLabel==0 ); + assert( pParse->nLabel==0 ); + assert( pParse->nOpAlloc==0 ); return p; } @@ -91,13 +92,14 @@ void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){ ** unchanged (this is so that any opcodes already allocated can be ** correctly deallocated along with the rest of the Vdbe). */ -static int growOpArray(Vdbe *p){ +static int growOpArray(Vdbe *v){ VdbeOp *pNew; + Parse *p = v->pParse; int nNew = (p->nOpAlloc ? p->nOpAlloc*2 : (int)(1024/sizeof(Op))); - pNew = sqlite3DbRealloc(p->db, p->aOp, nNew*sizeof(Op)); + pNew = sqlite3DbRealloc(p->db, v->aOp, nNew*sizeof(Op)); if( pNew ){ p->nOpAlloc = sqlite3DbMallocSize(p->db, pNew)/sizeof(Op); - p->aOp = pNew; + v->aOp = pNew; } return (pNew ? SQLITE_OK : SQLITE_NOMEM); } @@ -136,7 +138,7 @@ int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){ i = p->nOp; assert( p->magic==VDBE_MAGIC_INIT ); assert( op>0 && op<0xff ); - if( p->nOpAlloc<=i ){ + if( p->pParse->nOpAlloc<=i ){ if( growOpArray(p) ){ return 1; } @@ -247,9 +249,10 @@ int sqlite3VdbeAddOp4Int( ** ** Zero is returned if a malloc() fails. */ -int sqlite3VdbeMakeLabel(Vdbe *p){ +int sqlite3VdbeMakeLabel(Vdbe *v){ + Parse *p = v->pParse; int i = p->nLabel++; - assert( p->magic==VDBE_MAGIC_INIT ); + assert( v->magic==VDBE_MAGIC_INIT ); if( (i & (i-1))==0 ){ p->aLabel = sqlite3DbReallocOrFree(p->db, p->aLabel, (i*2+1)*sizeof(p->aLabel[0])); @@ -265,12 +268,13 @@ int sqlite3VdbeMakeLabel(Vdbe *p){ ** be inserted. The parameter "x" must have been obtained from ** a prior call to sqlite3VdbeMakeLabel(). */ -void sqlite3VdbeResolveLabel(Vdbe *p, int x){ +void sqlite3VdbeResolveLabel(Vdbe *v, int x){ + Parse *p = v->pParse; int j = -1-x; - assert( p->magic==VDBE_MAGIC_INIT ); + assert( v->magic==VDBE_MAGIC_INIT ); assert( jnLabel ); if( j>=0 && p->aLabel ){ - p->aLabel[j] = p->nOp; + p->aLabel[j] = v->nOp; } } @@ -419,7 +423,8 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ int i; int nMaxArgs = *pMaxFuncArgs; Op *pOp; - int *aLabel = p->aLabel; + Parse *pParse = p->pParse; + int *aLabel = pParse->aLabel; p->readOnly = 1; p->bIsReader = 0; for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){ @@ -482,12 +487,13 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ pOp->opflags = sqlite3OpcodeProperty[opcode]; if( (pOp->opflags & OPFLG_JUMP)!=0 && pOp->p2<0 ){ - assert( -1-pOp->p2nLabel ); + assert( -1-pOp->p2nLabel ); pOp->p2 = aLabel[-1-pOp->p2]; } } - sqlite3DbFree(p->db, p->aLabel); - p->aLabel = 0; + sqlite3DbFree(p->db, pParse->aLabel); + pParse->aLabel = 0; + pParse->nLabel = 0; *pMaxFuncArgs = nMaxArgs; assert( p->bIsReader!=0 || p->btreeMask==0 ); } @@ -531,7 +537,7 @@ VdbeOp *sqlite3VdbeTakeOpArray(Vdbe *p, int *pnOp, int *pnMaxArg){ int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp){ int addr; assert( p->magic==VDBE_MAGIC_INIT ); - if( p->nOp + nOp > p->nOpAlloc && growOpArray(p) ){ + if( p->nOp + nOp > p->pParse->nOpAlloc && growOpArray(p) ){ return 0; } addr = p->nOp; @@ -1601,6 +1607,7 @@ void sqlite3VdbeMakeReady( assert( p->nOp>0 ); assert( pParse!=0 ); assert( p->magic==VDBE_MAGIC_INIT ); + assert( pParse==p->pParse ); db = p->db; assert( db->mallocFailed==0 ); nVar = pParse->nVar; @@ -1624,8 +1631,8 @@ void sqlite3VdbeMakeReady( /* Allocate space for memory registers, SQL variables, VDBE cursors and ** an array to marshal SQL function arguments in. */ - zCsr = (u8*)&p->aOp[p->nOp]; /* Memory avaliable for allocation */ - zEnd = (u8*)&p->aOp[p->nOpAlloc]; /* First byte past end of zCsr[] */ + zCsr = (u8*)&p->aOp[p->nOp]; /* Memory avaliable for allocation */ + zEnd = (u8*)&p->aOp[pParse->nOpAlloc]; /* First byte past end of zCsr[] */ resolveP2Values(p, &nArg); p->usesStmtJournal = (u8)(pParse->isMultiWrite && pParse->mayAbort); @@ -2628,7 +2635,6 @@ void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){ } for(i=p->nzVar-1; i>=0; i--) sqlite3DbFree(db, p->azVar[i]); vdbeFreeOpArray(db, p->aOp, p->nOp); - sqlite3DbFree(db, p->aLabel); sqlite3DbFree(db, p->aColName); sqlite3DbFree(db, p->zSql); sqlite3DbFree(db, p->pFree); From 3312348cf8d88eb170825aa7b52254ea6219ff4b Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 24 Dec 2013 12:04:24 +0000 Subject: [PATCH 110/276] Add -I. to the main.mk makefile for building sqlite3.o and speedtest1. FossilOrigin-Name: cc72c5aec7fe93d4a1368517aab949dc98d33003 --- main.mk | 4 ++-- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/main.mk b/main.mk index a53727c904..ebd508a279 100644 --- a/main.mk +++ b/main.mk @@ -389,7 +389,7 @@ mptester$(EXE): sqlite3.c $(TOP)/mptest/mptest.c $(TLIBS) $(THREADLIB) sqlite3.o: sqlite3.c - $(TCCX) -c sqlite3.c + $(TCCX) -I. -c sqlite3.c # This target creates a directory named "tsrc" and fills it with # copies of all of the C source code and header files needed to @@ -631,7 +631,7 @@ wordcount$(EXE): $(TOP)/test/wordcount.c sqlite3.c $(TOP)/test/wordcount.c sqlite3.c speedtest1$(EXE): $(TOP)/test/speedtest1.c sqlite3.o - $(TCC) -o speedtest1$(EXE) $(TOP)/test/speedtest1.c sqlite3.o $(THREADLIB) + $(TCC) -I. -o speedtest1$(EXE) $(TOP)/test/speedtest1.c sqlite3.o $(THREADLIB) # This target will fail if the SQLite amalgamation contains any exported # symbols that do not begin with "sqlite3_". It is run as part of the diff --git a/manifest b/manifest index 1efd07ffd6..56fb6db832 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Move\selements\sof\sthe\sVdbe\sobject\sthat\sare\sonly\sused\sduring\sstatement\npreparation\sout\sinto\sthe\sParse\sobject. -D 2013-12-23T19:09:07.173 +C Add\s-I.\sto\sthe\smain.mk\smakefile\sfor\sbuilding\ssqlite3.o\sand\sspeedtest1. +D 2013-12-24T12:04:24.811 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -142,7 +142,7 @@ F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt f439556c5ce01ced70987e5ee86549a45165d9ff -F main.mk 9f091ea7920f8b15e48c7b6e5b6fb0182577ab2e +F main.mk 3ae543fa446525c1dec55f58de67f41b78651812 F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a F mkextu.sh 416f9b7089d80e5590a29692c9d9280a10dbad9f F mkextw.sh d2a981497b404d6498f5ff3e3b1f3816bdfcb338 @@ -1147,7 +1147,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 25b8a1c9ba77df3b7c78cbce922cb593d661696d -R d5977954dd1c2aa7ce7a7105c092a6e6 +P c289a253c0c053ac8fc344efe138262c327d8096 +R 2bb3d3295c5bbe58e528a8069b6e67b9 U drh -Z 0801871ae5fea7f25834aba0df14ec53 +Z 2be15cf525011fea6a70c12bcaf2ac37 diff --git a/manifest.uuid b/manifest.uuid index 3d041c730a..5e0ef5b21c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c289a253c0c053ac8fc344efe138262c327d8096 \ No newline at end of file +cc72c5aec7fe93d4a1368517aab949dc98d33003 \ No newline at end of file From fe98081e18e03e4f3a3389f94b44eeb201276721 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 1 Jan 2014 14:00:13 +0000 Subject: [PATCH 111/276] Enhance sqlite3_randomness(N,P) such that it resets the internal PRNG if N is less than 1. Subsequent calls to sqlite3_randomness() will reinitialize the internal PRNG by calling the xRandomness() method of the default VFS. FossilOrigin-Name: a221aa82bb5496885fd0bf76e4601443799511de --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/main.c | 2 +- src/random.c | 14 +++++++++----- src/sqlite.h.in | 10 ++++++---- src/sqliteInt.h | 1 - 6 files changed, 26 insertions(+), 21 deletions(-) diff --git a/manifest b/manifest index 56fb6db832..df2e8029ab 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\s-I.\sto\sthe\smain.mk\smakefile\sfor\sbuilding\ssqlite3.o\sand\sspeedtest1. -D 2013-12-24T12:04:24.811 +C Enhance\ssqlite3_randomness(N,P)\ssuch\sthat\sit\sresets\sthe\sinternal\sPRNG\nif\sN\sis\sless\sthan\s1.\s\sSubsequent\scalls\sto\ssqlite3_randomness()\swill\sreinitialize\nthe\sinternal\sPRNG\sby\scalling\sthe\sxRandomness()\smethod\sof\sthe\sdefault\sVFS. +D 2014-01-01T14:00:13.905 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -188,7 +188,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b F src/loadext.c 867c7b330b740c6c917af9956b13b81d0a048303 -F src/main.c 5307601c58b6e08153a15846098399a59c166d8d +F src/main.c 37f55de2000f6c882414ad3e1bcdb751c531fddd F src/malloc.c 0203ebce9152c6a0e5de520140b8ba65187350be F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c0c990fcaddff810ea277b4fb5d9138603dd5d4b @@ -216,15 +216,15 @@ F src/pcache1.c 57fee9a9a617218f5037afbbe49b09da65bde56b F src/pragma.c 5ab7279d132143feb77f773688a24ab05da75fd7 F src/prepare.c 677521ab7132615a8a26107a1d1c3132f44ae337 F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 -F src/random.c 0b2dbc37fdfbfa6bd455b091dfcef5bdb32dba68 +F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c 819bb090c9a348d17f69f136cad2bfa9ee9cbb41 F src/shell.c a3541193d5fce37e91dad8ef46a9505aa7c9b344 -F src/sqlite.h.in 4ef56464aeaa3785a2c5ca37fb3a0fb229d68b2e +F src/sqlite.h.in d94a8b89522f526ba711182ee161e06f8669bcc9 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h fdb8c1e4bc5424ad82a9394a845781abf0d7d849 +F src/sqliteInt.h 62664868458b53a815380733f059ff9d92cb08be F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -1147,7 +1147,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P c289a253c0c053ac8fc344efe138262c327d8096 -R 2bb3d3295c5bbe58e528a8069b6e67b9 +P cc72c5aec7fe93d4a1368517aab949dc98d33003 +R 4dbb82094f79fe324b8594c5661b9532 U drh -Z 2be15cf525011fea6a70c12bcaf2ac37 +Z 7f33812905741a2d8942dba59b43dd66 diff --git a/manifest.uuid b/manifest.uuid index 5e0ef5b21c..691c3bd9a8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cc72c5aec7fe93d4a1368517aab949dc98d33003 \ No newline at end of file +a221aa82bb5496885fd0bf76e4601443799511de \ No newline at end of file diff --git a/src/main.c b/src/main.c index fff1bc42e6..13ad2b9081 100644 --- a/src/main.c +++ b/src/main.c @@ -3101,7 +3101,7 @@ int sqlite3_test_control(int op, ...){ ** to the xRandomness method of the default VFS. */ case SQLITE_TESTCTRL_PRNG_RESET: { - sqlite3PrngResetState(); + sqlite3_randomness(0,0); break; } diff --git a/src/random.c b/src/random.c index 7afff50885..b82566524c 100644 --- a/src/random.c +++ b/src/random.c @@ -52,6 +52,12 @@ void sqlite3_randomness(int N, void *pBuf){ sqlite3_mutex_enter(mutex); #endif + if( N<=0 ){ + wsdPrng.isInit = 0; + sqlite3_mutex_leave(mutex); + return; + } + /* Initialize the state of the random number generator once, ** the first time this routine is called. The seed value does ** not need to contain a lot of randomness since we are not @@ -79,7 +85,8 @@ void sqlite3_randomness(int N, void *pBuf){ wsdPrng.isInit = 1; } - while( N-- ){ + assert( N>0 ); + do{ wsdPrng.i++; t = wsdPrng.s[wsdPrng.i]; wsdPrng.j += t; @@ -87,7 +94,7 @@ void sqlite3_randomness(int N, void *pBuf){ wsdPrng.s[wsdPrng.j] = t; t += wsdPrng.s[wsdPrng.i]; *(zBuf++) = wsdPrng.s[t]; - } + }while( --N ); sqlite3_mutex_leave(mutex); } @@ -116,7 +123,4 @@ void sqlite3PrngRestoreState(void){ sizeof(sqlite3Prng) ); } -void sqlite3PrngResetState(void){ - GLOBAL(struct sqlite3PrngType, sqlite3Prng).isInit = 0; -} #endif /* SQLITE_OMIT_BUILTIN_TEST */ diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 7b0e648bfc..5012f864a5 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -2395,11 +2395,13 @@ sqlite3_int64 sqlite3_memory_highwater(int resetFlag); ** applications to access the same PRNG for other purposes. ** ** ^A call to this routine stores N bytes of randomness into buffer P. +** ^If N is less than one, then P can be a NULL pointer. ** -** ^The first time this routine is invoked (either internally or by -** the application) the PRNG is seeded using randomness obtained -** from the xRandomness method of the default [sqlite3_vfs] object. -** ^On all subsequent invocations, the pseudo-randomness is generated +** ^If this routine has not been previously called or if the previous +** call had N less than one, then the PRNG is seeded using randomness +** obtained from the xRandomness method of the default [sqlite3_vfs] object. +** ^If the previous call to this routine had an N of 1 or more then +** the pseudo-randomness is generated ** internally and without recourse to the [sqlite3_vfs] xRandomness ** method. */ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index e7dc69cc73..77ed38374f 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2972,7 +2972,6 @@ int sqlite3FunctionUsesThisSrc(Expr*, SrcList*); Vdbe *sqlite3GetVdbe(Parse*); void sqlite3PrngSaveState(void); void sqlite3PrngRestoreState(void); -void sqlite3PrngResetState(void); void sqlite3RollbackAll(sqlite3*,int); void sqlite3CodeVerifySchema(Parse*, int); void sqlite3CodeVerifyNamedSchema(Parse*, const char *zDb); From b00d8621392397de9104e5d191ad1d6f018dcd7a Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 1 Jan 2014 15:18:36 +0000 Subject: [PATCH 112/276] Try to detect process ID changes due to fork() calls in os_unix.c and reset the PRNG when a process ID change is detected. FossilOrigin-Name: e1eba1fb09d7db49d77928bd115b27b8002ae640 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/os_unix.c | 26 +++++++++++++++++++++----- 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index df2e8029ab..e254e7cba0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\ssqlite3_randomness(N,P)\ssuch\sthat\sit\sresets\sthe\sinternal\sPRNG\nif\sN\sis\sless\sthan\s1.\s\sSubsequent\scalls\sto\ssqlite3_randomness()\swill\sreinitialize\nthe\sinternal\sPRNG\sby\scalling\sthe\sxRandomness()\smethod\sof\sthe\sdefault\sVFS. -D 2014-01-01T14:00:13.905 +C Try\sto\sdetect\sprocess\sID\schanges\sdue\sto\sfork()\scalls\sin\sos_unix.c\sand\nreset\sthe\sPRNG\swhen\sa\sprocess\sID\schange\sis\sdetected. +D 2014-01-01T15:18:36.453 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -205,7 +205,7 @@ F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30 F src/os.c 1b147e4cf7cc39e618115c14a086aed44bc91ace F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 -F src/os_unix.c 60a7b3b23e6fcf83a50d1e320b280b551724e11f +F src/os_unix.c abeb9d54036aaea6f4395050ce823f51217ae4d4 F src/os_win.c 16eac0961603182ffc10c02b39fe830126538e07 F src/pager.c efa923693e958696eee69b205a20bfbc402c8480 F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428 @@ -1147,7 +1147,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P cc72c5aec7fe93d4a1368517aab949dc98d33003 -R 4dbb82094f79fe324b8594c5661b9532 +P a221aa82bb5496885fd0bf76e4601443799511de +R 0b5cbfb8643918ccfe030368af8a9f9c U drh -Z 7f33812905741a2d8942dba59b43dd66 +Z 8d0b25dd26eff92b0e8709464c57dd81 diff --git a/manifest.uuid b/manifest.uuid index 691c3bd9a8..002b2fbf68 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a221aa82bb5496885fd0bf76e4601443799511de \ No newline at end of file +e1eba1fb09d7db49d77928bd115b27b8002ae640 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 485b32fd90..4b76d4fec4 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -260,6 +260,12 @@ struct unixFile { #endif }; +/* This variable holds the process id (pid) from when the xRandomness() +** method was called. If xOpen() is called from a different process id, +** indicating that a fork() has occurred, the PRNG will be reset. +*/ +static int randomnessPid = 0; + /* ** Allowed values for the unixFile.ctrlFlags bitmask: */ @@ -5651,6 +5657,16 @@ static int unixOpen( || eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL ); + /* Detect a pid change and reset the PRNG. There is a race condition + ** here such that two or more threads all trying to open databases at + ** the same instant might all reset the PRNG. But multiple resets + ** are harmless. + */ + if( randomnessPid!=getpid() ){ + randomnessPid = getpid(); + sqlite3_randomness(0,0); + } + memset(p, 0, sizeof(unixFile)); if( eType==SQLITE_OPEN_MAIN_DB ){ @@ -6038,18 +6054,18 @@ static int unixRandomness(sqlite3_vfs *NotUsed, int nBuf, char *zBuf){ ** tests repeatable. */ memset(zBuf, 0, nBuf); + randomnessPid = getpid(); #if !defined(SQLITE_TEST) { - int pid, fd, got; + int fd, got; fd = robust_open("/dev/urandom", O_RDONLY, 0); if( fd<0 ){ time_t t; time(&t); memcpy(zBuf, &t, sizeof(t)); - pid = getpid(); - memcpy(&zBuf[sizeof(t)], &pid, sizeof(pid)); - assert( sizeof(t)+sizeof(pid)<=(size_t)nBuf ); - nBuf = sizeof(t) + sizeof(pid); + memcpy(&zBuf[sizeof(t)], &randomnessPid, sizeof(randomnessPid)); + assert( sizeof(t)+sizeof(randomnessPid)<=(size_t)nBuf ); + nBuf = sizeof(t) + sizeof(randomnessPid); }else{ do{ got = osRead(fd, zBuf, nBuf); }while( got<0 && errno==EINTR ); robust_close(0, fd, __LINE__); From 991a19851112ffb03946a003350e9e148d631348 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 2 Jan 2014 17:57:16 +0000 Subject: [PATCH 113/276] Be more aggressive in optimizing constant conditional expressions. FossilOrigin-Name: b7e39851a75b87ebca747b26a39989560fd6362b --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 47 ++++++++++++++++++++++++++++++++++------------- 3 files changed, 41 insertions(+), 20 deletions(-) diff --git a/manifest b/manifest index e254e7cba0..142a875f5d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Try\sto\sdetect\sprocess\sID\schanges\sdue\sto\sfork()\scalls\sin\sos_unix.c\sand\nreset\sthe\sPRNG\swhen\sa\sprocess\sID\schange\sis\sdetected. -D 2014-01-01T15:18:36.453 +C Be\smore\saggressive\sin\soptimizing\sconstant\sconditional\sexpressions. +D 2014-01-02T17:57:16.874 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -175,7 +175,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 F src/delete.c 821da82527c24496bef0677ed4f61a53b44c27ee -F src/expr.c ffe4bc79c66f711f450a6113fbd1943b9b2380f7 +F src/expr.c ca0959386f01d6e5d4dc67b362a4e4c912ebd054 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 2ab0f5384b70594468ef3ac5c7ed8ca24bfd17d5 F src/func.c 6325ac2ec10833ccf4d5c36d323709221d37ea19 @@ -1147,7 +1147,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P a221aa82bb5496885fd0bf76e4601443799511de -R 0b5cbfb8643918ccfe030368af8a9f9c +P e1eba1fb09d7db49d77928bd115b27b8002ae640 +R 8c33ee4ecd82143d9dd9bc5270372c1d U drh -Z 8d0b25dd26eff92b0e8709464c57dd81 +Z 948115126ed1b38f36b2ba1121c24109 diff --git a/manifest.uuid b/manifest.uuid index 002b2fbf68..38faece72d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e1eba1fb09d7db49d77928bd115b27b8002ae640 \ No newline at end of file +b7e39851a75b87ebca747b26a39989560fd6362b \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 8ee73acb78..0db51fe43f 100644 --- a/src/expr.c +++ b/src/expr.c @@ -523,16 +523,25 @@ Expr *sqlite3PExpr( } /* -** Return 1 if an expression must be FALSE in all cases and 0 if the -** expression might be true. This is an optimization. If is OK to -** return 0 here even if the expression really is always false (a -** false negative). But it is a bug to return 1 if the expression -** might be true in some rare circumstances (a false positive.) +** If the expression is always either TRUE or FALSE (respectively), +** then return 1. If one cannot determine the truth value of the +** expression at compile-time return 0. +** +** This is an optimization. If is OK to return 0 here even if +** the expression really is always false or false (a false negative). +** But it is a bug to return 1 if the expression might have different +** boolean values in different circumstances (a false positive.) ** ** Note that if the expression is part of conditional for a ** LEFT JOIN, then we cannot determine at compile-time whether or not ** is it true or false, so always return 0. */ +static int exprAlwaysTrue(Expr *p){ + int v = 0; + if( ExprHasProperty(p, EP_FromJoin) ) return 0; + if( !sqlite3ExprIsInteger(p, &v) ) return 0; + return v!=0; +} static int exprAlwaysFalse(Expr *p){ int v = 0; if( ExprHasProperty(p, EP_FromJoin) ) return 0; @@ -3614,10 +3623,16 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ } #endif default: { - r1 = sqlite3ExprCodeTemp(pParse, pExpr, ®Free1); - sqlite3VdbeAddOp3(v, OP_If, r1, dest, jumpIfNull!=0); - testcase( regFree1==0 ); - testcase( jumpIfNull==0 ); + if( exprAlwaysTrue(pExpr) ){ + sqlite3VdbeAddOp2(v, OP_Goto, 0, dest); + }else if( exprAlwaysFalse(pExpr) ){ + /* No-op */ + }else{ + r1 = sqlite3ExprCodeTemp(pParse, pExpr, ®Free1); + sqlite3VdbeAddOp3(v, OP_If, r1, dest, jumpIfNull!=0); + testcase( regFree1==0 ); + testcase( jumpIfNull==0 ); + } break; } } @@ -3759,10 +3774,16 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ } #endif default: { - r1 = sqlite3ExprCodeTemp(pParse, pExpr, ®Free1); - sqlite3VdbeAddOp3(v, OP_IfNot, r1, dest, jumpIfNull!=0); - testcase( regFree1==0 ); - testcase( jumpIfNull==0 ); + if( exprAlwaysFalse(pExpr) ){ + sqlite3VdbeAddOp2(v, OP_Goto, 0, dest); + }else if( exprAlwaysTrue(pExpr) ){ + /* no-op */ + }else{ + r1 = sqlite3ExprCodeTemp(pParse, pExpr, ®Free1); + sqlite3VdbeAddOp3(v, OP_IfNot, r1, dest, jumpIfNull!=0); + testcase( regFree1==0 ); + testcase( jumpIfNull==0 ); + } break; } } From 762c1c4071bbc4c73ec1aa70d017ee0e9c03d729 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 2 Jan 2014 19:35:30 +0000 Subject: [PATCH 114/276] Avoid unnecessary affinity transformations when building indices using data from a table. FossilOrigin-Name: 10d851353c2abeadbd2852c210a7ff9f7f513e5d --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/delete.c | 18 +++++++++--------- src/sqliteInt.h | 2 +- src/test1.c | 1 - src/vdbe.h | 1 + src/vdbeaux.c | 7 +++++++ 7 files changed, 29 insertions(+), 22 deletions(-) diff --git a/manifest b/manifest index 142a875f5d..b647b373c8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Be\smore\saggressive\sin\soptimizing\sconstant\sconditional\sexpressions. -D 2014-01-02T17:57:16.874 +C Avoid\sunnecessary\saffinity\stransformations\swhen\sbuilding\sindices\susing\ndata\sfrom\sa\stable. +D 2014-01-02T19:35:30.181 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -174,7 +174,7 @@ F src/callback.c 174e3c8656bc29f91d710ab61550d16eea34be98 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 -F src/delete.c 821da82527c24496bef0677ed4f61a53b44c27ee +F src/delete.c 22f3dc3fd6b82ebce3dabf951a4b157026943ac1 F src/expr.c ca0959386f01d6e5d4dc67b362a4e4c912ebd054 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 2ab0f5384b70594468ef3ac5c7ed8ca24bfd17d5 @@ -224,12 +224,12 @@ F src/shell.c a3541193d5fce37e91dad8ef46a9505aa7c9b344 F src/sqlite.h.in d94a8b89522f526ba711182ee161e06f8669bcc9 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h 62664868458b53a815380733f059ff9d92cb08be +F src/sqliteInt.h a77cb6c7404d1a20e536211be4a2e4be01cde213 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e F src/tclsqlite.c c43379f77f90399802b0e215faa71c0adc3a4d2e -F src/test1.c 633e5e6a116acf4473b9289240bcceb5320a9d93 +F src/test1.c db16ba651453b15001c7f2838c446284dde4ecaf F src/test2.c 7355101c085304b90024f2261e056cdff13c6c35 F src/test3.c 1c0e5d6f080b8e33c1ce8b3078e7013fdbcd560c F src/test4.c 9b32d22f5f150abe23c1830e2057c4037c45b3df @@ -281,10 +281,10 @@ F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c e71f19b272f05c8695cf747b4bac1732685f9e5c F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 F src/vdbe.c b110887e415b5d2af58c2374c4dfdcf774c5d46c -F src/vdbe.h c3278ab2b410f17acf61faf91be7bce3fd466e8b +F src/vdbe.h 298e0492827ef9db626934d060df62ed27ba56bc F src/vdbeInt.h 42db251e9f863401ff847b90d5fe1614c89a6a56 F src/vdbeapi.c ce4e68ea4842cc6081046f533d088dcf01d247ad -F src/vdbeaux.c bc6799db8795cd1480f2cab6cb22acf47e3e640f +F src/vdbeaux.c 915fda7ca876aa2df2a13b0621ad0326342c0638 F src/vdbeblob.c bc40f98f256f0b34116d6a44b114da4a81a15d33 F src/vdbemem.c 0e69351b2c6ff7d8b638688c0ae336a26befa6b2 F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147 @@ -1147,7 +1147,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P e1eba1fb09d7db49d77928bd115b27b8002ae640 -R 8c33ee4ecd82143d9dd9bc5270372c1d +P b7e39851a75b87ebca747b26a39989560fd6362b +R 8c4d4f58f19d587102e868c570c261da U drh -Z 948115126ed1b38f36b2ba1121c24109 +Z 387b8179fd8db58dae028273b1bc8ad7 diff --git a/manifest.uuid b/manifest.uuid index 38faece72d..b39edb4e71 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b7e39851a75b87ebca747b26a39989560fd6362b \ No newline at end of file +10d851353c2abeadbd2852c210a7ff9f7f513e5d \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index 8746cd324a..0180ec48c8 100644 --- a/src/delete.c +++ b/src/delete.c @@ -784,18 +784,18 @@ int sqlite3GenerateIndexKey( for(j=0; jaiColumn[j], regBase+j); + /* If the column affinity is REAL but the number is an integer, then it + ** might be stored in the table as an integer (using a compact + ** representation) then converted to REAL by an OP_RealAffinity opcode. + ** But we are getting ready to store this value back into an index, where + ** it should be converted by to INTEGER again. So omit the OP_RealAffinity + ** opcode if it is present */ + if( sqlite3VdbeGetOp(v, -1)->opcode==OP_RealAffinity ){ + sqlite3VdbeDeleteLastOpcode(v); + } } if( regOut ){ - const char *zAff; - if( pTab->pSelect - || OptimizationDisabled(pParse->db, SQLITE_IdxRealAsInt) - ){ - zAff = 0; - }else{ - zAff = sqlite3IndexAffinityStr(v, pIdx); - } sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regOut); - sqlite3VdbeChangeP4(v, -1, zAff, P4_TRANSIENT); } sqlite3ReleaseTempRange(pParse, regBase, nCol); return regBase; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 77ed38374f..5943ced2a0 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1056,7 +1056,7 @@ struct sqlite3 { #define SQLITE_ColumnCache 0x0002 /* Column cache */ #define SQLITE_GroupByOrder 0x0004 /* GROUPBY cover of ORDERBY */ #define SQLITE_FactorOutConst 0x0008 /* Constant factoring */ -#define SQLITE_IdxRealAsInt 0x0010 /* Store REAL as INT in indices */ +/* not used 0x0010 // Was: SQLITE_IdxRealAsInt */ #define SQLITE_DistinctOpt 0x0020 /* DISTINCT using indexes */ #define SQLITE_CoverIdxScan 0x0040 /* Covering index scans */ #define SQLITE_OrderByIdxJoin 0x0080 /* ORDER BY of joins via index */ diff --git a/src/test1.c b/src/test1.c index a96b298661..109f90143f 100644 --- a/src/test1.c +++ b/src/test1.c @@ -6160,7 +6160,6 @@ static int optimization_control( { "column-cache", SQLITE_ColumnCache }, { "groupby-order", SQLITE_GroupByOrder }, { "factor-constants", SQLITE_FactorOutConst }, - { "real-as-int", SQLITE_IdxRealAsInt }, { "distinct-opt", SQLITE_DistinctOpt }, { "cover-idx-scan", SQLITE_CoverIdxScan }, { "order-by-idx-join", SQLITE_OrderByIdxJoin }, diff --git a/src/vdbe.h b/src/vdbe.h index 51cf60b520..46bc89cee8 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -175,6 +175,7 @@ void sqlite3VdbeChangeP3(Vdbe*, u32 addr, int P3); void sqlite3VdbeChangeP5(Vdbe*, u8 P5); void sqlite3VdbeJumpHere(Vdbe*, int addr); void sqlite3VdbeChangeToNoop(Vdbe*, int addr); +void sqlite3VdbeDeleteLastOpcode(Vdbe*); void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N); void sqlite3VdbeSetP4KeyInfo(Parse*, Index*); void sqlite3VdbeUsesBtree(Vdbe*, int); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index d917e8540e..e0b3c5485f 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -726,6 +726,13 @@ void sqlite3VdbeChangeToNoop(Vdbe *p, int addr){ } } +/* +** Remove the last opcode inserted +*/ +void sqlite3VdbeDeleteLastOpcode(Vdbe *p){ + p->nOp--; +} + /* ** Change the value of the P4 operand for a specific instruction. ** This routine is useful when a large program is loaded from a From 759e8588117ef04a0ef331b0128e2a684049f00c Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 2 Jan 2014 21:05:10 +0000 Subject: [PATCH 115/276] Try to factor constant subcomponents of the WHERE clause out of the loop. FossilOrigin-Name: 9d05777fe24e1a5ce71762de38db840931ef0bc8 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/where.c | 9 ++++++--- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index b647b373c8..07bca20bb5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sunnecessary\saffinity\stransformations\swhen\sbuilding\sindices\susing\ndata\sfrom\sa\stable. -D 2014-01-02T19:35:30.181 +C Try\sto\sfactor\sconstant\ssubcomponents\sof\sthe\sWHERE\sclause\sout\sof\sthe\sloop. +D 2014-01-02T21:05:10.654 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -293,7 +293,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c e9e593d5bb798c3e67fc3893dfe7055c9e7d8d74 -F src/where.c 60bc8c5b00e2292c24a42455d022eeeda33a16f1 +F src/where.c 8e3cb2030eaa242defb804aa30115b5d870e5cd4 F src/whereInt.h 96a75c61f1d2b9d4a8e4bb17d89deb0cf7cba358 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1147,7 +1147,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P b7e39851a75b87ebca747b26a39989560fd6362b -R 8c4d4f58f19d587102e868c570c261da +P 10d851353c2abeadbd2852c210a7ff9f7f513e5d +R c2b1a12fe347b39aeab4feaef9309c2b U drh -Z 387b8179fd8db58dae028273b1bc8ad7 +Z c170c664d17a9fc9f22716e0d87d4dc7 diff --git a/manifest.uuid b/manifest.uuid index b39edb4e71..a55e61dfa1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -10d851353c2abeadbd2852c210a7ff9f7f513e5d \ No newline at end of file +9d05777fe24e1a5ce71762de38db840931ef0bc8 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 59028b9921..0acc0db53f 100644 --- a/src/where.c +++ b/src/where.c @@ -5430,9 +5430,12 @@ WhereInfo *sqlite3WhereBegin( /* Special case: a WHERE clause that is constant. Evaluate the ** expression and either jump over all of the code or fall thru. */ - if( pWhere && (nTabList==0 || sqlite3ExprIsConstantNotJoin(pWhere)) ){ - sqlite3ExprIfFalse(pParse, pWhere, pWInfo->iBreak, SQLITE_JUMPIFNULL); - pWhere = 0; + for(ii=0; iinTerm; ii++){ + if( nTabList==0 || sqlite3ExprIsConstantNotJoin(sWLB.pWC->a[ii].pExpr) ){ + sqlite3ExprIfFalse(pParse, sWLB.pWC->a[ii].pExpr, pWInfo->iBreak, + SQLITE_JUMPIFNULL); + sWLB.pWC->a[ii].wtFlags |= TERM_CODED; + } } /* Special case: No FROM clause From 5426d80948c18c9dda289aa92f48328003e36193 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 3 Jan 2014 16:03:43 +0000 Subject: [PATCH 116/276] Avoid some unnecessary OP_SCopy operations when inserting into a table with multiple indices. FossilOrigin-Name: 429018b19cb525a4bb0843d20955457b53900d4b --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/insert.c | 3 +++ 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 07bca20bb5..3c6dfd1b82 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Try\sto\sfactor\sconstant\ssubcomponents\sof\sthe\sWHERE\sclause\sout\sof\sthe\sloop. -D 2014-01-02T21:05:10.654 +C Avoid\ssome\sunnecessary\sOP_SCopy\soperations\swhen\sinserting\sinto\sa\stable\nwith\smultiple\sindices. +D 2014-01-03T16:03:43.440 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -183,7 +183,7 @@ F src/global.c 1d7bb7ea8254ae6a68ed9bfaf65fcb3d1690b486 F src/hash.c ac3470bbf1ca4ae4e306a8ecb0fdf1731810ffe4 F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c f165ba414eda735b327c8126def0a2428f9138de +F src/insert.c e6b3d7847aaf06170967ff6ea9076717fbc08d3f F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b @@ -1147,7 +1147,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 10d851353c2abeadbd2852c210a7ff9f7f513e5d -R c2b1a12fe347b39aeab4feaef9309c2b +P 9d05777fe24e1a5ce71762de38db840931ef0bc8 +R 3a4d1de2d6235e13c562ba377a9da47e U drh -Z c170c664d17a9fc9f22716e0d87d4dc7 +Z f5e03e0d190fce062c51c7968e7436da diff --git a/manifest.uuid b/manifest.uuid index a55e61dfa1..ce9867dde2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9d05777fe24e1a5ce71762de38db840931ef0bc8 \ No newline at end of file +429018b19cb525a4bb0843d20955457b53900d4b \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index b3b8444f34..abc34c03ca 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1233,6 +1233,7 @@ void sqlite3GenerateConstraintChecks( int ipkTop = 0; /* Top of the rowid change constraint check */ int ipkBottom = 0; /* Bottom of the rowid change constraint check */ u8 isUpdate; /* True if this is an UPDATE operation */ + int regRowid = -1; /* Register holding ROWID value */ isUpdate = regOldData!=0; db = pParse->db; @@ -1463,7 +1464,9 @@ void sqlite3GenerateConstraintChecks( int iField = pIdx->aiColumn[i]; int x; if( iField<0 || iField==pTab->iPKey ){ + if( regRowid==regIdx+i ) continue; /* ROWID already in regIdx+i */ x = regNewData; + regRowid = pIdx->pPartIdxWhere ? -1 : regIdx+i; }else{ x = iField + regNewData + 1; } From 42899543f8423aaebf0f2e4e436330d99a6e4529 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 4 Jan 2014 14:16:06 +0000 Subject: [PATCH 117/276] Have the planner detect cases where a MATCH constraint is applied to a virtual table, and ignore any plans that do not allow the virtual table implementation to implement the MATCH filtering. FossilOrigin-Name: 19f3208b26597625728d1ef716d4e44407cf96ac --- manifest | 18 ++++++++----- manifest.uuid | 2 +- src/where.c | 5 ++++ test/fts3join.test | 66 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 83 insertions(+), 8 deletions(-) create mode 100644 test/fts3join.test diff --git a/manifest b/manifest index 3c6dfd1b82..32c49321f0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\ssome\sunnecessary\sOP_SCopy\soperations\swhen\sinserting\sinto\sa\stable\nwith\smultiple\sindices. -D 2014-01-03T16:03:43.440 +C Have\sthe\splanner\sdetect\scases\swhere\sa\sMATCH\sconstraint\sis\sapplied\sto\sa\svirtual\stable,\sand\signore\sany\splans\sthat\sdo\snot\sallow\sthe\svirtual\stable\simplementation\sto\simplement\sthe\sMATCH\sfiltering. +D 2014-01-04T14:16:06.902 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -293,7 +293,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c e9e593d5bb798c3e67fc3893dfe7055c9e7d8d74 -F src/where.c 8e3cb2030eaa242defb804aa30115b5d870e5cd4 +F src/where.c 14403429f7ad11b13b6ae0e466d089b8875ba195 F src/whereInt.h 96a75c61f1d2b9d4a8e4bb17d89deb0cf7cba358 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -547,6 +547,7 @@ F test/fts3expr3.test 9e91b8edbcb197bf2e92161aa7696446d96dce5f F test/fts3fault.test cb72dccb0a3b9f730f16c5240f3fcb9303eb1660 F test/fts3fault2.test 3198eef2804deea7cac8403e771d9cbcb752d887 F test/fts3first.test dbdedd20914c8d539aa3206c9b34a23775644641 +F test/fts3join.test bc8e5ca3e6b6577cf98e81b5271291e33e020e87 F test/fts3malloc.test b0e4c133b8d61d4f6d112d8110f8320e9e453ef6 F test/fts3matchinfo.test ff423e73faab8fc6d7adeefedf74dd8e2b0b14e0 F test/fts3near.test 7e3354d46f155a822b59c0e957fd2a70c1d7e905 @@ -1147,7 +1148,10 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 9d05777fe24e1a5ce71762de38db840931ef0bc8 -R 3a4d1de2d6235e13c562ba377a9da47e -U drh -Z f5e03e0d190fce062c51c7968e7436da +P 429018b19cb525a4bb0843d20955457b53900d4b +R 6571bb57c7cea9164f2f0721e5f9106f +T *branch * avoid-unusable-match +T *sym-avoid-unusable-match * +T -sym-trunk * +U dan +Z 6e1a68d01b84e17020c8f255059d7b13 diff --git a/manifest.uuid b/manifest.uuid index ce9867dde2..d3155e3c85 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -429018b19cb525a4bb0843d20955457b53900d4b \ No newline at end of file +19f3208b26597625728d1ef716d4e44407cf96ac \ No newline at end of file diff --git a/src/where.c b/src/where.c index 0acc0db53f..83ec748679 100644 --- a/src/where.c +++ b/src/where.c @@ -4338,6 +4338,7 @@ static int whereLoopAddVirtual( int nConstraint; int seenIn = 0; /* True if an IN operator is seen */ int seenVar = 0; /* True if a non-constant constraint is seen */ + int seenVarMatch = 0; /* If a non-constant MATCH constraint is seen */ int iPhase; /* 0: const w/o IN, 1: const, 2: no IN, 2: IN */ WhereLoop *pNew; int rc = SQLITE_OK; @@ -4382,6 +4383,7 @@ static int whereLoopAddVirtual( } if( pTerm->prereqRight!=0 ){ seenVar = 1; + if( pTerm->eOperator & WO_MATCH ) seenVarMatch = 1; }else if( (pTerm->eOperator & WO_IN)==0 ){ pIdxCons->usable = 1; } @@ -4400,6 +4402,9 @@ static int whereLoopAddVirtual( break; } } + /* The following line ensures that, if there exists a MATCH constraint, + ** no plans for which the MATCH constraint is not usable are considered. */ + if( seenVarMatch && iPhase<=1 ) continue; memset(pUsage, 0, sizeof(pUsage[0])*pIdxInfo->nConstraint); if( pIdxInfo->needToFreeIdxStr ) sqlite3_free(pIdxInfo->idxStr); pIdxInfo->idxStr = 0; diff --git a/test/fts3join.test b/test/fts3join.test new file mode 100644 index 0000000000..f02e21513e --- /dev/null +++ b/test/fts3join.test @@ -0,0 +1,66 @@ +# 2014 January 4 +# +# 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 script is testing the FTS3 module. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set ::testprefix fts3join + +# If SQLITE_ENABLE_FTS3 is defined, omit this file. +ifcapable !fts3 { + finish_test + return +} + +do_execsql_test 1.0 { + CREATE VIRTUAL TABLE ft1 USING fts4(x); + INSERT INTO ft1 VALUES('aaa aaa'); + INSERT INTO ft1 VALUES('aaa bbb'); + INSERT INTO ft1 VALUES('bbb aaa'); + INSERT INTO ft1 VALUES('bbb bbb'); + + CREATE TABLE t1(id, y); + INSERT INTO t1 VALUES(1, 'aaa'); + INSERT INTO t1 VALUES(2, 'bbb'); +} + +do_execsql_test 1.1 { + SELECT docid FROM ft1, t1 WHERE ft1 MATCH y AND id=1; +} {1 2 3} + +do_execsql_test 1.2 { + SELECT docid FROM ft1, t1 WHERE ft1 MATCH y AND id=1 ORDER BY docid; +} {1 2 3} + +do_execsql_test 2.0 { + CREATE VIRTUAL TABLE ft2 USING fts4(x); + CREATE VIRTUAL TABLE ft3 USING fts4(y); + + INSERT INTO ft2 VALUES('abc'); + INSERT INTO ft2 VALUES('def'); + INSERT INTO ft3 VALUES('ghi'); + INSERT INTO ft3 VALUES('abc'); +} + +do_execsql_test 2.1 { SELECT * FROM ft2, ft3 WHERE x MATCH y; } {abc abc} +do_execsql_test 2.2 { SELECT * FROM ft2, ft3 WHERE y MATCH x; } {abc abc} +do_execsql_test 2.3 { SELECT * FROM ft3, ft2 WHERE x MATCH y; } {abc abc} +do_execsql_test 2.4 { SELECT * FROM ft3, ft2 WHERE y MATCH x; } {abc abc} + +do_catchsql_test 2.5 { + SELECT * FROM ft3, ft2 WHERE y MATCH x AND x MATCH y; +} {1 {no query solution}} + +finish_test + + From 69014393f87e6b89b8c32207ff1aee2202a665e2 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 4 Jan 2014 14:42:14 +0000 Subject: [PATCH 118/276] Instead of having the planner ignore plans with unusable MATCH constraints, have FTS assign extremely high costs to such plans in order to discourage the planner from using them. FossilOrigin-Name: 24f84b38131866f7b435ffe641bb2f6991a70db2 --- ext/fts3/fts3.c | 28 +++++++++++++++++++++++++++- manifest | 19 ++++++++----------- manifest.uuid | 2 +- src/where.c | 5 ----- test/fts3join.test | 2 +- 5 files changed, 37 insertions(+), 19 deletions(-) diff --git a/ext/fts3/fts3.c b/ext/fts3/fts3.c index 3b9efee54c..62ff1437b9 100644 --- a/ext/fts3/fts3.c +++ b/ext/fts3/fts3.c @@ -1472,6 +1472,19 @@ static int fts3CreateMethod( return fts3InitVtab(1, db, pAux, argc, argv, ppVtab, pzErr); } +/* +** Set the pIdxInfo->estimatedRows variable to nRow. Unless this +** extension is currently being used by a version of SQLite too old to +** support estimatedRows. In that case this function is a no-op. +*/ +static void setEstimatedRows(sqlite3_index_info *pIdxInfo, i64 nRow){ +#if SQLITE_VERSION_NUMBER>=3008002 + if( sqlite3_libversion_number()>=3008002 ){ + pIdxInfo->estimatedRows = nRow; + } +#endif +} + /* ** Implementation of the xBestIndex method for FTS3 tables. There ** are three possible strategies, in order of preference: @@ -1499,7 +1512,20 @@ static int fts3BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ for(i=0; inConstraint; i++){ int bDocid; /* True if this constraint is on docid */ struct sqlite3_index_constraint *pCons = &pInfo->aConstraint[i]; - if( pCons->usable==0 ) continue; + if( pCons->usable==0 ){ + if( pCons->op==SQLITE_INDEX_CONSTRAINT_MATCH ){ + /* There exists an unusable MATCH constraint. This means that if + ** the planner does elect to use the results of this call as part + ** of the overall query plan the user will see an "unable to use + ** function MATCH in the requested context" error. To discourage + ** this, return a very high cost here. */ + pInfo->idxNum = FTS3_FULLSCAN_SEARCH; + pInfo->estimatedCost = 1e50; + setEstimatedRows(pInfo, ((sqlite3_int64)1) << 50); + return SQLITE_OK; + } + continue; + } bDocid = (pCons->iColumn<0 || pCons->iColumn==p->nColumn+1); diff --git a/manifest b/manifest index 32c49321f0..8e2e2e7378 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Have\sthe\splanner\sdetect\scases\swhere\sa\sMATCH\sconstraint\sis\sapplied\sto\sa\svirtual\stable,\sand\signore\sany\splans\sthat\sdo\snot\sallow\sthe\svirtual\stable\simplementation\sto\simplement\sthe\sMATCH\sfiltering. -D 2014-01-04T14:16:06.902 +C Instead\sof\shaving\sthe\splanner\signore\splans\swith\sunusable\sMATCH\sconstraints,\shave\sFTS\sassign\sextremely\shigh\scosts\sto\ssuch\splans\sin\sorder\sto\sdiscourage\sthe\splanner\sfrom\susing\sthem. +D 2014-01-04T14:42:14.057 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -78,7 +78,7 @@ F ext/fts3/README.content fdc666a70d5257a64fee209f97cf89e0e6e32b51 F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a F ext/fts3/README.tokenizers e0a8b81383ea60d0334d274fadf305ea14a8c314 F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d -F ext/fts3/fts3.c 1e667eacb3fe4b4ad6f863920da4286f071f6e07 +F ext/fts3/fts3.c 2af2cb2e742461b79710c132c7969fc7d949a59a F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe F ext/fts3/fts3Int.h eb5f8029589f3d8f1dc7fd50c773326a640388b1 F ext/fts3/fts3_aux.c 5c211e17a64885faeb16b9ba7772f9d5445c2365 @@ -293,7 +293,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c e9e593d5bb798c3e67fc3893dfe7055c9e7d8d74 -F src/where.c 14403429f7ad11b13b6ae0e466d089b8875ba195 +F src/where.c 8e3cb2030eaa242defb804aa30115b5d870e5cd4 F src/whereInt.h 96a75c61f1d2b9d4a8e4bb17d89deb0cf7cba358 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -547,7 +547,7 @@ F test/fts3expr3.test 9e91b8edbcb197bf2e92161aa7696446d96dce5f F test/fts3fault.test cb72dccb0a3b9f730f16c5240f3fcb9303eb1660 F test/fts3fault2.test 3198eef2804deea7cac8403e771d9cbcb752d887 F test/fts3first.test dbdedd20914c8d539aa3206c9b34a23775644641 -F test/fts3join.test bc8e5ca3e6b6577cf98e81b5271291e33e020e87 +F test/fts3join.test 53e66a0c21eb568580674a43b21c059acb26f499 F test/fts3malloc.test b0e4c133b8d61d4f6d112d8110f8320e9e453ef6 F test/fts3matchinfo.test ff423e73faab8fc6d7adeefedf74dd8e2b0b14e0 F test/fts3near.test 7e3354d46f155a822b59c0e957fd2a70c1d7e905 @@ -1148,10 +1148,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 429018b19cb525a4bb0843d20955457b53900d4b -R 6571bb57c7cea9164f2f0721e5f9106f -T *branch * avoid-unusable-match -T *sym-avoid-unusable-match * -T -sym-trunk * +P 19f3208b26597625728d1ef716d4e44407cf96ac +R 2d783783dbaa85fb88df6c2aa4454d7b U dan -Z 6e1a68d01b84e17020c8f255059d7b13 +Z 4059190156e7afb8f8755a31ed7148b9 diff --git a/manifest.uuid b/manifest.uuid index d3155e3c85..4eab7c326e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -19f3208b26597625728d1ef716d4e44407cf96ac \ No newline at end of file +24f84b38131866f7b435ffe641bb2f6991a70db2 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 83ec748679..0acc0db53f 100644 --- a/src/where.c +++ b/src/where.c @@ -4338,7 +4338,6 @@ static int whereLoopAddVirtual( int nConstraint; int seenIn = 0; /* True if an IN operator is seen */ int seenVar = 0; /* True if a non-constant constraint is seen */ - int seenVarMatch = 0; /* If a non-constant MATCH constraint is seen */ int iPhase; /* 0: const w/o IN, 1: const, 2: no IN, 2: IN */ WhereLoop *pNew; int rc = SQLITE_OK; @@ -4383,7 +4382,6 @@ static int whereLoopAddVirtual( } if( pTerm->prereqRight!=0 ){ seenVar = 1; - if( pTerm->eOperator & WO_MATCH ) seenVarMatch = 1; }else if( (pTerm->eOperator & WO_IN)==0 ){ pIdxCons->usable = 1; } @@ -4402,9 +4400,6 @@ static int whereLoopAddVirtual( break; } } - /* The following line ensures that, if there exists a MATCH constraint, - ** no plans for which the MATCH constraint is not usable are considered. */ - if( seenVarMatch && iPhase<=1 ) continue; memset(pUsage, 0, sizeof(pUsage[0])*pIdxInfo->nConstraint); if( pIdxInfo->needToFreeIdxStr ) sqlite3_free(pIdxInfo->idxStr); pIdxInfo->idxStr = 0; diff --git a/test/fts3join.test b/test/fts3join.test index f02e21513e..64363639db 100644 --- a/test/fts3join.test +++ b/test/fts3join.test @@ -59,7 +59,7 @@ do_execsql_test 2.4 { SELECT * FROM ft3, ft2 WHERE y MATCH x; } {abc abc} do_catchsql_test 2.5 { SELECT * FROM ft3, ft2 WHERE y MATCH x AND x MATCH y; -} {1 {no query solution}} +} {1 {unable to use function MATCH in the requested context}} finish_test From 54e2adb5f3b2d9ddd561fec1b36aec5ac85693b4 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 4 Jan 2014 15:17:04 +0000 Subject: [PATCH 119/276] Improvements to the column-cache for nested AND/OR operators. FossilOrigin-Name: 4e725f53131d3584319c710c8710a068989543c6 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/expr.c | 10 +++++++--- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 4e1d000e17..6bd605599f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Have\sFTS\sassign\sextremely\shigh\scosts\sto\splans\sthat\sfeature\sunusable\sMATCH\sconstraints.\sThis\sdiscourages\sthe\splanner\sfrom\schoosing\ssuch\splans,\swhich\slead\sto\s"unable\sto\suse\sfunction\sMATCH\sin\sthe\srequested\scontext"\serrors. -D 2014-01-04T14:46:39.188 +C Improvements\sto\sthe\scolumn-cache\sfor\snested\sAND/OR\soperators. +D 2014-01-04T15:17:04.888 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -175,7 +175,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 F src/delete.c 22f3dc3fd6b82ebce3dabf951a4b157026943ac1 -F src/expr.c ca0959386f01d6e5d4dc67b362a4e4c912ebd054 +F src/expr.c 15a86b7632da09924ccffb53fafa86e7d8727b70 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 2ab0f5384b70594468ef3ac5c7ed8ca24bfd17d5 F src/func.c 6325ac2ec10833ccf4d5c36d323709221d37ea19 @@ -1148,7 +1148,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 429018b19cb525a4bb0843d20955457b53900d4b 24f84b38131866f7b435ffe641bb2f6991a70db2 -R 2d783783dbaa85fb88df6c2aa4454d7b -U dan -Z 183032db794c33dfd03471ac339127f5 +P fa8be488a3ad290722dae7a1a7396c77277b2149 +R 7b52b4a00e9a7616715e494e48bd3657 +U drh +Z 701e96c9216858714def7e53249e15db diff --git a/manifest.uuid b/manifest.uuid index 0232dbf208..b3d3207e4a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fa8be488a3ad290722dae7a1a7396c77277b2149 \ No newline at end of file +4e725f53131d3584319c710c8710a068989543c6 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 0db51fe43f..67aae870d9 100644 --- a/src/expr.c +++ b/src/expr.c @@ -3388,7 +3388,7 @@ void sqlite3ExplainExprList(Vdbe *pOut, ExprList *pList){ sqlite3ExplainPrintf(pOut, "item[%d] = ", i); sqlite3ExplainPush(pOut); sqlite3ExplainExpr(pOut, pList->a[i].pExpr); - sqlite3ExplainPop(pOut); + sqlite3ExplainPop(pOut, 1); if( pList->a[i].zName ){ sqlite3ExplainPrintf(pOut, " AS %s", pList->a[i].zName); } @@ -3538,8 +3538,8 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ case TK_AND: { int d2 = sqlite3VdbeMakeLabel(v); testcase( jumpIfNull==0 ); - sqlite3ExprCachePush(pParse); sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2,jumpIfNull^SQLITE_JUMPIFNULL); + sqlite3ExprCachePush(pParse); sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull); sqlite3VdbeResolveLabel(v, d2); sqlite3ExprCachePop(pParse, 1); @@ -3548,7 +3548,9 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ case TK_OR: { testcase( jumpIfNull==0 ); sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull); + sqlite3ExprCachePush(pParse); sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull); + sqlite3ExprCachePop(pParse, 1); break; } case TK_NOT: { @@ -3695,14 +3697,16 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ case TK_AND: { testcase( jumpIfNull==0 ); sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull); + sqlite3ExprCachePush(pParse); sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull); + sqlite3ExprCachePop(pParse, 1); break; } case TK_OR: { int d2 = sqlite3VdbeMakeLabel(v); testcase( jumpIfNull==0 ); - sqlite3ExprCachePush(pParse); sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2, jumpIfNull^SQLITE_JUMPIFNULL); + sqlite3ExprCachePush(pParse); sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull); sqlite3VdbeResolveLabel(v, d2); sqlite3ExprCachePop(pParse, 1); From 61019c788362b46aa9a2a89380f7525359d13a43 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 4 Jan 2014 16:49:02 +0000 Subject: [PATCH 120/276] Omit OP_Close operations that occur immediately prior to OP_Halt and which cannot be jumped over. FossilOrigin-Name: 874b7e9999811c288ad41d07709f88e458d2d497 --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/build.c | 1 + src/delete.c | 4 +--- src/sqliteInt.h | 1 + src/vdbe.h | 2 +- src/vdbeaux.c | 13 ++++++++++--- 7 files changed, 25 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index 6bd605599f..6426172ac4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvements\sto\sthe\scolumn-cache\sfor\snested\sAND/OR\soperators. -D 2014-01-04T15:17:04.888 +C Omit\sOP_Close\soperations\sthat\soccur\simmediately\sprior\sto\sOP_Halt\sand\swhich\ncannot\sbe\sjumped\sover. +D 2014-01-04T16:49:02.617 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -169,12 +169,12 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btree.c 11e29ef8cf16a42925fde036bcffbeffd9cc82df F src/btree.h a61ddebc78c66795a2b93181321a116746302cc9 F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0 -F src/build.c 47ef8209e56d840d2b35b8a243c6ee567ad52bda +F src/build.c 5597ffa6d60759f89da3dd8a326c291a75e83c23 F src/callback.c 174e3c8656bc29f91d710ab61550d16eea34be98 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 -F src/delete.c 22f3dc3fd6b82ebce3dabf951a4b157026943ac1 +F src/delete.c f7c47fbbcbddf83c4af5df3681aa05a741a8d536 F src/expr.c 15a86b7632da09924ccffb53fafa86e7d8727b70 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 2ab0f5384b70594468ef3ac5c7ed8ca24bfd17d5 @@ -224,7 +224,7 @@ F src/shell.c a3541193d5fce37e91dad8ef46a9505aa7c9b344 F src/sqlite.h.in d94a8b89522f526ba711182ee161e06f8669bcc9 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h a77cb6c7404d1a20e536211be4a2e4be01cde213 +F src/sqliteInt.h 40fa66cb72bc88bcd0a16967f4ad58cff7e2c4fd F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -281,10 +281,10 @@ F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c e71f19b272f05c8695cf747b4bac1732685f9e5c F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 F src/vdbe.c b110887e415b5d2af58c2374c4dfdcf774c5d46c -F src/vdbe.h 298e0492827ef9db626934d060df62ed27ba56bc +F src/vdbe.h e6c4c610fcabad4fa80ebb1efc6822a9367e2b26 F src/vdbeInt.h 42db251e9f863401ff847b90d5fe1614c89a6a56 F src/vdbeapi.c ce4e68ea4842cc6081046f533d088dcf01d247ad -F src/vdbeaux.c 915fda7ca876aa2df2a13b0621ad0326342c0638 +F src/vdbeaux.c 9f4bfc52672acbb0bb4493d6a03603dc5a595ac1 F src/vdbeblob.c bc40f98f256f0b34116d6a44b114da4a81a15d33 F src/vdbemem.c 0e69351b2c6ff7d8b638688c0ae336a26befa6b2 F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147 @@ -1148,7 +1148,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P fa8be488a3ad290722dae7a1a7396c77277b2149 -R 7b52b4a00e9a7616715e494e48bd3657 +P 4e725f53131d3584319c710c8710a068989543c6 +R 9d927180209ef7717259744d3fe6bde8 U drh -Z 701e96c9216858714def7e53249e15db +Z 5260028c0eafa272f25baa07be63a049 diff --git a/manifest.uuid b/manifest.uuid index b3d3207e4a..eb18276f5b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4e725f53131d3584319c710c8710a068989543c6 \ No newline at end of file +874b7e9999811c288ad41d07709f88e458d2d497 \ No newline at end of file diff --git a/src/build.c b/src/build.c index c83ce57cfa..5c8c9300f6 100644 --- a/src/build.c +++ b/src/build.c @@ -140,6 +140,7 @@ void sqlite3FinishCoding(Parse *pParse){ assert( !pParse->isMultiWrite || sqlite3VdbeAssertMayAbort(v, pParse->mayAbort)); if( v ){ + while( sqlite3VdbeDeletePriorOpcode(v, OP_Close) ){} sqlite3VdbeAddOp0(v, OP_Halt); /* The cookie mask contains one bit for each database file open. diff --git a/src/delete.c b/src/delete.c index 0180ec48c8..641b4a763f 100644 --- a/src/delete.c +++ b/src/delete.c @@ -790,9 +790,7 @@ int sqlite3GenerateIndexKey( ** But we are getting ready to store this value back into an index, where ** it should be converted by to INTEGER again. So omit the OP_RealAffinity ** opcode if it is present */ - if( sqlite3VdbeGetOp(v, -1)->opcode==OP_RealAffinity ){ - sqlite3VdbeDeleteLastOpcode(v); - } + sqlite3VdbeDeletePriorOpcode(v, OP_RealAffinity); } if( regOut ){ sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regOut); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 5943ced2a0..035e590bfe 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2293,6 +2293,7 @@ struct Parse { int nOpAlloc; /* Number of slots allocated for Vdbe.aOp[] */ int nLabel; /* Number of labels used */ int *aLabel; /* Space to hold the labels */ + int iFixedOp; /* Never back out opcodes iFixedOp-1 or earlier */ int ckBase; /* Base register of data during check constraints */ int iPartIdxTab; /* Table corresponding to a partial index */ int iCacheLevel; /* ColCache valid when aColCache[].iLevel<=iCacheLevel */ diff --git a/src/vdbe.h b/src/vdbe.h index 46bc89cee8..620f2eaf72 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -175,7 +175,7 @@ void sqlite3VdbeChangeP3(Vdbe*, u32 addr, int P3); void sqlite3VdbeChangeP5(Vdbe*, u8 P5); void sqlite3VdbeJumpHere(Vdbe*, int addr); void sqlite3VdbeChangeToNoop(Vdbe*, int addr); -void sqlite3VdbeDeleteLastOpcode(Vdbe*); +int sqlite3VdbeDeletePriorOpcode(Vdbe*, u8 op); void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N); void sqlite3VdbeSetP4KeyInfo(Parse*, Index*); void sqlite3VdbeUsesBtree(Vdbe*, int); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index e0b3c5485f..faabaf75d7 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -276,6 +276,7 @@ void sqlite3VdbeResolveLabel(Vdbe *v, int x){ if( j>=0 && p->aLabel ){ p->aLabel[j] = v->nOp; } + p->iFixedOp = v->nOp - 1; } /* @@ -624,7 +625,8 @@ void sqlite3VdbeChangeP5(Vdbe *p, u8 val){ ** the address of the next instruction to be coded. */ void sqlite3VdbeJumpHere(Vdbe *p, int addr){ - if( ALWAYS(addr>=0) ) sqlite3VdbeChangeP2(p, addr, p->nOp); + sqlite3VdbeChangeP2(p, addr, p->nOp); + p->pParse->iFixedOp = p->nOp - 1; } @@ -729,8 +731,13 @@ void sqlite3VdbeChangeToNoop(Vdbe *p, int addr){ /* ** Remove the last opcode inserted */ -void sqlite3VdbeDeleteLastOpcode(Vdbe *p){ - p->nOp--; +int sqlite3VdbeDeletePriorOpcode(Vdbe *p, u8 op){ + if( (p->nOp-1)>(p->pParse->iFixedOp) && p->aOp[p->nOp-1].opcode==op ){ + sqlite3VdbeChangeToNoop(p, p->nOp-1); + return 1; + }else{ + return 0; + } } /* From 1c2c0b776fdd1e12e7d844c8766157b82e4265a0 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 4 Jan 2014 19:27:05 +0000 Subject: [PATCH 121/276] Avoid redundant register loads during index key generation when doing a DELETE or INTEGRITY_CHECK on a table with multiple indices. FossilOrigin-Name: 8f6e6149a165f516be6395fd753e163d52ffd52e --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/build.c | 2 +- src/delete.c | 24 +++++++++++++++++++++--- src/pragma.c | 7 +++++-- src/sqliteInt.h | 2 +- src/where.c | 2 +- 7 files changed, 40 insertions(+), 19 deletions(-) diff --git a/manifest b/manifest index 6426172ac4..66e96c4c62 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Omit\sOP_Close\soperations\sthat\soccur\simmediately\sprior\sto\sOP_Halt\sand\swhich\ncannot\sbe\sjumped\sover. -D 2014-01-04T16:49:02.617 +C Avoid\sredundant\sregister\sloads\sduring\sindex\skey\sgeneration\swhen\sdoing\sa\nDELETE\sor\sINTEGRITY_CHECK\son\sa\stable\swith\smultiple\sindices. +D 2014-01-04T19:27:05.589 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -169,12 +169,12 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btree.c 11e29ef8cf16a42925fde036bcffbeffd9cc82df F src/btree.h a61ddebc78c66795a2b93181321a116746302cc9 F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0 -F src/build.c 5597ffa6d60759f89da3dd8a326c291a75e83c23 +F src/build.c 3609c8aa26947d7a035faa23eb1cb2cfc54b4680 F src/callback.c 174e3c8656bc29f91d710ab61550d16eea34be98 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 -F src/delete.c f7c47fbbcbddf83c4af5df3681aa05a741a8d536 +F src/delete.c 91e1321021db5dc266360531b8b6550009d771ff F src/expr.c 15a86b7632da09924ccffb53fafa86e7d8727b70 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 2ab0f5384b70594468ef3ac5c7ed8ca24bfd17d5 @@ -213,7 +213,7 @@ F src/parse.y acee1a9958539e21263362b194594c5255ad2fca F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222 F src/pcache1.c 57fee9a9a617218f5037afbbe49b09da65bde56b -F src/pragma.c 5ab7279d132143feb77f773688a24ab05da75fd7 +F src/pragma.c ed409ce4104cf4d9de6ead40ace70974f124853b F src/prepare.c 677521ab7132615a8a26107a1d1c3132f44ae337 F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece @@ -224,7 +224,7 @@ F src/shell.c a3541193d5fce37e91dad8ef46a9505aa7c9b344 F src/sqlite.h.in d94a8b89522f526ba711182ee161e06f8669bcc9 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h 40fa66cb72bc88bcd0a16967f4ad58cff7e2c4fd +F src/sqliteInt.h 672ef78e9e6f8b03fc9d37884f9784fb02e6ce2d F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -293,7 +293,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c e9e593d5bb798c3e67fc3893dfe7055c9e7d8d74 -F src/where.c 8e3cb2030eaa242defb804aa30115b5d870e5cd4 +F src/where.c 18f07fd0fd116a5880773c689eb7cd8e60175107 F src/whereInt.h 96a75c61f1d2b9d4a8e4bb17d89deb0cf7cba358 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1148,7 +1148,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 4e725f53131d3584319c710c8710a068989543c6 -R 9d927180209ef7717259744d3fe6bde8 +P 874b7e9999811c288ad41d07709f88e458d2d497 +R fc5dbcd7a08b2e4b11ffb23dc1241ea1 U drh -Z 5260028c0eafa272f25baa07be63a049 +Z 86dc65664e674593ae8c26084106bce8 diff --git a/manifest.uuid b/manifest.uuid index eb18276f5b..cc46b176ca 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -874b7e9999811c288ad41d07709f88e458d2d497 \ No newline at end of file +8f6e6149a165f516be6395fd753e163d52ffd52e \ No newline at end of file diff --git a/src/build.c b/src/build.c index 5c8c9300f6..15430fd28b 100644 --- a/src/build.c +++ b/src/build.c @@ -2678,7 +2678,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0); regRecord = sqlite3GetTempReg(pParse); - sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 0, &iPartIdxLabel); + sqlite3GenerateIndexKey(pParse,pIndex,iTab,regRecord,0,&iPartIdxLabel,0,0); sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord); sqlite3VdbeResolveLabel(v, iPartIdxLabel); sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1); diff --git a/src/delete.c b/src/delete.c index 641b4a763f..e448e47b02 100644 --- a/src/delete.c +++ b/src/delete.c @@ -716,9 +716,10 @@ void sqlite3GenerateRowIndexDelete( int *aRegIdx /* Only delete if aRegIdx!=0 && aRegIdx[i]>0 */ ){ int i; /* Index loop counter */ - int r1; /* Register holding an index key */ + int r1 = -1; /* Register holding an index key */ int iPartIdxLabel; /* Jump destination for skipping partial index entries */ Index *pIdx; /* Current index */ + Index *pPrior = 0; /* Prior index */ Vdbe *v; /* The prepared statement under construction */ Index *pPk; /* PRIMARY KEY index, or NULL for rowid tables */ @@ -729,10 +730,12 @@ void sqlite3GenerateRowIndexDelete( if( aRegIdx!=0 && aRegIdx[i]==0 ) continue; if( pIdx==pPk ) continue; VdbeModuleComment((v, "GenRowIdxDel for %s", pIdx->zName)); - r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 1, &iPartIdxLabel); + r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 1, + &iPartIdxLabel, pPrior, r1); sqlite3VdbeAddOp3(v, OP_IdxDelete, iIdxCur+i, r1, pIdx->uniqNotNull ? pIdx->nKeyCol : pIdx->nColumn); sqlite3VdbeResolveLabel(v, iPartIdxLabel); + pPrior = pIdx; } } @@ -754,6 +757,17 @@ void sqlite3GenerateRowIndexDelete( ** to false or null. If pIdx is not a partial index, *piPartIdxLabel ** will be set to zero which is an empty label that is ignored by ** sqlite3VdbeResolveLabel(). +** +** The pPrior and regPrior parameters are used to implement a cache to +** avoid unnecessary register loads. If pPrior is not NULL, then it is +** a pointer to a different index for which an index key has just been +** computed into register regPrior. If the current pIdx index is generating +** its key into the same sequence of registers and if pPrior and pIdx share +** a column in common, then the register corresponding to that column already +** holds the correct value and the loading of that register is skipped. +** This optimization is helpful when doing a DELETE or an INTEGRITY_CHECK +** on a table with multiple indices, and especially with the ROWID or +** PRIMARY KEY columns of the index. */ int sqlite3GenerateIndexKey( Parse *pParse, /* Parsing context */ @@ -761,7 +775,9 @@ int sqlite3GenerateIndexKey( int iDataCur, /* Cursor number from which to take column data */ int regOut, /* Put the new key into this register if not 0 */ int prefixOnly, /* Compute only a unique prefix of the key */ - int *piPartIdxLabel /* OUT: Jump to this label to skip partial index */ + int *piPartIdxLabel, /* OUT: Jump to this label to skip partial index */ + Index *pPrior, /* Previously generated index key */ + int regPrior /* Register holding previous generated key */ ){ Vdbe *v = pParse->pVdbe; int j; @@ -781,7 +797,9 @@ int sqlite3GenerateIndexKey( } nCol = (prefixOnly && pIdx->uniqNotNull) ? pIdx->nKeyCol : pIdx->nColumn; regBase = sqlite3GetTempRange(pParse, nCol); + if( pPrior && (regBase!=regPrior || pPrior->pPartIdxWhere) ) pPrior = 0; for(j=0; jaiColumn[j]==pIdx->aiColumn[j] ) continue; sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, pIdx->aiColumn[j], regBase+j); /* If the column affinity is REAL but the number is an integer, then it diff --git a/src/pragma.c b/src/pragma.c index bbd27b8c18..7383bce96f 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1881,8 +1881,10 @@ void sqlite3Pragma( for(x=sqliteHashFirst(pTbls); x && !isQuick; x=sqliteHashNext(x)){ Table *pTab = sqliteHashData(x); Index *pIdx, *pPk; + Index *pPrior = 0; int loopTop; int iDataCur, iIdxCur; + int r1 = -1; if( pTab->pIndex==0 ) continue; pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab); @@ -1901,9 +1903,10 @@ void sqlite3Pragma( loopTop = sqlite3VdbeAddOp2(v, OP_AddImm, 7, 1); for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ int jmp2, jmp3, jmp4; - int r1; if( pPk==pIdx ) continue; - r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 0, &jmp3); + r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 0, &jmp3, + pPrior, r1); + pPrior = pIdx; sqlite3VdbeAddOp2(v, OP_AddImm, 8+j, 1); /* increment entry count */ jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, iIdxCur+j, 0, r1, pIdx->nColumn); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 035e590bfe..d3e993c135 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2992,7 +2992,7 @@ int sqlite3ExprNeedsNoAffinityChange(const Expr*, char); int sqlite3IsRowid(const char*); void sqlite3GenerateRowDelete(Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8); void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*); -int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*); +int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*,Index*,int); void sqlite3GenerateConstraintChecks(Parse*,Table*,int*,int,int,int,int, u8,u8,int,int*); void sqlite3CompleteInsertion(Parse*,Table*,int,int,int,int*,int,int,int); diff --git a/src/where.c b/src/where.c index 0acc0db53f..d5444a6054 100644 --- a/src/where.c +++ b/src/where.c @@ -1710,7 +1710,7 @@ static void constructAutomaticIndex( /* Fill the automatic index with content */ addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); regRecord = sqlite3GetTempReg(pParse); - sqlite3GenerateIndexKey(pParse, pIdx, pLevel->iTabCur, regRecord, 0, 0); + sqlite3GenerateIndexKey(pParse, pIdx, pLevel->iTabCur, regRecord, 0, 0, 0, 0); sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord); sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); From 2e08486a08a41e251b594566c8ef37e51c9facf8 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 4 Jan 2014 19:58:29 +0000 Subject: [PATCH 122/276] Add the usual "fts3" prefix to new static method setEstimatedRows() in fts3.c. This fixes a problem when compiling the amalgamation, as the r-tree module also contains a static method named setEstimatedRows. FossilOrigin-Name: d6fcfc8890489b942e5b3f1bc271835d77c5ef96 --- ext/fts3/fts3.c | 4 ++-- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/ext/fts3/fts3.c b/ext/fts3/fts3.c index 62ff1437b9..44b7f431df 100644 --- a/ext/fts3/fts3.c +++ b/ext/fts3/fts3.c @@ -1477,7 +1477,7 @@ static int fts3CreateMethod( ** extension is currently being used by a version of SQLite too old to ** support estimatedRows. In that case this function is a no-op. */ -static void setEstimatedRows(sqlite3_index_info *pIdxInfo, i64 nRow){ +static void fts3SetEstimatedRows(sqlite3_index_info *pIdxInfo, i64 nRow){ #if SQLITE_VERSION_NUMBER>=3008002 if( sqlite3_libversion_number()>=3008002 ){ pIdxInfo->estimatedRows = nRow; @@ -1521,7 +1521,7 @@ static int fts3BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ ** this, return a very high cost here. */ pInfo->idxNum = FTS3_FULLSCAN_SEARCH; pInfo->estimatedCost = 1e50; - setEstimatedRows(pInfo, ((sqlite3_int64)1) << 50); + fts3SetEstimatedRows(pInfo, ((sqlite3_int64)1) << 50); return SQLITE_OK; } continue; diff --git a/manifest b/manifest index 66e96c4c62..20a04a96bd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sredundant\sregister\sloads\sduring\sindex\skey\sgeneration\swhen\sdoing\sa\nDELETE\sor\sINTEGRITY_CHECK\son\sa\stable\swith\smultiple\sindices. -D 2014-01-04T19:27:05.589 +C Add\sthe\susual\s"fts3"\sprefix\sto\snew\sstatic\smethod\ssetEstimatedRows()\sin\sfts3.c.\sThis\sfixes\sa\sproblem\swhen\scompiling\sthe\samalgamation,\sas\sthe\sr-tree\smodule\salso\scontains\sa\sstatic\smethod\snamed\ssetEstimatedRows. +D 2014-01-04T19:58:29.359 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -78,7 +78,7 @@ F ext/fts3/README.content fdc666a70d5257a64fee209f97cf89e0e6e32b51 F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a F ext/fts3/README.tokenizers e0a8b81383ea60d0334d274fadf305ea14a8c314 F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d -F ext/fts3/fts3.c 2af2cb2e742461b79710c132c7969fc7d949a59a +F ext/fts3/fts3.c 3fe91e36a0304ad4b35020f0e22ff37e95873166 F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe F ext/fts3/fts3Int.h eb5f8029589f3d8f1dc7fd50c773326a640388b1 F ext/fts3/fts3_aux.c 5c211e17a64885faeb16b9ba7772f9d5445c2365 @@ -1148,7 +1148,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 874b7e9999811c288ad41d07709f88e458d2d497 -R fc5dbcd7a08b2e4b11ffb23dc1241ea1 -U drh -Z 86dc65664e674593ae8c26084106bce8 +P 8f6e6149a165f516be6395fd753e163d52ffd52e +R 2ae7b961fa0019d77bff10a5332fc93d +U dan +Z 855ecbcf8fda10bc6c9a4ba8bd1399e1 diff --git a/manifest.uuid b/manifest.uuid index cc46b176ca..d709dd888d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8f6e6149a165f516be6395fd753e163d52ffd52e \ No newline at end of file +d6fcfc8890489b942e5b3f1bc271835d77c5ef96 \ No newline at end of file From b66e21fda587a78079413d3588da69155b538141 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 4 Jan 2014 20:00:14 +0000 Subject: [PATCH 123/276] Fix an typo that breaks the build when SQLITE_ENABLE_TREE_EXPLAIN is defined. FossilOrigin-Name: f461e2b3973d0fe6a7b8cb7a3aaab8a30b3e16c0 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/expr.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 20a04a96bd..1d0ad0ed3f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\susual\s"fts3"\sprefix\sto\snew\sstatic\smethod\ssetEstimatedRows()\sin\sfts3.c.\sThis\sfixes\sa\sproblem\swhen\scompiling\sthe\samalgamation,\sas\sthe\sr-tree\smodule\salso\scontains\sa\sstatic\smethod\snamed\ssetEstimatedRows. -D 2014-01-04T19:58:29.359 +C Fix\san\stypo\sthat\sbreaks\sthe\sbuild\swhen\sSQLITE_ENABLE_TREE_EXPLAIN\sis\sdefined. +D 2014-01-04T20:00:14.172 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -175,7 +175,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 F src/delete.c 91e1321021db5dc266360531b8b6550009d771ff -F src/expr.c 15a86b7632da09924ccffb53fafa86e7d8727b70 +F src/expr.c 4115ad67088cdd55f4fa0ef3ddd22cb8da8f9c94 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 2ab0f5384b70594468ef3ac5c7ed8ca24bfd17d5 F src/func.c 6325ac2ec10833ccf4d5c36d323709221d37ea19 @@ -1148,7 +1148,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 8f6e6149a165f516be6395fd753e163d52ffd52e -R 2ae7b961fa0019d77bff10a5332fc93d -U dan -Z 855ecbcf8fda10bc6c9a4ba8bd1399e1 +P d6fcfc8890489b942e5b3f1bc271835d77c5ef96 +R 92a605458ee112680310df2ab331e715 +U drh +Z 1b6a595171700e1d6836f451072293d3 diff --git a/manifest.uuid b/manifest.uuid index d709dd888d..89e098a77e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d6fcfc8890489b942e5b3f1bc271835d77c5ef96 \ No newline at end of file +f461e2b3973d0fe6a7b8cb7a3aaab8a30b3e16c0 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 67aae870d9..aad6cd1cda 100644 --- a/src/expr.c +++ b/src/expr.c @@ -3388,7 +3388,7 @@ void sqlite3ExplainExprList(Vdbe *pOut, ExprList *pList){ sqlite3ExplainPrintf(pOut, "item[%d] = ", i); sqlite3ExplainPush(pOut); sqlite3ExplainExpr(pOut, pList->a[i].pExpr); - sqlite3ExplainPop(pOut, 1); + sqlite3ExplainPop(pOut); if( pList->a[i].zName ){ sqlite3ExplainPrintf(pOut, " AS %s", pList->a[i].zName); } From 1bcbc621dfbea87d52cba3988dbbf176ea041aa4 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 9 Jan 2014 13:39:07 +0000 Subject: [PATCH 124/276] Fix harmless compiler warning in unixUnfetch(). FossilOrigin-Name: 618f248f4ea9fb0b6ff019a4c2cd72857389301f --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/os_unix.c | 7 +++++-- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 1d0ad0ed3f..d4fa6de5fd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\stypo\sthat\sbreaks\sthe\sbuild\swhen\sSQLITE_ENABLE_TREE_EXPLAIN\sis\sdefined. -D 2014-01-04T20:00:14.172 +C Fix\sharmless\scompiler\swarning\sin\sunixUnfetch(). +D 2014-01-09T13:39:07.144 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -205,7 +205,7 @@ F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30 F src/os.c 1b147e4cf7cc39e618115c14a086aed44bc91ace F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 -F src/os_unix.c abeb9d54036aaea6f4395050ce823f51217ae4d4 +F src/os_unix.c 9270957b8ebab7a6c930cc6891f98cf396771d9d F src/os_win.c 16eac0961603182ffc10c02b39fe830126538e07 F src/pager.c efa923693e958696eee69b205a20bfbc402c8480 F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428 @@ -1148,7 +1148,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P d6fcfc8890489b942e5b3f1bc271835d77c5ef96 -R 92a605458ee112680310df2ab331e715 +P f461e2b3973d0fe6a7b8cb7a3aaab8a30b3e16c0 +R d5e72e34ba57bc2641d05089f26a27b4 U drh -Z 1b6a595171700e1d6836f451072293d3 +Z 8832e3e8b28de8e986889f1676a8ae62 diff --git a/manifest.uuid b/manifest.uuid index 89e098a77e..6db219b4e4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f461e2b3973d0fe6a7b8cb7a3aaab8a30b3e16c0 \ No newline at end of file +618f248f4ea9fb0b6ff019a4c2cd72857389301f \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 4b76d4fec4..420275b3f9 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -4848,10 +4848,10 @@ static int unixFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){ ** may now be invalid and should be unmapped. */ static int unixUnfetch(sqlite3_file *fd, i64 iOff, void *p){ - unixFile *pFd = (unixFile *)fd; /* The underlying database file */ UNUSED_PARAMETER(iOff); - #if SQLITE_MAX_MMAP_SIZE>0 + unixFile *pFd = (unixFile *)fd; /* The underlying database file */ + /* If p==0 (unmap the entire file) then there must be no outstanding ** xFetch references. Or, if p!=0 (meaning it is an xFetch reference), ** then there must be at least one outstanding. */ @@ -4867,6 +4867,9 @@ static int unixUnfetch(sqlite3_file *fd, i64 iOff, void *p){ } assert( pFd->nFetchOut>=0 ); +#else + UNUSED_PARAMETER(fd); + UNUSED_PARAMETER(p); #endif return SQLITE_OK; } From 9871c59a2d18e0b07ef97118aa13843f666a6bb0 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 10 Jan 2014 16:40:21 +0000 Subject: [PATCH 125/276] Fix another harmless compiler warning in unixUnfetch(). FossilOrigin-Name: 0484549bb82ca5246488330c8d266e429ccd19b9 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/os_unix.c | 3 ++- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index d4fa6de5fd..19878b4a97 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarning\sin\sunixUnfetch(). -D 2014-01-09T13:39:07.144 +C Fix\sanother\sharmless\scompiler\swarning\sin\sunixUnfetch(). +D 2014-01-10T16:40:21.047 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -205,7 +205,7 @@ F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30 F src/os.c 1b147e4cf7cc39e618115c14a086aed44bc91ace F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 -F src/os_unix.c 9270957b8ebab7a6c930cc6891f98cf396771d9d +F src/os_unix.c 3a4dcb554d3c915075766162f28c3fd4cdb75968 F src/os_win.c 16eac0961603182ffc10c02b39fe830126538e07 F src/pager.c efa923693e958696eee69b205a20bfbc402c8480 F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428 @@ -1148,7 +1148,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P f461e2b3973d0fe6a7b8cb7a3aaab8a30b3e16c0 -R d5e72e34ba57bc2641d05089f26a27b4 -U drh -Z 8832e3e8b28de8e986889f1676a8ae62 +P 618f248f4ea9fb0b6ff019a4c2cd72857389301f +R 680b9cb5772eadf3cf119ad0606b2737 +U dan +Z 5d71bf2b25857007a3e37b3d6409191a diff --git a/manifest.uuid b/manifest.uuid index 6db219b4e4..d04b2a2897 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -618f248f4ea9fb0b6ff019a4c2cd72857389301f \ No newline at end of file +0484549bb82ca5246488330c8d266e429ccd19b9 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 420275b3f9..96cd5e6191 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -4848,9 +4848,9 @@ static int unixFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){ ** may now be invalid and should be unmapped. */ static int unixUnfetch(sqlite3_file *fd, i64 iOff, void *p){ - UNUSED_PARAMETER(iOff); #if SQLITE_MAX_MMAP_SIZE>0 unixFile *pFd = (unixFile *)fd; /* The underlying database file */ + UNUSED_PARAMETER(iOff); /* If p==0 (unmap the entire file) then there must be no outstanding ** xFetch references. Or, if p!=0 (meaning it is an xFetch reference), @@ -4870,6 +4870,7 @@ static int unixUnfetch(sqlite3_file *fd, i64 iOff, void *p){ #else UNUSED_PARAMETER(fd); UNUSED_PARAMETER(p); + UNUSED_PARAMETER(iOff); #endif return SQLITE_OK; } From c740752470a0557b03299c5fd5036e5e096b78e3 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 10 Jan 2014 20:38:12 +0000 Subject: [PATCH 126/276] Fix CREATE TABLE ... AS so that it works with column names that are empty strings. FossilOrigin-Name: 632045f21c553e10f59a14c772d50d7824ca0c2c --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/build.c | 8 ++++---- test/misc1.test | 13 +++++++++++++ 4 files changed, 26 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 19878b4a97..ef3aae89ea 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sanother\sharmless\scompiler\swarning\sin\sunixUnfetch(). -D 2014-01-10T16:40:21.047 +C Fix\sCREATE\sTABLE\s...\sAS\sso\sthat\sit\sworks\swith\scolumn\snames\sthat\sare\sempty\nstrings. +D 2014-01-10T20:38:12.815 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -169,7 +169,7 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btree.c 11e29ef8cf16a42925fde036bcffbeffd9cc82df F src/btree.h a61ddebc78c66795a2b93181321a116746302cc9 F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0 -F src/build.c 3609c8aa26947d7a035faa23eb1cb2cfc54b4680 +F src/build.c 8c56d91447770a746b16d08a6510109c161dbc1a F src/callback.c 174e3c8656bc29f91d710ab61550d16eea34be98 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd @@ -693,7 +693,7 @@ F test/minmax.test 42fbad0e81afaa6e0de41c960329f2b2c3526efd F test/minmax2.test b44bae787fc7b227597b01b0ca5575c7cb54d3bc F test/minmax3.test cc1e8b010136db0d01a6f2a29ba5a9f321034354 F test/minmax4.test 536a3360470633a177e42fbc19660d146b51daef -F test/misc1.test 9bed1bd334065a57dc841cff969d4fc1eeb6d49b +F test/misc1.test 441a0fafc7087f841db09fbfca54e7aea9f5a84c F test/misc2.test 00d7de54eda90e237fc9a38b9e5ccc769ebf6d4d F test/misc3.test cf3dda47d5dda3e53fc5804a100d3c82be736c9d F test/misc4.test 9c078510fbfff05a9869a0b6d8b86a623ad2c4f6 @@ -1148,7 +1148,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 618f248f4ea9fb0b6ff019a4c2cd72857389301f -R 680b9cb5772eadf3cf119ad0606b2737 -U dan -Z 5d71bf2b25857007a3e37b3d6409191a +P 0484549bb82ca5246488330c8d266e429ccd19b9 +R 00ef541b0e35ee7a66a11f656f6dc3e2 +U drh +Z 1394adca743ceab6563433db8e16d260 diff --git a/manifest.uuid b/manifest.uuid index d04b2a2897..7a50b80671 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0484549bb82ca5246488330c8d266e429ccd19b9 \ No newline at end of file +632045f21c553e10f59a14c772d50d7824ca0c2c \ No newline at end of file diff --git a/src/build.c b/src/build.c index 15430fd28b..fa82d56cc7 100644 --- a/src/build.c +++ b/src/build.c @@ -1452,10 +1452,10 @@ static void identPut(char *z, int *pIdx, char *zSignedIdent){ for(j=0; zIdent[j]; j++){ if( !sqlite3Isalnum(zIdent[j]) && zIdent[j]!='_' ) break; } - needQuote = sqlite3Isdigit(zIdent[0]) || sqlite3KeywordCode(zIdent, j)!=TK_ID; - if( !needQuote ){ - needQuote = zIdent[j]; - } + needQuote = sqlite3Isdigit(zIdent[0]) + || sqlite3KeywordCode(zIdent, j)!=TK_ID + || zIdent[j]!=0 + || j==0; if( needQuote ) z[i++] = '"'; for(j=0; zIdent[j]; j++){ diff --git a/test/misc1.test b/test/misc1.test index 8573d349b3..f886f896e2 100644 --- a/test/misc1.test +++ b/test/misc1.test @@ -592,4 +592,17 @@ do_test misc1-18.1 { expr {$n>=100} } {1} +# 2014-01-10: In a CREATE TABLE AS, if one or more of the column names +# are an empty string, that is still OK. +# +do_execsql_test misc1-19.1 { + CREATE TABLE t19 AS SELECT 1, 2 AS '', 3; + SELECT * FROM t19; +} {1 2 3} +do_execsql_test misc1-19.2 { + CREATE TABLE t19b AS SELECT 4 AS '', 5 AS '', 6 AS ''; + SELECT * FROM t19b; +} {4 5 6} + + finish_test From 75593d96be4062a3fd6cf86135b945e95367b10b Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 10 Jan 2014 20:46:55 +0000 Subject: [PATCH 127/276] Allow a VALUES clause to be used any place that a SELECT statement can be used. FossilOrigin-Name: c9ea7d199f06a7801ab639e7ac98ebeb98706f24 --- manifest | 18 ++++++------- manifest.uuid | 2 +- src/insert.c | 13 ++++++++- src/parse.y | 70 ++++++++++++++----------------------------------- src/sqliteInt.h | 6 ++--- src/trigger.c | 7 +---- 6 files changed, 46 insertions(+), 70 deletions(-) diff --git a/manifest b/manifest index ef3aae89ea..3ad162dd48 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sCREATE\sTABLE\s...\sAS\sso\sthat\sit\sworks\swith\scolumn\snames\sthat\sare\sempty\nstrings. -D 2014-01-10T20:38:12.815 +C Allow\sa\sVALUES\sclause\sto\sbe\sused\sany\splace\sthat\sa\sSELECT\sstatement\scan\sbe\nused. +D 2014-01-10T20:46:55.338 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -183,7 +183,7 @@ F src/global.c 1d7bb7ea8254ae6a68ed9bfaf65fcb3d1690b486 F src/hash.c ac3470bbf1ca4ae4e306a8ecb0fdf1731810ffe4 F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c e6b3d7847aaf06170967ff6ea9076717fbc08d3f +F src/insert.c 5ddb48c7f1cb399993744f23f03948989ce1790e F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b @@ -209,7 +209,7 @@ F src/os_unix.c 3a4dcb554d3c915075766162f28c3fd4cdb75968 F src/os_win.c 16eac0961603182ffc10c02b39fe830126538e07 F src/pager.c efa923693e958696eee69b205a20bfbc402c8480 F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428 -F src/parse.y acee1a9958539e21263362b194594c5255ad2fca +F src/parse.y 0a284e3f2bb78363ddce6f796ca2074e1e265eb7 F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222 F src/pcache1.c 57fee9a9a617218f5037afbbe49b09da65bde56b @@ -224,7 +224,7 @@ F src/shell.c a3541193d5fce37e91dad8ef46a9505aa7c9b344 F src/sqlite.h.in d94a8b89522f526ba711182ee161e06f8669bcc9 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h 672ef78e9e6f8b03fc9d37884f9784fb02e6ce2d +F src/sqliteInt.h 0c65967bb807dee3c9eef2bbd17f880eeb28ea30 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -275,7 +275,7 @@ F src/test_vfs.c e72f555ef7a59080f898fcf1a233deb9eb704ea9 F src/test_vfstrace.c 3a0ab304682fecbceb689e7d9b904211fde11d78 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/tokenize.c ec4c1a62b890bf1dbcdb966399e140b904c700a4 -F src/trigger.c d84e1f3669e9a217731a14a9d472b1c7b87c87ba +F src/trigger.c 5c1c0b899ac0ce284763dcb8fdbaa38ecf15ef98 F src/update.c c2706a6eb232a96345c35b7e1e75a188e26812bb F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c e71f19b272f05c8695cf747b4bac1732685f9e5c @@ -1148,7 +1148,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 0484549bb82ca5246488330c8d266e429ccd19b9 -R 00ef541b0e35ee7a66a11f656f6dc3e2 +P 632045f21c553e10f59a14c772d50d7824ca0c2c +R cf996bb200e200afa8de950e78c84a55 U drh -Z 1394adca743ceab6563433db8e16d260 +Z 54c4a7cb2ec6e5258f05fa3eca37aefd diff --git a/manifest.uuid b/manifest.uuid index 7a50b80671..76d9f0f1fb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -632045f21c553e10f59a14c772d50d7824ca0c2c \ No newline at end of file +c9ea7d199f06a7801ab639e7ac98ebeb98706f24 \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index abc34c03ca..038d08a40d 100644 --- a/src/insert.c +++ b/src/insert.c @@ -540,7 +540,6 @@ static int xferOptimization( void sqlite3Insert( Parse *pParse, /* Parser context */ SrcList *pTabList, /* Name of table into which we are inserting */ - ExprList *pList, /* List of values to be inserted */ Select *pSelect, /* A SELECT statement to use as the data source */ IdList *pColumn, /* Column names corresponding to IDLIST. */ int onError /* How to handle constraint errors */ @@ -568,6 +567,7 @@ void sqlite3Insert( Db *pDb; /* The database containing table being inserted into */ int appendFlag = 0; /* True if the insert is likely to be an append */ int withoutRowid; /* 0 for normal table. 1 for WITHOUT ROWID table */ + ExprList *pList = 0; /* List of VALUES() to be inserted */ /* Register allocations */ int regFromSelect = 0;/* Base register for data coming from SELECT */ @@ -591,6 +591,17 @@ void sqlite3Insert( goto insert_cleanup; } + /* If the Select object is really just a simple VALUES() list with a + ** single row values (the common case) then keep that one row of values + ** and go ahead and discard the Select object + */ + if( pSelect && (pSelect->selFlags & SF_Values)!=0 && pSelect->pPrior==0 ){ + pList = pSelect->pEList; + pSelect->pEList = 0; + sqlite3SelectDelete(db, pSelect); + pSelect = 0; + } + /* Locate the table into which we will be inserting new information. */ assert( pTabList->nSrc==1 ); diff --git a/src/parse.y b/src/parse.y index ba9feb10fc..00d47cd3ea 100644 --- a/src/parse.y +++ b/src/parse.y @@ -442,6 +442,23 @@ oneselect(A) ::= SELECT distinct(D) selcollist(W) from(X) where_opt(Y) groupby_opt(P) having_opt(Q) orderby_opt(Z) limit_opt(L). { A = sqlite3SelectNew(pParse,W,X,Y,P,Q,Z,D,L.pLimit,L.pOffset); } +oneselect(A) ::= values(X). {A = X;} + +%type values {Select*} +%destructor values {sqlite3SelectDelete(pParse->db, $$);} +values(A) ::= VALUES LP nexprlist(X) RP. { + A = sqlite3SelectNew(pParse,X,0,0,0,0,0,SF_Values,0,0); +} +values(A) ::= values(X) COMMA LP exprlist(Y) RP. { + Select *pRight = sqlite3SelectNew(pParse,Y,0,0,0,0,0,SF_Values,0,0); + if( pRight ){ + pRight->op = TK_ALL; + pRight->pPrior = X; + A = pRight; + }else{ + A = X; + } +} // The "distinct" nonterminal is true (1) if the DISTINCT keyword is // present and false (0) if it is not. @@ -696,58 +713,15 @@ setlist(A) ::= nm(X) EQ expr(Y). { ////////////////////////// The INSERT command ///////////////////////////////// // -cmd ::= insert_cmd(R) INTO fullname(X) inscollist_opt(F) valuelist(Y). - {sqlite3Insert(pParse, X, Y.pList, Y.pSelect, F, R);} cmd ::= insert_cmd(R) INTO fullname(X) inscollist_opt(F) select(S). - {sqlite3Insert(pParse, X, 0, S, F, R);} + {sqlite3Insert(pParse, X, S, F, R);} cmd ::= insert_cmd(R) INTO fullname(X) inscollist_opt(F) DEFAULT VALUES. - {sqlite3Insert(pParse, X, 0, 0, F, R);} + {sqlite3Insert(pParse, X, 0, F, R);} %type insert_cmd {u8} insert_cmd(A) ::= INSERT orconf(R). {A = R;} insert_cmd(A) ::= REPLACE. {A = OE_Replace;} -// A ValueList is either a single VALUES clause or a comma-separated list -// of VALUES clauses. If it is a single VALUES clause then the -// ValueList.pList field points to the expression list of that clause. -// If it is a list of VALUES clauses, then those clauses are transformed -// into a set of SELECT statements without FROM clauses and connected by -// UNION ALL and the ValueList.pSelect points to the right-most SELECT in -// that compound. -%type valuelist {struct ValueList} -%destructor valuelist { - sqlite3ExprListDelete(pParse->db, $$.pList); - sqlite3SelectDelete(pParse->db, $$.pSelect); -} -valuelist(A) ::= VALUES LP nexprlist(X) RP. { - A.pList = X; - A.pSelect = 0; -} - -// Since a list of VALUEs is inplemented as a compound SELECT, we have -// to disable the value list option if compound SELECTs are disabled. -%ifndef SQLITE_OMIT_COMPOUND_SELECT -valuelist(A) ::= valuelist(X) COMMA LP exprlist(Y) RP. { - Select *pRight = sqlite3SelectNew(pParse, Y, 0, 0, 0, 0, 0, 0, 0, 0); - if( X.pList ){ - X.pSelect = sqlite3SelectNew(pParse, X.pList, 0, 0, 0, 0, 0, 0, 0, 0); - X.pList = 0; - } - A.pList = 0; - if( X.pSelect==0 || pRight==0 ){ - sqlite3SelectDelete(pParse->db, pRight); - sqlite3SelectDelete(pParse->db, X.pSelect); - A.pSelect = 0; - }else{ - pRight->op = TK_ALL; - pRight->pPrior = X.pSelect; - pRight->selFlags |= SF_Values; - pRight->pPrior->selFlags |= SF_Values; - A.pSelect = pRight; - } -} -%endif SQLITE_OMIT_COMPOUND_SELECT - %type inscollist_opt {IdList*} %destructor inscollist_opt {sqlite3IdListDelete(pParse->db, $$);} %type idlist {IdList*} @@ -1295,12 +1269,8 @@ trigger_cmd(A) ::= { A = sqlite3TriggerUpdateStep(pParse->db, &X, Y, Z, R); } // INSERT -trigger_cmd(A) ::= - insert_cmd(R) INTO trnm(X) inscollist_opt(F) valuelist(Y). - {A = sqlite3TriggerInsertStep(pParse->db, &X, F, Y.pList, Y.pSelect, R);} - trigger_cmd(A) ::= insert_cmd(R) INTO trnm(X) inscollist_opt(F) select(S). - {A = sqlite3TriggerInsertStep(pParse->db, &X, F, 0, S, R);} + {A = sqlite3TriggerInsertStep(pParse->db, &X, F, S, R);} // DELETE trigger_cmd(A) ::= DELETE FROM trnm(X) tridxby where_opt(Y). diff --git a/src/sqliteInt.h b/src/sqliteInt.h index d3e993c135..188a7cacc4 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2483,7 +2483,7 @@ struct TriggerStep { Select *pSelect; /* SELECT statment or RHS of INSERT INTO .. SELECT ... */ Token target; /* Target table for DELETE, UPDATE, INSERT */ Expr *pWhere; /* The WHERE clause for DELETE or UPDATE steps */ - ExprList *pExprList; /* SET clause for UPDATE. VALUES clause for INSERT */ + ExprList *pExprList; /* SET clause for UPDATE. */ IdList *pIdList; /* Column names for INSERT */ TriggerStep *pNext; /* Next in the link-list */ TriggerStep *pLast; /* Last element in link-list. Valid for 1st elem only */ @@ -2898,7 +2898,7 @@ void sqlite3DeleteTable(sqlite3*, Table*); # define sqlite3AutoincrementEnd(X) #endif int sqlite3CodeCoroutine(Parse*, Select*, SelectDest*); -void sqlite3Insert(Parse*, SrcList*, ExprList*, Select*, IdList*, int); +void sqlite3Insert(Parse*, SrcList*, Select*, IdList*, int); void *sqlite3ArrayAllocate(sqlite3*,void*,int,int*,int*); IdList *sqlite3IdListAppend(sqlite3*, IdList*, Token*); int sqlite3IdListIndex(IdList*,const char*); @@ -3036,7 +3036,7 @@ void sqlite3MaterializeView(Parse*, Table*, Expr*, int); void sqlite3DeleteTriggerStep(sqlite3*, TriggerStep*); TriggerStep *sqlite3TriggerSelectStep(sqlite3*,Select*); TriggerStep *sqlite3TriggerInsertStep(sqlite3*,Token*, IdList*, - ExprList*,Select*,u8); + Select*,u8); TriggerStep *sqlite3TriggerUpdateStep(sqlite3*,Token*,ExprList*, Expr*, u8); TriggerStep *sqlite3TriggerDeleteStep(sqlite3*,Token*, Expr*); void sqlite3DeleteTrigger(sqlite3*, Trigger*); diff --git a/src/trigger.c b/src/trigger.c index 1c68a708dd..fdc2a0388c 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -397,25 +397,21 @@ TriggerStep *sqlite3TriggerInsertStep( sqlite3 *db, /* The database connection */ Token *pTableName, /* Name of the table into which we insert */ IdList *pColumn, /* List of columns in pTableName to insert into */ - ExprList *pEList, /* The VALUE clause: a list of values to be inserted */ Select *pSelect, /* A SELECT statement that supplies values */ u8 orconf /* The conflict algorithm (OE_Abort, OE_Replace, etc.) */ ){ TriggerStep *pTriggerStep; - assert(pEList == 0 || pSelect == 0); - assert(pEList != 0 || pSelect != 0 || db->mallocFailed); + assert(pSelect != 0 || db->mallocFailed); pTriggerStep = triggerStepAllocate(db, TK_INSERT, pTableName); if( pTriggerStep ){ pTriggerStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE); pTriggerStep->pIdList = pColumn; - pTriggerStep->pExprList = sqlite3ExprListDup(db, pEList, EXPRDUP_REDUCE); pTriggerStep->orconf = orconf; }else{ sqlite3IdListDelete(db, pColumn); } - sqlite3ExprListDelete(db, pEList); sqlite3SelectDelete(db, pSelect); return pTriggerStep; @@ -753,7 +749,6 @@ static int codeTriggerProgram( case TK_INSERT: { sqlite3Insert(pParse, targetSrcList(pParse, pStep), - sqlite3ExprListDup(db, pStep->pExprList, 0), sqlite3SelectDup(db, pStep->pSelect, 0), sqlite3IdListDup(db, pStep->pIdList), pParse->eOrconf From 144ffe7bfb9036ded7e294a0d92320ad97d2f8be Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 10 Jan 2014 20:51:16 +0000 Subject: [PATCH 128/276] Remove unused structure definition from parse.y. FossilOrigin-Name: 7f1e7ae313c7625ef2623d78883dce776eecca30 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/parse.y | 8 -------- 3 files changed, 7 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 3ad162dd48..78da6bddd4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Allow\sa\sVALUES\sclause\sto\sbe\sused\sany\splace\sthat\sa\sSELECT\sstatement\scan\sbe\nused. -D 2014-01-10T20:46:55.338 +C Remove\sunused\sstructure\sdefinition\sfrom\sparse.y. +D 2014-01-10T20:51:16.498 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -209,7 +209,7 @@ F src/os_unix.c 3a4dcb554d3c915075766162f28c3fd4cdb75968 F src/os_win.c 16eac0961603182ffc10c02b39fe830126538e07 F src/pager.c efa923693e958696eee69b205a20bfbc402c8480 F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428 -F src/parse.y 0a284e3f2bb78363ddce6f796ca2074e1e265eb7 +F src/parse.y 60baa3aced02c9f91259719d196315bc28580719 F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222 F src/pcache1.c 57fee9a9a617218f5037afbbe49b09da65bde56b @@ -1148,7 +1148,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 632045f21c553e10f59a14c772d50d7824ca0c2c -R cf996bb200e200afa8de950e78c84a55 +P c9ea7d199f06a7801ab639e7ac98ebeb98706f24 +R b8682b1b95c61647eceb7cac2c7aa836 U drh -Z 54c4a7cb2ec6e5258f05fa3eca37aefd +Z 2b3078d680e621e51a9cb7dd08f4a256 diff --git a/manifest.uuid b/manifest.uuid index 76d9f0f1fb..2faf2ec7b2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c9ea7d199f06a7801ab639e7ac98ebeb98706f24 \ No newline at end of file +7f1e7ae313c7625ef2623d78883dce776eecca30 \ No newline at end of file diff --git a/src/parse.y b/src/parse.y index 00d47cd3ea..154929c8d9 100644 --- a/src/parse.y +++ b/src/parse.y @@ -94,14 +94,6 @@ struct TrigEvent { int a; IdList * b; }; */ struct AttachKey { int type; Token key; }; -/* -** One or more VALUES claues -*/ -struct ValueList { - ExprList *pList; - Select *pSelect; -}; - } // end %include // Input is a single SQL command From 898799fa00dfd21887a9870f5262350e495af046 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 10 Jan 2014 23:21:00 +0000 Subject: [PATCH 129/276] Do not use sprintf(), strcpy() or strcat() in the implementation of the lemon parser generator tool, to avoid compiler warnings in OpenBSD. FossilOrigin-Name: e43c522dde01e134f1adc94f534d2b3eda74afc2 --- manifest | 12 ++--- manifest.uuid | 2 +- tool/lemon.c | 125 +++++++++++++++++++++++++++++++++++++++++++------- 3 files changed, 115 insertions(+), 24 deletions(-) diff --git a/manifest b/manifest index 78da6bddd4..edfa17a7d1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sunused\sstructure\sdefinition\sfrom\sparse.y. -D 2014-01-10T20:51:16.498 +C Do\snot\suse\ssprintf(),\sstrcpy()\sor\sstrcat()\sin\sthe\simplementation\sof\sthe\nlemon\sparser\sgenerator\stool,\sto\savoid\scompiler\swarnings\sin\sOpenBSD. +D 2014-01-10T23:21:00.243 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -1109,7 +1109,7 @@ F tool/fragck.tcl 5265a95126abcf6ab357f7efa544787e5963f439 F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4 F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce -F tool/lemon.c 796930d5fc2036c7636f3f1ee12f9ae03719a2eb +F tool/lemon.c 04f60c891f6c07643221b068bbc2621be46c039a F tool/lempar.c 01ca97f87610d1dac6d8cd96ab109ab1130e76dc F tool/logest.c 7ad625cac3d54012b27d468b7af6612f78b9ba75 F tool/mkautoconfamal.sh f8d8dbf7d62f409ebed5134998bf5b51d7266383 @@ -1148,7 +1148,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P c9ea7d199f06a7801ab639e7ac98ebeb98706f24 -R b8682b1b95c61647eceb7cac2c7aa836 +P 7f1e7ae313c7625ef2623d78883dce776eecca30 +R 153a0201d8a4a180b2a188d3abd169a6 U drh -Z 2b3078d680e621e51a9cb7dd08f4a256 +Z c49dfd6bd62bb08d757d02ffce1c49c4 diff --git a/manifest.uuid b/manifest.uuid index 2faf2ec7b2..fdbe371621 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7f1e7ae313c7625ef2623d78883dce776eecca30 \ No newline at end of file +e43c522dde01e134f1adc94f534d2b3eda74afc2 \ No newline at end of file diff --git a/tool/lemon.c b/tool/lemon.c index 58f13880f0..191ab0d88b 100644 --- a/tool/lemon.c +++ b/tool/lemon.c @@ -50,6 +50,97 @@ static char *msort(char*,char**,int(*)(const char*,const char*)); */ #define lemonStrlen(X) ((int)strlen(X)) +/* +** Compilers are starting to complain about the use of sprintf() and strcpy(), +** saying they are unsafe. So we define our own versions of those routines too. +** +** There are three routines here: lemon_sprintf(), lemon_vsprintf(), and +** lemon_addtext(). The first two are replacements for sprintf() and vsprintf(). +** The third is a helper routine for vsnprintf() that adds texts to the end of a +** buffer, making sure the buffer is always zero-terminated. +** +** The string formatter is a minimal subset of stdlib sprintf() supporting only +** a few simply conversions: +** +** %d +** %s +** %.*s +** +*/ +static void lemon_addtext( + char *zBuf, /* The buffer to which text is added */ + int *pnUsed, /* Slots of the buffer used so far */ + const char *zIn, /* Text to add */ + int nIn /* Bytes of text to add. -1 to use strlen() */ +){ + if( nIn<0 ) for(nIn=0; zIn[nIn]; nIn++){} + if( nIn==0 ) return; + memcpy(&zBuf[*pnUsed], zIn, nIn); + *pnUsed += nIn; + zBuf[*pnUsed] = 0; +} +static int lemon_vsprintf(char *str, const char *zFormat, va_list ap){ + int i, j, k, c, size; + int nUsed = 0; + const char *z; + char zTemp[50]; + str[0] = 0; + for(i=j=0; (c = zFormat[i])!=0; i++){ + if( c=='%' ){ + lemon_addtext(str, &nUsed, &zFormat[j], i-j); + c = zFormat[++i]; + if( c=='d' ){ + int v = va_arg(ap, int); + if( v<0 ){ + lemon_addtext(str, &nUsed, "-", 1); + v = -v; + }else if( v==0 ){ + lemon_addtext(str, &nUsed, "0", 1); + } + k = 0; + while( v>0 ){ + k++; + zTemp[sizeof(zTemp)-k] = (v%10) + '0'; + v /= 10; + } + lemon_addtext(str, &nUsed, &zTemp[sizeof(zTemp)-k], k); + }else if( c=='s' ){ + z = va_arg(ap, const char*); + lemon_addtext(str, &nUsed, z, -1); + }else if( c=='.' && memcmp(&zFormat[i], ".*s", 3)==0 ){ + i += 2; + k = va_arg(ap, int); + z = va_arg(ap, const char*); + lemon_addtext(str, &nUsed, z, k); + }else if( c=='%' ){ + lemon_addtext(str, &nUsed, "%", 1); + }else{ + fprintf(stderr, "illegal format\n"); + exit(1); + } + j = i+1; + } + } + lemon_addtext(str, &nUsed, &zFormat[j], i-j); + return nUsed; +} +static int lemon_sprintf(char *str, const char *format, ...){ + va_list ap; + int rc; + va_start(ap, format); + rc = lemon_vsprintf(str, format, ap); + va_end(ap); + return rc; +} +static void lemon_strcpy(char *dest, const char *src){ + while( (*(dest++) = *(src++))!=0 ){} +} +static void lemon_strcat(char *dest, const char *src){ + while( *dest ) dest++; + lemon_strcpy(dest, src); +} + + /* a few forward declarations... */ struct rule; struct lemon; @@ -1367,7 +1458,7 @@ static void handle_D_option(char *z){ fprintf(stderr,"out of memory\n"); exit(1); } - strcpy(*paz, z); + lemon_strcpy(*paz, z); for(z=*paz; *z && *z!='='; z++){} *z = 0; } @@ -1378,7 +1469,7 @@ static void handle_T_option(char *z){ if( user_templatename==0 ){ memory_error(); } - strcpy(user_templatename, z); + lemon_strcpy(user_templatename, z); } /* The main program. Parse the command line and do it... */ @@ -2347,7 +2438,7 @@ to follow the previous rule."); for(z=psp->filename, nBack=0; *z; z++){ if( *z=='\\' ) nBack++; } - sprintf(zLine, "#line %d ", psp->tokenlineno); + lemon_sprintf(zLine, "#line %d ", psp->tokenlineno); nLine = lemonStrlen(zLine); n += nLine + lemonStrlen(psp->filename) + nBack; } @@ -2716,10 +2807,10 @@ PRIVATE char *file_makename(struct lemon *lemp, const char *suffix) fprintf(stderr,"Can't allocate space for a filename.\n"); exit(1); } - strcpy(name,lemp->filename); + lemon_strcpy(name,lemp->filename); cp = strrchr(name,'.'); if( cp ) *cp = 0; - strcat(name,suffix); + lemon_strcat(name,suffix); return name; } @@ -2916,7 +3007,7 @@ void ReportOutput(struct lemon *lemp) while( cfp ){ char buf[20]; if( cfp->dot==cfp->rp->nrhs ){ - sprintf(buf,"(%d)",cfp->rp->index); + lemon_sprintf(buf,"(%d)",cfp->rp->index); fprintf(fp," %5s ",buf); }else{ fprintf(fp," "); @@ -2981,7 +3072,7 @@ PRIVATE char *pathsearch(char *argv0, char *name, int modemask) c = *cp; *cp = 0; path = (char *)malloc( lemonStrlen(argv0) + lemonStrlen(name) + 2 ); - if( path ) sprintf(path,"%s/%s",argv0,name); + if( path ) lemon_sprintf(path,"%s/%s",argv0,name); *cp = c; }else{ pathlist = getenv("PATH"); @@ -2990,13 +3081,13 @@ PRIVATE char *pathsearch(char *argv0, char *name, int modemask) path = (char *)malloc( lemonStrlen(pathlist)+lemonStrlen(name)+2 ); if( (pathbuf != 0) && (path!=0) ){ pathbufptr = pathbuf; - strcpy(pathbuf, pathlist); + lemon_strcpy(pathbuf, pathlist); while( *pathbuf ){ cp = strchr(pathbuf,':'); if( cp==0 ) cp = &pathbuf[lemonStrlen(pathbuf)]; c = *cp; *cp = 0; - sprintf(path,"%s/%s",pathbuf,name); + lemon_sprintf(path,"%s/%s",pathbuf,name); *cp = c; if( c==0 ) pathbuf[0] = 0; else pathbuf = &cp[1]; @@ -3087,9 +3178,9 @@ PRIVATE FILE *tplt_open(struct lemon *lemp) cp = strrchr(lemp->filename,'.'); if( cp ){ - sprintf(buf,"%.*s.lt",(int)(cp-lemp->filename),lemp->filename); + lemon_sprintf(buf,"%.*s.lt",(int)(cp-lemp->filename),lemp->filename); }else{ - sprintf(buf,"%s.lt",lemp->filename); + lemon_sprintf(buf,"%s.lt",lemp->filename); } if( access(buf,004)==0 ){ tpltname = buf; @@ -3240,9 +3331,9 @@ PRIVATE char *append_str(const char *zText, int n, int p1, int p2){ while( n-- > 0 ){ c = *(zText++); if( c=='%' && n>0 && zText[0]=='d' ){ - sprintf(zInt, "%d", p1); + lemon_sprintf(zInt, "%d", p1); p1 = p2; - strcpy(&z[used], zInt); + lemon_strcpy(&z[used], zInt); used += lemonStrlen(&z[used]); zText++; n--; @@ -3467,7 +3558,7 @@ void print_stack_union( fprintf(stderr,"Out of memory.\n"); exit(1); } - strcpy(types[hash],stddt); + lemon_strcpy(types[hash],stddt); } } @@ -3856,7 +3947,7 @@ void ReportTable( /* Generate a table containing the symbolic name of every symbol */ for(i=0; insymbol; i++){ - sprintf(line,"\"%s\",",lemp->symbols[i]->name); + lemon_sprintf(line,"\"%s\",",lemp->symbols[i]->name); fprintf(out," %-15s",line); if( (i&3)==3 ){ fprintf(out,"\n"); lineno++; } } @@ -4023,7 +4114,7 @@ void ReportHeader(struct lemon *lemp) if( in ){ int nextChar; for(i=1; interminal && fgets(line,LINESIZE,in); i++){ - sprintf(pattern,"#define %s%-30s %2d\n",prefix,lemp->symbols[i]->name,i); + lemon_sprintf(pattern,"#define %s%-30s %2d\n",prefix,lemp->symbols[i]->name,i); if( strcmp(line,pattern) ) break; } nextChar = fgetc(in); @@ -4253,7 +4344,7 @@ const char *Strsafe(const char *y) if( y==0 ) return 0; z = Strsafe_find(y); if( z==0 && (cpy=(char *)malloc( lemonStrlen(y)+1 ))!=0 ){ - strcpy(cpy,y); + lemon_strcpy(cpy,y); z = cpy; Strsafe_insert(z); } From 61f92cd045319f19e12125d2f49bb3d521c0934c Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 11 Jan 2014 03:06:18 +0000 Subject: [PATCH 130/276] In LEMON, fix a bug in the text formatter introduced by the previous commit. Also add the new "%token_class" directive for defining symbolic names that stand any one of a collection of tokens. FossilOrigin-Name: da7890ca6b1d8e511377a469047120220e8c3b2d --- manifest | 12 ++--- manifest.uuid | 2 +- tool/lemon.c | 118 ++++++++++++++++++++++++++++++++++++++------------ 3 files changed, 97 insertions(+), 35 deletions(-) diff --git a/manifest b/manifest index edfa17a7d1..b56fe09692 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\suse\ssprintf(),\sstrcpy()\sor\sstrcat()\sin\sthe\simplementation\sof\sthe\nlemon\sparser\sgenerator\stool,\sto\savoid\scompiler\swarnings\sin\sOpenBSD. -D 2014-01-10T23:21:00.243 +C In\sLEMON,\sfix\sa\sbug\sin\sthe\stext\sformatter\sintroduced\sby\sthe\sprevious\ncommit.\s\sAlso\sadd\sthe\snew\s"%token_class"\sdirective\sfor\sdefining\ssymbolic\nnames\sthat\sstand\sany\sone\sof\sa\scollection\sof\stokens. +D 2014-01-11T03:06:18.172 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -1109,7 +1109,7 @@ F tool/fragck.tcl 5265a95126abcf6ab357f7efa544787e5963f439 F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4 F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce -F tool/lemon.c 04f60c891f6c07643221b068bbc2621be46c039a +F tool/lemon.c 4a3d4a579c5dff6a42785e97d1f2b59789f3b8dd F tool/lempar.c 01ca97f87610d1dac6d8cd96ab109ab1130e76dc F tool/logest.c 7ad625cac3d54012b27d468b7af6612f78b9ba75 F tool/mkautoconfamal.sh f8d8dbf7d62f409ebed5134998bf5b51d7266383 @@ -1148,7 +1148,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 7f1e7ae313c7625ef2623d78883dce776eecca30 -R 153a0201d8a4a180b2a188d3abd169a6 +P e43c522dde01e134f1adc94f534d2b3eda74afc2 +R 498b2eca2a4d9bdf3c22bba6f4386191 U drh -Z c49dfd6bd62bb08d757d02ffce1c49c4 +Z 303f39885598d1865b7eb401105ea9ea diff --git a/manifest.uuid b/manifest.uuid index fdbe371621..2d1234c95c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e43c522dde01e134f1adc94f534d2b3eda74afc2 \ No newline at end of file +da7890ca6b1d8e511377a469047120220e8c3b2d \ No newline at end of file diff --git a/tool/lemon.c b/tool/lemon.c index 191ab0d88b..25787abf8d 100644 --- a/tool/lemon.c +++ b/tool/lemon.c @@ -71,12 +71,15 @@ static void lemon_addtext( char *zBuf, /* The buffer to which text is added */ int *pnUsed, /* Slots of the buffer used so far */ const char *zIn, /* Text to add */ - int nIn /* Bytes of text to add. -1 to use strlen() */ + int nIn, /* Bytes of text to add. -1 to use strlen() */ + int iWidth /* Field width. Negative to left justify */ ){ if( nIn<0 ) for(nIn=0; zIn[nIn]; nIn++){} + while( iWidth>nIn ){ zBuf[*(pnUsed++)] = ' '; iWidth--; } if( nIn==0 ) return; memcpy(&zBuf[*pnUsed], zIn, nIn); *pnUsed += nIn; + while( (-iWidth)>nIn ){ zBuf[*(pnUsed++)] = ' '; iWidth++; } zBuf[*pnUsed] = 0; } static int lemon_vsprintf(char *str, const char *zFormat, va_list ap){ @@ -87,15 +90,22 @@ static int lemon_vsprintf(char *str, const char *zFormat, va_list ap){ str[0] = 0; for(i=j=0; (c = zFormat[i])!=0; i++){ if( c=='%' ){ - lemon_addtext(str, &nUsed, &zFormat[j], i-j); + int iWidth = 0; + lemon_addtext(str, &nUsed, &zFormat[j], i-j, 0); c = zFormat[++i]; + if( isdigit(c) || (c=='-' && isdigit(zFormat[i+1])) ){ + if( c=='-' ) i++; + while( isdigit(zFormat[i]) ) iWidth = iWidth*10 + zFormat[i++] - '0'; + if( c=='-' ) iWidth = -iWidth; + c = zFormat[i]; + } if( c=='d' ){ int v = va_arg(ap, int); if( v<0 ){ - lemon_addtext(str, &nUsed, "-", 1); + lemon_addtext(str, &nUsed, "-", 1, iWidth); v = -v; }else if( v==0 ){ - lemon_addtext(str, &nUsed, "0", 1); + lemon_addtext(str, &nUsed, "0", 1, iWidth); } k = 0; while( v>0 ){ @@ -103,17 +113,17 @@ static int lemon_vsprintf(char *str, const char *zFormat, va_list ap){ zTemp[sizeof(zTemp)-k] = (v%10) + '0'; v /= 10; } - lemon_addtext(str, &nUsed, &zTemp[sizeof(zTemp)-k], k); + lemon_addtext(str, &nUsed, &zTemp[sizeof(zTemp)-k], k, iWidth); }else if( c=='s' ){ z = va_arg(ap, const char*); - lemon_addtext(str, &nUsed, z, -1); + lemon_addtext(str, &nUsed, z, -1, iWidth); }else if( c=='.' && memcmp(&zFormat[i], ".*s", 3)==0 ){ i += 2; k = va_arg(ap, int); z = va_arg(ap, const char*); - lemon_addtext(str, &nUsed, z, k); + lemon_addtext(str, &nUsed, z, k, iWidth); }else if( c=='%' ){ - lemon_addtext(str, &nUsed, "%", 1); + lemon_addtext(str, &nUsed, "%", 1, 0); }else{ fprintf(stderr, "illegal format\n"); exit(1); @@ -121,7 +131,7 @@ static int lemon_vsprintf(char *str, const char *zFormat, va_list ap){ j = i+1; } } - lemon_addtext(str, &nUsed, &zFormat[j], i-j); + lemon_addtext(str, &nUsed, &zFormat[j], i-j, 0); return nUsed; } static int lemon_sprintf(char *str, const char *format, ...){ @@ -1538,12 +1548,15 @@ int main(int argc, char **argv) } /* Count and index the symbols of the grammar */ - lem.nsymbol = Symbol_count(); Symbol_new("{default}"); + lem.nsymbol = Symbol_count(); lem.symbols = Symbol_arrayof(); - for(i=0; i<=lem.nsymbol; i++) lem.symbols[i]->index = i; - qsort(lem.symbols,lem.nsymbol+1,sizeof(struct symbol*), Symbolcmpp); - for(i=0; i<=lem.nsymbol; i++) lem.symbols[i]->index = i; + for(i=0; iindex = i; + qsort(lem.symbols,lem.nsymbol,sizeof(struct symbol*), Symbolcmpp); + for(i=0; iindex = i; + while( lem.symbols[i-1]->type==MULTITERMINAL ){ i--; } + assert( strcmp(lem.symbols[i-1]->name,"{default}")==0 ); + lem.nsymbol = i - 1; for(i=1; isupper(lem.symbols[i]->name[0]); i++); lem.nterminal = i; @@ -2031,7 +2044,9 @@ enum e_state { WAITING_FOR_DESTRUCTOR_SYMBOL, WAITING_FOR_DATATYPE_SYMBOL, WAITING_FOR_FALLBACK_ID, - WAITING_FOR_WILDCARD_ID + WAITING_FOR_WILDCARD_ID, + WAITING_FOR_CLASS_ID, + WAITING_FOR_CLASS_TOKEN }; struct pstate { char *filename; /* Name of the input file */ @@ -2041,6 +2056,7 @@ struct pstate { struct lemon *gp; /* Global state vector */ enum e_state state; /* The state of the parser */ struct symbol *fallback; /* The fallback token */ + struct symbol *tkclass; /* Token class symbol */ struct symbol *lhs; /* Left-hand side of current rule */ const char *lhsalias; /* Alias for the LHS */ int nrhs; /* Number of right-hand side symbols seen */ @@ -2345,6 +2361,8 @@ to follow the previous rule."); psp->state = WAITING_FOR_FALLBACK_ID; }else if( strcmp(x,"wildcard")==0 ){ psp->state = WAITING_FOR_WILDCARD_ID; + }else if( strcmp(x,"token_class")==0 ){ + psp->state = WAITING_FOR_CLASS_ID; }else{ ErrorMsg(psp->filename,psp->tokenlineno, "Unknown declaration keyword: \"%%%s\".",x); @@ -2513,6 +2531,40 @@ to follow the previous rule."); } } break; + case WAITING_FOR_CLASS_ID: + if( !islower(x[0]) ){ + ErrorMsg(psp->filename, psp->tokenlineno, + "%%token_class must be followed by an identifier: ", x); + psp->errorcnt++; + psp->state = RESYNC_AFTER_DECL_ERROR; + }else if( Symbol_find(x) ){ + ErrorMsg(psp->filename, psp->tokenlineno, + "Symbol \"%s\" already used", x); + psp->errorcnt++; + psp->state = RESYNC_AFTER_DECL_ERROR; + }else{ + psp->tkclass = Symbol_new(x); + psp->tkclass->type = MULTITERMINAL; + psp->state = WAITING_FOR_CLASS_TOKEN; + } + break; + case WAITING_FOR_CLASS_TOKEN: + if( x[0]=='.' ){ + psp->state = WAITING_FOR_DECL_OR_RULE; + }else if( isupper(x[0]) || ((x[0]=='|' || x[0]=='/') && isupper(x[1])) ){ + struct symbol *msp = psp->tkclass; + msp->nsubsym++; + msp->subsym = (struct symbol **) realloc(msp->subsym, + sizeof(struct symbol*)*msp->nsubsym); + if( !isupper(x[0]) ) x++; + msp->subsym[msp->nsubsym-1] = Symbol_new(x); + }else{ + ErrorMsg(psp->filename, psp->tokenlineno, + "%%token_class argument \"%s\" should be a token", x); + psp->errorcnt++; + psp->state = RESYNC_AFTER_DECL_ERROR; + } + break; case RESYNC_AFTER_RULE_ERROR: /* if( x[0]=='.' ) psp->state = WAITING_FOR_DECL_OR_RULE; ** break; */ @@ -2867,11 +2919,13 @@ void Reprint(struct lemon *lemp) printf(" ::="); for(i=0; inrhs; i++){ sp = rp->rhs[i]; - printf(" %s", sp->name); if( sp->type==MULTITERMINAL ){ + printf(" %s", sp->subsym[0]->name); for(j=1; jnsubsym; j++){ printf("|%s", sp->subsym[j]->name); } + }else{ + printf(" %s", sp->name); } /* if( rp->rhsalias[i] ) printf("(%s)",rp->rhsalias[i]); */ } @@ -2893,11 +2947,13 @@ void ConfigPrint(FILE *fp, struct config *cfp) if( i==cfp->dot ) fprintf(fp," *"); if( i==rp->nrhs ) break; sp = rp->rhs[i]; - fprintf(fp," %s", sp->name); if( sp->type==MULTITERMINAL ){ + fprintf(fp," %s", sp->subsym[0]->name); for(j=1; jnsubsym; j++){ fprintf(fp,"|%s",sp->subsym[j]->name); } + }else{ + fprintf(fp," %s", sp->name); } } } @@ -3644,9 +3700,11 @@ static void writeRuleText(FILE *out, struct rule *rp){ fprintf(out,"%s ::=", rp->lhs->name); for(j=0; jnrhs; j++){ struct symbol *sp = rp->rhs[j]; - fprintf(out," %s", sp->name); - if( sp->type==MULTITERMINAL ){ + if( sp->type!=MULTITERMINAL ){ + fprintf(out," %s", sp->name); + }else{ int k; + fprintf(out," %s", sp->subsym[0]->name); for(k=1; knsubsym; k++){ fprintf(out,"|%s",sp->subsym[k]->name); } @@ -4114,7 +4172,8 @@ void ReportHeader(struct lemon *lemp) if( in ){ int nextChar; for(i=1; interminal && fgets(line,LINESIZE,in); i++){ - lemon_sprintf(pattern,"#define %s%-30s %2d\n",prefix,lemp->symbols[i]->name,i); + lemon_sprintf(pattern,"#define %s%-30s %3d\n", + prefix,lemp->symbols[i]->name,i); if( strcmp(line,pattern) ) break; } nextChar = fgetc(in); @@ -4127,7 +4186,7 @@ void ReportHeader(struct lemon *lemp) out = file_open(lemp,".h","wb"); if( out ){ for(i=1; interminal; i++){ - fprintf(out,"#define %s%-30s %2d\n",prefix,lemp->symbols[i]->name,i); + fprintf(out,"#define %s%-30s %3d\n",prefix,lemp->symbols[i]->name,i); } fclose(out); } @@ -4497,11 +4556,15 @@ struct symbol *Symbol_new(const char *x) return sp; } -/* Compare two symbols for working purposes +/* Compare two symbols for sorting purposes. Return negative, +** zero, or positive if a is less then, equal to, or greater +** than b. ** ** Symbols that begin with upper case letters (terminals or tokens) ** must sort before symbols that begin with lower case letters -** (non-terminals). Other than that, the order does not matter. +** (non-terminals). And MULTITERMINAL symbols (created using the +** %token_class directive) must sort at the very end. Other than +** that, the order does not matter. ** ** We find experimentally that leaving the symbols in their original ** order (the order they appeared in the grammar file) gives the @@ -4509,12 +4572,11 @@ struct symbol *Symbol_new(const char *x) */ int Symbolcmpp(const void *_a, const void *_b) { - const struct symbol **a = (const struct symbol **) _a; - const struct symbol **b = (const struct symbol **) _b; - int i1 = (**a).index + 10000000*((**a).name[0]>'Z'); - int i2 = (**b).index + 10000000*((**b).name[0]>'Z'); - assert( i1!=i2 || strcmp((**a).name,(**b).name)==0 ); - return i1-i2; + const struct symbol *a = *(const struct symbol **) _a; + const struct symbol *b = *(const struct symbol **) _b; + int i1 = a->type==MULTITERMINAL ? 3 : a->name[0]>'Z' ? 2 : 1; + int i2 = b->type==MULTITERMINAL ? 3 : b->name[0]>'Z' ? 2 : 1; + return i1==i2 ? a->index - b->index : i1 - i2; } /* There is one instance of the following structure for each From f59b12fbc1db8c734cbe2b659a30155937887122 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 11 Jan 2014 03:54:05 +0000 Subject: [PATCH 131/276] Optimizations to the SQL language grammar that result in a small size reduction and speed increase. FossilOrigin-Name: cb5d1f83e0a33d546d4c0cb817ef1f8440d1f738 --- addopcodes.awk | 1 + manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/parse.y | 44 ++++++++++++++++++++------------------------ src/tokenize.c | 15 +++------------ 5 files changed, 33 insertions(+), 45 deletions(-) diff --git a/addopcodes.awk b/addopcodes.awk index c18c4f3599..dcd31eff84 100644 --- a/addopcodes.awk +++ b/addopcodes.awk @@ -30,4 +30,5 @@ END { printf "#define TK_%-29s %4d\n", "AGG_COLUMN", ++max printf "#define TK_%-29s %4d\n", "UMINUS", ++max printf "#define TK_%-29s %4d\n", "UPLUS", ++max + printf "#define TK_%-29s %4d\n", "REGISTER", ++max } diff --git a/manifest b/manifest index 7c63bcd427..bac5d7c5b5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s"%token_class"\sdirective\sto\sthe\sLEMON\sparser\sgenerator.\s\sThis\sopens\sup\nthe\spossibility\sof\ssimplifying\sthe\sparser.\s\sAlso\sremove\sall\scalls\sto\s\nsprintf(),\sstrcpy(),\sand\sstrcat()\sfrom\sLEMON\sto\savoid\scompiler\swarnings\non\sOpenBSD.\s\s(Aside:\s\sIt\sis\sthis\schange\sto\savoid\sharmless\scompiler\swarnings\nthat\swas\sthe\scause\sof\sthe\sreason\sspat\sof\sbugs.) -D 2014-01-11T03:27:37.624 +C Optimizations\sto\sthe\sSQL\slanguage\sgrammar\sthat\sresult\sin\sa\ssmall\ssize\nreduction\sand\sspeed\sincrease. +D 2014-01-11T03:54:05.594 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -8,7 +8,7 @@ F Makefile.vxworks db21ed42a01d5740e656b16f92cb5d8d5e5dd315 F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6 F VERSION 8ed548d87d0a27fd7d7620476f9e25f9fa742d73 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 -F addopcodes.awk 87ca612393d0f439550634bd2c156ea9ff6195ae +F addopcodes.awk 9eb448a552d5c0185cf62c463f9c173cedae3811 F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 @@ -209,7 +209,7 @@ F src/os_unix.c 3a4dcb554d3c915075766162f28c3fd4cdb75968 F src/os_win.c 16eac0961603182ffc10c02b39fe830126538e07 F src/pager.c efa923693e958696eee69b205a20bfbc402c8480 F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428 -F src/parse.y 60baa3aced02c9f91259719d196315bc28580719 +F src/parse.y 3c5384533a8bfce5abd256cc9cb2c38bec05ad61 F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222 F src/pcache1.c 57fee9a9a617218f5037afbbe49b09da65bde56b @@ -274,7 +274,7 @@ F src/test_thread.c 1e133a40b50e9c035b00174035b846e7eef481cb F src/test_vfs.c e72f555ef7a59080f898fcf1a233deb9eb704ea9 F src/test_vfstrace.c 3a0ab304682fecbceb689e7d9b904211fde11d78 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 -F src/tokenize.c ec4c1a62b890bf1dbcdb966399e140b904c700a4 +F src/tokenize.c 5d04a1b7d1fe7e18556a869788f5d3e132a586b6 F src/trigger.c 5c1c0b899ac0ce284763dcb8fdbaa38ecf15ef98 F src/update.c c2706a6eb232a96345c35b7e1e75a188e26812bb F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 @@ -1148,7 +1148,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 7f1e7ae313c7625ef2623d78883dce776eecca30 da7890ca6b1d8e511377a469047120220e8c3b2d -R 4ba60b3fb47af12fdb784f3275ccdc2b +P 8eb48c04bd0a14031488b3160fde67307eb8b35d +R 754b7dd57633ea486f18a04af0e67e46 U drh -Z 11bef21bd681893c7b5fd9fec7621236 +Z 0bb5f8caa9532d2db9247df525167cc7 diff --git a/manifest.uuid b/manifest.uuid index f08dc2b5ea..1bd734a197 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8eb48c04bd0a14031488b3160fde67307eb8b35d \ No newline at end of file +cb5d1f83e0a33d546d4c0cb817ef1f8440d1f738 \ No newline at end of file diff --git a/src/parse.y b/src/parse.y index 154929c8d9..f8e813d115 100644 --- a/src/parse.y +++ b/src/parse.y @@ -194,9 +194,7 @@ columnid(A) ::= nm(X). { // An IDENTIFIER can be a generic identifier, or one of several // keywords. Any non-standard keyword can also be an identifier. // -%type id {Token} -id(A) ::= ID(X). {A = X;} -id(A) ::= INDEXED(X). {A = X;} +%token_class id ID|INDEXED. // The following directive causes tokens ABORT, AFTER, ASC, etc. to // fallback to ID if they will not parse as their original value. @@ -241,8 +239,7 @@ id(A) ::= INDEXED(X). {A = X;} // And "ids" is an identifer-or-string. // -%type ids {Token} -ids(A) ::= ID|STRING(X). {A = X;} +%token_class ids ID|STRING. // The name of a column or table can be any of the following: // @@ -776,22 +773,22 @@ expr(A) ::= nm(X) DOT nm(Y) DOT nm(Z). { } term(A) ::= INTEGER|FLOAT|BLOB(X). {spanExpr(&A, pParse, @X, &X);} term(A) ::= STRING(X). {spanExpr(&A, pParse, @X, &X);} -expr(A) ::= REGISTER(X). { - /* When doing a nested parse, one can include terms in an expression - ** that look like this: #1 #2 ... These terms refer to registers - ** in the virtual machine. #N is the N-th register. */ - if( pParse->nested==0 ){ - sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &X); - A.pExpr = 0; - }else{ - A.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, &X); - if( A.pExpr ) sqlite3GetInt32(&X.z[1], &A.pExpr->iTable); - } - spanSet(&A, &X, &X); -} expr(A) ::= VARIABLE(X). { - spanExpr(&A, pParse, TK_VARIABLE, &X); - sqlite3ExprAssignVarNumber(pParse, A.pExpr); + if( X.n>=2 && X.z[0]=='#' && sqlite3Isdigit(X.z[1]) ){ + /* When doing a nested parse, one can include terms in an expression + ** that look like this: #1 #2 ... These terms refer to registers + ** in the virtual machine. #N is the N-th register. */ + if( pParse->nested==0 ){ + sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &X); + A.pExpr = 0; + }else{ + A.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, &X); + if( A.pExpr ) sqlite3GetInt32(&X.z[1], &A.pExpr->iTable); + } + }else{ + spanExpr(&A, pParse, TK_VARIABLE, &X); + sqlite3ExprAssignVarNumber(pParse, A.pExpr); + } spanSet(&A, &X, &X); } expr(A) ::= expr(E) COLLATE ids(C). { @@ -805,7 +802,7 @@ expr(A) ::= CAST(X) LP expr(E) AS typetoken(T) RP(Y). { spanSet(&A,&X,&Y); } %endif SQLITE_OMIT_CAST -expr(A) ::= ID(X) LP distinct(D) exprlist(Y) RP(E). { +expr(A) ::= id(X) LP distinct(D) exprlist(Y) RP(E). { if( Y && Y->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){ sqlite3ErrorMsg(pParse, "too many arguments on function %T", &X); } @@ -815,7 +812,7 @@ expr(A) ::= ID(X) LP distinct(D) exprlist(Y) RP(E). { A.pExpr->flags |= EP_Distinct; } } -expr(A) ::= ID(X) LP STAR RP(E). { +expr(A) ::= id(X) LP STAR RP(E). { A.pExpr = sqlite3ExprFunction(pParse, 0, &X); spanSet(&A,&X,&E); } @@ -1165,11 +1162,10 @@ nmnum(A) ::= ON(X). {A = X;} nmnum(A) ::= DELETE(X). {A = X;} nmnum(A) ::= DEFAULT(X). {A = X;} %endif SQLITE_OMIT_PRAGMA +%token_class number INTEGER|FLOAT. plus_num(A) ::= PLUS number(X). {A = X;} plus_num(A) ::= number(X). {A = X;} minus_num(A) ::= MINUS number(X). {A = X;} -number(A) ::= INTEGER|FLOAT(X). {A = X;} - //////////////////////////// The CREATE TRIGGER command ///////////////////// %ifndef SQLITE_OMIT_TRIGGER diff --git a/src/tokenize.c b/src/tokenize.c index f27929ea5b..6e796ef82e 100644 --- a/src/tokenize.c +++ b/src/tokenize.c @@ -303,24 +303,15 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){ for(i=1; sqlite3Isdigit(z[i]); i++){} return i; } - case '#': { - for(i=1; sqlite3Isdigit(z[i]); i++){} - if( i>1 ){ - /* Parameters of the form #NNN (where NNN is a number) are used - ** internally by sqlite3NestedParse. */ - *tokenType = TK_REGISTER; - return i; - } - /* Fall through into the next case if the '#' is not followed by - ** a digit. Try to match #AAAA where AAAA is a parameter name. */ - } #ifndef SQLITE_OMIT_TCL_VARIABLE case '$': #endif case '@': /* For compatibility with MS SQL Server */ + case '#': case ':': { int n = 0; - testcase( z[0]=='$' ); testcase( z[0]=='@' ); testcase( z[0]==':' ); + testcase( z[0]=='$' ); testcase( z[0]=='@' ); + testcase( z[0]==':' ); testcase( z[0]=='#' ); *tokenType = TK_VARIABLE; for(i=1; (c=z[i])!=0; i++){ if( IdChar(c) ){ From 03e1b1f5fffb0d9aa621db37132e6b1cc711238c Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 11 Jan 2014 12:52:25 +0000 Subject: [PATCH 132/276] In LEMON, limit the size of the grammar file to 100MB. This ensures that the program will never experience integer overflow. To be doubly sure, use calloc() instead of malloc() when allocating arrays. FossilOrigin-Name: 29ba458d849ad8864711cbe59fb10447a947e06a --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/lemon.c | 31 +++++++++++-------------------- 3 files changed, 18 insertions(+), 27 deletions(-) diff --git a/manifest b/manifest index bac5d7c5b5..03003dd0c5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Optimizations\sto\sthe\sSQL\slanguage\sgrammar\sthat\sresult\sin\sa\ssmall\ssize\nreduction\sand\sspeed\sincrease. -D 2014-01-11T03:54:05.594 +C In\sLEMON,\slimit\sthe\ssize\sof\sthe\sgrammar\sfile\sto\s100MB.\s\sThis\sensures\sthat\nthe\sprogram\swill\snever\sexperience\sinteger\soverflow.\s\sTo\sbe\sdoubly\ssure,\nuse\scalloc()\sinstead\sof\smalloc()\swhen\sallocating\sarrays. +D 2014-01-11T12:52:25.201 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -1109,7 +1109,7 @@ F tool/fragck.tcl 5265a95126abcf6ab357f7efa544787e5963f439 F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4 F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce -F tool/lemon.c 624b24c5dc048e09979f88a03e148bc728c70b73 +F tool/lemon.c 6842b2e7af12835f9f6e55808a0b1861cd0696fe F tool/lempar.c 01ca97f87610d1dac6d8cd96ab109ab1130e76dc F tool/logest.c 7ad625cac3d54012b27d468b7af6612f78b9ba75 F tool/mkautoconfamal.sh f8d8dbf7d62f409ebed5134998bf5b51d7266383 @@ -1148,7 +1148,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 8eb48c04bd0a14031488b3160fde67307eb8b35d -R 754b7dd57633ea486f18a04af0e67e46 +P cb5d1f83e0a33d546d4c0cb817ef1f8440d1f738 +R 28679f157b50c114aa03e50f74a7a104 U drh -Z 0bb5f8caa9532d2db9247df525167cc7 +Z 608e7b6009060d93ac39bb2434b3c874 diff --git a/manifest.uuid b/manifest.uuid index 1bd734a197..d8b23d3f34 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cb5d1f83e0a33d546d4c0cb817ef1f8440d1f738 \ No newline at end of file +29ba458d849ad8864711cbe59fb10447a947e06a \ No newline at end of file diff --git a/tool/lemon.c b/tool/lemon.c index c4adc20864..8dca20c451 100644 --- a/tool/lemon.c +++ b/tool/lemon.c @@ -2659,9 +2659,8 @@ void Parse(struct lemon *gp) filesize = ftell(fp); rewind(fp); filebuf = (char *)malloc( filesize+1 ); - if( filebuf==0 ){ - ErrorMsg(ps.filename,0,"Can't allocate %d of memory to hold this file.", - filesize+1); + if( filesize>100000000 || filebuf==0 ){ + ErrorMsg(ps.filename,0,"Input file too large."); gp->errorcnt++; fclose(fp); return; @@ -4442,8 +4441,7 @@ void Strsafe_init(){ if( x1a ){ x1a->size = 1024; x1a->count = 0; - x1a->tbl = (x1node*)malloc( - (sizeof(x1node) + sizeof(x1node*))*1024 ); + x1a->tbl = (x1node*)calloc(1024, sizeof(x1node) + sizeof(x1node*)); if( x1a->tbl==0 ){ free(x1a); x1a = 0; @@ -4480,8 +4478,7 @@ int Strsafe_insert(const char *data) struct s_x1 array; array.size = size = x1a->size*2; array.count = x1a->count; - array.tbl = (x1node*)malloc( - (sizeof(x1node) + sizeof(x1node*))*size ); + array.tbl = (x1node*)calloc(size, sizeof(x1node) + sizeof(x1node*)); if( array.tbl==0 ) return 0; /* Fail due to malloc failure */ array.ht = (x1node**)&(array.tbl[size]); for(i=0; isize = 128; x2a->count = 0; - x2a->tbl = (x2node*)malloc( - (sizeof(x2node) + sizeof(x2node*))*128 ); + x2a->tbl = (x2node*)calloc(128, sizeof(x2node) + sizeof(x2node*)); if( x2a->tbl==0 ){ free(x2a); x2a = 0; @@ -4649,8 +4645,7 @@ int Symbol_insert(struct symbol *data, const char *key) struct s_x2 array; array.size = size = x2a->size*2; array.count = x2a->count; - array.tbl = (x2node*)malloc( - (sizeof(x2node) + sizeof(x2node*))*size ); + array.tbl = (x2node*)calloc(size, sizeof(x2node) + sizeof(x2node*)); if( array.tbl==0 ) return 0; /* Fail due to malloc failure */ array.ht = (x2node**)&(array.tbl[size]); for(i=0; isize = 128; x3a->count = 0; - x3a->tbl = (x3node*)malloc( - (sizeof(x3node) + sizeof(x3node*))*128 ); + x3a->tbl = (x3node*)calloc(128, sizeof(x3node) + sizeof(x3node*)); if( x3a->tbl==0 ){ free(x3a); x3a = 0; @@ -4848,8 +4842,7 @@ int State_insert(struct state *data, struct config *key) struct s_x3 array; array.size = size = x3a->size*2; array.count = x3a->count; - array.tbl = (x3node*)malloc( - (sizeof(x3node) + sizeof(x3node*))*size ); + array.tbl = (x3node*)calloc(size, sizeof(x3node) + sizeof(x3node*)); if( array.tbl==0 ) return 0; /* Fail due to malloc failure */ array.ht = (x3node**)&(array.tbl[size]); for(i=0; icount; - array = (struct state **)malloc( sizeof(struct state *)*size ); + array = (struct state **)calloc(size, sizeof(struct state *)); if( array ){ for(i=0; itbl[i].data; } @@ -4952,8 +4945,7 @@ void Configtable_init(){ if( x4a ){ x4a->size = 64; x4a->count = 0; - x4a->tbl = (x4node*)malloc( - (sizeof(x4node) + sizeof(x4node*))*64 ); + x4a->tbl = (x4node*)calloc(64, sizeof(x4node) + sizeof(x4node*)); if( x4a->tbl==0 ){ free(x4a); x4a = 0; @@ -4990,8 +4982,7 @@ int Configtable_insert(struct config *data) struct s_x4 array; array.size = size = x4a->size*2; array.count = x4a->count; - array.tbl = (x4node*)malloc( - (sizeof(x4node) + sizeof(x4node*))*size ); + array.tbl = (x4node*)calloc(size, sizeof(x4node) + sizeof(x4node*)); if( array.tbl==0 ) return 0; /* Fail due to malloc failure */ array.ht = (x4node**)&(array.tbl[size]); for(i=0; i Date: Sat, 11 Jan 2014 13:22:17 +0000 Subject: [PATCH 133/276] Parse common table expressions. But do not do anything with them (yet). FossilOrigin-Name: da98b7205eb3d7ec2ddbf8a8e24eee0b2ff499a5 --- manifest | 21 ++++++++++++--------- manifest.uuid | 2 +- src/build.c | 21 +++++++++++++++++++++ src/parse.y | 39 +++++++++++++++++++++++++-------------- src/sqliteInt.h | 4 ++++ tool/mkkeywordhash.c | 7 +++++++ 6 files changed, 70 insertions(+), 24 deletions(-) diff --git a/manifest b/manifest index 03003dd0c5..16d294c829 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sLEMON,\slimit\sthe\ssize\sof\sthe\sgrammar\sfile\sto\s100MB.\s\sThis\sensures\sthat\nthe\sprogram\swill\snever\sexperience\sinteger\soverflow.\s\sTo\sbe\sdoubly\ssure,\nuse\scalloc()\sinstead\sof\smalloc()\swhen\sallocating\sarrays. -D 2014-01-11T12:52:25.201 +C Parse\scommon\stable\sexpressions.\s\sBut\sdo\snot\sdo\sanything\swith\sthem\s(yet). +D 2014-01-11T13:22:17.016 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -169,7 +169,7 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btree.c 11e29ef8cf16a42925fde036bcffbeffd9cc82df F src/btree.h a61ddebc78c66795a2b93181321a116746302cc9 F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0 -F src/build.c 8c56d91447770a746b16d08a6510109c161dbc1a +F src/build.c 198670a78fe748b6e60d6345a8aa1db57794511a F src/callback.c 174e3c8656bc29f91d710ab61550d16eea34be98 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd @@ -209,7 +209,7 @@ F src/os_unix.c 3a4dcb554d3c915075766162f28c3fd4cdb75968 F src/os_win.c 16eac0961603182ffc10c02b39fe830126538e07 F src/pager.c efa923693e958696eee69b205a20bfbc402c8480 F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428 -F src/parse.y 3c5384533a8bfce5abd256cc9cb2c38bec05ad61 +F src/parse.y 0ccd364dd3670ad5763a5e94dd11196ddc10927a F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222 F src/pcache1.c 57fee9a9a617218f5037afbbe49b09da65bde56b @@ -224,7 +224,7 @@ F src/shell.c a3541193d5fce37e91dad8ef46a9505aa7c9b344 F src/sqlite.h.in d94a8b89522f526ba711182ee161e06f8669bcc9 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h 0c65967bb807dee3c9eef2bbd17f880eeb28ea30 +F src/sqliteInt.h bb093076ba1eb956330cca0ca2a206c91facab4b F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -1113,7 +1113,7 @@ F tool/lemon.c 6842b2e7af12835f9f6e55808a0b1861cd0696fe F tool/lempar.c 01ca97f87610d1dac6d8cd96ab109ab1130e76dc F tool/logest.c 7ad625cac3d54012b27d468b7af6612f78b9ba75 F tool/mkautoconfamal.sh f8d8dbf7d62f409ebed5134998bf5b51d7266383 -F tool/mkkeywordhash.c 189d76644e373c7d0864c628deb8ce7b4f403591 +F tool/mkkeywordhash.c c9e05e4a7bcab8fab9f583d5b321fb72f565ad97 F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e F tool/mkpragmatab.tcl 78a77b2c554d534c6f2dc903130186ed15715460 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 @@ -1148,7 +1148,10 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P cb5d1f83e0a33d546d4c0cb817ef1f8440d1f738 -R 28679f157b50c114aa03e50f74a7a104 +P 29ba458d849ad8864711cbe59fb10447a947e06a +R b8f42a0591e43b680c1e09056e8afd6e +T *branch * common-table-expr +T *sym-common-table-expr * +T -sym-trunk * U drh -Z 608e7b6009060d93ac39bb2434b3c874 +Z 9a38087dfe69ad33926bbf7c01c0b22a diff --git a/manifest.uuid b/manifest.uuid index d8b23d3f34..17610fd9e7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -29ba458d849ad8864711cbe59fb10447a947e06a \ No newline at end of file +da98b7205eb3d7ec2ddbf8a8e24eee0b2ff499a5 \ No newline at end of file diff --git a/src/build.c b/src/build.c index fa82d56cc7..4fb4b4efa9 100644 --- a/src/build.c +++ b/src/build.c @@ -4198,3 +4198,24 @@ KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){ } return sqlite3KeyInfoRef(pIdx->pKeyInfo); } + +#ifndef SQLITE_OMIT_CTE +/* This routine is invoked when a single with_query of a +** common-table-expression has been parsed. Record the query. +*/ +void sqlite3CteAdd( + Parse *pParse, /* Parsing context */ + Token *pName, /* Name of the common-table */ + ExprList *pArgList, /* Optional column name list for the table */ + Select *pQuery /* Query used to initialize the table */ +){ + sqlite3ExprListDelete(pParse->db, pArgList); + sqlite3SelectDelete(pParse->db, pQuery); +} + +/* This routine is invoked at the end of the entire WITH clause. +*/ +void sqlite3CteFinish(Parse *pParse, int isRecursive){ + /* TBD */ +} +#endif /* !defined(SQLITE_OMIT_CTE) */ diff --git a/src/parse.y b/src/parse.y index f8e813d115..f4fa4b276d 100644 --- a/src/parse.y +++ b/src/parse.y @@ -204,8 +204,8 @@ columnid(A) ::= nm(X). { ABORT ACTION AFTER ANALYZE ASC ATTACH BEFORE BEGIN BY CASCADE CAST COLUMNKW CONFLICT DATABASE DEFERRED DESC DETACH EACH END EXCLUSIVE EXPLAIN FAIL FOR IGNORE IMMEDIATE INITIALLY INSTEAD LIKE_KW MATCH NO PLAN - QUERY KEY OF OFFSET PRAGMA RAISE RELEASE REPLACE RESTRICT ROW ROLLBACK - SAVEPOINT TEMP TRIGGER VACUUM VIEW VIRTUAL WITHOUT + QUERY KEY OF OFFSET PRAGMA RAISE RECURSIVE RELEASE REPLACE RESTRICT ROW + ROLLBACK SAVEPOINT TEMP TRIGGER VACUUM VIEW VIRTUAL WITH WITHOUT %ifdef SQLITE_OMIT_COMPOUND_SELECT EXCEPT INTERSECT UNION %endif SQLITE_OMIT_COMPOUND_SELECT @@ -396,7 +396,7 @@ cmd ::= DROP VIEW ifexists(E) fullname(X). { //////////////////////// The SELECT statement ///////////////////////////////// // -cmd ::= select(X). { +cmd ::= with select(X). { SelectDest dest = {SRT_Output, 0, 0, 0, 0}; sqlite3Select(pParse, X, &dest); sqlite3ExplainBegin(pParse->pVdbe); @@ -648,7 +648,7 @@ limit_opt(A) ::= LIMIT expr(X) COMMA expr(Y). /////////////////////////// The DELETE statement ///////////////////////////// // %ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT -cmd ::= DELETE FROM fullname(X) indexed_opt(I) where_opt(W) +cmd ::= with DELETE FROM fullname(X) indexed_opt(I) where_opt(W) orderby_opt(O) limit_opt(L). { sqlite3SrcListIndexedBy(pParse, X, &I); W = sqlite3LimitWhere(pParse, X, W, O, L.pLimit, L.pOffset, "DELETE"); @@ -656,7 +656,7 @@ cmd ::= DELETE FROM fullname(X) indexed_opt(I) where_opt(W) } %endif %ifndef SQLITE_ENABLE_UPDATE_DELETE_LIMIT -cmd ::= DELETE FROM fullname(X) indexed_opt(I) where_opt(W). { +cmd ::= with DELETE FROM fullname(X) indexed_opt(I) where_opt(W). { sqlite3SrcListIndexedBy(pParse, X, &I); sqlite3DeleteFrom(pParse,X,W); } @@ -671,8 +671,8 @@ where_opt(A) ::= WHERE expr(X). {A = X.pExpr;} ////////////////////////// The UPDATE command //////////////////////////////// // %ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT -cmd ::= UPDATE orconf(R) fullname(X) indexed_opt(I) SET setlist(Y) where_opt(W) - orderby_opt(O) limit_opt(L). { +cmd ::= with UPDATE orconf(R) fullname(X) indexed_opt(I) SET setlist(Y) + where_opt(W) orderby_opt(O) limit_opt(L). { sqlite3SrcListIndexedBy(pParse, X, &I); sqlite3ExprListCheckLength(pParse,Y,"set list"); W = sqlite3LimitWhere(pParse, X, W, O, L.pLimit, L.pOffset, "UPDATE"); @@ -680,7 +680,7 @@ cmd ::= UPDATE orconf(R) fullname(X) indexed_opt(I) SET setlist(Y) where_opt(W) } %endif %ifndef SQLITE_ENABLE_UPDATE_DELETE_LIMIT -cmd ::= UPDATE orconf(R) fullname(X) indexed_opt(I) SET setlist(Y) +cmd ::= with UPDATE orconf(R) fullname(X) indexed_opt(I) SET setlist(Y) where_opt(W). { sqlite3SrcListIndexedBy(pParse, X, &I); sqlite3ExprListCheckLength(pParse,Y,"set list"); @@ -702,9 +702,9 @@ setlist(A) ::= nm(X) EQ expr(Y). { ////////////////////////// The INSERT command ///////////////////////////////// // -cmd ::= insert_cmd(R) INTO fullname(X) inscollist_opt(F) select(S). +cmd ::= with insert_cmd(R) INTO fullname(X) inscollist_opt(F) select(S). {sqlite3Insert(pParse, X, S, F, R);} -cmd ::= insert_cmd(R) INTO fullname(X) inscollist_opt(F) DEFAULT VALUES. +cmd ::= with insert_cmd(R) INTO fullname(X) inscollist_opt(F) DEFAULT VALUES. {sqlite3Insert(pParse, X, 0, F, R);} %type insert_cmd {u8} @@ -851,10 +851,8 @@ expr(A) ::= expr(X) STAR|SLASH|REM(OP) expr(Y). {spanBinaryExpr(&A,pParse,@OP,&X,&Y);} expr(A) ::= expr(X) CONCAT(OP) expr(Y). {spanBinaryExpr(&A,pParse,@OP,&X,&Y);} %type likeop {struct LikeOp} -likeop(A) ::= LIKE_KW(X). {A.eOperator = X; A.bNot = 0;} -likeop(A) ::= NOT LIKE_KW(X). {A.eOperator = X; A.bNot = 1;} -likeop(A) ::= MATCH(X). {A.eOperator = X; A.bNot = 0;} -likeop(A) ::= NOT MATCH(X). {A.eOperator = X; A.bNot = 1;} +likeop(A) ::= LIKE_KW|MATCH(X). {A.eOperator = X; A.bNot = 0;} +likeop(A) ::= NOT LIKE_KW|MATCH(X). {A.eOperator = X; A.bNot = 1;} expr(A) ::= expr(X) likeop(OP) expr(Y). [LIKE_KW] { ExprList *pList; pList = sqlite3ExprListAppend(pParse,0, Y.pExpr); @@ -1364,3 +1362,16 @@ anylist ::= . anylist ::= anylist LP anylist RP. anylist ::= anylist ANY. %endif SQLITE_OMIT_VIRTUALTABLE + + +//////////////////////// COMMON TABLE EXPRESSIONS //////////////////////////// +with ::= . +%ifndef SQLITE_OMIT_CTE +with ::= WITH wqlist. {sqlite3CteFinish(pParse, 0);} +with ::= WITH RECURSIVE wqlist. {sqlite3CteFinish(pParse, 1);} +wqlist ::= with_query. +wqlist ::= wqlist COMMA with_query. +with_query ::= nm(X) idxlist_opt(Y) AS LP select(Z) RP. { + sqlite3CteAdd(pParse, &X, Y, Z); +} +%endif SQLITE_OMIT_CTE diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 188a7cacc4..d517789da0 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3329,6 +3329,10 @@ const char *sqlite3JournalModename(int); int sqlite3Checkpoint(sqlite3*, int, int, int*, int*); int sqlite3WalDefaultHook(void*,sqlite3*,const char*,int); #endif +#ifndef SQLITE_OMIT_CTE + void sqlite3CteAdd(Parse*,Token*,ExprList*,Select*); + void sqlite3CteFinish(Parse*,int); +#endif /* Declarations for functions in fkey.c. All of these are replaced by ** no-op macros if OMIT_FOREIGN_KEY is defined. In this case no foreign diff --git a/tool/mkkeywordhash.c b/tool/mkkeywordhash.c index f3ef73f394..a467931c30 100644 --- a/tool/mkkeywordhash.c +++ b/tool/mkkeywordhash.c @@ -138,6 +138,11 @@ struct Keyword { #else # define AUTOVACUUM 0x00020000 #endif +#ifdef SQLITE_OMIT_CTE +# define CTE 0 +#else +# define CTE 0x00040000 +#endif /* ** These are the keywords @@ -234,6 +239,7 @@ static Keyword aKeywordTable[] = { { "PRIMARY", "TK_PRIMARY", ALWAYS }, { "QUERY", "TK_QUERY", EXPLAIN }, { "RAISE", "TK_RAISE", TRIGGER }, + { "RECURSIVE", "TK_RECURSIVE", CTE }, { "REFERENCES", "TK_REFERENCES", FKEY }, { "REGEXP", "TK_LIKE_KW", ALWAYS }, { "REINDEX", "TK_REINDEX", REINDEX }, @@ -262,6 +268,7 @@ static Keyword aKeywordTable[] = { { "VALUES", "TK_VALUES", ALWAYS }, { "VIEW", "TK_VIEW", VIEW }, { "VIRTUAL", "TK_VIRTUAL", VTAB }, + { "WITH", "TK_WITH", CTE }, { "WITHOUT", "TK_WITHOUT", ALWAYS }, { "WHEN", "TK_WHEN", ALWAYS }, { "WHERE", "TK_WHERE", ALWAYS }, From 7d562dbe023a06bc8b7116c5415c5cb9b6a25cfc Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 11 Jan 2014 19:19:36 +0000 Subject: [PATCH 134/276] Update the parser so that sub-queries and CTEs may have WITH clauses. FossilOrigin-Name: 704d3931b855562a619769955969d439c42ca406 --- manifest | 22 ++++++++++------------ manifest.uuid | 2 +- src/build.c | 18 +++++++++++------- src/parse.y | 30 ++++++++++++++++++++---------- src/sqliteInt.h | 18 ++++++++++++++++-- test/with1.test | 40 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 98 insertions(+), 32 deletions(-) create mode 100644 test/with1.test diff --git a/manifest b/manifest index 16d294c829..c9d03126cd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Parse\scommon\stable\sexpressions.\s\sBut\sdo\snot\sdo\sanything\swith\sthem\s(yet). -D 2014-01-11T13:22:17.016 +C Update\sthe\sparser\sso\sthat\ssub-queries\sand\sCTEs\smay\shave\sWITH\sclauses. +D 2014-01-11T19:19:36.147 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -169,7 +169,7 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btree.c 11e29ef8cf16a42925fde036bcffbeffd9cc82df F src/btree.h a61ddebc78c66795a2b93181321a116746302cc9 F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0 -F src/build.c 198670a78fe748b6e60d6345a8aa1db57794511a +F src/build.c 1da29e4e93d9774599f1f791d011ba46d841000c F src/callback.c 174e3c8656bc29f91d710ab61550d16eea34be98 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd @@ -209,7 +209,7 @@ F src/os_unix.c 3a4dcb554d3c915075766162f28c3fd4cdb75968 F src/os_win.c 16eac0961603182ffc10c02b39fe830126538e07 F src/pager.c efa923693e958696eee69b205a20bfbc402c8480 F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428 -F src/parse.y 0ccd364dd3670ad5763a5e94dd11196ddc10927a +F src/parse.y 1e3fd22fc82930d0cce01f2ab90616100c59ee0c F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222 F src/pcache1.c 57fee9a9a617218f5037afbbe49b09da65bde56b @@ -224,7 +224,7 @@ F src/shell.c a3541193d5fce37e91dad8ef46a9505aa7c9b344 F src/sqlite.h.in d94a8b89522f526ba711182ee161e06f8669bcc9 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h bb093076ba1eb956330cca0ca2a206c91facab4b +F src/sqliteInt.h 2710b3a6c66edda9f193453268f6fe878ff5a0ca F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -1091,6 +1091,7 @@ F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c F test/win32lock.test 7a6bd73a5dcdee39b5bb93e92395e1773a194361 F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d +F test/with1.test e8146198319c3627bb21ef085c58a827f35686a7 F test/without_rowid1.test aaa26da19d543cd8d3d2d0e686dfa255556c15c8 F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99 F test/without_rowid3.test eac3d5c8a1924725b58503a368f2cbd24fd6c8a0 @@ -1148,10 +1149,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 29ba458d849ad8864711cbe59fb10447a947e06a -R b8f42a0591e43b680c1e09056e8afd6e -T *branch * common-table-expr -T *sym-common-table-expr * -T -sym-trunk * -U drh -Z 9a38087dfe69ad33926bbf7c01c0b22a +P da98b7205eb3d7ec2ddbf8a8e24eee0b2ff499a5 +R bbb9d541af414d7b8bb3f418deb50875 +U dan +Z a973a84816d55810384771a899b1092b diff --git a/manifest.uuid b/manifest.uuid index 17610fd9e7..f6a009da18 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -da98b7205eb3d7ec2ddbf8a8e24eee0b2ff499a5 \ No newline at end of file +704d3931b855562a619769955969d439c42ca406 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 4fb4b4efa9..23628f73be 100644 --- a/src/build.c +++ b/src/build.c @@ -4200,22 +4200,26 @@ KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){ } #ifndef SQLITE_OMIT_CTE -/* This routine is invoked when a single with_query of a -** common-table-expression has been parsed. Record the query. +/* +** This routine is invoked once per CTE by the parser while parsing a +** WITH clause. */ -void sqlite3CteAdd( +With *sqlite3WithAdd( Parse *pParse, /* Parsing context */ + With *pWith, /* Existing WITH clause, or NULL */ Token *pName, /* Name of the common-table */ - ExprList *pArgList, /* Optional column name list for the table */ + IdList *pArglist, /* Optional column name list for the table */ Select *pQuery /* Query used to initialize the table */ ){ - sqlite3ExprListDelete(pParse->db, pArgList); + sqlite3IdListDelete(pParse->db, pArglist); sqlite3SelectDelete(pParse->db, pQuery); + return 0; } -/* This routine is invoked at the end of the entire WITH clause. +/* +** Free the contents of the With object passed as the second argument. */ -void sqlite3CteFinish(Parse *pParse, int isRecursive){ +void sqlite3WithDelete(sqlite3 *db, With *pWith){ /* TBD */ } #endif /* !defined(SQLITE_OMIT_CTE) */ diff --git a/src/parse.y b/src/parse.y index f4fa4b276d..c3cb2d62aa 100644 --- a/src/parse.y +++ b/src/parse.y @@ -396,7 +396,7 @@ cmd ::= DROP VIEW ifexists(E) fullname(X). { //////////////////////// The SELECT statement ///////////////////////////////// // -cmd ::= with select(X). { +cmd ::= select(X). { SelectDest dest = {SRT_Output, 0, 0, 0, 0}; sqlite3Select(pParse, X, &dest); sqlite3ExplainBegin(pParse->pVdbe); @@ -407,12 +407,16 @@ cmd ::= with select(X). { %type select {Select*} %destructor select {sqlite3SelectDelete(pParse->db, $$);} +%type selectnowith {Select*} +%destructor selectnowith {sqlite3SelectDelete(pParse->db, $$);} %type oneselect {Select*} %destructor oneselect {sqlite3SelectDelete(pParse->db, $$);} -select(A) ::= oneselect(X). {A = X;} +select(A) ::= with selectnowith(X). {A = X;} + +selectnowith(A) ::= oneselect(X). {A = X;} %ifndef SQLITE_OMIT_COMPOUND_SELECT -select(A) ::= select(X) multiselect_op(Y) oneselect(Z). { +selectnowith(A) ::= selectnowith(X) multiselect_op(Y) oneselect(Z). { if( Z ){ Z->op = (u8)Y; Z->pPrior = X; @@ -1365,13 +1369,19 @@ anylist ::= anylist ANY. //////////////////////// COMMON TABLE EXPRESSIONS //////////////////////////// -with ::= . +%type with {With*} +%type wqlist {With*} +%destructor with {sqlite3WithDelete(pParse->db, $$);} + +with(A) ::= . {A = 0;} %ifndef SQLITE_OMIT_CTE -with ::= WITH wqlist. {sqlite3CteFinish(pParse, 0);} -with ::= WITH RECURSIVE wqlist. {sqlite3CteFinish(pParse, 1);} -wqlist ::= with_query. -wqlist ::= wqlist COMMA with_query. -with_query ::= nm(X) idxlist_opt(Y) AS LP select(Z) RP. { - sqlite3CteAdd(pParse, &X, Y, Z); +with(A) ::= WITH wqlist(W). { A = W; } +with(A) ::= WITH RECURSIVE wqlist(W). { A = W; } + +wqlist(A) ::= nm(X) inscollist_opt(Y) AS LP select(Z) RP. { + A = sqlite3WithAdd(pParse, 0, &X, Y, Z); +} +wqlist(A) ::= wqlist(W) COMMA nm(X) inscollist_opt(Y) AS LP select(Z) RP. { + A = sqlite3WithAdd(pParse, W, &X, Y, Z); } %endif SQLITE_OMIT_CTE diff --git a/src/sqliteInt.h b/src/sqliteInt.h index d517789da0..8846ffb04c 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -760,6 +760,7 @@ typedef struct VTable VTable; typedef struct VtabCtx VtabCtx; typedef struct Walker Walker; typedef struct WhereInfo WhereInfo; +typedef struct With With; /* ** Defer sourcing vdbe.h and btree.h until after the "u8" and @@ -2631,6 +2632,19 @@ int sqlite3WalkSelectFrom(Walker*, Select*); #define WRC_Prune 1 /* Omit children but continue walking siblings */ #define WRC_Abort 2 /* Abandon the tree walk */ +/* +** An instance of this structure represents a set of CTEs (common table +** expressions) created by a single WITH clause. +*/ +struct With { + int nCte; /* Number of CTEs */ + struct Cte { + const char *zName; /* Name of this CTE */ + IdList *pCol; /* List of explicit column names, or NULL */ + Select *pSelect; /* The contents of the CTE */ + } a[1]; +}; + /* ** Assuming zIn points to the first byte of a UTF-8 character, ** advance zIn to point to the first byte of the next UTF-8 character. @@ -3330,8 +3344,8 @@ const char *sqlite3JournalModename(int); int sqlite3WalDefaultHook(void*,sqlite3*,const char*,int); #endif #ifndef SQLITE_OMIT_CTE - void sqlite3CteAdd(Parse*,Token*,ExprList*,Select*); - void sqlite3CteFinish(Parse*,int); + With *sqlite3WithAdd(Parse*,With*,Token*,IdList*,Select*); + void sqlite3WithDelete(sqlite3*,With*); #endif /* Declarations for functions in fkey.c. All of these are replaced by diff --git a/test/with1.test b/test/with1.test new file mode 100644 index 0000000000..80e879ada0 --- /dev/null +++ b/test/with1.test @@ -0,0 +1,40 @@ +# 2014 January 11 +# +# 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 WITH clause. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set ::testprefix with1 + +do_execsql_test 1.0 { + CREATE TABLE t1(x INTEGER, y INTEGER); + WITH x(a) AS ( SELECT * FROM t1) SELECT 10 +} {10} + +do_execsql_test 1.1 { + SELECT * FROM ( WITH x AS ( SELECT * FROM t1) SELECT 10 ); +} {10} + +do_execsql_test 1.2 { + WITH x(a) AS ( SELECT * FROM t1) INSERT INTO t1 VALUES(1,2); +} {} + +do_execsql_test 1.3 { + WITH x(a) AS ( SELECT * FROM t1) DELETE FROM t1; +} {} + +do_execsql_test 1.4 { + WITH x(a) AS ( SELECT * FROM t1) UPDATE t1 SET x = y; +} {} + +finish_test From 4e9119d9e8bc3ed4c75b2c77f9ec80c6cf5f5463 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 13 Jan 2014 15:12:23 +0000 Subject: [PATCH 135/276] Add code to handle non-recursive CTEs in the same way as SQL views. FossilOrigin-Name: a26f399ba485e8127c276c5f103ec6c555e11734 --- manifest | 29 ++++++------ manifest.uuid | 2 +- src/build.c | 53 +++++++++++++++++++--- src/expr.c | 19 ++++++++ src/insert.c | 3 +- src/parse.y | 29 +++++++----- src/select.c | 87 ++++++++++++++++++++++++++++++++++-- src/sqliteInt.h | 14 ++++-- src/tokenize.c | 2 + test/pagerfault.test | 1 + test/with1.test | 103 +++++++++++++++++++++++++++++++++++++++++++ test/withM.test | 40 +++++++++++++++++ 12 files changed, 345 insertions(+), 37 deletions(-) create mode 100644 test/withM.test diff --git a/manifest b/manifest index c9d03126cd..010cb6fcfd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sthe\sparser\sso\sthat\ssub-queries\sand\sCTEs\smay\shave\sWITH\sclauses. -D 2014-01-11T19:19:36.147 +C Add\scode\sto\shandle\snon-recursive\sCTEs\sin\sthe\ssame\sway\sas\sSQL\sviews. +D 2014-01-13T15:12:23.149 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -169,13 +169,13 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btree.c 11e29ef8cf16a42925fde036bcffbeffd9cc82df F src/btree.h a61ddebc78c66795a2b93181321a116746302cc9 F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0 -F src/build.c 1da29e4e93d9774599f1f791d011ba46d841000c +F src/build.c 1efdc65020e1f566383b66b30ccf730b4ef6f926 F src/callback.c 174e3c8656bc29f91d710ab61550d16eea34be98 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 F src/delete.c 91e1321021db5dc266360531b8b6550009d771ff -F src/expr.c 4115ad67088cdd55f4fa0ef3ddd22cb8da8f9c94 +F src/expr.c de86bf987c532ec9d63fb1bf8a6eb6ec2cf5ba69 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 2ab0f5384b70594468ef3ac5c7ed8ca24bfd17d5 F src/func.c 6325ac2ec10833ccf4d5c36d323709221d37ea19 @@ -183,7 +183,7 @@ F src/global.c 1d7bb7ea8254ae6a68ed9bfaf65fcb3d1690b486 F src/hash.c ac3470bbf1ca4ae4e306a8ecb0fdf1731810ffe4 F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c 5ddb48c7f1cb399993744f23f03948989ce1790e +F src/insert.c cb4c8ad02b6feb95d34614d94a3c68e0116fbf07 F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b @@ -209,7 +209,7 @@ F src/os_unix.c 3a4dcb554d3c915075766162f28c3fd4cdb75968 F src/os_win.c 16eac0961603182ffc10c02b39fe830126538e07 F src/pager.c efa923693e958696eee69b205a20bfbc402c8480 F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428 -F src/parse.y 1e3fd22fc82930d0cce01f2ab90616100c59ee0c +F src/parse.y b433588d7993d6475d9944be0fda2fb3df3cb138 F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222 F src/pcache1.c 57fee9a9a617218f5037afbbe49b09da65bde56b @@ -219,12 +219,12 @@ F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c 819bb090c9a348d17f69f136cad2bfa9ee9cbb41 +F src/select.c 9dc9177bfb9278a603e3835e828ff60ec68fba6f F src/shell.c a3541193d5fce37e91dad8ef46a9505aa7c9b344 F src/sqlite.h.in d94a8b89522f526ba711182ee161e06f8669bcc9 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h 2710b3a6c66edda9f193453268f6fe878ff5a0ca +F src/sqliteInt.h a350bcf6d62204b6b4720ce1922c95a575a0b5ad F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -274,7 +274,7 @@ F src/test_thread.c 1e133a40b50e9c035b00174035b846e7eef481cb F src/test_vfs.c e72f555ef7a59080f898fcf1a233deb9eb704ea9 F src/test_vfstrace.c 3a0ab304682fecbceb689e7d9b904211fde11d78 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 -F src/tokenize.c 5d04a1b7d1fe7e18556a869788f5d3e132a586b6 +F src/tokenize.c 7dc42e9beb8c3263b79d10c195b3f5264b5f874a F src/trigger.c 5c1c0b899ac0ce284763dcb8fdbaa38ecf15ef98 F src/update.c c2706a6eb232a96345c35b7e1e75a188e26812bb F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 @@ -728,7 +728,7 @@ F test/pager1.test 1acbdb14c5952a72dd43129cabdbf69aaa3ed1fa F test/pager2.test 67b8f40ae98112bcdba1f2b2d03ea83266418c71 F test/pager3.test 3856d9c80839be0668efee1b74811b1b7f7fc95f F test/pager4.test b40ecb4cc7dff957ee7916e41ab21d1ed702a642 -F test/pagerfault.test 7285379906ab2f1108b8e82bbdf2d386cc8ff3ff +F test/pagerfault.test cee8488a935e42a4a2e241e0317dc2814c997783 F test/pagerfault2.test caf4c7facb914fd3b03a17b31ae2b180c8d6ca1f F test/pagerfault3.test 1003fcda009bf48a8e22a516e193b6ef0dd1bbd8 F test/pageropt.test 6b8f6a123a5572c195ad4ae40f2987007923bbd6 @@ -1091,7 +1091,8 @@ F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c F test/win32lock.test 7a6bd73a5dcdee39b5bb93e92395e1773a194361 F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d -F test/with1.test e8146198319c3627bb21ef085c58a827f35686a7 +F test/with1.test fb8409a35b1314be6e73a87597322f3369b59b2b +F test/withM.test 036349a9ec081fee8b1f72e71ad8a5a5b80f1674 F test/without_rowid1.test aaa26da19d543cd8d3d2d0e686dfa255556c15c8 F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99 F test/without_rowid3.test eac3d5c8a1924725b58503a368f2cbd24fd6c8a0 @@ -1149,7 +1150,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P da98b7205eb3d7ec2ddbf8a8e24eee0b2ff499a5 -R bbb9d541af414d7b8bb3f418deb50875 +P 704d3931b855562a619769955969d439c42ca406 +R fb5ad7a801e83802b92e3793bba4fd6c U dan -Z a973a84816d55810384771a899b1092b +Z 663a5542bd9dc2bb50ed6e3a07d040fb diff --git a/manifest.uuid b/manifest.uuid index f6a009da18..267d8a5499 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -704d3931b855562a619769955969d439c42ca406 \ No newline at end of file +a26f399ba485e8127c276c5f103ec6c555e11734 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 23628f73be..ca184766f9 100644 --- a/src/build.c +++ b/src/build.c @@ -4208,18 +4208,61 @@ With *sqlite3WithAdd( Parse *pParse, /* Parsing context */ With *pWith, /* Existing WITH clause, or NULL */ Token *pName, /* Name of the common-table */ - IdList *pArglist, /* Optional column name list for the table */ + ExprList *pArglist, /* Optional column name list for the table */ Select *pQuery /* Query used to initialize the table */ ){ - sqlite3IdListDelete(pParse->db, pArglist); - sqlite3SelectDelete(pParse->db, pQuery); - return 0; + sqlite3 *db = pParse->db; + With *pNew; + char *zName; + + /* Check that the CTE name is unique within this WITH clause. If + ** not, store an error in the Parse structure. */ + zName = sqlite3NameFromToken(pParse->db, pName); + if( zName && pWith ){ + int i; + for(i=0; inCte; i++){ + if( sqlite3StrICmp(zName, pWith->a[i].zName)==0 ){ + sqlite3ErrorMsg(pParse, "duplicate cte name: %s", zName); + } + } + } + + if( pWith ){ + int nByte = sizeof(*pWith) + (sizeof(pWith->a[1]) * pWith->nCte); + pNew = sqlite3DbRealloc(db, pWith, nByte); + }else{ + pNew = sqlite3DbMallocZero(db, sizeof(*pWith)); + } + assert( zName!=0 || pNew==0 ); + + if( pNew==0 ){ + sqlite3WithDelete(db, pWith); + sqlite3ExprListDelete(db, pArglist); + sqlite3SelectDelete(db, pQuery); + sqlite3DbFree(db, zName); + }else{ + pNew->a[pNew->nCte].pSelect = pQuery; + pNew->a[pNew->nCte].pCols = pArglist; + pNew->a[pNew->nCte].zName = zName; + pNew->nCte++; + } + + return pNew; } /* ** Free the contents of the With object passed as the second argument. */ void sqlite3WithDelete(sqlite3 *db, With *pWith){ - /* TBD */ + if( pWith ){ + int i; + for(i=0; inCte; i++){ + struct Cte *pCte = &pWith->a[i]; + sqlite3ExprListDelete(db, pCte->pCols); + sqlite3SelectDelete(db, pCte->pSelect); + sqlite3DbFree(db, pCte->zName); + } + sqlite3DbFree(db, pWith); + } } #endif /* !defined(SQLITE_OMIT_CTE) */ diff --git a/src/expr.c b/src/expr.c index aad6cd1cda..d0ea280029 100644 --- a/src/expr.c +++ b/src/expr.c @@ -895,6 +895,24 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){ return pNew; } +With *withDup(sqlite3 *db, With *p){ + With *pRet = 0; + if( p ){ + int nByte = sizeof(*p) + sizeof(p->a[0]) * (p->nCte-1); + pRet = sqlite3DbMallocZero(db, nByte); + if( pRet ){ + int i; + pRet->nCte = p->nCte; + for(i=0; inCte; i++){ + pRet->a[i].pSelect = sqlite3SelectDup(db, p->a[i].pSelect, 0); + pRet->a[i].pCols = sqlite3ExprListDup(db, p->a[i].pCols, 0); + pRet->a[i].zName = sqlite3DbStrDup(db, p->a[i].zName); + } + } + } + return pRet; +} + /* ** The following group of routines make deep copies of expressions, ** expression lists, ID lists, and select statements. The copies can @@ -1036,6 +1054,7 @@ Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){ pNew->addrOpenEphm[0] = -1; pNew->addrOpenEphm[1] = -1; pNew->addrOpenEphm[2] = -1; + pNew->pWith = withDup(db, p->pWith); return pNew; } #else diff --git a/src/insert.c b/src/insert.c index 038d08a40d..b4bd6b7160 100644 --- a/src/insert.c +++ b/src/insert.c @@ -667,7 +667,8 @@ void sqlite3Insert( ** ** This is the 2nd template. */ - if( pColumn==0 && xferOptimization(pParse, pTab, pSelect, onError, iDb) ){ + if( pColumn==0 && pParse->pWith==0 + && xferOptimization(pParse, pTab, pSelect, onError, iDb) ){ assert( !pTrigger ); assert( pList==0 ); goto insert_end; diff --git a/src/parse.y b/src/parse.y index c3cb2d62aa..1c6465e933 100644 --- a/src/parse.y +++ b/src/parse.y @@ -412,7 +412,7 @@ cmd ::= select(X). { %type oneselect {Select*} %destructor oneselect {sqlite3SelectDelete(pParse->db, $$);} -select(A) ::= with selectnowith(X). {A = X;} +select(A) ::= with(W) selectnowith(X). { if( X ) X->pWith = W; A = X; } selectnowith(A) ::= oneselect(X). {A = X;} %ifndef SQLITE_OMIT_COMPOUND_SELECT @@ -652,15 +652,17 @@ limit_opt(A) ::= LIMIT expr(X) COMMA expr(Y). /////////////////////////// The DELETE statement ///////////////////////////// // %ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT -cmd ::= with DELETE FROM fullname(X) indexed_opt(I) where_opt(W) +cmd ::= with(C) DELETE FROM fullname(X) indexed_opt(I) where_opt(W) orderby_opt(O) limit_opt(L). { + sqlite3WithPush(pParse,C); sqlite3SrcListIndexedBy(pParse, X, &I); W = sqlite3LimitWhere(pParse, X, W, O, L.pLimit, L.pOffset, "DELETE"); sqlite3DeleteFrom(pParse,X,W); } %endif %ifndef SQLITE_ENABLE_UPDATE_DELETE_LIMIT -cmd ::= with DELETE FROM fullname(X) indexed_opt(I) where_opt(W). { +cmd ::= with(C) DELETE FROM fullname(X) indexed_opt(I) where_opt(W). { + sqlite3WithPush(pParse,C); sqlite3SrcListIndexedBy(pParse, X, &I); sqlite3DeleteFrom(pParse,X,W); } @@ -684,8 +686,9 @@ cmd ::= with UPDATE orconf(R) fullname(X) indexed_opt(I) SET setlist(Y) } %endif %ifndef SQLITE_ENABLE_UPDATE_DELETE_LIMIT -cmd ::= with UPDATE orconf(R) fullname(X) indexed_opt(I) SET setlist(Y) +cmd ::= with(C) UPDATE orconf(R) fullname(X) indexed_opt(I) SET setlist(Y) where_opt(W). { + sqlite3WithPush(pParse, C); sqlite3SrcListIndexedBy(pParse, X, &I); sqlite3ExprListCheckLength(pParse,Y,"set list"); sqlite3Update(pParse,X,Y,W,R); @@ -706,10 +709,15 @@ setlist(A) ::= nm(X) EQ expr(Y). { ////////////////////////// The INSERT command ///////////////////////////////// // -cmd ::= with insert_cmd(R) INTO fullname(X) inscollist_opt(F) select(S). - {sqlite3Insert(pParse, X, S, F, R);} -cmd ::= with insert_cmd(R) INTO fullname(X) inscollist_opt(F) DEFAULT VALUES. - {sqlite3Insert(pParse, X, 0, F, R);} +cmd ::= with(W) insert_cmd(R) INTO fullname(X) inscollist_opt(F) select(S). { + sqlite3WithPush(pParse, W); + sqlite3Insert(pParse, X, S, F, R); +} +cmd ::= with(W) insert_cmd(R) INTO fullname(X) inscollist_opt(F) DEFAULT VALUES. +{ + sqlite3WithPush(pParse, W); + sqlite3Insert(pParse, X, 0, F, R); +} %type insert_cmd {u8} insert_cmd(A) ::= INSERT orconf(R). {A = R;} @@ -1372,16 +1380,17 @@ anylist ::= anylist ANY. %type with {With*} %type wqlist {With*} %destructor with {sqlite3WithDelete(pParse->db, $$);} +%destructor wqlist {sqlite3WithDelete(pParse->db, $$);} with(A) ::= . {A = 0;} %ifndef SQLITE_OMIT_CTE with(A) ::= WITH wqlist(W). { A = W; } with(A) ::= WITH RECURSIVE wqlist(W). { A = W; } -wqlist(A) ::= nm(X) inscollist_opt(Y) AS LP select(Z) RP. { +wqlist(A) ::= nm(X) idxlist_opt(Y) AS LP select(Z) RP. { A = sqlite3WithAdd(pParse, 0, &X, Y, Z); } -wqlist(A) ::= wqlist(W) COMMA nm(X) inscollist_opt(Y) AS LP select(Z) RP. { +wqlist(A) ::= wqlist(W) COMMA nm(X) idxlist_opt(Y) AS LP select(Z) RP. { A = sqlite3WithAdd(pParse, W, &X, Y, Z); } %endif SQLITE_OMIT_CTE diff --git a/src/select.c b/src/select.c index d075116749..b054489b00 100644 --- a/src/select.c +++ b/src/select.c @@ -29,6 +29,7 @@ static void clearSelect(sqlite3 *db, Select *p){ sqlite3SelectDelete(db, p->pPrior); sqlite3ExprDelete(db, p->pLimit); sqlite3ExprDelete(db, p->pOffset); + sqlite3WithDelete(db, p->pWith); } /* @@ -3393,6 +3394,62 @@ static int convertCompoundSelectToSubquery(Walker *pWalker, Select *p){ return WRC_Continue; } +static struct Cte *searchWith(Parse *pParse, struct SrcList_item *p){ + if( p->zDatabase==0 ){ + char *zName = p->zName; + With *pWith; + + for(pWith=pParse->pWith; pWith; pWith=pWith->pOuter){ + int i; + for(i=0; inCte; i++){ + if( sqlite3StrICmp(zName, pWith->a[i].zName)==0 ){ + return &pWith->a[i]; + } + } + } + } + return 0; +} + +void sqlite3WithPush(Parse *pParse, With *pWith){ + if( pWith ){ + pWith->pOuter = pParse->pWith; + pParse->pWith = pWith; + } +} +static void withPop(Parse *pParse, With *pWith){ + if( pWith ){ + assert( pParse->pWith==pWith ); + pParse->pWith = pWith->pOuter; + } +} + +static int ctePush(Parse *pParse, struct Cte *pCte){ + if( pCte ){ + struct Cte *p; + for(p=pParse->pCte; p; p=p->pOuterCte){ + if( p==pCte ){ + sqlite3ErrorMsg( + pParse, "illegal recursive defininition in cte: %s", pCte->zName + ); + return SQLITE_ERROR; + } + } + + pCte->pOuterCte = pParse->pCte; + pParse->pCte = pCte; + } + return SQLITE_OK; +} + +static void ctePop(Parse *pParse, struct Cte *pCte){ + if( pCte ){ + assert( pParse->pCte==pCte ); + pParse->pCte = pCte->pOuterCte; + } +} + + /* ** This routine is a Walker callback for "expanding" a SELECT statement. ** "Expanding" means to do the following: @@ -3447,6 +3504,7 @@ static int selectExpander(Walker *pWalker, Select *p){ ** then create a transient table structure to describe the subquery. */ for(i=0, pFrom=pTabList->a; inSrc; i++, pFrom++){ + struct Cte *pCte = 0; Table *pTab; if( pFrom->pTab!=0 ){ /* This statement has already been prepared. There is no need @@ -3454,19 +3512,34 @@ static int selectExpander(Walker *pWalker, Select *p){ assert( i==0 ); return WRC_Prune; } - if( pFrom->zName==0 ){ +#ifndef SQLITE_OMIT_CTE + pCte = searchWith(pParse, pFrom); + if( pCte ){ + pFrom->pSelect = sqlite3SelectDup(db, pCte->pSelect, 0); + if( pFrom->pSelect==0 ) return WRC_Abort; + } +#endif + if( pFrom->zName==0 || pCte ){ #ifndef SQLITE_OMIT_SUBQUERY + ExprList *pEList; Select *pSel = pFrom->pSelect; /* A sub-query in the FROM clause of a SELECT */ assert( pSel!=0 ); assert( pFrom->pTab==0 ); + if( ctePush(pParse, pCte) ) return WRC_Abort; sqlite3WalkSelect(pWalker, pSel); + ctePop(pParse, pCte); pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table)); if( pTab==0 ) return WRC_Abort; pTab->nRef = 1; pTab->zName = sqlite3MPrintf(db, "sqlite_sq_%p", (void*)pTab); while( pSel->pPrior ){ pSel = pSel->pPrior; } - selectColumnsFromExprList(pParse, pSel->pEList, &pTab->nCol, &pTab->aCol); + if( pCte && pCte->pCols ){ + pEList = pCte->pCols; + }else{ + pEList = pSel->pEList; + } + selectColumnsFromExprList(pParse, pEList, &pTab->nCol, &pTab->aCol); pTab->iPKey = -1; pTab->nRowEst = 1048576; pTab->tabFlags |= TF_Ephemeral; @@ -3679,6 +3752,14 @@ static int selectExpander(Walker *pWalker, Select *p){ return WRC_Continue; } +static int selectExpanderWith(Walker *pWalker, Select *p){ + int res; + sqlite3WithPush(pWalker->pParse, p->pWith); + res = selectExpander(pWalker, p); + withPop(pWalker->pParse, p->pWith); + return res; +} + /* ** No-op routine for the parse-tree walker. ** @@ -3715,7 +3796,7 @@ static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){ w.xSelectCallback = convertCompoundSelectToSubquery; sqlite3WalkSelect(&w, pSelect); } - w.xSelectCallback = selectExpander; + w.xSelectCallback = selectExpanderWith; sqlite3WalkSelect(&w, pSelect); } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 8846ffb04c..6bd65592b7 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2144,6 +2144,7 @@ struct Select { Select *pRightmost; /* Right-most select in a compound select statement */ Expr *pLimit; /* LIMIT expression. NULL means not used. */ Expr *pOffset; /* OFFSET expression. NULL means not used. */ + With *pWith; /* WITH clause attached to this select. Or NULL. */ }; /* @@ -2365,6 +2366,8 @@ struct Parse { #endif Table *pZombieTab; /* List of Table objects to delete after code gen */ TriggerPrg *pTriggerPrg; /* Linked list of coded triggers */ + With *pWith; /* Current WITH clause, or NULL */ + struct Cte *pCte; /* Current CTE, or NULL */ }; /* @@ -2638,10 +2641,12 @@ int sqlite3WalkSelectFrom(Walker*, Select*); */ struct With { int nCte; /* Number of CTEs */ + With *pOuter; /* Containing WITH clause, or NULL */ struct Cte { - const char *zName; /* Name of this CTE */ - IdList *pCol; /* List of explicit column names, or NULL */ + char *zName; /* Name of this CTE */ + ExprList *pCols; /* List of explicit column names, or NULL */ Select *pSelect; /* The contents of the CTE */ + struct Cte *pOuterCte; } a[1]; }; @@ -3344,8 +3349,11 @@ const char *sqlite3JournalModename(int); int sqlite3WalDefaultHook(void*,sqlite3*,const char*,int); #endif #ifndef SQLITE_OMIT_CTE - With *sqlite3WithAdd(Parse*,With*,Token*,IdList*,Select*); + With *sqlite3WithAdd(Parse*,With*,Token*,ExprList*,Select*); void sqlite3WithDelete(sqlite3*,With*); + void sqlite3WithPush(Parse*, With*); +#else +#define sqlite3WithPush(x,y) #endif /* Declarations for functions in fkey.c. All of these are replaced by diff --git a/src/tokenize.c b/src/tokenize.c index 6e796ef82e..3fd4f78f7a 100644 --- a/src/tokenize.c +++ b/src/tokenize.c @@ -494,6 +494,8 @@ abort_parse: sqlite3DeleteTable(db, pParse->pNewTable); } + assert( pParse->pWith==0 || pParse->pWith->pOuter==0 ); + sqlite3WithDelete(db, pParse->pWith); sqlite3DeleteTrigger(db, pParse->pNewTrigger); for(i=pParse->nzVar-1; i>=0; i--) sqlite3DbFree(db, pParse->azVar[i]); sqlite3DbFree(db, pParse->azVar); diff --git a/test/pagerfault.test b/test/pagerfault.test index 796f531c37..1e57c93903 100644 --- a/test/pagerfault.test +++ b/test/pagerfault.test @@ -63,6 +63,7 @@ do_faultsim_test pagerfault-1 -prep { error "Database content appears incorrect" } } +finish_test #------------------------------------------------------------------------- # Test fault-injection while rolling back a hot-journal file with a diff --git a/test/with1.test b/test/with1.test index 80e879ada0..0b7810ebd3 100644 --- a/test/with1.test +++ b/test/with1.test @@ -37,4 +37,107 @@ do_execsql_test 1.4 { WITH x(a) AS ( SELECT * FROM t1) UPDATE t1 SET x = y; } {} +#-------------------------------------------------------------------------- + +do_execsql_test 2.1 { + DROP TABLE IF EXISTS t1; + CREATE TABLE t1(x); + INSERT INTO t1 VALUES(1); + INSERT INTO t1 VALUES(2); + WITH tmp AS ( SELECT * FROM t1 ) SELECT x FROM tmp; +} {1 2} + +do_execsql_test 2.2 { + WITH tmp(a) AS ( SELECT * FROM t1 ) SELECT a FROM tmp; +} {1 2} + +do_execsql_test 2.3 { + SELECT * FROM ( + WITH tmp(a) AS ( SELECT * FROM t1 ) SELECT a FROM tmp + ); +} {1 2} + +do_execsql_test 2.4 { + WITH tmp1(a) AS ( SELECT * FROM t1 ), + tmp2(x) AS ( SELECT * FROM tmp1) + SELECT * FROM tmp2; +} {1 2} + +do_execsql_test 2.5 { + WITH tmp2(x) AS ( SELECT * FROM tmp1), + tmp1(a) AS ( SELECT * FROM t1 ) + SELECT * FROM tmp2; +} {1 2} + +#------------------------------------------------------------------------- +do_catchsql_test 3.1 { + WITH tmp2(x) AS ( SELECT * FROM tmp1), + tmp1(a) AS ( SELECT * FROM tmp2 ) + SELECT * FROM tmp1; +} {1 {illegal recursive defininition in cte: tmp1}} + +do_catchsql_test 3.2 { + CREATE TABLE t2(x INTEGER); + WITH tmp(a) AS (SELECT * FROM t1), + tmp(a) AS (SELECT * FROM t1) + SELECT * FROM tmp; +} {1 {duplicate cte name: tmp}} + +do_execsql_test 3.3 { + CREATE TABLE t3(x); + CREATE TABLE t4(x); + + INSERT INTO t3 VALUES('T3'); + INSERT INTO t4 VALUES('T4'); + + WITH t3(a) AS (SELECT * FROM t4) + SELECT * FROM t3; +} {T4} + +do_execsql_test 3.4 { + WITH tmp AS ( SELECT * FROM t3 ), + tmp2 AS ( WITH tmp AS ( SELECT * FROM t4 ) SELECT * FROM tmp ) + SELECT * FROM tmp2; +} {T4} + +do_execsql_test 3.5 { + WITH tmp AS ( SELECT * FROM t3 ), + tmp2 AS ( WITH xxxx AS ( SELECT * FROM t4 ) SELECT * FROM tmp ) + SELECT * FROM tmp2; +} {T3} + +do_catchsql_test 3.6 { + WITH tmp AS ( SELECT * FROM t3 ), + SELECT * FROM tmp; +} {1 {near "SELECT": syntax error}} + +#------------------------------------------------------------------------- +do_execsql_test 4.1 { + DROP TABLE IF EXISTS t1; + CREATE TABLE t1(x); + INSERT INTO t1 VALUES(1); + INSERT INTO t1 VALUES(2); + INSERT INTO t1 VALUES(3); + INSERT INTO t1 VALUES(4); + + WITH dset AS ( SELECT 2 UNION ALL SELECT 4 ) + DELETE FROM t1 WHERE x IN dset; + SELECT * FROM t1; +} {1 3} + +do_execsql_test 4.2 { + WITH iset AS ( SELECT 2 UNION ALL SELECT 4 ) + INSERT INTO t1 SELECT * FROM iset; + SELECT * FROM t1; +} {1 3 2 4} + +do_execsql_test 4.3 { + WITH uset(a, b) AS ( SELECT 2, 8 UNION ALL SELECT 4, 9 ) + UPDATE t1 SET x = COALESCE( (SELECT b FROM uset WHERE a=x), x ); + SELECT * FROM t1; +} {1 3 8 9} + finish_test + + + diff --git a/test/withM.test b/test/withM.test new file mode 100644 index 0000000000..de46c85228 --- /dev/null +++ b/test/withM.test @@ -0,0 +1,40 @@ +# 2014 January 11 +# +# 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 WITH clause. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +source $testdir/malloc_common.tcl +set ::testprefix withM + +do_execsql_test 1.0 { + CREATE TABLE t1(x INTEGER, y INTEGER); + INSERT INTO t1 VALUES(123, 456); +} + +do_faultsim_test withM-1 -prep { + sqlite3 db test.db +} -body { + execsql { + WITH tmp AS ( SELECT * FROM t1 ) + SELECT * FROM tmp; + } +} -test { + faultsim_test_result {0 {123 456}} + db close +} + +finish_test + + + From a9f5c13d0c7fd6c718ea8c8811e7824eba78e6e9 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 13 Jan 2014 16:36:40 +0000 Subject: [PATCH 136/276] Fix some memory leaks and crashes that could follow an OOM condition during WITH clause parsing. FossilOrigin-Name: 8839850c44a8938883e493eacd752fa686e542df --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/build.c | 3 ++- src/parse.y | 9 ++++++++- test/withM.test | 18 +++++++++++++++++- 5 files changed, 36 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 010cb6fcfd..a1a39b1a65 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\scode\sto\shandle\snon-recursive\sCTEs\sin\sthe\ssame\sway\sas\sSQL\sviews. -D 2014-01-13T15:12:23.149 +C Fix\ssome\smemory\sleaks\sand\scrashes\sthat\scould\sfollow\san\sOOM\scondition\sduring\sWITH\sclause\sparsing. +D 2014-01-13T16:36:40.215 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -169,7 +169,7 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btree.c 11e29ef8cf16a42925fde036bcffbeffd9cc82df F src/btree.h a61ddebc78c66795a2b93181321a116746302cc9 F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0 -F src/build.c 1efdc65020e1f566383b66b30ccf730b4ef6f926 +F src/build.c 5a2daa6649640711ca60114046903be932348e52 F src/callback.c 174e3c8656bc29f91d710ab61550d16eea34be98 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd @@ -209,7 +209,7 @@ F src/os_unix.c 3a4dcb554d3c915075766162f28c3fd4cdb75968 F src/os_win.c 16eac0961603182ffc10c02b39fe830126538e07 F src/pager.c efa923693e958696eee69b205a20bfbc402c8480 F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428 -F src/parse.y b433588d7993d6475d9944be0fda2fb3df3cb138 +F src/parse.y e5c4a23f445cde4b30d50948df8f21bc586dd7a4 F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222 F src/pcache1.c 57fee9a9a617218f5037afbbe49b09da65bde56b @@ -1092,7 +1092,7 @@ F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c F test/win32lock.test 7a6bd73a5dcdee39b5bb93e92395e1773a194361 F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d F test/with1.test fb8409a35b1314be6e73a87597322f3369b59b2b -F test/withM.test 036349a9ec081fee8b1f72e71ad8a5a5b80f1674 +F test/withM.test ac3ec7ee0b33a02d0fa15da91214d97ddea64e34 F test/without_rowid1.test aaa26da19d543cd8d3d2d0e686dfa255556c15c8 F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99 F test/without_rowid3.test eac3d5c8a1924725b58503a368f2cbd24fd6c8a0 @@ -1150,7 +1150,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 704d3931b855562a619769955969d439c42ca406 -R fb5ad7a801e83802b92e3793bba4fd6c +P a26f399ba485e8127c276c5f103ec6c555e11734 +R 7e06730d3714a8aceb489d831c2bc18d U dan -Z 663a5542bd9dc2bb50ed6e3a07d040fb +Z 780f0749f7ee296248db4bd00ffb23e3 diff --git a/manifest.uuid b/manifest.uuid index 267d8a5499..6382ccbc9d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a26f399ba485e8127c276c5f103ec6c555e11734 \ No newline at end of file +8839850c44a8938883e493eacd752fa686e542df \ No newline at end of file diff --git a/src/build.c b/src/build.c index ca184766f9..c7d956a9b7 100644 --- a/src/build.c +++ b/src/build.c @@ -4234,12 +4234,13 @@ With *sqlite3WithAdd( pNew = sqlite3DbMallocZero(db, sizeof(*pWith)); } assert( zName!=0 || pNew==0 ); + assert( db->mallocFailed==0 || pNew==0 ); if( pNew==0 ){ - sqlite3WithDelete(db, pWith); sqlite3ExprListDelete(db, pArglist); sqlite3SelectDelete(db, pQuery); sqlite3DbFree(db, zName); + pNew = pWith; }else{ pNew->a[pNew->nCte].pSelect = pQuery; pNew->a[pNew->nCte].pCols = pArglist; diff --git a/src/parse.y b/src/parse.y index 1c6465e933..b1992f2415 100644 --- a/src/parse.y +++ b/src/parse.y @@ -412,7 +412,14 @@ cmd ::= select(X). { %type oneselect {Select*} %destructor oneselect {sqlite3SelectDelete(pParse->db, $$);} -select(A) ::= with(W) selectnowith(X). { if( X ) X->pWith = W; A = X; } +select(A) ::= with(W) selectnowith(X). { + if( X ){ + X->pWith = W; + }else{ + sqlite3WithDelete(pParse->db, W); + } + A = X; +} selectnowith(A) ::= oneselect(X). {A = X;} %ifndef SQLITE_OMIT_COMPOUND_SELECT diff --git a/test/withM.test b/test/withM.test index de46c85228..431cca187e 100644 --- a/test/withM.test +++ b/test/withM.test @@ -22,7 +22,7 @@ do_execsql_test 1.0 { INSERT INTO t1 VALUES(123, 456); } -do_faultsim_test withM-1 -prep { +do_faultsim_test withM-1.1 -prep { sqlite3 db test.db } -body { execsql { @@ -34,6 +34,22 @@ do_faultsim_test withM-1 -prep { db close } +do_faultsim_test withM-1.2 -prep { + sqlite3 db test.db +} -body { + execsql { + WITH w1 AS ( SELECT * FROM t1 ), + w2 AS ( + WITH w3 AS ( SELECT * FROM w1 ) + SELECT * FROM w3 + ) + SELECT * FROM w2; + } +} -test { + faultsim_test_result {0 {123 456}} + db close +} + finish_test From 859bc542c6ea1cbca600da863bce8c0207319611 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 13 Jan 2014 20:32:18 +0000 Subject: [PATCH 137/276] For statements of just an unadorned VALUES clause, assign column names as "columnN" for increasing whole numbers N. FossilOrigin-Name: 260587d2727f66d7fd65ef672ee46c92024f1d30 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/select.c | 5 +++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 03003dd0c5..f27dba4a8e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sLEMON,\slimit\sthe\ssize\sof\sthe\sgrammar\sfile\sto\s100MB.\s\sThis\sensures\sthat\nthe\sprogram\swill\snever\sexperience\sinteger\soverflow.\s\sTo\sbe\sdoubly\ssure,\nuse\scalloc()\sinstead\sof\smalloc()\swhen\sallocating\sarrays. -D 2014-01-11T12:52:25.201 +C For\sstatements\sof\sjust\san\sunadorned\sVALUES\sclause,\sassign\scolumn\snames\nas\s"columnN"\sfor\sincreasing\swhole\snumbers\sN. +D 2014-01-13T20:32:18.451 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -219,7 +219,7 @@ F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c 819bb090c9a348d17f69f136cad2bfa9ee9cbb41 +F src/select.c 996d8b88603edbd478aaa70b75d535a3ddea933d F src/shell.c a3541193d5fce37e91dad8ef46a9505aa7c9b344 F src/sqlite.h.in d94a8b89522f526ba711182ee161e06f8669bcc9 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e @@ -1148,7 +1148,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P cb5d1f83e0a33d546d4c0cb817ef1f8440d1f738 -R 28679f157b50c114aa03e50f74a7a104 +P 29ba458d849ad8864711cbe59fb10447a947e06a +R cfc0f0611de592f2675967818ec833a9 U drh -Z 608e7b6009060d93ac39bb2434b3c874 +Z 9bc6839af49500894d0d88a693460511 diff --git a/manifest.uuid b/manifest.uuid index d8b23d3f34..169cbd691e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -29ba458d849ad8864711cbe59fb10447a947e06a \ No newline at end of file +260587d2727f66d7fd65ef672ee46c92024f1d30 \ No newline at end of file diff --git a/src/select.c b/src/select.c index d075116749..5845897409 100644 --- a/src/select.c +++ b/src/select.c @@ -1363,8 +1363,9 @@ static void generateColumnNames( sqlite3VdbeSetColName(v, i, COLNAME_NAME, zCol, SQLITE_TRANSIENT); } }else{ - sqlite3VdbeSetColName(v, i, COLNAME_NAME, - sqlite3DbStrDup(db, pEList->a[i].zSpan), SQLITE_DYNAMIC); + const char *z = pEList->a[i].zSpan; + z = z==0 ? sqlite3MPrintf(db, "column%d", i+1) : sqlite3DbStrDup(db, z); + sqlite3VdbeSetColName(v, i, COLNAME_NAME, z, SQLITE_DYNAMIC); } } generateColumnTypes(pParse, pTabList, pEList); From c3d6ba49c6b78ca807a68ee6d0e403c073793540 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 13 Jan 2014 20:38:35 +0000 Subject: [PATCH 138/276] In the command-line shell, defend against a NULL-pointer dereference in the case where sqlite3_column_name() returns NULL (as might happen following an OOM error). FossilOrigin-Name: ac15455abcb9bdb88b53129348668a1442f6899f --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index f27dba4a8e..e68fe680fc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C For\sstatements\sof\sjust\san\sunadorned\sVALUES\sclause,\sassign\scolumn\snames\nas\s"columnN"\sfor\sincreasing\swhole\snumbers\sN. -D 2014-01-13T20:32:18.451 +C In\sthe\scommand-line\sshell,\sdefend\sagainst\sa\sNULL-pointer\sdereference\sin\sthe\ncase\swhere\ssqlite3_column_name()\sreturns\sNULL\s(as\smight\shappen\sfollowing\san\nOOM\serror). +D 2014-01-13T20:38:35.227 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -220,7 +220,7 @@ F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c 996d8b88603edbd478aaa70b75d535a3ddea933d -F src/shell.c a3541193d5fce37e91dad8ef46a9505aa7c9b344 +F src/shell.c 9f3bc02a658b8f61d2cbe60cfc482f660c1c6c48 F src/sqlite.h.in d94a8b89522f526ba711182ee161e06f8669bcc9 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc @@ -1148,7 +1148,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 29ba458d849ad8864711cbe59fb10447a947e06a -R cfc0f0611de592f2675967818ec833a9 +P 260587d2727f66d7fd65ef672ee46c92024f1d30 +R 10a3b37371baf3bb8cfb66250579708d U drh -Z 9bc6839af49500894d0d88a693460511 +Z b723d9f207dc3deb542b9214e1e7a09c diff --git a/manifest.uuid b/manifest.uuid index 169cbd691e..ffa41c2bbd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -260587d2727f66d7fd65ef672ee46c92024f1d30 \ No newline at end of file +ac15455abcb9bdb88b53129348668a1442f6899f \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 00cff6a8e5..b5ce90208c 100644 --- a/src/shell.c +++ b/src/shell.c @@ -597,6 +597,7 @@ static void output_c_string(FILE *out, const char *z){ */ static void output_html_string(FILE *out, const char *z){ int i; + if( z==0 ) z = ""; while( *z ){ for(i=0; z[i] && z[i]!='<' From 866b53eb5a4efabf6a958cbf541bb949b4439b1e Mon Sep 17 00:00:00 2001 From: mistachkin Date: Tue, 14 Jan 2014 10:17:02 +0000 Subject: [PATCH 139/276] For the Win32 VFS, defining winShmMutexHeld should be controlled by NDEBUG, not SQLITE_DEBUG. FossilOrigin-Name: 1e131094b522103a0829f72193b067b04e42ce82 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/os_win.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index e68fe680fc..9bf7f9b689 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\scommand-line\sshell,\sdefend\sagainst\sa\sNULL-pointer\sdereference\sin\sthe\ncase\swhere\ssqlite3_column_name()\sreturns\sNULL\s(as\smight\shappen\sfollowing\san\nOOM\serror). -D 2014-01-13T20:38:35.227 +C For\sthe\sWin32\sVFS,\sdefining\swinShmMutexHeld\sshould\sbe\scontrolled\sby\sNDEBUG,\snot\sSQLITE_DEBUG. +D 2014-01-14T10:17:02.428 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -206,7 +206,7 @@ F src/os.c 1b147e4cf7cc39e618115c14a086aed44bc91ace F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_unix.c 3a4dcb554d3c915075766162f28c3fd4cdb75968 -F src/os_win.c 16eac0961603182ffc10c02b39fe830126538e07 +F src/os_win.c 1b21af72c5fa6f9e519a5fcab33e80d182b1aedb F src/pager.c efa923693e958696eee69b205a20bfbc402c8480 F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428 F src/parse.y 3c5384533a8bfce5abd256cc9cb2c38bec05ad61 @@ -1148,7 +1148,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 260587d2727f66d7fd65ef672ee46c92024f1d30 -R 10a3b37371baf3bb8cfb66250579708d -U drh -Z b723d9f207dc3deb542b9214e1e7a09c +P ac15455abcb9bdb88b53129348668a1442f6899f +R 455bba3b3836db70e207929cfbe74107 +U mistachkin +Z 3f9ab398a4d1da777d1daf83b531e5c4 diff --git a/manifest.uuid b/manifest.uuid index ffa41c2bbd..727b07185c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ac15455abcb9bdb88b53129348668a1442f6899f \ No newline at end of file +1e131094b522103a0829f72193b067b04e42ce82 \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index faa60569c9..4fb4f02703 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -3224,7 +3224,7 @@ static void winShmEnterMutex(void){ static void winShmLeaveMutex(void){ sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); } -#ifdef SQLITE_DEBUG +#ifndef NDEBUG static int winShmMutexHeld(void) { return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); } From 7a429658d7e38e0ff52a9f0591a17fd9cb71929d Mon Sep 17 00:00:00 2001 From: mistachkin Date: Tue, 14 Jan 2014 10:17:21 +0000 Subject: [PATCH 140/276] Fix harmless compiler warning in LEMON. FossilOrigin-Name: f61a70589ac7e05008a362bd9d5b7bde5d07a758 --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/lemon.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 9bf7f9b689..b7d3993e06 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C For\sthe\sWin32\sVFS,\sdefining\swinShmMutexHeld\sshould\sbe\scontrolled\sby\sNDEBUG,\snot\sSQLITE_DEBUG. -D 2014-01-14T10:17:02.428 +C Fix\sharmless\scompiler\swarning\sin\sLEMON. +D 2014-01-14T10:17:21.693 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -1109,7 +1109,7 @@ F tool/fragck.tcl 5265a95126abcf6ab357f7efa544787e5963f439 F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4 F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce -F tool/lemon.c 6842b2e7af12835f9f6e55808a0b1861cd0696fe +F tool/lemon.c 07aba6270d5a5016ba8107b09e431eea4ecdc123 F tool/lempar.c 01ca97f87610d1dac6d8cd96ab109ab1130e76dc F tool/logest.c 7ad625cac3d54012b27d468b7af6612f78b9ba75 F tool/mkautoconfamal.sh f8d8dbf7d62f409ebed5134998bf5b51d7266383 @@ -1148,7 +1148,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P ac15455abcb9bdb88b53129348668a1442f6899f -R 455bba3b3836db70e207929cfbe74107 +P 1e131094b522103a0829f72193b067b04e42ce82 +R fe4a4148cfbc4d588ee2679597656da4 U mistachkin -Z 3f9ab398a4d1da777d1daf83b531e5c4 +Z d589f5ec7c09b4ac8c97497c20166016 diff --git a/manifest.uuid b/manifest.uuid index 727b07185c..d14b8afba5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1e131094b522103a0829f72193b067b04e42ce82 \ No newline at end of file +f61a70589ac7e05008a362bd9d5b7bde5d07a758 \ No newline at end of file diff --git a/tool/lemon.c b/tool/lemon.c index 8dca20c451..d7179ad423 100644 --- a/tool/lemon.c +++ b/tool/lemon.c @@ -83,7 +83,7 @@ static void lemon_addtext( zBuf[*pnUsed] = 0; } static int lemon_vsprintf(char *str, const char *zFormat, va_list ap){ - int i, j, k, c, size; + int i, j, k, c; int nUsed = 0; const char *z; char zTemp[50]; From 8ce7184bc26b1330817a68bca751beac4712cbb0 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 14 Jan 2014 20:14:09 +0000 Subject: [PATCH 141/276] Add code to handle recursive CTEs. FossilOrigin-Name: a5c2a54a07d35166911abc792008c05dea897742 --- manifest | 24 +++---- manifest.uuid | 2 +- src/btree.c | 6 +- src/expr.c | 1 + src/select.c | 176 +++++++++++++++++++++++++++++++++++++++++++----- src/sqliteInt.h | 6 +- src/vdbe.c | 47 +++++++++++++ src/where.c | 6 +- test/with1.test | 27 ++++++++ 9 files changed, 262 insertions(+), 33 deletions(-) diff --git a/manifest b/manifest index a1a39b1a65..56fe478fb2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\ssome\smemory\sleaks\sand\scrashes\sthat\scould\sfollow\san\sOOM\scondition\sduring\sWITH\sclause\sparsing. -D 2014-01-13T16:36:40.215 +C Add\scode\sto\shandle\srecursive\sCTEs. +D 2014-01-14T20:14:09.053 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,7 +166,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c a729e63cf5cd1829507cb7b8e89f99b95141bb53 F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c 11e29ef8cf16a42925fde036bcffbeffd9cc82df +F src/btree.c c15e1722696b66c4029c487acfb830b0985bf142 F src/btree.h a61ddebc78c66795a2b93181321a116746302cc9 F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0 F src/build.c 5a2daa6649640711ca60114046903be932348e52 @@ -175,7 +175,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 F src/delete.c 91e1321021db5dc266360531b8b6550009d771ff -F src/expr.c de86bf987c532ec9d63fb1bf8a6eb6ec2cf5ba69 +F src/expr.c fee4b54fdcf5a979e6f5012da3dfb084ac5d3aac F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 2ab0f5384b70594468ef3ac5c7ed8ca24bfd17d5 F src/func.c 6325ac2ec10833ccf4d5c36d323709221d37ea19 @@ -219,12 +219,12 @@ F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c 9dc9177bfb9278a603e3835e828ff60ec68fba6f +F src/select.c 0f7779b0c1c317dcac0f65f695d036030c16775f F src/shell.c a3541193d5fce37e91dad8ef46a9505aa7c9b344 F src/sqlite.h.in d94a8b89522f526ba711182ee161e06f8669bcc9 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h a350bcf6d62204b6b4720ce1922c95a575a0b5ad +F src/sqliteInt.h fc7b2516260c4e14bd4342cd9ed47f3d0ca27cc5 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -280,7 +280,7 @@ F src/update.c c2706a6eb232a96345c35b7e1e75a188e26812bb F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c e71f19b272f05c8695cf747b4bac1732685f9e5c F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c b110887e415b5d2af58c2374c4dfdcf774c5d46c +F src/vdbe.c 9b918126afb9a7b7ad232db7453680c7ef5821a4 F src/vdbe.h e6c4c610fcabad4fa80ebb1efc6822a9367e2b26 F src/vdbeInt.h 42db251e9f863401ff847b90d5fe1614c89a6a56 F src/vdbeapi.c ce4e68ea4842cc6081046f533d088dcf01d247ad @@ -293,7 +293,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c e9e593d5bb798c3e67fc3893dfe7055c9e7d8d74 -F src/where.c 18f07fd0fd116a5880773c689eb7cd8e60175107 +F src/where.c 830b42f452cfbc4e17582f6c1d388e15b379b833 F src/whereInt.h 96a75c61f1d2b9d4a8e4bb17d89deb0cf7cba358 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1091,7 +1091,7 @@ F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c F test/win32lock.test 7a6bd73a5dcdee39b5bb93e92395e1773a194361 F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d -F test/with1.test fb8409a35b1314be6e73a87597322f3369b59b2b +F test/with1.test 12a6661eabcc9ae299020f7b4197a75a9c084748 F test/withM.test ac3ec7ee0b33a02d0fa15da91214d97ddea64e34 F test/without_rowid1.test aaa26da19d543cd8d3d2d0e686dfa255556c15c8 F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99 @@ -1150,7 +1150,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P a26f399ba485e8127c276c5f103ec6c555e11734 -R 7e06730d3714a8aceb489d831c2bc18d +P 8839850c44a8938883e493eacd752fa686e542df +R 1d5d9f6beb143e76aa04b4bf9953f5da U dan -Z 780f0749f7ee296248db4bd00ffb23e3 +Z 1616366ca894deb1473f9b1eb1563ebc diff --git a/manifest.uuid b/manifest.uuid index 6382ccbc9d..f994f09e97 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8839850c44a8938883e493eacd752fa686e542df \ No newline at end of file +a5c2a54a07d35166911abc792008c05dea897742 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 20bed057e1..e28a97c846 100644 --- a/src/btree.c +++ b/src/btree.c @@ -7350,6 +7350,7 @@ static int clearDatabasePage( int rc; unsigned char *pCell; int i; + int hdr; assert( sqlite3_mutex_held(pBt->mutex) ); if( pgno>btreePagecount(pBt) ){ @@ -7358,6 +7359,7 @@ static int clearDatabasePage( rc = getAndInitPage(pBt, pgno, &pPage, 0); if( rc ) return rc; + hdr = pPage->hdrOffset; for(i=0; inCell; i++){ pCell = findCell(pPage, i); if( !pPage->leaf ){ @@ -7368,7 +7370,7 @@ static int clearDatabasePage( if( rc ) goto cleardatabasepage_out; } if( !pPage->leaf ){ - rc = clearDatabasePage(pBt, get4byte(&pPage->aData[8]), 1, pnChange); + rc = clearDatabasePage(pBt, get4byte(&pPage->aData[hdr+8]), 1, pnChange); if( rc ) goto cleardatabasepage_out; }else if( pnChange ){ assert( pPage->intKey ); @@ -7377,7 +7379,7 @@ static int clearDatabasePage( if( freePageFlag ){ freePage(pPage, &rc); }else if( (rc = sqlite3PagerWrite(pPage->pDbPage))==0 ){ - zeroPage(pPage, pPage->aData[0] | PTF_LEAF); + zeroPage(pPage, pPage->aData[hdr] | PTF_LEAF); } cleardatabasepage_out: diff --git a/src/expr.c b/src/expr.c index d0ea280029..e271e46796 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1055,6 +1055,7 @@ Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){ pNew->addrOpenEphm[1] = -1; pNew->addrOpenEphm[2] = -1; pNew->pWith = withDup(db, p->pWith); + pNew->pRecurse = p->pRecurse; return pNew; } #else diff --git a/src/select.c b/src/select.c index b054489b00..0db4b01807 100644 --- a/src/select.c +++ b/src/select.c @@ -691,12 +691,26 @@ static void selectInnerLoop( /* Store the result as data using a unique key. */ + case SRT_DistTable: case SRT_Table: case SRT_EphemTab: { int r1 = sqlite3GetTempReg(pParse); testcase( eDest==SRT_Table ); testcase( eDest==SRT_EphemTab ); sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nColumn, r1); +#ifndef SQLITE_OMIT_CTE + if( eDest==SRT_DistTable ){ + /* If the destination is DistTable, then cursor (iParm+1) is open + ** on an ephemeral index. If the current row is already present + ** in the index, do not write it to the output. If not, add the + ** current row to the index and proceed with writing it to the + ** output table as well. */ + int addr = sqlite3VdbeCurrentAddr(v) + 4; + sqlite3VdbeAddOp4Int(v, OP_Found, iParm+1, addr, r1, 0); + sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm+1, r1); + assert( pOrderBy==0 ); + } +#endif if( pOrderBy ){ pushOntoSorter(pParse, pOrderBy, p, r1); }else{ @@ -1729,6 +1743,7 @@ static int multiSelect( ** the last (right-most) SELECT in the series may have an ORDER BY or LIMIT. */ assert( p && p->pPrior ); /* Calling function guarantees this much */ + assert( p->pRecurse==0 || p->op==TK_ALL || p->op==TK_UNION ); db = pParse->db; pPrior = p->pPrior; assert( pPrior->pRightmost!=pPrior ); @@ -1774,12 +1789,82 @@ static int multiSelect( goto multi_select_end; } + /* If this is a recursive query, check that there is no ORDER BY or + ** LIMIT clause. Neither of these are supported. */ + assert( p->pOffset==0 || p->pLimit ); + if( p->pRecurse && (p->pOrderBy || p->pLimit) ){ + sqlite3ErrorMsg(pParse, "%s in a recursive query is not allowed", + p->pOrderBy ? "ORDER BY" : "LIMIT" + ); + goto multi_select_end; + } + /* Compound SELECTs that have an ORDER BY clause are handled separately. */ if( p->pOrderBy ){ return multiSelectOrderBy(pParse, p, pDest); } +#ifndef SQLITE_OMIT_CTE + if( p->pRecurse ){ + int nCol = p->pEList->nExpr; + int addrNext; + int addrSwap; + int iCont, iBreak; + int tmp1, tmp2; /* Cursors used to access temporary tables */ + int tmp3 = 0; /* To ensure unique results if UNION */ + int eDest = SRT_Table; + SelectDest tmp2dest; + + iBreak = sqlite3VdbeMakeLabel(v); + iCont = sqlite3VdbeMakeLabel(v); + + tmp1 = pParse->nTab++; + tmp2 = pParse->nTab++; + if( p->op==TK_UNION ){ + eDest = SRT_DistTable; + tmp3 = pParse->nTab++; + } + sqlite3SelectDestInit(&tmp2dest, eDest, tmp2); + + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tmp1, nCol); + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tmp2, nCol); + if( tmp3 ){ + p->addrOpenEphm[0] = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tmp3, 0); + p->selFlags |= SF_UsesEphemeral; + } + + /* Store the results of the initial SELECT in tmp2. */ + rc = sqlite3Select(pParse, pPrior, &tmp2dest); + if( rc ) goto multi_select_end; + + /* Clear tmp1. Then switch the contents of tmp1 and tmp2. Then teturn + ** the contents of tmp1 to the caller. Or, if tmp1 is empty at this + ** point, the recursive query has finished - jump to address iBreak. */ + addrSwap = sqlite3VdbeAddOp2(v, OP_SwapCursors, tmp1, tmp2); + sqlite3VdbeAddOp2(v, OP_Rewind, tmp1, iBreak); + addrNext = sqlite3VdbeCurrentAddr(v); + selectInnerLoop(pParse, p, p->pEList, tmp1, p->pEList->nExpr, + 0, 0, &dest, iCont, iBreak); + sqlite3VdbeResolveLabel(v, iCont); + sqlite3VdbeAddOp2(v, OP_Next, tmp1, addrNext); + + /* Execute the recursive SELECT. Store the results in tmp2. While this + ** SELECT is running, the contents of tmp1 are read by recursive + ** references to the current CTE. */ + p->pPrior = 0; + p->pRecurse->tnum = tmp1; + p->pRecurse->tabFlags |= TF_Recursive; + rc = sqlite3Select(pParse, p, &tmp2dest); + p->pRecurse->tabFlags &= ~TF_Recursive; + p->pPrior = pPrior; + if( rc ) goto multi_select_end; + + sqlite3VdbeAddOp2(v, OP_Goto, 0, addrSwap); + sqlite3VdbeResolveLabel(v, iBreak); + }else +#endif + /* Generate code for the left and right SELECT statements. */ switch( p->op ){ @@ -3449,6 +3534,73 @@ static void ctePop(Parse *pParse, struct Cte *pCte){ } } +static int withExpand( + Walker *pWalker, + struct SrcList_item *pFrom, + struct Cte *pCte +){ + Table *pTab; + Parse *pParse = pWalker->pParse; + sqlite3 *db = pParse->db; + + assert( pFrom->pSelect==0 ); + assert( pFrom->pTab==0 ); + + if( pCte==pParse->pCte && (pTab = pCte->pTab) ){ + /* This is the recursive part of a recursive CTE */ + pFrom->pTab = pTab; + pTab->nRef++; + }else{ + ExprList *pEList; + Select *pSel; + int bRecursive; + + pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table)); + if( pTab==0 ) return WRC_Abort; + pTab->nRef = 1; + pTab->zName = sqlite3MPrintf(db, "sqlite_sq_%p", (void*)pTab); + pTab->iPKey = -1; + pTab->nRowEst = 1048576; + pTab->tabFlags |= TF_Ephemeral; + pFrom->pSelect = sqlite3SelectDup(db, pCte->pSelect, 0); + if( db->mallocFailed ) return SQLITE_NOMEM; + assert( pFrom->pSelect ); + + if( ctePush(pParse, pCte) ) return WRC_Abort; + pSel = pFrom->pSelect; + bRecursive = (pSel->op==TK_ALL || pSel->op==TK_UNION); + if( bRecursive ){ + assert( pSel->pPrior ); + sqlite3WalkSelect(pWalker, pSel->pPrior); + }else{ + sqlite3WalkSelect(pWalker, pSel); + } + + if( pCte->pCols ){ + pEList = pCte->pCols; + }else{ + Select *pLeft; + for(pLeft=pSel; pLeft->pPrior; pLeft=pLeft->pPrior); + pEList = pLeft->pEList; + } + selectColumnsFromExprList(pParse, pEList, &pTab->nCol, &pTab->aCol); + + if( bRecursive ){ + int nRef = pTab->nRef; + pCte->pTab = pTab; + sqlite3WalkSelect(pWalker, pSel); + pCte->pTab = 0; + if( pTab->nRef > nRef){ + pSel->pRecurse = pTab; + assert( pTab->tnum==0 ); + } + } + + ctePop(pParse, pCte); + } + + return SQLITE_OK; +} /* ** This routine is a Walker callback for "expanding" a SELECT statement. @@ -3515,31 +3667,22 @@ static int selectExpander(Walker *pWalker, Select *p){ #ifndef SQLITE_OMIT_CTE pCte = searchWith(pParse, pFrom); if( pCte ){ - pFrom->pSelect = sqlite3SelectDup(db, pCte->pSelect, 0); - if( pFrom->pSelect==0 ) return WRC_Abort; - } + if( withExpand(pWalker, pFrom, pCte) ) return WRC_Abort; + }else #endif - if( pFrom->zName==0 || pCte ){ + if( pFrom->zName==0 ){ #ifndef SQLITE_OMIT_SUBQUERY - ExprList *pEList; Select *pSel = pFrom->pSelect; /* A sub-query in the FROM clause of a SELECT */ assert( pSel!=0 ); assert( pFrom->pTab==0 ); - if( ctePush(pParse, pCte) ) return WRC_Abort; sqlite3WalkSelect(pWalker, pSel); - ctePop(pParse, pCte); pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table)); if( pTab==0 ) return WRC_Abort; pTab->nRef = 1; pTab->zName = sqlite3MPrintf(db, "sqlite_sq_%p", (void*)pTab); while( pSel->pPrior ){ pSel = pSel->pPrior; } - if( pCte && pCte->pCols ){ - pEList = pCte->pCols; - }else{ - pEList = pSel->pEList; - } - selectColumnsFromExprList(pParse, pEList, &pTab->nCol, &pTab->aCol); + selectColumnsFromExprList(pParse, pSel->pEList, &pTab->nCol, &pTab->aCol); pTab->iPKey = -1; pTab->nRowEst = 1048576; pTab->tabFlags |= TF_Ephemeral; @@ -3831,9 +3974,10 @@ static int selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){ if( ALWAYS(pTab!=0) && (pTab->tabFlags & TF_Ephemeral)!=0 ){ /* A sub-query in the FROM clause of a SELECT */ Select *pSel = pFrom->pSelect; - assert( pSel ); - while( pSel->pPrior ) pSel = pSel->pPrior; - selectAddColumnTypeAndCollation(pParse, pTab, pSel); + if( pSel ){ + while( pSel->pPrior ) pSel = pSel->pPrior; + selectAddColumnTypeAndCollation(pParse, pTab, pSel); + } } } } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 6bd65592b7..c7f0609ba1 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1429,7 +1429,7 @@ struct Table { }; /* -** Allowed values for Tabe.tabFlags. +** Allowed values for Table.tabFlags. */ #define TF_Readonly 0x01 /* Read-only system table */ #define TF_Ephemeral 0x02 /* An ephemeral table */ @@ -1437,6 +1437,7 @@ struct Table { #define TF_Autoincrement 0x08 /* Integer primary key is autoincrement */ #define TF_Virtual 0x10 /* Is a virtual table */ #define TF_WithoutRowid 0x20 /* No rowid used. PRIMARY KEY is the key */ +#define TF_Recursive 0x40 /* Recursive reference within CTE */ /* @@ -2129,6 +2130,7 @@ struct NameContext { */ struct Select { ExprList *pEList; /* The fields of the result */ + Table *pRecurse; /* Non-NULL for the recursive part of recursive CTE */ u8 op; /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */ u16 selFlags; /* Various SF_* values */ int iLimit, iOffset; /* Memory registers holding LIMIT & OFFSET counters */ @@ -2182,6 +2184,7 @@ struct Select { #define SRT_Table 8 /* Store result as data with an automatic rowid */ #define SRT_EphemTab 9 /* Create transient tab and store like SRT_Table */ #define SRT_Coroutine 10 /* Generate a single row of result */ +#define SRT_DistTable 11 /* Like SRT_TABLE, but unique results only */ /* ** An instance of this object describes where to put of the results of @@ -2647,6 +2650,7 @@ struct With { ExprList *pCols; /* List of explicit column names, or NULL */ Select *pSelect; /* The contents of the CTE */ struct Cte *pOuterCte; + Table *pTab; } a[1]; }; diff --git a/src/vdbe.c b/src/vdbe.c index 286bc45ba3..ffb4dd19bd 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3369,6 +3369,53 @@ case OP_OpenEphemeral: { break; } +/* Opcode: OpenEphreader P1 P2 * * * +** +** P2 is a cursor opened by the OpenEphemeral opcode. This opcode opens +** a new read-only cursor named P1 that accesses the same epheremal table +** as P2. +*/ +case OP_OpenEphreader: { + VdbeCursor *pEph; + VdbeCursor *pCx; + Pgno pgno; + + pEph = p->apCsr[pOp->p2]; + pCx = allocateCursor(p, pOp->p1, pEph->nField, -1, 1); + if( pCx==0 ) goto no_mem; + pCx->nullRow = 1; + pCx->pKeyInfo = pEph->pKeyInfo; + pCx->isTable = pEph->isTable; + pCx->isOrdered = pEph->isOrdered; + pgno = MASTER_ROOT + !pCx->isTable; + rc = sqlite3BtreeCursor(pEph->pBt, pgno, 0, pCx->pKeyInfo, pCx->pCursor); + break; +} + +/* Opcode: SwapCursors P1 P2 * * * +** +** Parameters P1 and P2 are both cursors opened by the OpenEphemeral +** opcode. This opcode deletes the contents of epheremal table P1, +** then renames P2 to P1 and P1 to P2. In other words, following this +** opcode cursor P2 is open on an empty table and P1 is open on the +** table that was initially accessed by P2. +*/ +case OP_SwapCursors: { + Mem tmp; + VdbeCursor *pTmp; + + tmp = p->aMem[p->nMem - pOp->p1]; + p->aMem[p->nMem - pOp->p1] = p->aMem[p->nMem - pOp->p2]; + p->aMem[p->nMem - pOp->p2] = tmp; + + pTmp = p->apCsr[pOp->p1]; + p->apCsr[pOp->p1] = p->apCsr[pOp->p2]; + p->apCsr[pOp->p2] = pTmp; + + rc = sqlite3BtreeClearTable(pTmp->pBt, MASTER_ROOT + !pTmp->isTable, 0); + break; +} + /* Opcode: SorterOpen P1 * * P4 * ** ** This opcode works like OP_OpenEphemeral except that it opens diff --git a/src/where.c b/src/where.c index d5444a6054..8827faa839 100644 --- a/src/where.c +++ b/src/where.c @@ -5653,7 +5653,11 @@ WhereInfo *sqlite3WhereBegin( iDb = sqlite3SchemaToIndex(db, pTab->pSchema); pLoop = pLevel->pWLoop; if( (pTab->tabFlags & TF_Ephemeral)!=0 || pTab->pSelect ){ - /* Do nothing */ + if( pTab->tabFlags & TF_Recursive ){ + int iCur = pTabItem->iCursor; + sqlite3VdbeAddOp2(v, OP_OpenEphreader, iCur, pTab->tnum); + } + /* Otherwise do nothing */ }else #ifndef SQLITE_OMIT_VIRTUALTABLE if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 ){ diff --git a/test/with1.test b/test/with1.test index 0b7810ebd3..3dd8c47ea2 100644 --- a/test/with1.test +++ b/test/with1.test @@ -137,6 +137,33 @@ do_execsql_test 4.3 { SELECT * FROM t1; } {1 3 8 9} +#------------------------------------------------------------------------- +# +do_execsql_test 5.1 { + WITH i(x) AS ( VALUES(1) UNION ALL SELECT x+1 FROM i) + SELECT x FROM i LIMIT 10; +} {1 2 3 4 5 6 7 8 9 10} + +do_catchsql_test 5.2 { + WITH i(x) AS ( VALUES(1) UNION ALL SELECT x+1 FROM i ORDER BY 1) + SELECT x FROM i LIMIT 10; +} {1 {ORDER BY in a recursive query is not allowed}} + +do_catchsql_test 5.3 { + WITH i(x) AS ( VALUES(1) UNION ALL SELECT x+1 FROM i LIMIT 10 ) + SELECT x FROM i LIMIT 10; +} {1 {LIMIT in a recursive query is not allowed}} + +do_execsql_test 5.4 { + WITH i(x) AS ( VALUES(1) UNION ALL SELECT (x+1)%10 FROM i) + SELECT x FROM i LIMIT 20; +} {1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0} + +do_execsql_test 5.5 { + WITH i(x) AS ( VALUES(1) UNION SELECT (x+1)%10 FROM i) + SELECT x FROM i LIMIT 20; +} {1 2 3 4 5 6 7 8 9 0} + finish_test From f9db522fee74370e6994fe2c323da2412a097cf9 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 15 Jan 2014 02:40:11 +0000 Subject: [PATCH 142/276] Use the user-supplied table name in WITH RECURSIVE tables as the internal name of the table and the name of the table in VDBE comments. FossilOrigin-Name: a29330238be6366444269a0b1b328475b2d01ae2 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/select.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 56fe478fb2..3d4a6ad897 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\scode\sto\shandle\srecursive\sCTEs. -D 2014-01-14T20:14:09.053 +C Use\sthe\suser-supplied\stable\sname\sin\sWITH\sRECURSIVE\stables\sas\sthe\sinternal\nname\sof\sthe\stable\sand\sthe\sname\sof\sthe\stable\sin\sVDBE\scomments. +D 2014-01-15T02:40:11.688 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -219,7 +219,7 @@ F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c 0f7779b0c1c317dcac0f65f695d036030c16775f +F src/select.c 3d93e3b4736a95507540b708106c1db6d01c41a8 F src/shell.c a3541193d5fce37e91dad8ef46a9505aa7c9b344 F src/sqlite.h.in d94a8b89522f526ba711182ee161e06f8669bcc9 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e @@ -1150,7 +1150,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 8839850c44a8938883e493eacd752fa686e542df -R 1d5d9f6beb143e76aa04b4bf9953f5da -U dan -Z 1616366ca894deb1473f9b1eb1563ebc +P a5c2a54a07d35166911abc792008c05dea897742 +R cc1fc541222b981017b72fc3aee14bde +U drh +Z dcce44e449a071e984cc874f0c8e1e54 diff --git a/manifest.uuid b/manifest.uuid index f994f09e97..1be3de1308 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a5c2a54a07d35166911abc792008c05dea897742 \ No newline at end of file +a29330238be6366444269a0b1b328475b2d01ae2 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 0db4b01807..22eaf1b1cb 100644 --- a/src/select.c +++ b/src/select.c @@ -3558,7 +3558,7 @@ static int withExpand( pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table)); if( pTab==0 ) return WRC_Abort; pTab->nRef = 1; - pTab->zName = sqlite3MPrintf(db, "sqlite_sq_%p", (void*)pTab); + pTab->zName = sqlite3MPrintf(db, "%s", pCte->zName); pTab->iPKey = -1; pTab->nRowEst = 1048576; pTab->tabFlags |= TF_Ephemeral; From bfe31e7f80a97601c4d68e9dbc359493669ab7e8 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 15 Jan 2014 14:17:31 +0000 Subject: [PATCH 143/276] Disable the flattening optimization if the sub-query is a recursive CTE. FossilOrigin-Name: 9472f6d820a7fb233936d9b8f7a39c9d4c4d6d73 --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/expr.c | 10 ++++++++-- src/parse.y | 3 ++- src/select.c | 3 +++ test/with1.test | 44 ++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 68 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 3d4a6ad897..1f819eb388 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Use\sthe\suser-supplied\stable\sname\sin\sWITH\sRECURSIVE\stables\sas\sthe\sinternal\nname\sof\sthe\stable\sand\sthe\sname\sof\sthe\stable\sin\sVDBE\scomments. -D 2014-01-15T02:40:11.688 +C Disable\sthe\sflattening\soptimization\sif\sthe\ssub-query\sis\sa\srecursive\sCTE. +D 2014-01-15T14:17:31.048 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -175,7 +175,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 F src/delete.c 91e1321021db5dc266360531b8b6550009d771ff -F src/expr.c fee4b54fdcf5a979e6f5012da3dfb084ac5d3aac +F src/expr.c 2277282d8938b8eab782e4f5111ca0cd492529b3 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 2ab0f5384b70594468ef3ac5c7ed8ca24bfd17d5 F src/func.c 6325ac2ec10833ccf4d5c36d323709221d37ea19 @@ -209,7 +209,7 @@ F src/os_unix.c 3a4dcb554d3c915075766162f28c3fd4cdb75968 F src/os_win.c 16eac0961603182ffc10c02b39fe830126538e07 F src/pager.c efa923693e958696eee69b205a20bfbc402c8480 F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428 -F src/parse.y e5c4a23f445cde4b30d50948df8f21bc586dd7a4 +F src/parse.y 824eeb752c026b551bda2b66163889d7664b42e4 F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222 F src/pcache1.c 57fee9a9a617218f5037afbbe49b09da65bde56b @@ -219,7 +219,7 @@ F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c 3d93e3b4736a95507540b708106c1db6d01c41a8 +F src/select.c 51c74176eb949d1ff5797735acedd6c08d19450a F src/shell.c a3541193d5fce37e91dad8ef46a9505aa7c9b344 F src/sqlite.h.in d94a8b89522f526ba711182ee161e06f8669bcc9 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e @@ -1091,7 +1091,7 @@ F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c F test/win32lock.test 7a6bd73a5dcdee39b5bb93e92395e1773a194361 F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d -F test/with1.test 12a6661eabcc9ae299020f7b4197a75a9c084748 +F test/with1.test 77739a9e5e88873e7655634297d9dc4360334f9a F test/withM.test ac3ec7ee0b33a02d0fa15da91214d97ddea64e34 F test/without_rowid1.test aaa26da19d543cd8d3d2d0e686dfa255556c15c8 F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99 @@ -1150,7 +1150,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P a5c2a54a07d35166911abc792008c05dea897742 -R cc1fc541222b981017b72fc3aee14bde -U drh -Z dcce44e449a071e984cc874f0c8e1e54 +P a29330238be6366444269a0b1b328475b2d01ae2 +R baaf1d38169072daf03c7e43cc689f3b +U dan +Z e4d26324d0deafbbb1cfbafb0f22db9f diff --git a/manifest.uuid b/manifest.uuid index 1be3de1308..493b55e692 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a29330238be6366444269a0b1b328475b2d01ae2 \ No newline at end of file +9472f6d820a7fb233936d9b8f7a39c9d4c4d6d73 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index e271e46796..4da9d6263c 100644 --- a/src/expr.c +++ b/src/expr.c @@ -895,7 +895,12 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){ return pNew; } -With *withDup(sqlite3 *db, With *p){ +/* +** Create and return a deep copy of the object passed as the second +** argument. If an OOM condition is encountered, NULL is returned +** and the db->mallocFailed flag set. +*/ +static With *withDup(sqlite3 *db, With *p){ With *pRet = 0; if( p ){ int nByte = sizeof(*p) + sizeof(p->a[0]) * (p->nCte-1); @@ -1055,7 +1060,8 @@ Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){ pNew->addrOpenEphm[1] = -1; pNew->addrOpenEphm[2] = -1; pNew->pWith = withDup(db, p->pWith); - pNew->pRecurse = p->pRecurse; + assert( p->pRecurse==0 ); + pNew->pRecurse = 0; return pNew; } #else diff --git a/src/parse.y b/src/parse.y index b1992f2415..937669eb5c 100644 --- a/src/parse.y +++ b/src/parse.y @@ -684,8 +684,9 @@ where_opt(A) ::= WHERE expr(X). {A = X.pExpr;} ////////////////////////// The UPDATE command //////////////////////////////// // %ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT -cmd ::= with UPDATE orconf(R) fullname(X) indexed_opt(I) SET setlist(Y) +cmd ::= with(C) UPDATE orconf(R) fullname(X) indexed_opt(I) SET setlist(Y) where_opt(W) orderby_opt(O) limit_opt(L). { + sqlite3WithPush(pParse, C); sqlite3SrcListIndexedBy(pParse, X, &I); sqlite3ExprListCheckLength(pParse,Y,"set list"); W = sqlite3LimitWhere(pParse, X, W, O, L.pLimit, L.pOffset, "UPDATE"); diff --git a/src/select.c b/src/select.c index 22eaf1b1cb..35edcbb03c 100644 --- a/src/select.c +++ b/src/select.c @@ -2844,6 +2844,8 @@ static void substSelect( ** ** Flattening is only attempted if all of the following are true: ** +** (0) The subquery is not a recursive CTE. +** ** (1) The subquery and the outer query do not both use aggregates. ** ** (2) The subquery is not an aggregate or the outer query is not a join. @@ -2968,6 +2970,7 @@ static int flattenSubquery( iParent = pSubitem->iCursor; pSub = pSubitem->pSelect; assert( pSub!=0 ); + if( pSub->pRecurse ) return 0; /* Restriction (0) */ if( isAgg && subqueryIsAgg ) return 0; /* Restriction (1) */ if( subqueryIsAgg && pSrc->nSrc>1 ) return 0; /* Restriction (2) */ pSubSrc = pSub->pSrc; diff --git a/test/with1.test b/test/with1.test index 3dd8c47ea2..480afa8074 100644 --- a/test/with1.test +++ b/test/with1.test @@ -164,6 +164,50 @@ do_execsql_test 5.5 { SELECT x FROM i LIMIT 20; } {1 2 3 4 5 6 7 8 9 0} +#------------------------------------------------------------------------- +# +do_execsql_test 6.1 { + CREATE TABLE f( + id INTEGER PRIMARY KEY, parentid REFERENCES f, name TEXT + ); + + INSERT INTO f VALUES(0, NULL, ''); + INSERT INTO f VALUES(1, 0, 'bin'); + INSERT INTO f VALUES(2, 1, 'true'); + INSERT INTO f VALUES(3, 1, 'false'); + INSERT INTO f VALUES(4, 1, 'ls'); + INSERT INTO f VALUES(5, 1, 'grep'); + INSERT INTO f VALUES(6, 0, 'etc'); + INSERT INTO f VALUES(7, 6, 'rc.d'); + INSERT INTO f VALUES(8, 7, 'rc.apache'); + INSERT INTO f VALUES(9, 7, 'rc.samba'); + INSERT INTO f VALUES(10, 0, 'home'); + INSERT INTO f VALUES(11, 10, 'dan'); + INSERT INTO f VALUES(12, 11, 'public_html'); + INSERT INTO f VALUES(13, 12, 'index.html'); + INSERT INTO f VALUES(14, 13, 'logo.gif'); +} + +do_execsql_test 6.2 { + WITH flat(fid, fpath) AS ( + SELECT id, '' FROM f WHERE parentid IS NULL + UNION ALL + SELECT id, fpath || '/' || name FROM f, flat WHERE +parentid=+fid + ) + SELECT fpath FROM flat WHERE fpath!='' ORDER BY 1; +} { + /bin + /bin/false /bin/grep /bin/ls /bin/true + /etc + /etc/rc.d + /etc/rc.d/rc.apache /etc/rc.d/rc.samba + /home + /home/dan + /home/dan/public_html + /home/dan/public_html/index.html + /home/dan/public_html/index.html/logo.gif +} + finish_test From a379b32f336f4ec5ff35c9a9acf323e95538eec4 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 15 Jan 2014 14:40:41 +0000 Subject: [PATCH 144/276] Don't try to verify the schema of transient table (such as generated inside a WITH clause) when generating code for "IN table" operators. FossilOrigin-Name: 860aa936634a60d68e3954fc408a96a9260394e0 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/expr.c | 8 +++++--- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 1f819eb388..c853513dbd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Disable\sthe\sflattening\soptimization\sif\sthe\ssub-query\sis\sa\srecursive\sCTE. -D 2014-01-15T14:17:31.048 +C Don't\stry\sto\sverify\sthe\sschema\sof\stransient\stable\s(such\sas\sgenerated\sinside\na\sWITH\sclause)\swhen\sgenerating\scode\sfor\s"IN\stable"\soperators. +D 2014-01-15T14:40:41.242 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -175,7 +175,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 F src/delete.c 91e1321021db5dc266360531b8b6550009d771ff -F src/expr.c 2277282d8938b8eab782e4f5111ca0cd492529b3 +F src/expr.c 46ad3b4161aeaf299130305efd0259bc5643bfd6 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 2ab0f5384b70594468ef3ac5c7ed8ca24bfd17d5 F src/func.c 6325ac2ec10833ccf4d5c36d323709221d37ea19 @@ -1150,7 +1150,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P a29330238be6366444269a0b1b328475b2d01ae2 -R baaf1d38169072daf03c7e43cc689f3b -U dan -Z e4d26324d0deafbbb1cfbafb0f22db9f +P 9472f6d820a7fb233936d9b8f7a39c9d4c4d6d73 +R 719190df89fa0f9b34e7fe5eb5626240 +U drh +Z 58f028530f5aaa7c16053558b5f5262a diff --git a/manifest.uuid b/manifest.uuid index 493b55e692..cc099a86d2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9472f6d820a7fb233936d9b8f7a39c9d4c4d6d73 \ No newline at end of file +860aa936634a60d68e3954fc408a96a9260394e0 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 4da9d6263c..fca03a8d99 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1581,9 +1581,11 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){ iCol = (i16)pExpr->iColumn; /* Code an OP_VerifyCookie and OP_TableLock for . */ - iDb = sqlite3SchemaToIndex(db, pTab->pSchema); - sqlite3CodeVerifySchema(pParse, iDb); - sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); + if( pTab->pSchema ){ + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + sqlite3CodeVerifySchema(pParse, iDb); + sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); + } /* This function is only called from two places. In both cases the vdbe ** has already been allocated. So assume sqlite3GetVdbe() is always From 60e7068d75acc643cfd045a7cb90d635079f3457 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 15 Jan 2014 15:27:51 +0000 Subject: [PATCH 145/276] Return an error if a CTE specifies a different number of columns than its SELECT statement returns. FossilOrigin-Name: 9a514b50e4b01f109fbdb0aabcbfe1ddab129b44 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/select.c | 14 ++++++++++---- test/with1.test | 36 ++++++++++++++++++++++++++++++++++++ 4 files changed, 55 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index c853513dbd..d314554380 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Don't\stry\sto\sverify\sthe\sschema\sof\stransient\stable\s(such\sas\sgenerated\sinside\na\sWITH\sclause)\swhen\sgenerating\scode\sfor\s"IN\stable"\soperators. -D 2014-01-15T14:40:41.242 +C Return\san\serror\sif\sa\sCTE\sspecifies\sa\sdifferent\snumber\sof\scolumns\sthan\sits\sSELECT\sstatement\sreturns. +D 2014-01-15T15:27:51.337 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -219,7 +219,7 @@ F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c 51c74176eb949d1ff5797735acedd6c08d19450a +F src/select.c 7d0d85f5d0a0f35be49230a3b6609fa534980015 F src/shell.c a3541193d5fce37e91dad8ef46a9505aa7c9b344 F src/sqlite.h.in d94a8b89522f526ba711182ee161e06f8669bcc9 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e @@ -1091,7 +1091,7 @@ F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c F test/win32lock.test 7a6bd73a5dcdee39b5bb93e92395e1773a194361 F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d -F test/with1.test 77739a9e5e88873e7655634297d9dc4360334f9a +F test/with1.test babb3d9c4007596d2d74468e001b1dc02d1ada91 F test/withM.test ac3ec7ee0b33a02d0fa15da91214d97ddea64e34 F test/without_rowid1.test aaa26da19d543cd8d3d2d0e686dfa255556c15c8 F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99 @@ -1150,7 +1150,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 9472f6d820a7fb233936d9b8f7a39c9d4c4d6d73 -R 719190df89fa0f9b34e7fe5eb5626240 -U drh -Z 58f028530f5aaa7c16053558b5f5262a +P 860aa936634a60d68e3954fc408a96a9260394e0 +R 0c042289cd11db254af8c2a3a3653738 +U dan +Z d4b370476cdc85ae036fb519ef522aac diff --git a/manifest.uuid b/manifest.uuid index cc099a86d2..2aac3c13b1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -860aa936634a60d68e3954fc408a96a9260394e0 \ No newline at end of file +9a514b50e4b01f109fbdb0aabcbfe1ddab129b44 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 35edcbb03c..34a2297c96 100644 --- a/src/select.c +++ b/src/select.c @@ -3556,6 +3556,7 @@ static int withExpand( }else{ ExprList *pEList; Select *pSel; + Select *pLeft; /* Left-most SELECT statement */ int bRecursive; pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table)); @@ -3579,13 +3580,18 @@ static int withExpand( sqlite3WalkSelect(pWalker, pSel); } + for(pLeft=pSel; pLeft->pPrior; pLeft=pLeft->pPrior); + pEList = pLeft->pEList; if( pCte->pCols ){ + if( pEList->nExpr!=pCte->pCols->nExpr ){ + sqlite3ErrorMsg(pParse, "cte \"%s\" returns %d values for %d columns", + pCte->zName, pEList->nExpr, pCte->pCols->nExpr + ); + return WRC_Abort; + } pEList = pCte->pCols; - }else{ - Select *pLeft; - for(pLeft=pSel; pLeft->pPrior; pLeft=pLeft->pPrior); - pEList = pLeft->pEList; } + selectColumnsFromExprList(pParse, pEList, &pTab->nCol, &pTab->aCol); if( bRecursive ){ diff --git a/test/with1.test b/test/with1.test index 480afa8074..dd1d5c0ab0 100644 --- a/test/with1.test +++ b/test/with1.test @@ -164,6 +164,42 @@ do_execsql_test 5.5 { SELECT x FROM i LIMIT 20; } {1 2 3 4 5 6 7 8 9 0} +do_catchsql_test 5.6.1 { + WITH i(x, y) AS ( VALUES(1) ) + SELECT * FROM i; +} {1 {cte "i" returns 1 values for 2 columns}} + +do_catchsql_test 5.6.2 { + WITH i(x) AS ( VALUES(1,2) ) + SELECT * FROM i; +} {1 {cte "i" returns 2 values for 1 columns}} + +do_catchsql_test 5.6.3 { + CREATE TABLE t5(a, b); + WITH i(x) AS ( SELECT * FROM t5 ) + SELECT * FROM i; +} {1 {cte "i" returns 2 values for 1 columns}} + +do_catchsql_test 5.6.4 { + WITH i(x) AS ( SELECT 1, 2 UNION ALL SELECT 1 ) + SELECT * FROM i; +} {1 {cte "i" returns 2 values for 1 columns}} + +do_catchsql_test 5.6.5 { + WITH i(x) AS ( SELECT 1 UNION ALL SELECT 1, 2 ) + SELECT * FROM i; +} {1 {SELECTs to the left and right of UNION ALL do not have the same number of result columns}} + +do_catchsql_test 5.6.6 { + WITH i(x) AS ( SELECT 1 UNION ALL SELECT x+1, x*2 FROM i ) + SELECT * FROM i; +} {1 {SELECTs to the left and right of UNION ALL do not have the same number of result columns}} + +do_catchsql_test 5.6.7 { + WITH i(x) AS ( SELECT 1, 2 UNION SELECT x+1 FROM i ) + SELECT * FROM i; +} {1 {cte "i" returns 2 values for 1 columns}} + #------------------------------------------------------------------------- # do_execsql_test 6.1 { From f43fe6e9f6e8e7e7c2ab43234f46c5767f63b27c Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 15 Jan 2014 18:12:00 +0000 Subject: [PATCH 146/276] When resolving names, consider a reference to a recursive CTE column as equivalent to a reference to the outermost name-context. This ensures that correlated sub-queries are correctly identified as such. FossilOrigin-Name: 61be2da0ae623c1572819481508b044e9d32f294 --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/expr.c | 1 + src/resolve.c | 8 ++++++++ src/select.c | 2 ++ src/sqliteInt.h | 1 + test/with1.test | 19 +++++++++++++++++++ 7 files changed, 42 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index d314554380..7847f8e691 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Return\san\serror\sif\sa\sCTE\sspecifies\sa\sdifferent\snumber\sof\scolumns\sthan\sits\sSELECT\sstatement\sreturns. -D 2014-01-15T15:27:51.337 +C When\sresolving\snames,\sconsider\sa\sreference\sto\sa\srecursive\sCTE\scolumn\sas\sequivalent\sto\sa\sreference\sto\sthe\soutermost\sname-context.\sThis\sensures\sthat\scorrelated\ssub-queries\sare\scorrectly\sidentified\sas\ssuch. +D 2014-01-15T18:12:00.359 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -175,7 +175,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 F src/delete.c 91e1321021db5dc266360531b8b6550009d771ff -F src/expr.c 46ad3b4161aeaf299130305efd0259bc5643bfd6 +F src/expr.c fccff6c8cd170dc1df244fdd4befb2ec783b72b1 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 2ab0f5384b70594468ef3ac5c7ed8ca24bfd17d5 F src/func.c 6325ac2ec10833ccf4d5c36d323709221d37ea19 @@ -217,14 +217,14 @@ F src/pragma.c ed409ce4104cf4d9de6ead40ace70974f124853b F src/prepare.c 677521ab7132615a8a26107a1d1c3132f44ae337 F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece -F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 +F src/resolve.c 41d0cf644aa98131204e6243e108829797f038ab F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c 7d0d85f5d0a0f35be49230a3b6609fa534980015 +F src/select.c c6ba9c34f5092aeada10928b93c798a5a262c85a F src/shell.c a3541193d5fce37e91dad8ef46a9505aa7c9b344 F src/sqlite.h.in d94a8b89522f526ba711182ee161e06f8669bcc9 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h fc7b2516260c4e14bd4342cd9ed47f3d0ca27cc5 +F src/sqliteInt.h 31bcde5190ca666e4873188a9039ac6ff017a0a8 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -1091,7 +1091,7 @@ F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c F test/win32lock.test 7a6bd73a5dcdee39b5bb93e92395e1773a194361 F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d -F test/with1.test babb3d9c4007596d2d74468e001b1dc02d1ada91 +F test/with1.test 951807f7246215ec26cf5e9946f1b355ba892f89 F test/withM.test ac3ec7ee0b33a02d0fa15da91214d97ddea64e34 F test/without_rowid1.test aaa26da19d543cd8d3d2d0e686dfa255556c15c8 F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99 @@ -1150,7 +1150,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 860aa936634a60d68e3954fc408a96a9260394e0 -R 0c042289cd11db254af8c2a3a3653738 +P 9a514b50e4b01f109fbdb0aabcbfe1ddab129b44 +R 7a326e6d7d898da8a108f7b49c21709d U dan -Z d4b370476cdc85ae036fb519ef522aac +Z a1fae4bd21e81652e55bd538f546aecf diff --git a/manifest.uuid b/manifest.uuid index 2aac3c13b1..7d2b8e9f8a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9a514b50e4b01f109fbdb0aabcbfe1ddab129b44 \ No newline at end of file +61be2da0ae623c1572819481508b044e9d32f294 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index fca03a8d99..9a288b73b2 100644 --- a/src/expr.c +++ b/src/expr.c @@ -998,6 +998,7 @@ SrcList *sqlite3SrcListDup(sqlite3 *db, SrcList *p, int flags){ pNewItem->regReturn = pOldItem->regReturn; pNewItem->isCorrelated = pOldItem->isCorrelated; pNewItem->viaCoroutine = pOldItem->viaCoroutine; + pNewItem->isRecursive = pOldItem->isRecursive; pNewItem->zIndex = sqlite3DbStrDup(db, pOldItem->zIndex); pNewItem->notIndexed = pOldItem->notIndexed; pNewItem->pIndex = pOldItem->pIndex; diff --git a/src/resolve.c b/src/resolve.c index b0adb86295..d54442e79c 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -502,6 +502,14 @@ lookupname_end: if( pExpr->op!=TK_AS ){ sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList); } + + /* If this expression reads a column value from a recursive CTE + ** reference, then this is equivalent to reading from the outermost + ** available name-context. */ + if( pMatch && pMatch->isRecursive ){ + while( pNC->pNext ) pNC = pNC->pNext; + } + /* Increment the nRef value on all name contexts from TopNC up to ** the point where the name matched. */ for(;;){ diff --git a/src/select.c b/src/select.c index 34a2297c96..3f9f2de551 100644 --- a/src/select.c +++ b/src/select.c @@ -3551,7 +3551,9 @@ static int withExpand( if( pCte==pParse->pCte && (pTab = pCte->pTab) ){ /* This is the recursive part of a recursive CTE */ + assert( pFrom->pTab==0 && pFrom->isRecursive==0 ); pFrom->pTab = pTab; + pFrom->isRecursive = 1; pTab->nRef++; }else{ ExprList *pEList; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index c7f0609ba1..c52013f87f 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2019,6 +2019,7 @@ struct SrcList { unsigned notIndexed :1; /* True if there is a NOT INDEXED clause */ unsigned isCorrelated :1; /* True if sub-query is correlated */ unsigned viaCoroutine :1; /* Implemented as a co-routine */ + unsigned isRecursive :1; /* True for recursive reference in WITH */ #ifndef SQLITE_OMIT_EXPLAIN u8 iSelectId; /* If pSelect!=0, the id of the sub-select in EQP */ #endif diff --git a/test/with1.test b/test/with1.test index dd1d5c0ab0..1f227e8165 100644 --- a/test/with1.test +++ b/test/with1.test @@ -244,6 +244,25 @@ do_execsql_test 6.2 { /home/dan/public_html/index.html/logo.gif } +do_execsql_test 6.3 { + WITH flat(fid, fpath) AS ( + SELECT id, '' FROM f WHERE parentid IS NULL + UNION ALL + SELECT id, fpath || '/' || name FROM f, flat WHERE parentid=+fid + ) + SELECT count(*) FROM flat; +} {15} + +do_execsql_test 6.4 { + WITH x(i) AS ( + SELECT 1 + UNION ALL + SELECT i+1 FROM x WHERE i<10 + ) + SELECT count(*) FROM x +} {10} + + finish_test From 62ba4e418d9105671599b7f9287aa0d3dce031bc Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 15 Jan 2014 18:21:41 +0000 Subject: [PATCH 147/276] Disable automatic indices on recursive CTE references. FossilOrigin-Name: 28aa6db8c878655255dbfb618f8d65be78e3d7e5 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 1 + test/with1.test | 4 ++-- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 7847f8e691..e2d4787ec4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\sresolving\snames,\sconsider\sa\sreference\sto\sa\srecursive\sCTE\scolumn\sas\sequivalent\sto\sa\sreference\sto\sthe\soutermost\sname-context.\sThis\sensures\sthat\scorrelated\ssub-queries\sare\scorrectly\sidentified\sas\ssuch. -D 2014-01-15T18:12:00.359 +C Disable\sautomatic\sindices\son\srecursive\sCTE\sreferences. +D 2014-01-15T18:21:41.108 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -293,7 +293,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c e9e593d5bb798c3e67fc3893dfe7055c9e7d8d74 -F src/where.c 830b42f452cfbc4e17582f6c1d388e15b379b833 +F src/where.c 9448a176c10020a4446a8d5e2cdaecf7526e593d F src/whereInt.h 96a75c61f1d2b9d4a8e4bb17d89deb0cf7cba358 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1091,7 +1091,7 @@ F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c F test/win32lock.test 7a6bd73a5dcdee39b5bb93e92395e1773a194361 F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d -F test/with1.test 951807f7246215ec26cf5e9946f1b355ba892f89 +F test/with1.test fcd45b0128292d57f4435df873b51b7261edc9ba F test/withM.test ac3ec7ee0b33a02d0fa15da91214d97ddea64e34 F test/without_rowid1.test aaa26da19d543cd8d3d2d0e686dfa255556c15c8 F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99 @@ -1150,7 +1150,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 9a514b50e4b01f109fbdb0aabcbfe1ddab129b44 -R 7a326e6d7d898da8a108f7b49c21709d +P 61be2da0ae623c1572819481508b044e9d32f294 +R 054a2146ee506f873fefb3d9cec1bd30 U dan -Z a1fae4bd21e81652e55bd538f546aecf +Z 902f9935ce7a37fa7329c31a191dfe9e diff --git a/manifest.uuid b/manifest.uuid index 7d2b8e9f8a..5d6578e47c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -61be2da0ae623c1572819481508b044e9d32f294 \ No newline at end of file +28aa6db8c878655255dbfb618f8d65be78e3d7e5 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 8827faa839..7ac8c57f23 100644 --- a/src/where.c +++ b/src/where.c @@ -4196,6 +4196,7 @@ static int whereLoopAddBtree( && !pSrc->notIndexed && HasRowid(pTab) && !pSrc->isCorrelated + && !pSrc->isRecursive ){ /* Generate auto-index WhereLoops */ WhereTerm *pTerm; diff --git a/test/with1.test b/test/with1.test index 1f227e8165..5c59755ce0 100644 --- a/test/with1.test +++ b/test/with1.test @@ -228,7 +228,7 @@ do_execsql_test 6.2 { WITH flat(fid, fpath) AS ( SELECT id, '' FROM f WHERE parentid IS NULL UNION ALL - SELECT id, fpath || '/' || name FROM f, flat WHERE +parentid=+fid + SELECT id, fpath || '/' || name FROM f, flat WHERE parentid=fid ) SELECT fpath FROM flat WHERE fpath!='' ORDER BY 1; } { @@ -248,7 +248,7 @@ do_execsql_test 6.3 { WITH flat(fid, fpath) AS ( SELECT id, '' FROM f WHERE parentid IS NULL UNION ALL - SELECT id, fpath || '/' || name FROM f, flat WHERE parentid=+fid + SELECT id, fpath || '/' || name FROM f, flat WHERE parentid=fid ) SELECT count(*) FROM flat; } {15} From 60c1a2f0b5aae5e0660306d3f996d826953e117a Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 15 Jan 2014 18:23:00 +0000 Subject: [PATCH 148/276] Add a header comment to the searchWith() routine. FossilOrigin-Name: d9ae0f5d9f8230ca7ca10ebed300e2f6635a0614 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/select.c | 4 ++++ 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index e2d4787ec4..7b7db93b32 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Disable\sautomatic\sindices\son\srecursive\sCTE\sreferences. -D 2014-01-15T18:21:41.108 +C Add\sa\sheader\scomment\sto\sthe\ssearchWith()\sroutine. +D 2014-01-15T18:23:00.349 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -219,7 +219,7 @@ F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 41d0cf644aa98131204e6243e108829797f038ab F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c c6ba9c34f5092aeada10928b93c798a5a262c85a +F src/select.c 240e9795df3fbaca15e2fa9c3b0a95796e60e5d7 F src/shell.c a3541193d5fce37e91dad8ef46a9505aa7c9b344 F src/sqlite.h.in d94a8b89522f526ba711182ee161e06f8669bcc9 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e @@ -1150,7 +1150,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 61be2da0ae623c1572819481508b044e9d32f294 -R 054a2146ee506f873fefb3d9cec1bd30 -U dan -Z 902f9935ce7a37fa7329c31a191dfe9e +P 28aa6db8c878655255dbfb618f8d65be78e3d7e5 +R 19b67b003a2571a98d1dce07a86e95af +U drh +Z 5c4be2977b3d2e13595e058b593ca068 diff --git a/manifest.uuid b/manifest.uuid index 5d6578e47c..3f055fe737 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -28aa6db8c878655255dbfb618f8d65be78e3d7e5 \ No newline at end of file +d9ae0f5d9f8230ca7ca10ebed300e2f6635a0614 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 3f9f2de551..3a30031c00 100644 --- a/src/select.c +++ b/src/select.c @@ -3482,6 +3482,10 @@ static int convertCompoundSelectToSubquery(Walker *pWalker, Select *p){ return WRC_Continue; } +/* If the table identified by p is a transient table of +** a common-table-expression (CTE) then return a pointer to the +** CTE that defines table p. If p is not a CTE, then return NULL. +*/ static struct Cte *searchWith(Parse *pParse, struct SrcList_item *p){ if( p->zDatabase==0 ){ char *zName = p->zName; From c49832c208283ee22b107d00246af355585320a9 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 15 Jan 2014 18:35:52 +0000 Subject: [PATCH 149/276] Further comments on WITH-clause processing routines in select.c. FossilOrigin-Name: c948384dfdd9f68a832d5a452af44f35337f66e7 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/select.c | 13 ++++++++++--- src/sqliteInt.h | 18 +++++++++--------- 4 files changed, 27 insertions(+), 20 deletions(-) diff --git a/manifest b/manifest index 7b7db93b32..b46bf3bc83 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\sheader\scomment\sto\sthe\ssearchWith()\sroutine. -D 2014-01-15T18:23:00.349 +C Further\scomments\son\sWITH-clause\sprocessing\sroutines\sin\sselect.c. +D 2014-01-15T18:35:52.482 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -219,12 +219,12 @@ F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 41d0cf644aa98131204e6243e108829797f038ab F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c 240e9795df3fbaca15e2fa9c3b0a95796e60e5d7 +F src/select.c 6bdb90db59e3e8277b8953e4cd3df01ccc253d70 F src/shell.c a3541193d5fce37e91dad8ef46a9505aa7c9b344 F src/sqlite.h.in d94a8b89522f526ba711182ee161e06f8669bcc9 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h 31bcde5190ca666e4873188a9039ac6ff017a0a8 +F src/sqliteInt.h d91991457386b4a1414fa96f51a9a5bfd2b8606d F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -1150,7 +1150,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 28aa6db8c878655255dbfb618f8d65be78e3d7e5 -R 19b67b003a2571a98d1dce07a86e95af +P d9ae0f5d9f8230ca7ca10ebed300e2f6635a0614 +R de20d9dcfc2fdd09cc5e9c05dc6deb70 U drh -Z 5c4be2977b3d2e13595e058b593ca068 +Z 626093c1115d7d3f00c431f06f508aa1 diff --git a/manifest.uuid b/manifest.uuid index 3f055fe737..fc2d2ece54 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d9ae0f5d9f8230ca7ca10ebed300e2f6635a0614 \ No newline at end of file +c948384dfdd9f68a832d5a452af44f35337f66e7 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 3a30031c00..0984bd30ed 100644 --- a/src/select.c +++ b/src/select.c @@ -3482,9 +3482,9 @@ static int convertCompoundSelectToSubquery(Walker *pWalker, Select *p){ return WRC_Continue; } -/* If the table identified by p is a transient table of +/* If the table identified by FROM clause element p is really ** a common-table-expression (CTE) then return a pointer to the -** CTE that defines table p. If p is not a CTE, then return NULL. +** CTE definition for that table. */ static struct Cte *searchWith(Parse *pParse, struct SrcList_item *p){ if( p->zDatabase==0 ){ @@ -3503,6 +3503,11 @@ static struct Cte *searchWith(Parse *pParse, struct SrcList_item *p){ return 0; } +/* The code generator maintains a stack of active WITH clauses +** with the inner-most WITH clause being at the top of the stack. +** +** These routines push and pull WITH clauses on the stack. +*/ void sqlite3WithPush(Parse *pParse, With *pWith){ if( pWith ){ pWith->pOuter = pParse->pWith; @@ -3516,6 +3521,9 @@ static void withPop(Parse *pParse, With *pWith){ } } +/* Push or pull a CTE on the stack of all CTEs currently being +** coded. +*/ static int ctePush(Parse *pParse, struct Cte *pCte){ if( pCte ){ struct Cte *p; @@ -3533,7 +3541,6 @@ static int ctePush(Parse *pParse, struct Cte *pCte){ } return SQLITE_OK; } - static void ctePop(Parse *pParse, struct Cte *pCte){ if( pCte ){ assert( pParse->pCte==pCte ); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index c52013f87f..3973c02830 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2640,18 +2640,18 @@ int sqlite3WalkSelectFrom(Walker*, Select*); #define WRC_Abort 2 /* Abandon the tree walk */ /* -** An instance of this structure represents a set of CTEs (common table -** expressions) created by a single WITH clause. +** An instance of this structure represents a set of on or more CTEs +** (common table expressions) created by a single WITH clause. */ struct With { - int nCte; /* Number of CTEs */ + int nCte; /* Number of CTEs in the WITH clause */ With *pOuter; /* Containing WITH clause, or NULL */ - struct Cte { - char *zName; /* Name of this CTE */ - ExprList *pCols; /* List of explicit column names, or NULL */ - Select *pSelect; /* The contents of the CTE */ - struct Cte *pOuterCte; - Table *pTab; + struct Cte { /* For each CTE in the WITH clause.... */ + char *zName; /* Name of this CTE */ + ExprList *pCols; /* List of explicit column names, or NULL */ + Select *pSelect; /* The definition of this CTE */ + struct Cte *pOuterCte; /* Next WITH clause in outer context */ + Table *pTab; /* Table object for this CTE */ } a[1]; }; From eede6a538d32de61cc644e09fcb90264496791ac Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 15 Jan 2014 19:42:23 +0000 Subject: [PATCH 150/276] Fixes so that SQLITE_OMIT_CTE builds work. FossilOrigin-Name: 3908e2ea2e7e5f466cbbbffdc27e0fe8dc9751ac --- manifest | 30 ++++++------ manifest.uuid | 2 +- src/expr.c | 4 ++ src/resolve.c | 2 + src/select.c | 121 ++++++++++++++++++++++++++++++---------------- src/sqliteInt.h | 1 + src/test_config.c | 6 +++ src/vdbe.c | 2 + src/where.c | 2 + test/with1.test | 5 ++ test/withM.test | 5 ++ 11 files changed, 123 insertions(+), 57 deletions(-) diff --git a/manifest b/manifest index b46bf3bc83..dae060c0f8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Further\scomments\son\sWITH-clause\sprocessing\sroutines\sin\sselect.c. -D 2014-01-15T18:35:52.482 +C Fixes\sso\sthat\sSQLITE_OMIT_CTE\sbuilds\swork. +D 2014-01-15T19:42:23.894 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -175,7 +175,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 F src/delete.c 91e1321021db5dc266360531b8b6550009d771ff -F src/expr.c fccff6c8cd170dc1df244fdd4befb2ec783b72b1 +F src/expr.c 36c313049a716c3edcdd99d703f0f16ce96a4cc6 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 2ab0f5384b70594468ef3ac5c7ed8ca24bfd17d5 F src/func.c 6325ac2ec10833ccf4d5c36d323709221d37ea19 @@ -217,14 +217,14 @@ F src/pragma.c ed409ce4104cf4d9de6ead40ace70974f124853b F src/prepare.c 677521ab7132615a8a26107a1d1c3132f44ae337 F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece -F src/resolve.c 41d0cf644aa98131204e6243e108829797f038ab +F src/resolve.c ae278d8ce037883323f677e78c241f64289f12ec F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c 6bdb90db59e3e8277b8953e4cd3df01ccc253d70 +F src/select.c b55e726c8dff607790038bf41e6d47925a832b14 F src/shell.c a3541193d5fce37e91dad8ef46a9505aa7c9b344 F src/sqlite.h.in d94a8b89522f526ba711182ee161e06f8669bcc9 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h d91991457386b4a1414fa96f51a9a5bfd2b8606d +F src/sqliteInt.h 6db445ce172c249c29d8f532af64fd7051fe05dd F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -242,7 +242,7 @@ F src/test_async.c 21e11293a2f72080eda70e1124e9102044531cd8 F src/test_autoext.c dea8a01a7153b9adc97bd26161e4226329546e12 F src/test_backup.c 3875e899222b651e18b662f86e0e50daa946344e F src/test_btree.c 5b89601dcb42a33ba8b820a6b763cc9cb48bac16 -F src/test_config.c 10d0e00dd6315879a6d9fac20bd063c7bbbfb8f8 +F src/test_config.c 0336e0bdbe541b4af89d7e3dd0656e8e6b51e585 F src/test_demovfs.c 69b2085076654ebc18014cbc6386f04409c959a9 F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc F src/test_fs.c ced436e3d4b8e4681328409b8081051ce614e28f @@ -280,7 +280,7 @@ F src/update.c c2706a6eb232a96345c35b7e1e75a188e26812bb F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c e71f19b272f05c8695cf747b4bac1732685f9e5c F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c 9b918126afb9a7b7ad232db7453680c7ef5821a4 +F src/vdbe.c b06d79951a3f0da9cb41cb0aae5fdf5612f718a9 F src/vdbe.h e6c4c610fcabad4fa80ebb1efc6822a9367e2b26 F src/vdbeInt.h 42db251e9f863401ff847b90d5fe1614c89a6a56 F src/vdbeapi.c ce4e68ea4842cc6081046f533d088dcf01d247ad @@ -293,7 +293,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c e9e593d5bb798c3e67fc3893dfe7055c9e7d8d74 -F src/where.c 9448a176c10020a4446a8d5e2cdaecf7526e593d +F src/where.c 27eb508c4184599a826e2ef3b4319cd28ba2c7af F src/whereInt.h 96a75c61f1d2b9d4a8e4bb17d89deb0cf7cba358 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1091,8 +1091,8 @@ F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c F test/win32lock.test 7a6bd73a5dcdee39b5bb93e92395e1773a194361 F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d -F test/with1.test fcd45b0128292d57f4435df873b51b7261edc9ba -F test/withM.test ac3ec7ee0b33a02d0fa15da91214d97ddea64e34 +F test/with1.test 8ac68051fce8f2fe4a7bb6cb7ba62c0e941b1c84 +F test/withM.test 52448ce23e1c2ecba79d10e130ee49ce9f9a2a7a F test/without_rowid1.test aaa26da19d543cd8d3d2d0e686dfa255556c15c8 F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99 F test/without_rowid3.test eac3d5c8a1924725b58503a368f2cbd24fd6c8a0 @@ -1150,7 +1150,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P d9ae0f5d9f8230ca7ca10ebed300e2f6635a0614 -R de20d9dcfc2fdd09cc5e9c05dc6deb70 -U drh -Z 626093c1115d7d3f00c431f06f508aa1 +P c948384dfdd9f68a832d5a452af44f35337f66e7 +R 366ade7d6e8c82851813f265ff0c51f5 +U dan +Z a6417c60f97c097fa8d751079d1185b1 diff --git a/manifest.uuid b/manifest.uuid index fc2d2ece54..cab35f4394 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c948384dfdd9f68a832d5a452af44f35337f66e7 \ No newline at end of file +3908e2ea2e7e5f466cbbbffdc27e0fe8dc9751ac \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 9a288b73b2..68bb2fe53e 100644 --- a/src/expr.c +++ b/src/expr.c @@ -900,6 +900,7 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){ ** argument. If an OOM condition is encountered, NULL is returned ** and the db->mallocFailed flag set. */ +#ifndef SQLITE_OMIT_CTE static With *withDup(sqlite3 *db, With *p){ With *pRet = 0; if( p ){ @@ -917,6 +918,9 @@ static With *withDup(sqlite3 *db, With *p){ } return pRet; } +#else +# define withDup(x,y) 0 +#endif /* ** The following group of routines make deep copies of expressions, diff --git a/src/resolve.c b/src/resolve.c index d54442e79c..724b8538fa 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -503,12 +503,14 @@ lookupname_end: sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList); } +#ifndef SQLITE_OMIT_CTE /* If this expression reads a column value from a recursive CTE ** reference, then this is equivalent to reading from the outermost ** available name-context. */ if( pMatch && pMatch->isRecursive ){ while( pNC->pNext ) pNC = pNC->pNext; } +#endif /* Increment the nRef value on all name contexts from TopNC up to ** the point where the name matched. */ diff --git a/src/select.c b/src/select.c index 0984bd30ed..7f20dc689a 100644 --- a/src/select.c +++ b/src/select.c @@ -1789,6 +1789,7 @@ static int multiSelect( goto multi_select_end; } +#ifndef SQLITE_OMIT_CTE /* If this is a recursive query, check that there is no ORDER BY or ** LIMIT clause. Neither of these are supported. */ assert( p->pOffset==0 || p->pLimit ); @@ -1799,13 +1800,6 @@ static int multiSelect( goto multi_select_end; } - /* Compound SELECTs that have an ORDER BY clause are handled separately. - */ - if( p->pOrderBy ){ - return multiSelectOrderBy(pParse, p, pDest); - } - -#ifndef SQLITE_OMIT_CTE if( p->pRecurse ){ int nCol = p->pEList->nExpr; int addrNext; @@ -1838,7 +1832,7 @@ static int multiSelect( rc = sqlite3Select(pParse, pPrior, &tmp2dest); if( rc ) goto multi_select_end; - /* Clear tmp1. Then switch the contents of tmp1 and tmp2. Then teturn + /* Clear tmp1. Then switch the contents of tmp1 and tmp2. Then return ** the contents of tmp1 to the caller. Or, if tmp1 is empty at this ** point, the recursive query has finished - jump to address iBreak. */ addrSwap = sqlite3VdbeAddOp2(v, OP_SwapCursors, tmp1, tmp2); @@ -1865,6 +1859,12 @@ static int multiSelect( }else #endif + /* Compound SELECTs that have an ORDER BY clause are handled separately. + */ + if( p->pOrderBy ){ + return multiSelectOrderBy(pParse, p, pDest); + }else + /* Generate code for the left and right SELECT statements. */ switch( p->op ){ @@ -3482,20 +3482,23 @@ static int convertCompoundSelectToSubquery(Walker *pWalker, Select *p){ return WRC_Continue; } -/* If the table identified by FROM clause element p is really -** a common-table-expression (CTE) then return a pointer to the -** CTE definition for that table. +#ifndef SQLITE_OMIT_CTE +/* +** Argument pWith (which may be NULL) points to a linked list of nested +** WITH contexts, from inner to outermost. If the table identified by +** FROM clause element pItem is really a common-table-expression (CTE) +** then return a pointer to the CTE definition for that table. Otherwise +** return NULL. */ -static struct Cte *searchWith(Parse *pParse, struct SrcList_item *p){ - if( p->zDatabase==0 ){ - char *zName = p->zName; - With *pWith; - - for(pWith=pParse->pWith; pWith; pWith=pWith->pOuter){ +static struct Cte *searchWith(With *pWith, struct SrcList_item *pItem){ + if( pItem->zDatabase==0 ){ + const char *zName = pItem->zName; + With *p; + for(p=pWith; p; p=p->pOuter){ int i; - for(i=0; inCte; i++){ - if( sqlite3StrICmp(zName, pWith->a[i].zName)==0 ){ - return &pWith->a[i]; + for(i=0; inCte; i++){ + if( sqlite3StrICmp(zName, p->a[i].zName)==0 ){ + return &p->a[i]; } } } @@ -3514,16 +3517,16 @@ void sqlite3WithPush(Parse *pParse, With *pWith){ pParse->pWith = pWith; } } -static void withPop(Parse *pParse, With *pWith){ - if( pWith ){ - assert( pParse->pWith==pWith ); - pParse->pWith = pWith->pOuter; - } -} -/* Push or pull a CTE on the stack of all CTEs currently being -** coded. -*/ +/* +** If argument pCte is not NULL, check if it is already a part of the +** stack of CTEs stored by the parser. If so, this indicates an illegal +** recursive reference in a CTE, set of mutually recursive CTEs. Store +** an error in the parser and return SQLITE_ERROR if this is the case. +** +** Otherwise, if pCte is not already part of the stack of CTEs stored +** in the parser, push it onto the stop of that stack. +*/ static int ctePush(Parse *pParse, struct Cte *pCte){ if( pCte ){ struct Cte *p; @@ -3541,6 +3544,11 @@ static int ctePush(Parse *pParse, struct Cte *pCte){ } return SQLITE_OK; } +/* +** If argument pCte is not NULL, it must be a pointer to the CTE currently +** on top of the stack of CTEs stored in the parser. Remove it from that +** stack. +*/ static void ctePop(Parse *pParse, struct Cte *pCte){ if( pCte ){ assert( pParse->pCte==pCte ); @@ -3548,21 +3556,38 @@ static void ctePop(Parse *pParse, struct Cte *pCte){ } } +/* +** This function checks if argument pFrom refers to a CTE declared by +** a WITH clause on the stack currently maintained by the parser. And, +** if currently processing a CTE expression, if it is a recursive +** reference to the current CTE. +** +** If pFrom falls into either of the two categories above, pFrom->pTab +** and other fields are populated accordingly. The caller should check +** (pFrom->pTab!=0) to determine whether or not a successful match +** was found. +** +** Whether or not a match is found, SQLITE_OK is returned if no error +** occurs. If an error does occur, an error message is stored in the +** parser and some error code other than SQLITE_OK returned. +*/ static int withExpand( Walker *pWalker, - struct SrcList_item *pFrom, - struct Cte *pCte + struct SrcList_item *pFrom ){ Table *pTab; Parse *pParse = pWalker->pParse; sqlite3 *db = pParse->db; + struct Cte *pCte; - assert( pFrom->pSelect==0 ); assert( pFrom->pTab==0 ); - if( pCte==pParse->pCte && (pTab = pCte->pTab) ){ + pCte = searchWith(pParse->pWith, pFrom); + if( pCte==0 ){ + /* no-op */ + }else if( pCte==pParse->pCte && (pTab = pCte->pTab) ){ /* This is the recursive part of a recursive CTE */ - assert( pFrom->pTab==0 && pFrom->isRecursive==0 ); + assert( pFrom->pTab==0 && pFrom->isRecursive==0 && pFrom->pSelect==0 ); pFrom->pTab = pTab; pFrom->isRecursive = 1; pTab->nRef++; @@ -3623,6 +3648,7 @@ static int withExpand( return SQLITE_OK; } +#endif /* ** This routine is a Walker callback for "expanding" a SELECT statement. @@ -3678,7 +3704,6 @@ static int selectExpander(Walker *pWalker, Select *p){ ** then create a transient table structure to describe the subquery. */ for(i=0, pFrom=pTabList->a; inSrc; i++, pFrom++){ - struct Cte *pCte = 0; Table *pTab; if( pFrom->pTab!=0 ){ /* This statement has already been prepared. There is no need @@ -3687,10 +3712,8 @@ static int selectExpander(Walker *pWalker, Select *p){ return WRC_Prune; } #ifndef SQLITE_OMIT_CTE - pCte = searchWith(pParse, pFrom); - if( pCte ){ - if( withExpand(pWalker, pFrom, pCte) ) return WRC_Abort; - }else + if( withExpand(pWalker, pFrom) ) return WRC_Abort; + if( pFrom->pTab ) {} else #endif if( pFrom->zName==0 ){ #ifndef SQLITE_OMIT_SUBQUERY @@ -3917,13 +3940,29 @@ static int selectExpander(Walker *pWalker, Select *p){ return WRC_Continue; } +/* +** Function (or macro) selectExpanderWith is used as the SELECT callback +** by sqlite3SelectExpand(). In builds that do not support CTEs, this +** is equivalent to the selectExpander() function. In CTE-enabled builds, +** any WITH clause associated with the SELECT statement needs to be +** pushed onto the stack before calling selectExpander(), and popped +** off again afterwards. +*/ +#ifndef SQLITE_OMIT_CTE static int selectExpanderWith(Walker *pWalker, Select *p){ + Parse *pParse = pWalker->pParse; int res; - sqlite3WithPush(pWalker->pParse, p->pWith); + sqlite3WithPush(pParse, p->pWith); res = selectExpander(pWalker, p); - withPop(pWalker->pParse, p->pWith); + if( p->pWith ){ + assert( pParse->pWith==p->pWith ); + pParse->pWith = p->pWith->pOuter; + } return res; } +#else +#define selectExpanderWith selectExpander +#endif /* ** No-op routine for the parse-tree walker. diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 3973c02830..733dad2d8f 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3359,6 +3359,7 @@ const char *sqlite3JournalModename(int); void sqlite3WithPush(Parse*, With*); #else #define sqlite3WithPush(x,y) +#define sqlite3WithDelete(x,y) #endif /* Declarations for functions in fkey.c. All of these are replaced by diff --git a/src/test_config.c b/src/test_config.c index f44be40508..1db8198641 100644 --- a/src/test_config.c +++ b/src/test_config.c @@ -225,6 +225,12 @@ static void set_options(Tcl_Interp *interp){ Tcl_SetVar2(interp, "sqlite_options", "check", "1", TCL_GLOBAL_ONLY); #endif +#ifdef SQLITE_OMIT_CTE + Tcl_SetVar2(interp, "sqlite_options", "cte", "0", TCL_GLOBAL_ONLY); +#else + Tcl_SetVar2(interp, "sqlite_options", "cte", "1", TCL_GLOBAL_ONLY); +#endif + #ifdef SQLITE_ENABLE_COLUMN_METADATA Tcl_SetVar2(interp, "sqlite_options", "columnmetadata", "1", TCL_GLOBAL_ONLY); #else diff --git a/src/vdbe.c b/src/vdbe.c index ffb4dd19bd..301707677d 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3369,6 +3369,7 @@ case OP_OpenEphemeral: { break; } +#ifndef SQLITE_OMIT_CTE /* Opcode: OpenEphreader P1 P2 * * * ** ** P2 is a cursor opened by the OpenEphemeral opcode. This opcode opens @@ -3415,6 +3416,7 @@ case OP_SwapCursors: { rc = sqlite3BtreeClearTable(pTmp->pBt, MASTER_ROOT + !pTmp->isTable, 0); break; } +#endif /* ifndef SQLITE_OMIT_CTE */ /* Opcode: SorterOpen P1 * * P4 * ** diff --git a/src/where.c b/src/where.c index 7ac8c57f23..f1cf29b2e7 100644 --- a/src/where.c +++ b/src/where.c @@ -5654,10 +5654,12 @@ WhereInfo *sqlite3WhereBegin( iDb = sqlite3SchemaToIndex(db, pTab->pSchema); pLoop = pLevel->pWLoop; if( (pTab->tabFlags & TF_Ephemeral)!=0 || pTab->pSelect ){ +#ifndef SQLITE_OMIT_CTE if( pTab->tabFlags & TF_Recursive ){ int iCur = pTabItem->iCursor; sqlite3VdbeAddOp2(v, OP_OpenEphreader, iCur, pTab->tnum); } +#endif /* Otherwise do nothing */ }else #ifndef SQLITE_OMIT_VIRTUALTABLE diff --git a/test/with1.test b/test/with1.test index 5c59755ce0..861c722543 100644 --- a/test/with1.test +++ b/test/with1.test @@ -16,6 +16,11 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl set ::testprefix with1 +ifcapable {!cte} { + finish_test + return +} + do_execsql_test 1.0 { CREATE TABLE t1(x INTEGER, y INTEGER); WITH x(a) AS ( SELECT * FROM t1) SELECT 10 diff --git a/test/withM.test b/test/withM.test index 431cca187e..9bf7ceed3f 100644 --- a/test/withM.test +++ b/test/withM.test @@ -17,6 +17,11 @@ source $testdir/tester.tcl source $testdir/malloc_common.tcl set ::testprefix withM +ifcapable {!cte} { + finish_test + return +} + do_execsql_test 1.0 { CREATE TABLE t1(x INTEGER, y INTEGER); INSERT INTO t1 VALUES(123, 456); From 93c36bb399cee329b8bc0a10bff0af8b3d498f6e Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 15 Jan 2014 20:10:15 +0000 Subject: [PATCH 151/276] Remove an ALWAYS() that is no longer always true. FossilOrigin-Name: c95823cd451f7721174393817a801403647467db --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/select.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index dae060c0f8..ddbc250138 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fixes\sso\sthat\sSQLITE_OMIT_CTE\sbuilds\swork. -D 2014-01-15T19:42:23.894 +C Remove\san\sALWAYS()\sthat\sis\sno\slonger\salways\strue. +D 2014-01-15T20:10:15.729 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -219,7 +219,7 @@ F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c ae278d8ce037883323f677e78c241f64289f12ec F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c b55e726c8dff607790038bf41e6d47925a832b14 +F src/select.c ab437f252415754963b1adfa501120d5364da3ef F src/shell.c a3541193d5fce37e91dad8ef46a9505aa7c9b344 F src/sqlite.h.in d94a8b89522f526ba711182ee161e06f8669bcc9 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e @@ -1150,7 +1150,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P c948384dfdd9f68a832d5a452af44f35337f66e7 -R 366ade7d6e8c82851813f265ff0c51f5 -U dan -Z a6417c60f97c097fa8d751079d1185b1 +P 3908e2ea2e7e5f466cbbbffdc27e0fe8dc9751ac +R ec33026d9a1a4e4ae1384253da1cbe65 +U drh +Z d40f91394b02fb8b902b74395abcc185 diff --git a/manifest.uuid b/manifest.uuid index cab35f4394..d95e8d3935 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3908e2ea2e7e5f466cbbbffdc27e0fe8dc9751ac \ No newline at end of file +c95823cd451f7721174393817a801403647467db \ No newline at end of file diff --git a/src/select.c b/src/select.c index 7f20dc689a..b4ce7be9ed 100644 --- a/src/select.c +++ b/src/select.c @@ -1217,7 +1217,7 @@ static const char *columnTypeImpl( sNC.pParse = pNC->pParse; zType = columnType(&sNC, p,&zOrigDb,&zOrigTab,&zOrigCol, &estWidth); } - }else if( ALWAYS(pTab->pSchema) ){ + }else if( pTab->pSchema ){ /* A real table */ assert( !pS ); if( iCol<0 ) iCol = pTab->iPKey; From 8290c2ad5ad48cffe78f51a25109398ad2b49c41 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 16 Jan 2014 10:58:39 +0000 Subject: [PATCH 152/276] Disable the flattening optimization if the parent query is the recursive part of a recursive CTE and the sub-query is a compound query. FossilOrigin-Name: 6bfa387e82de47ca1f40225fe28d873e29d6f481 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/expr.c | 3 +-- src/select.c | 15 ++++++++++++--- 4 files changed, 22 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index dce447d221..86132841cd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\strunk\schanges.\s\sFix\sa\spossible\sNULL-pointer\sdeference\sin\sWITH\sclause\nname\sresolution. -D 2014-01-16T04:37:13.145 +C Disable\sthe\sflattening\soptimization\sif\sthe\sparent\squery\sis\sthe\srecursive\spart\sof\sa\srecursive\sCTE\sand\sthe\ssub-query\sis\sa\scompound\squery. +D 2014-01-16T10:58:39.954 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -175,7 +175,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 F src/delete.c 91e1321021db5dc266360531b8b6550009d771ff -F src/expr.c 36c313049a716c3edcdd99d703f0f16ce96a4cc6 +F src/expr.c c09e34fa7c58995009135b81f83cb62a676ad181 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 2ab0f5384b70594468ef3ac5c7ed8ca24bfd17d5 F src/func.c 6325ac2ec10833ccf4d5c36d323709221d37ea19 @@ -219,7 +219,7 @@ F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c ae278d8ce037883323f677e78c241f64289f12ec F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c c9af659146dd1fe924fbfb14a7477f6b2b90f03b +F src/select.c 29976d169853492a20d3201e8a83eeefa39a868f F src/shell.c 9f3bc02a658b8f61d2cbe60cfc482f660c1c6c48 F src/sqlite.h.in d94a8b89522f526ba711182ee161e06f8669bcc9 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e @@ -1150,7 +1150,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P c95823cd451f7721174393817a801403647467db f61a70589ac7e05008a362bd9d5b7bde5d07a758 -R 8a379a80b7992f91c6a6d54869d6bc5d -U drh -Z 69979a1b738527f03c61f40bf3b0d3cb +P 7f953b568baa3eede0b9c144be0b9bc86496341a +R 1f82ce2970e79b42a60992cde0f0f626 +U dan +Z da04231961fbad92750efdf2d0f0da36 diff --git a/manifest.uuid b/manifest.uuid index b6146d545b..23deb3b819 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7f953b568baa3eede0b9c144be0b9bc86496341a \ No newline at end of file +6bfa387e82de47ca1f40225fe28d873e29d6f481 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 68bb2fe53e..897da77ed7 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1065,8 +1065,7 @@ Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){ pNew->addrOpenEphm[1] = -1; pNew->addrOpenEphm[2] = -1; pNew->pWith = withDup(db, p->pWith); - assert( p->pRecurse==0 ); - pNew->pRecurse = 0; + pNew->pRecurse = p->pRecurse; return pNew; } #else diff --git a/src/select.c b/src/select.c index 96eae3ff6a..c5fb15cd86 100644 --- a/src/select.c +++ b/src/select.c @@ -1849,9 +1849,11 @@ static int multiSelect( ** references to the current CTE. */ p->pPrior = 0; p->pRecurse->tnum = tmp1; + assert( (p->pRecurse->tabFlags & TF_Recursive)==0 ); p->pRecurse->tabFlags |= TF_Recursive; rc = sqlite3Select(pParse, p, &tmp2dest); p->pRecurse->tabFlags &= ~TF_Recursive; + assert( p->pPrior==0 ); p->pPrior = pPrior; if( rc ) goto multi_select_end; @@ -2845,8 +2847,6 @@ static void substSelect( ** ** Flattening is only attempted if all of the following are true: ** -** (0) The subquery is not a recursive CTE. -** ** (1) The subquery and the outer query do not both use aggregates. ** ** (2) The subquery is not an aggregate or the outer query is not a join. @@ -2930,6 +2930,14 @@ static void substSelect( ** (21) The subquery does not use LIMIT or the outer query is not ** DISTINCT. (See ticket [752e1646fc]). ** +** (22) The subquery is not a recursive CTE. +** +** (23) The parent is not a recursive CTE, or the sub-query is not a +** compound query. This restriction is because transforming the +** parent to a compound query confuses the code that handles +** recursive queries in multiSelect(). +** +** ** In this routine, the "p" parameter is a pointer to the outer query. ** The subquery is p->pSrc->a[iFrom]. isAgg is true if the outer query ** uses aggregates and subqueryIsAgg is true if the subquery uses aggregates. @@ -2971,7 +2979,6 @@ static int flattenSubquery( iParent = pSubitem->iCursor; pSub = pSubitem->pSelect; assert( pSub!=0 ); - if( pSub->pRecurse ) return 0; /* Restriction (0) */ if( isAgg && subqueryIsAgg ) return 0; /* Restriction (1) */ if( subqueryIsAgg && pSrc->nSrc>1 ) return 0; /* Restriction (2) */ pSubSrc = pSub->pSrc; @@ -3002,6 +3009,8 @@ static int flattenSubquery( if( pSub->pLimit && (p->selFlags & SF_Distinct)!=0 ){ return 0; /* Restriction (21) */ } + if( pSub->pRecurse ) return 0; /* Restriction (22) */ + if( p->pRecurse && pSub->pPrior ) return 0; /* Restriction (23) */ /* OBSOLETE COMMENT 1: ** Restriction 3: If the subquery is a join, make sure the subquery is From 6ade453cd844a1cc65648477557d6cb770b60364 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 16 Jan 2014 15:31:41 +0000 Subject: [PATCH 153/276] Always use available indices to optimize LIKE operators even if the pattern of the LIKE operator has a COLLATE modifier. This fixes an ineffiency that was introduced into 3.7.15 by check-in [8542e6180d4] on 2012-12-08. FossilOrigin-Name: 16bd54783a3f5531c55564ddefdada657c078eb0 --- manifest | 16 +++++++-------- manifest.uuid | 2 +- src/where.c | 2 +- test/like.test | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 65 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index b7d3993e06..1aa2634f3e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarning\sin\sLEMON. -D 2014-01-14T10:17:21.693 +C Always\suse\savailable\sindices\sto\soptimize\sLIKE\soperators\seven\sif\sthe\spattern\nof\sthe\sLIKE\soperator\shas\sa\sCOLLATE\smodifier.\s\sThis\sfixes\san\sineffiency\sthat\nwas\sintroduced\sinto\s3.7.15\sby\scheck-in\s[8542e6180d4]\son\s2012-12-08. +D 2014-01-16T15:31:41.806 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -293,7 +293,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c e9e593d5bb798c3e67fc3893dfe7055c9e7d8d74 -F src/where.c 18f07fd0fd116a5880773c689eb7cd8e60175107 +F src/where.c 81cec50fe73633144b0730de477e141c53485862 F src/whereInt.h 96a75c61f1d2b9d4a8e4bb17d89deb0cf7cba358 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -646,7 +646,7 @@ F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa F test/keyword1.test a2400977a2e4fde43bf33754c2929fda34dbca05 F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63 F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200 -F test/like.test 935fb4f608e3ea126891496a6e99b9468372bf5c +F test/like.test e191e536d0fcd722a6b965e7cd1ee0bfd12a5991 F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da F test/limit.test cc0ab63385239b63c72452b0e93700bf5e8f0b99 F test/loadext.test 92e6dfefd1229c3ef4aaabd87419efd8fa57a7a5 @@ -1148,7 +1148,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 1e131094b522103a0829f72193b067b04e42ce82 -R fe4a4148cfbc4d588ee2679597656da4 -U mistachkin -Z d589f5ec7c09b4ac8c97497c20166016 +P f61a70589ac7e05008a362bd9d5b7bde5d07a758 +R c3393c71f3ebd7292d430bc7115b905d +U drh +Z 57df34b30b12b159eb99c0c8be54bec6 diff --git a/manifest.uuid b/manifest.uuid index d14b8afba5..b734040749 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f61a70589ac7e05008a362bd9d5b7bde5d07a758 \ No newline at end of file +16bd54783a3f5531c55564ddefdada657c078eb0 \ No newline at end of file diff --git a/src/where.c b/src/where.c index d5444a6054..a9f527313a 100644 --- a/src/where.c +++ b/src/where.c @@ -667,7 +667,7 @@ static int isLikeOrGlob( } assert( pLeft->iColumn!=(-1) ); /* Because IPK never has AFF_TEXT */ - pRight = pList->a[0].pExpr; + pRight = sqlite3ExprSkipCollate(pList->a[0].pExpr); op = pRight->op; if( op==TK_VARIABLE ){ Vdbe *pReprepare = pParse->pReprepare; diff --git a/test/like.test b/test/like.test index 230dc74fed..923272cfb2 100644 --- a/test/like.test +++ b/test/like.test @@ -893,5 +893,60 @@ do_test like-11.10 { } } {abc abcd sort {} t11cb} +# A COLLATE clause on the pattern does not change the result of a +# LIKE operator. +# +do_execsql_test like-12.1 { + CREATE TABLE t12nc(id INTEGER, x TEXT UNIQUE COLLATE nocase); + INSERT INTO t12nc VALUES(1,'abcde'),(2,'uvwxy'),(3,'ABCDEF'); + CREATE TABLE t12b(id INTEGER, x TEXT UNIQUE COLLATE binary); + INSERT INTO t12b VALUES(1,'abcde'),(2,'uvwxy'),(3,'ABCDEF'); + SELECT id FROM t12nc WHERE x LIKE 'abc%' ORDER BY +id; +} {1 3} +do_execsql_test like-12.2 { + SELECT id FROM t12b WHERE x LIKE 'abc%' ORDER BY +id; +} {1 3} +do_execsql_test like-12.3 { + SELECT id FROM t12nc WHERE x LIKE 'abc%' COLLATE binary ORDER BY +id; +} {1 3} +do_execsql_test like-12.4 { + SELECT id FROM t12b WHERE x LIKE 'abc%' COLLATE binary ORDER BY +id; +} {1 3} +do_execsql_test like-12.5 { + SELECT id FROM t12nc WHERE x LIKE 'abc%' COLLATE nocase ORDER BY +id; +} {1 3} +do_execsql_test like-12.6 { + SELECT id FROM t12b WHERE x LIKE 'abc%' COLLATE nocase ORDER BY +id; +} {1 3} + +# Adding a COLLATE clause to the pattern of a LIKE operator does nothing +# to change the suitability of using an index to satisfy that LIKE +# operator. +# +do_execsql_test like-12.11 { + EXPLAIN QUERY PLAN + SELECT id FROM t12nc WHERE x LIKE 'abc%' ORDER BY +id; +} {/SEARCH/} +do_execsql_test like-12.12 { + EXPLAIN QUERY PLAN + SELECT id FROM t12b WHERE x LIKE 'abc%' ORDER BY +id; +} {/SCAN/} +do_execsql_test like-12.13 { + EXPLAIN QUERY PLAN + SELECT id FROM t12nc WHERE x LIKE 'abc%' COLLATE nocase ORDER BY +id; +} {/SEARCH/} +do_execsql_test like-12.14 { + EXPLAIN QUERY PLAN + SELECT id FROM t12b WHERE x LIKE 'abc%' COLLATE nocase ORDER BY +id; +} {/SCAN/} +do_execsql_test like-12.15 { + EXPLAIN QUERY PLAN + SELECT id FROM t12nc WHERE x LIKE 'abc%' COLLATE binary ORDER BY +id; +} {/SEARCH/} +do_execsql_test like-12.16 { + EXPLAIN QUERY PLAN + SELECT id FROM t12b WHERE x LIKE 'abc%' COLLATE binary ORDER BY +id; +} {/SCAN/} + finish_test From eae73fbfb90594c3a56f16a55f69270f18d61bab Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 16 Jan 2014 18:34:33 +0000 Subject: [PATCH 154/276] Allow only a single recursive reference in a recursive CTE. Also require that this reference is not part of a sub-query. FossilOrigin-Name: a296b73360d34c9364eceb2cc09a9a92adc4abb8 --- manifest | 20 +++++------ manifest.uuid | 2 +- src/expr.c | 1 - src/select.c | 88 +++++++++++++++++++++++++++---------------------- src/sqliteInt.h | 5 ++- src/vdbe.c | 23 ------------- src/where.c | 8 +---- 7 files changed, 62 insertions(+), 85 deletions(-) diff --git a/manifest b/manifest index 86132841cd..817e0abe3d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Disable\sthe\sflattening\soptimization\sif\sthe\sparent\squery\sis\sthe\srecursive\spart\sof\sa\srecursive\sCTE\sand\sthe\ssub-query\sis\sa\scompound\squery. -D 2014-01-16T10:58:39.954 +C Allow\sonly\sa\ssingle\srecursive\sreference\sin\sa\srecursive\sCTE.\sAlso\srequire\sthat\sthis\sreference\sis\snot\spart\sof\sa\ssub-query. +D 2014-01-16T18:34:33.041 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -175,7 +175,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 F src/delete.c 91e1321021db5dc266360531b8b6550009d771ff -F src/expr.c c09e34fa7c58995009135b81f83cb62a676ad181 +F src/expr.c e239763d8b43356fa1f46f1cf41d62a076f7f72e F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 2ab0f5384b70594468ef3ac5c7ed8ca24bfd17d5 F src/func.c 6325ac2ec10833ccf4d5c36d323709221d37ea19 @@ -219,12 +219,12 @@ F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c ae278d8ce037883323f677e78c241f64289f12ec F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c 29976d169853492a20d3201e8a83eeefa39a868f +F src/select.c 2d2da29fd4c877646109f7d2fba26b5cc454cd37 F src/shell.c 9f3bc02a658b8f61d2cbe60cfc482f660c1c6c48 F src/sqlite.h.in d94a8b89522f526ba711182ee161e06f8669bcc9 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h 6db445ce172c249c29d8f532af64fd7051fe05dd +F src/sqliteInt.h b30bd95081be525b32551f180cf43ccfaff9f5bc F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -280,7 +280,7 @@ F src/update.c c2706a6eb232a96345c35b7e1e75a188e26812bb F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c e71f19b272f05c8695cf747b4bac1732685f9e5c F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c b06d79951a3f0da9cb41cb0aae5fdf5612f718a9 +F src/vdbe.c ccc8594e89751966022642464ec2b5c5fa7840a2 F src/vdbe.h e6c4c610fcabad4fa80ebb1efc6822a9367e2b26 F src/vdbeInt.h 42db251e9f863401ff847b90d5fe1614c89a6a56 F src/vdbeapi.c ce4e68ea4842cc6081046f533d088dcf01d247ad @@ -293,7 +293,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c e9e593d5bb798c3e67fc3893dfe7055c9e7d8d74 -F src/where.c 27eb508c4184599a826e2ef3b4319cd28ba2c7af +F src/where.c 369b0259fabfb22644d197736ae622f762cbaba8 F src/whereInt.h 96a75c61f1d2b9d4a8e4bb17d89deb0cf7cba358 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1150,7 +1150,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 7f953b568baa3eede0b9c144be0b9bc86496341a -R 1f82ce2970e79b42a60992cde0f0f626 +P 6bfa387e82de47ca1f40225fe28d873e29d6f481 +R d0f7d170eccd6b8c29b55960683e8b9a U dan -Z da04231961fbad92750efdf2d0f0da36 +Z 617b83d8e92edcc7afd63e19b605afe5 diff --git a/manifest.uuid b/manifest.uuid index 23deb3b819..8513fb5092 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6bfa387e82de47ca1f40225fe28d873e29d6f481 \ No newline at end of file +a296b73360d34c9364eceb2cc09a9a92adc4abb8 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 897da77ed7..0614be1cf5 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1065,7 +1065,6 @@ Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){ pNew->addrOpenEphm[1] = -1; pNew->addrOpenEphm[2] = -1; pNew->pWith = withDup(db, p->pWith); - pNew->pRecurse = p->pRecurse; return pNew; } #else diff --git a/src/select.c b/src/select.c index c5fb15cd86..d70d815a2a 100644 --- a/src/select.c +++ b/src/select.c @@ -1744,7 +1744,7 @@ static int multiSelect( ** the last (right-most) SELECT in the series may have an ORDER BY or LIMIT. */ assert( p && p->pPrior ); /* Calling function guarantees this much */ - assert( p->pRecurse==0 || p->op==TK_ALL || p->op==TK_UNION ); + assert( (p->selFlags & SF_Recursive)==0 || p->op==TK_ALL || p->op==TK_UNION ); db = pParse->db; pPrior = p->pPrior; assert( pPrior->pRightmost!=pPrior ); @@ -1794,27 +1794,36 @@ static int multiSelect( /* If this is a recursive query, check that there is no ORDER BY or ** LIMIT clause. Neither of these are supported. */ assert( p->pOffset==0 || p->pLimit ); - if( p->pRecurse && (p->pOrderBy || p->pLimit) ){ + if( (p->selFlags & SF_Recursive) && (p->pOrderBy || p->pLimit) ){ sqlite3ErrorMsg(pParse, "%s in a recursive query is not allowed", p->pOrderBy ? "ORDER BY" : "LIMIT" ); goto multi_select_end; } - if( p->pRecurse ){ + if( p->selFlags & SF_Recursive ){ + SrcList *pSrc = p->pSrc; int nCol = p->pEList->nExpr; int addrNext; int addrSwap; int iCont, iBreak; - int tmp1, tmp2; /* Cursors used to access temporary tables */ + int tmp1; /* Intermediate table */ + int tmp2; /* Next intermediate table */ int tmp3 = 0; /* To ensure unique results if UNION */ int eDest = SRT_Table; SelectDest tmp2dest; + int i; iBreak = sqlite3VdbeMakeLabel(v); iCont = sqlite3VdbeMakeLabel(v); - tmp1 = pParse->nTab++; + for(i=0; ALWAYS(inSrc); i++){ + if( pSrc->a[i].isRecursive ){ + tmp1 = pSrc->a[i].iCursor; + break; + } + } + tmp2 = pParse->nTab++; if( p->op==TK_UNION ){ eDest = SRT_DistTable; @@ -1848,11 +1857,7 @@ static int multiSelect( ** SELECT is running, the contents of tmp1 are read by recursive ** references to the current CTE. */ p->pPrior = 0; - p->pRecurse->tnum = tmp1; - assert( (p->pRecurse->tabFlags & TF_Recursive)==0 ); - p->pRecurse->tabFlags |= TF_Recursive; rc = sqlite3Select(pParse, p, &tmp2dest); - p->pRecurse->tabFlags &= ~TF_Recursive; assert( p->pPrior==0 ); p->pPrior = pPrior; if( rc ) goto multi_select_end; @@ -3009,8 +3014,8 @@ static int flattenSubquery( if( pSub->pLimit && (p->selFlags & SF_Distinct)!=0 ){ return 0; /* Restriction (21) */ } - if( pSub->pRecurse ) return 0; /* Restriction (22) */ - if( p->pRecurse && pSub->pPrior ) return 0; /* Restriction (23) */ + if( pSub->selFlags & SF_Recursive ) return 0; /* Restriction (22) */ + if( (p->selFlags & SF_Recursive) && pSub->pPrior ) return 0; /* (23) */ /* OBSOLETE COMMENT 1: ** Restriction 3: If the subquery is a join, make sure the subquery is @@ -3593,19 +3598,10 @@ static int withExpand( assert( pFrom->pTab==0 ); pCte = searchWith(pParse->pWith, pFrom); - if( pCte==0 ){ - /* no-op */ - }else if( pCte==pParse->pCte && (pTab = pCte->pTab) ){ - /* This is the recursive part of a recursive CTE */ - assert( pFrom->pTab==0 && pFrom->isRecursive==0 && pFrom->pSelect==0 ); - pFrom->pTab = pTab; - pFrom->isRecursive = 1; - pTab->nRef++; - }else{ + if( pCte ){ ExprList *pEList; Select *pSel; Select *pLeft; /* Left-most SELECT statement */ - int bRecursive; pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table)); if( pTab==0 ) return WRC_Abort; @@ -3618,16 +3614,37 @@ static int withExpand( if( db->mallocFailed ) return SQLITE_NOMEM; assert( pFrom->pSelect ); - if( ctePush(pParse, pCte) ) return WRC_Abort; + /* Check if this is a recursive CTE. */ pSel = pFrom->pSelect; - bRecursive = (pSel->op==TK_ALL || pSel->op==TK_UNION); - if( bRecursive ){ - assert( pSel->pPrior ); - sqlite3WalkSelect(pWalker, pSel->pPrior); - }else{ - sqlite3WalkSelect(pWalker, pSel); + if( pSel->op==TK_ALL || pSel->op==TK_UNION ){ + int i; + SrcList *pSrc = pFrom->pSelect->pSrc; + for(i=0; inSrc; i++){ + struct SrcList_item *pItem = &pSrc->a[i]; + if( pItem->zDatabase==0 + && pItem->zName!=0 + && 0==sqlite3StrICmp(pItem->zName, pCte->zName) + ){ + pItem->pTab = pTab; + pItem->isRecursive = 1; + pTab->nRef++; + pSel->selFlags |= SF_Recursive; + } + } } + /* Only one recursive reference is permitted. */ + if( pTab->nRef>2 ){ + sqlite3ErrorMsg( + pParse, "multiple recursive references in cte: %s", pCte->zName + ); + return WRC_Abort; + } + assert( pTab->nRef==1 || ((pSel->selFlags&SF_Recursive) && pTab->nRef==2 )); + + if( ctePush(pParse, pCte) ) return WRC_Abort; + sqlite3WalkSelect(pWalker, pTab->nRef==2 ? pSel->pPrior : pSel); + for(pLeft=pSel; pLeft->pPrior; pLeft=pLeft->pPrior); pEList = pLeft->pEList; if( pCte->pCols ){ @@ -3639,20 +3656,9 @@ static int withExpand( } pEList = pCte->pCols; } - selectColumnsFromExprList(pParse, pEList, &pTab->nCol, &pTab->aCol); - if( bRecursive ){ - int nRef = pTab->nRef; - pCte->pTab = pTab; - sqlite3WalkSelect(pWalker, pSel); - pCte->pTab = 0; - if( pTab->nRef > nRef){ - pSel->pRecurse = pTab; - assert( pTab->tnum==0 ); - } - } - + if( pSel->selFlags & SF_Recursive ) sqlite3WalkSelect(pWalker, pSel); ctePop(pParse, pCte); } @@ -3715,6 +3721,8 @@ static int selectExpander(Walker *pWalker, Select *p){ */ for(i=0, pFrom=pTabList->a; inSrc; i++, pFrom++){ Table *pTab; + assert( pFrom->isRecursive==0 || pFrom->pTab ); + if( pFrom->isRecursive ) continue; if( pFrom->pTab!=0 ){ /* This statement has already been prepared. There is no need ** to go further. */ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 733dad2d8f..43a1a57b0a 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2131,7 +2131,6 @@ struct NameContext { */ struct Select { ExprList *pEList; /* The fields of the result */ - Table *pRecurse; /* Non-NULL for the recursive part of recursive CTE */ u8 op; /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */ u16 selFlags; /* Various SF_* values */ int iLimit, iOffset; /* Memory registers holding LIMIT & OFFSET counters */ @@ -2165,6 +2164,7 @@ struct Select { #define SF_Materialize 0x0100 /* Force materialization of views */ #define SF_NestedFrom 0x0200 /* Part of a parenthesized FROM clause */ #define SF_MaybeConvert 0x0400 /* Need convertCompoundSelectToSubquery() */ +#define SF_Recursive 0x0800 /* The recursive part of a recursive CTE */ /* @@ -2640,7 +2640,7 @@ int sqlite3WalkSelectFrom(Walker*, Select*); #define WRC_Abort 2 /* Abandon the tree walk */ /* -** An instance of this structure represents a set of on or more CTEs +** An instance of this structure represents a set of one or more CTEs ** (common table expressions) created by a single WITH clause. */ struct With { @@ -2651,7 +2651,6 @@ struct With { ExprList *pCols; /* List of explicit column names, or NULL */ Select *pSelect; /* The definition of this CTE */ struct Cte *pOuterCte; /* Next WITH clause in outer context */ - Table *pTab; /* Table object for this CTE */ } a[1]; }; diff --git a/src/vdbe.c b/src/vdbe.c index 301707677d..9af4a62d7e 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3370,29 +3370,6 @@ case OP_OpenEphemeral: { } #ifndef SQLITE_OMIT_CTE -/* Opcode: OpenEphreader P1 P2 * * * -** -** P2 is a cursor opened by the OpenEphemeral opcode. This opcode opens -** a new read-only cursor named P1 that accesses the same epheremal table -** as P2. -*/ -case OP_OpenEphreader: { - VdbeCursor *pEph; - VdbeCursor *pCx; - Pgno pgno; - - pEph = p->apCsr[pOp->p2]; - pCx = allocateCursor(p, pOp->p1, pEph->nField, -1, 1); - if( pCx==0 ) goto no_mem; - pCx->nullRow = 1; - pCx->pKeyInfo = pEph->pKeyInfo; - pCx->isTable = pEph->isTable; - pCx->isOrdered = pEph->isOrdered; - pgno = MASTER_ROOT + !pCx->isTable; - rc = sqlite3BtreeCursor(pEph->pBt, pgno, 0, pCx->pKeyInfo, pCx->pCursor); - break; -} - /* Opcode: SwapCursors P1 P2 * * * ** ** Parameters P1 and P2 are both cursors opened by the OpenEphemeral diff --git a/src/where.c b/src/where.c index f1cf29b2e7..52bf46a74e 100644 --- a/src/where.c +++ b/src/where.c @@ -5654,13 +5654,7 @@ WhereInfo *sqlite3WhereBegin( iDb = sqlite3SchemaToIndex(db, pTab->pSchema); pLoop = pLevel->pWLoop; if( (pTab->tabFlags & TF_Ephemeral)!=0 || pTab->pSelect ){ -#ifndef SQLITE_OMIT_CTE - if( pTab->tabFlags & TF_Recursive ){ - int iCur = pTabItem->iCursor; - sqlite3VdbeAddOp2(v, OP_OpenEphreader, iCur, pTab->tnum); - } -#endif - /* Otherwise do nothing */ + /* Do nothing */ }else #ifndef SQLITE_OMIT_VIRTUALTABLE if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 ){ From f2655fe8b68be84a471389f0face897c82b02082 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 16 Jan 2014 21:02:02 +0000 Subject: [PATCH 155/276] Improve the error messages used to report illegal recursive cte references. FossilOrigin-Name: 54eee9fe99290e59469bd3e1a66bb749887d37ee --- manifest | 18 +++++++------- manifest.uuid | 2 +- src/build.c | 1 + src/select.c | 66 +++++++++++++++++-------------------------------- src/sqliteInt.h | 3 +-- test/with1.test | 62 ++++++++++++++++++++++++++++++++++++++++++++-- 6 files changed, 95 insertions(+), 57 deletions(-) diff --git a/manifest b/manifest index 817e0abe3d..9f4c9c003b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Allow\sonly\sa\ssingle\srecursive\sreference\sin\sa\srecursive\sCTE.\sAlso\srequire\sthat\sthis\sreference\sis\snot\spart\sof\sa\ssub-query. -D 2014-01-16T18:34:33.041 +C Improve\sthe\serror\smessages\sused\sto\sreport\sillegal\srecursive\scte\sreferences. +D 2014-01-16T21:02:02.206 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -169,7 +169,7 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btree.c c15e1722696b66c4029c487acfb830b0985bf142 F src/btree.h a61ddebc78c66795a2b93181321a116746302cc9 F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0 -F src/build.c 5a2daa6649640711ca60114046903be932348e52 +F src/build.c a6b9ba918f9194e955d198402076fe3203ff2567 F src/callback.c 174e3c8656bc29f91d710ab61550d16eea34be98 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd @@ -219,12 +219,12 @@ F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c ae278d8ce037883323f677e78c241f64289f12ec F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c 2d2da29fd4c877646109f7d2fba26b5cc454cd37 +F src/select.c 1b058f7ef37e2667fd33921531480a616a04bca2 F src/shell.c 9f3bc02a658b8f61d2cbe60cfc482f660c1c6c48 F src/sqlite.h.in d94a8b89522f526ba711182ee161e06f8669bcc9 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h b30bd95081be525b32551f180cf43ccfaff9f5bc +F src/sqliteInt.h d49c0bea5282f15c1eb1eb9d705770f70d19c1e2 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -1091,7 +1091,7 @@ F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c F test/win32lock.test 7a6bd73a5dcdee39b5bb93e92395e1773a194361 F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d -F test/with1.test 8ac68051fce8f2fe4a7bb6cb7ba62c0e941b1c84 +F test/with1.test f1602892682cd9bfa5b3b0a5d04b2283b61e7982 F test/withM.test 52448ce23e1c2ecba79d10e130ee49ce9f9a2a7a F test/without_rowid1.test aaa26da19d543cd8d3d2d0e686dfa255556c15c8 F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99 @@ -1150,7 +1150,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 6bfa387e82de47ca1f40225fe28d873e29d6f481 -R d0f7d170eccd6b8c29b55960683e8b9a +P a296b73360d34c9364eceb2cc09a9a92adc4abb8 +R 20dd6a1609afa0cf73fe04c795b9e1e4 U dan -Z 617b83d8e92edcc7afd63e19b605afe5 +Z 6bd9745179436f1c3b8a75548e64bd7b diff --git a/manifest.uuid b/manifest.uuid index 8513fb5092..2e74fdae17 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a296b73360d34c9364eceb2cc09a9a92adc4abb8 \ No newline at end of file +54eee9fe99290e59469bd3e1a66bb749887d37ee \ No newline at end of file diff --git a/src/build.c b/src/build.c index c7d956a9b7..353c938074 100644 --- a/src/build.c +++ b/src/build.c @@ -4245,6 +4245,7 @@ With *sqlite3WithAdd( pNew->a[pNew->nCte].pSelect = pQuery; pNew->a[pNew->nCte].pCols = pArglist; pNew->a[pNew->nCte].zName = zName; + pNew->a[pNew->nCte].zErr = 0; pNew->nCte++; } diff --git a/src/select.c b/src/select.c index d70d815a2a..7b6c5e9c2c 100644 --- a/src/select.c +++ b/src/select.c @@ -3533,44 +3533,6 @@ void sqlite3WithPush(Parse *pParse, With *pWith){ } } -/* -** If argument pCte is not NULL, check if it is already a part of the -** stack of CTEs stored by the parser. If so, this indicates an illegal -** recursive reference in a CTE, set of mutually recursive CTEs. Store -** an error in the parser and return SQLITE_ERROR if this is the case. -** -** Otherwise, if pCte is not already part of the stack of CTEs stored -** in the parser, push it onto the stop of that stack. -*/ -static int ctePush(Parse *pParse, struct Cte *pCte){ - if( pCte ){ - struct Cte *p; - for(p=pParse->pCte; p; p=p->pOuterCte){ - if( p==pCte ){ - sqlite3ErrorMsg( - pParse, "illegal recursive defininition in cte: %s", pCte->zName - ); - return SQLITE_ERROR; - } - } - - pCte->pOuterCte = pParse->pCte; - pParse->pCte = pCte; - } - return SQLITE_OK; -} -/* -** If argument pCte is not NULL, it must be a pointer to the CTE currently -** on top of the stack of CTEs stored in the parser. Remove it from that -** stack. -*/ -static void ctePop(Parse *pParse, struct Cte *pCte){ - if( pCte ){ - assert( pParse->pCte==pCte ); - pParse->pCte = pCte->pOuterCte; - } -} - /* ** This function checks if argument pFrom refers to a CTE declared by ** a WITH clause on the stack currently maintained by the parser. And, @@ -3602,6 +3564,16 @@ static int withExpand( ExprList *pEList; Select *pSel; Select *pLeft; /* Left-most SELECT statement */ + int bMayRecursive; /* True if compound joined by UNION [ALL] */ + + /* If pCte->zErr is non-NULL at this point, then this is an illegal + ** recursive reference to CTE pCte. Leave an error in pParse and return + ** early. If pCte->zErr is NULL, then this is not a recursive reference. + ** In this case, proceed. */ + if( pCte->zErr ){ + sqlite3ErrorMsg(pParse, pCte->zErr, pCte->zName); + return WRC_Abort; + } pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table)); if( pTab==0 ) return WRC_Abort; @@ -3616,7 +3588,8 @@ static int withExpand( /* Check if this is a recursive CTE. */ pSel = pFrom->pSelect; - if( pSel->op==TK_ALL || pSel->op==TK_UNION ){ + bMayRecursive = ( pSel->op==TK_ALL || pSel->op==TK_UNION ); + if( bMayRecursive ){ int i; SrcList *pSrc = pFrom->pSelect->pSrc; for(i=0; inSrc; i++){ @@ -3642,8 +3615,8 @@ static int withExpand( } assert( pTab->nRef==1 || ((pSel->selFlags&SF_Recursive) && pTab->nRef==2 )); - if( ctePush(pParse, pCte) ) return WRC_Abort; - sqlite3WalkSelect(pWalker, pTab->nRef==2 ? pSel->pPrior : pSel); + pCte->zErr = "circular reference to cte: %s"; + sqlite3WalkSelect(pWalker, bMayRecursive ? pSel->pPrior : pSel); for(pLeft=pSel; pLeft->pPrior; pLeft=pLeft->pPrior); pEList = pLeft->pEList; @@ -3658,8 +3631,15 @@ static int withExpand( } selectColumnsFromExprList(pParse, pEList, &pTab->nCol, &pTab->aCol); - if( pSel->selFlags & SF_Recursive ) sqlite3WalkSelect(pWalker, pSel); - ctePop(pParse, pCte); + if( bMayRecursive ){ + if( pSel->selFlags & SF_Recursive ){ + pCte->zErr = "multiple recursive references in cte: %s"; + }else{ + pCte->zErr = "recursive reference may not appear in sub-query: %s"; + } + sqlite3WalkSelect(pWalker, pSel); + } + pCte->zErr = 0; } return SQLITE_OK; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 43a1a57b0a..3f29f58d4e 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2371,7 +2371,6 @@ struct Parse { Table *pZombieTab; /* List of Table objects to delete after code gen */ TriggerPrg *pTriggerPrg; /* Linked list of coded triggers */ With *pWith; /* Current WITH clause, or NULL */ - struct Cte *pCte; /* Current CTE, or NULL */ }; /* @@ -2650,7 +2649,7 @@ struct With { char *zName; /* Name of this CTE */ ExprList *pCols; /* List of explicit column names, or NULL */ Select *pSelect; /* The definition of this CTE */ - struct Cte *pOuterCte; /* Next WITH clause in outer context */ + const char *zErr; /* Error message for circular references */ } a[1]; }; diff --git a/test/with1.test b/test/with1.test index 861c722543..4ad6260b78 100644 --- a/test/with1.test +++ b/test/with1.test @@ -76,10 +76,10 @@ do_execsql_test 2.5 { #------------------------------------------------------------------------- do_catchsql_test 3.1 { - WITH tmp2(x) AS ( SELECT * FROM tmp1), + WITH tmp2(x) AS ( SELECT * FROM tmp1 ), tmp1(a) AS ( SELECT * FROM tmp2 ) SELECT * FROM tmp1; -} {1 {illegal recursive defininition in cte: tmp1}} +} {1 {circular reference to cte: tmp1}} do_catchsql_test 3.2 { CREATE TABLE t2(x INTEGER); @@ -268,6 +268,64 @@ do_execsql_test 6.4 { } {10} +#------------------------------------------------------------------------- + +do_execsql_test 7.1 { + CREATE TABLE tree(i, p); + INSERT INTO tree VALUES(1, NULL); + INSERT INTO tree VALUES(2, 1); + INSERT INTO tree VALUES(3, 1); + INSERT INTO tree VALUES(4, 2); + INSERT INTO tree VALUES(5, 4); +} + +do_execsql_test 7.2 { + WITH t(id, path) AS ( + SELECT i, '' FROM tree WHERE p IS NULL + UNION ALL + SELECT i, path || '/' || i FROM tree, t WHERE p = id + ) + SELECT path FROM t; +} {{} /2 /3 /2/4 /2/4/5} + +do_execsql_test 7.3 { + WITH t(id) AS ( + VALUES(2) + UNION ALL + SELECT i FROM tree, t WHERE p = id + ) + SELECT id FROM t; +} {2 4 5} + +do_catchsql_test 7.4 { + WITH t(id) AS ( + VALUES(2) + UNION ALL + SELECT i FROM tree WHERE p IN (SELECT id FROM t) + ) + SELECT id FROM t; +} {1 {recursive reference may not appear in sub-query: t}} + +do_catchsql_test 7.5 { + WITH t(id) AS ( + VALUES(2) + UNION ALL + SELECT i FROM tree, t WHERE p = id AND p IN (SELECT id FROM t) + ) + SELECT id FROM t; +} {1 {multiple recursive references in cte: t}} + +do_catchsql_test 7.6 { + WITH t(id) AS ( + SELECT i FROM tree WHERE 2 IN (SELECT id FROM t) + UNION ALL + SELECT i FROM tree, t WHERE p = id + ) + SELECT id FROM t; +} {1 {circular reference to cte: t}} + + + finish_test From 727a99f1e313adecf162cf7c3199cc496d87099e Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 16 Jan 2014 21:59:51 +0000 Subject: [PATCH 156/276] Tweaks to error message text. FossilOrigin-Name: 090a77d97808b86d1e9f5c63c743a2b159a15f5d --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/build.c | 2 +- src/select.c | 10 +++++----- test/with1.test | 23 ++++++++++------------- 5 files changed, 26 insertions(+), 29 deletions(-) diff --git a/manifest b/manifest index 9f4c9c003b..f942fc379a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improve\sthe\serror\smessages\sused\sto\sreport\sillegal\srecursive\scte\sreferences. -D 2014-01-16T21:02:02.206 +C Tweaks\sto\serror\smessage\stext. +D 2014-01-16T21:59:51.988 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -169,7 +169,7 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btree.c c15e1722696b66c4029c487acfb830b0985bf142 F src/btree.h a61ddebc78c66795a2b93181321a116746302cc9 F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0 -F src/build.c a6b9ba918f9194e955d198402076fe3203ff2567 +F src/build.c 7e6c275ab1731510d6f793d0f88373ab3e858e69 F src/callback.c 174e3c8656bc29f91d710ab61550d16eea34be98 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd @@ -219,7 +219,7 @@ F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c ae278d8ce037883323f677e78c241f64289f12ec F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c 1b058f7ef37e2667fd33921531480a616a04bca2 +F src/select.c d75733ab2ad5e9f0d79fb4ab9f45d3d3d3675a3d F src/shell.c 9f3bc02a658b8f61d2cbe60cfc482f660c1c6c48 F src/sqlite.h.in d94a8b89522f526ba711182ee161e06f8669bcc9 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e @@ -1091,7 +1091,7 @@ F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c F test/win32lock.test 7a6bd73a5dcdee39b5bb93e92395e1773a194361 F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d -F test/with1.test f1602892682cd9bfa5b3b0a5d04b2283b61e7982 +F test/with1.test 90490c75e98e1914d84b7cef9e636b48917a020f F test/withM.test 52448ce23e1c2ecba79d10e130ee49ce9f9a2a7a F test/without_rowid1.test aaa26da19d543cd8d3d2d0e686dfa255556c15c8 F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99 @@ -1150,7 +1150,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P a296b73360d34c9364eceb2cc09a9a92adc4abb8 -R 20dd6a1609afa0cf73fe04c795b9e1e4 -U dan -Z 6bd9745179436f1c3b8a75548e64bd7b +P 54eee9fe99290e59469bd3e1a66bb749887d37ee +R 7385964692340c50e255f43b779c83ed +U drh +Z 3d3568f983c7b2bd0c47dd0558e3c02c diff --git a/manifest.uuid b/manifest.uuid index 2e74fdae17..bdfa111f79 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -54eee9fe99290e59469bd3e1a66bb749887d37ee \ No newline at end of file +090a77d97808b86d1e9f5c63c743a2b159a15f5d \ No newline at end of file diff --git a/src/build.c b/src/build.c index 353c938074..fa7364c3da 100644 --- a/src/build.c +++ b/src/build.c @@ -4222,7 +4222,7 @@ With *sqlite3WithAdd( int i; for(i=0; inCte; i++){ if( sqlite3StrICmp(zName, pWith->a[i].zName)==0 ){ - sqlite3ErrorMsg(pParse, "duplicate cte name: %s", zName); + sqlite3ErrorMsg(pParse, "duplicate WITH table name: %s", zName); } } } diff --git a/src/select.c b/src/select.c index 7b6c5e9c2c..ae2e0ce655 100644 --- a/src/select.c +++ b/src/select.c @@ -3609,20 +3609,20 @@ static int withExpand( /* Only one recursive reference is permitted. */ if( pTab->nRef>2 ){ sqlite3ErrorMsg( - pParse, "multiple recursive references in cte: %s", pCte->zName + pParse, "multiple references to recursive table: %s", pCte->zName ); return WRC_Abort; } assert( pTab->nRef==1 || ((pSel->selFlags&SF_Recursive) && pTab->nRef==2 )); - pCte->zErr = "circular reference to cte: %s"; + pCte->zErr = "circular reference: %s"; sqlite3WalkSelect(pWalker, bMayRecursive ? pSel->pPrior : pSel); for(pLeft=pSel; pLeft->pPrior; pLeft=pLeft->pPrior); pEList = pLeft->pEList; if( pCte->pCols ){ if( pEList->nExpr!=pCte->pCols->nExpr ){ - sqlite3ErrorMsg(pParse, "cte \"%s\" returns %d values for %d columns", + sqlite3ErrorMsg(pParse, "table %s has %d values for %d columns", pCte->zName, pEList->nExpr, pCte->pCols->nExpr ); return WRC_Abort; @@ -3633,9 +3633,9 @@ static int withExpand( if( bMayRecursive ){ if( pSel->selFlags & SF_Recursive ){ - pCte->zErr = "multiple recursive references in cte: %s"; + pCte->zErr = "multiple recursive references: %s"; }else{ - pCte->zErr = "recursive reference may not appear in sub-query: %s"; + pCte->zErr = "recursive reference in a subquery: %s"; } sqlite3WalkSelect(pWalker, pSel); } diff --git a/test/with1.test b/test/with1.test index 4ad6260b78..db0d7bc36e 100644 --- a/test/with1.test +++ b/test/with1.test @@ -79,14 +79,14 @@ do_catchsql_test 3.1 { WITH tmp2(x) AS ( SELECT * FROM tmp1 ), tmp1(a) AS ( SELECT * FROM tmp2 ) SELECT * FROM tmp1; -} {1 {circular reference to cte: tmp1}} +} {1 {circular reference: tmp1}} do_catchsql_test 3.2 { CREATE TABLE t2(x INTEGER); WITH tmp(a) AS (SELECT * FROM t1), tmp(a) AS (SELECT * FROM t1) SELECT * FROM tmp; -} {1 {duplicate cte name: tmp}} +} {1 {duplicate WITH table name: tmp}} do_execsql_test 3.3 { CREATE TABLE t3(x); @@ -172,23 +172,23 @@ do_execsql_test 5.5 { do_catchsql_test 5.6.1 { WITH i(x, y) AS ( VALUES(1) ) SELECT * FROM i; -} {1 {cte "i" returns 1 values for 2 columns}} +} {1 {table i has 1 values for 2 columns}} do_catchsql_test 5.6.2 { WITH i(x) AS ( VALUES(1,2) ) SELECT * FROM i; -} {1 {cte "i" returns 2 values for 1 columns}} +} {1 {table i has 2 values for 1 columns}} do_catchsql_test 5.6.3 { CREATE TABLE t5(a, b); WITH i(x) AS ( SELECT * FROM t5 ) SELECT * FROM i; -} {1 {cte "i" returns 2 values for 1 columns}} +} {1 {table i has 2 values for 1 columns}} do_catchsql_test 5.6.4 { WITH i(x) AS ( SELECT 1, 2 UNION ALL SELECT 1 ) SELECT * FROM i; -} {1 {cte "i" returns 2 values for 1 columns}} +} {1 {table i has 2 values for 1 columns}} do_catchsql_test 5.6.5 { WITH i(x) AS ( SELECT 1 UNION ALL SELECT 1, 2 ) @@ -203,7 +203,7 @@ do_catchsql_test 5.6.6 { do_catchsql_test 5.6.7 { WITH i(x) AS ( SELECT 1, 2 UNION SELECT x+1 FROM i ) SELECT * FROM i; -} {1 {cte "i" returns 2 values for 1 columns}} +} {1 {table i has 2 values for 1 columns}} #------------------------------------------------------------------------- # @@ -304,7 +304,7 @@ do_catchsql_test 7.4 { SELECT i FROM tree WHERE p IN (SELECT id FROM t) ) SELECT id FROM t; -} {1 {recursive reference may not appear in sub-query: t}} +} {1 {recursive reference in a subquery: t}} do_catchsql_test 7.5 { WITH t(id) AS ( @@ -313,7 +313,7 @@ do_catchsql_test 7.5 { SELECT i FROM tree, t WHERE p = id AND p IN (SELECT id FROM t) ) SELECT id FROM t; -} {1 {multiple recursive references in cte: t}} +} {1 {multiple recursive references: t}} do_catchsql_test 7.6 { WITH t(id) AS ( @@ -322,11 +322,8 @@ do_catchsql_test 7.6 { SELECT i FROM tree, t WHERE p = id ) SELECT id FROM t; -} {1 {circular reference to cte: t}} +} {1 {circular reference: t}} finish_test - - - From 65a2aaa633f1e8ab5a17be2af5e69dc90a0ea951 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 16 Jan 2014 22:40:02 +0000 Subject: [PATCH 157/276] Add the ability for the authorizer callback to disallow recursive queries. FossilOrigin-Name: 9efc120a1548c03f3d8aabbadf1050ff2a119c31 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/select.c | 3 +++ src/sqlite.h.in | 1 + src/tclsqlite.c | 1 + test/auth.test | 36 ++++++++++++++++++++++++++++++++++++ 6 files changed, 51 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index f942fc379a..4d2bec4250 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Tweaks\sto\serror\smessage\stext. -D 2014-01-16T21:59:51.988 +C Add\sthe\sability\sfor\sthe\sauthorizer\scallback\sto\sdisallow\srecursive\nqueries. +D 2014-01-16T22:40:02.405 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -219,16 +219,16 @@ F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c ae278d8ce037883323f677e78c241f64289f12ec F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c d75733ab2ad5e9f0d79fb4ab9f45d3d3d3675a3d +F src/select.c fc7499ac90fd4d49782e0a16372d3a5efde2aa3b F src/shell.c 9f3bc02a658b8f61d2cbe60cfc482f660c1c6c48 -F src/sqlite.h.in d94a8b89522f526ba711182ee161e06f8669bcc9 +F src/sqlite.h.in eed7f7d66a60daaa7b4a597dcd9bad87aad9611b F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc F src/sqliteInt.h d49c0bea5282f15c1eb1eb9d705770f70d19c1e2 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e -F src/tclsqlite.c c43379f77f90399802b0e215faa71c0adc3a4d2e +F src/tclsqlite.c 46073db71011b6542fde1f234c56a076d5ff23f9 F src/test1.c db16ba651453b15001c7f2838c446284dde4ecaf F src/test2.c 7355101c085304b90024f2261e056cdff13c6c35 F src/test3.c 1c0e5d6f080b8e33c1ce8b3078e7013fdbcd560c @@ -327,7 +327,7 @@ F test/attach2.test 0ec5defa340363de6cd50fd595046465e9aaba2d F test/attach3.test 359eb65d00102cdfcef6fa4e81dc1648f8f80b27 F test/attach4.test 53bf502f17647c6d6c5add46dda6bac8b6f4665c F test/attachmalloc.test 3a4bfca9545bfe906a8d2e622de10fbac5b711b0 -F test/auth.test 9bea29041871807d9f289ee679d05d3ed103642f +F test/auth.test 5bdf154eb28c0e4bbc0473f335858c0d96171768 F test/auth2.test c3b415b76c033bedb81292118fb7c01f5f10cbcd F test/auth3.test a4755e6a2a2fea547ffe63c874eb569e60a28eb5 F test/autoinc.test c58912526998a39e11f66b533e23cfabea7f25b7 @@ -1150,7 +1150,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 54eee9fe99290e59469bd3e1a66bb749887d37ee -R 7385964692340c50e255f43b779c83ed +P 090a77d97808b86d1e9f5c63c743a2b159a15f5d +R f01d2088e8545f61e859d9aad946ffb1 U drh -Z 3d3568f983c7b2bd0c47dd0558e3c02c +Z b5ce4714b23c3d6e2db0cb8e18c5a93d diff --git a/manifest.uuid b/manifest.uuid index bdfa111f79..dfccdb311f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -090a77d97808b86d1e9f5c63c743a2b159a15f5d \ No newline at end of file +9efc120a1548c03f3d8aabbadf1050ff2a119c31 \ No newline at end of file diff --git a/src/select.c b/src/select.c index ae2e0ce655..66eb4b3367 100644 --- a/src/select.c +++ b/src/select.c @@ -1814,6 +1814,9 @@ static int multiSelect( SelectDest tmp2dest; int i; + if( sqlite3AuthCheck(pParse, SQLITE_RECURSIVE, 0, 0, 0) ){ + goto multi_select_end; + } iBreak = sqlite3VdbeMakeLabel(v); iCont = sqlite3VdbeMakeLabel(v); diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 5012f864a5..51c864c5e2 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -2561,6 +2561,7 @@ int sqlite3_set_authorizer( #define SQLITE_FUNCTION 31 /* NULL Function Name */ #define SQLITE_SAVEPOINT 32 /* Operation Savepoint Name */ #define SQLITE_COPY 0 /* No longer used */ +#define SQLITE_RECURSIVE 33 /* NULL NULL */ /* ** CAPI3REF: Tracing And Profiling Functions diff --git a/src/tclsqlite.c b/src/tclsqlite.c index e3e5628b17..1e81912526 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -914,6 +914,7 @@ static int auth_callback( case SQLITE_DROP_VTABLE : zCode="SQLITE_DROP_VTABLE"; break; case SQLITE_FUNCTION : zCode="SQLITE_FUNCTION"; break; case SQLITE_SAVEPOINT : zCode="SQLITE_SAVEPOINT"; break; + case SQLITE_RECURSIVE : zCode="SQLITE_RECURSIVE"; break; default : zCode="????"; break; } Tcl_DStringInit(&str); diff --git a/test/auth.test b/test/auth.test index 5e91b33eaa..43e53ef2e3 100644 --- a/test/auth.test +++ b/test/auth.test @@ -2080,6 +2080,42 @@ ifcapable {altertable} { execsql {DROP TABLE t5} } ;# ifcapable altertable +ifcapable {cte} { + do_test auth-1.310 { + proc auth {code arg1 arg2 arg3 arg4} { + if {$code=="SQLITE_RECURSIVE"} { + return SQLITE_DENY + } + return SQLITE_OK + } + db eval { + DROP TABLE IF EXISTS t1; + CREATE TABLE t1(a,b); + INSERT INTO t1 VALUES(1,2),(3,4),(5,6); + } + } {} + do_catchsql_test auth-1.311 { + WITH + auth1311(x,y) AS (SELECT a+b, b-a FROM t1) + SELECT * FROM auth1311 ORDER BY x; + } {0 {3 1 7 1 11 1}} + do_catchsql_test auth-1.312 { + WITH RECURSIVE + auth1312(x,y) AS (SELECT a+b, b-a FROM t1) + SELECT x, y FROM auth1312 ORDER BY x; + } {0 {3 1 7 1 11 1}} + do_catchsql_test auth-1.313 { + WITH RECURSIVE + auth1313(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM auth1313 WHERE x<5) + SELECT * FROM t1; + } {0 {1 2 3 4 5 6}} + do_catchsql_test auth-1.314 { + WITH RECURSIVE + auth1314(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM auth1314 WHERE x<5) + SELECT * FROM t1 LEFT JOIN auth1314; + } {1 {not authorized}} +} ;# ifcapable cte + do_test auth-2.1 { proc auth {code arg1 arg2 arg3 arg4} { if {$code=="SQLITE_READ" && $arg1=="t3" && $arg2=="x"} { From 2d4dc5fc60b30abb406d7f5efcf5a1003b3fe300 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 17 Jan 2014 11:48:24 +0000 Subject: [PATCH 158/276] Remove some code from resolve.c that was only required for recursive cte references in sub-queries. Also a stray "finish_test" command in pagerfault.test. FossilOrigin-Name: f68c6c4d36481526a9348244adc571ea282dc9eb --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/resolve.c | 10 ---------- src/select.c | 22 +++++++++++----------- test/pagerfault.test | 1 - 5 files changed, 21 insertions(+), 32 deletions(-) diff --git a/manifest b/manifest index 4d2bec4250..5d2226d267 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sability\sfor\sthe\sauthorizer\scallback\sto\sdisallow\srecursive\nqueries. -D 2014-01-16T22:40:02.405 +C Remove\ssome\scode\sfrom\sresolve.c\sthat\swas\sonly\srequired\sfor\srecursive\scte\sreferences\sin\ssub-queries.\sAlso\sa\sstray\s"finish_test"\scommand\sin\spagerfault.test. +D 2014-01-17T11:48:24.294 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -217,9 +217,9 @@ F src/pragma.c ed409ce4104cf4d9de6ead40ace70974f124853b F src/prepare.c 677521ab7132615a8a26107a1d1c3132f44ae337 F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece -F src/resolve.c ae278d8ce037883323f677e78c241f64289f12ec +F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c fc7499ac90fd4d49782e0a16372d3a5efde2aa3b +F src/select.c 65c13f22edfd6af04829439955c7cf5749ea4e87 F src/shell.c 9f3bc02a658b8f61d2cbe60cfc482f660c1c6c48 F src/sqlite.h.in eed7f7d66a60daaa7b4a597dcd9bad87aad9611b F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e @@ -728,7 +728,7 @@ F test/pager1.test 1acbdb14c5952a72dd43129cabdbf69aaa3ed1fa F test/pager2.test 67b8f40ae98112bcdba1f2b2d03ea83266418c71 F test/pager3.test 3856d9c80839be0668efee1b74811b1b7f7fc95f F test/pager4.test b40ecb4cc7dff957ee7916e41ab21d1ed702a642 -F test/pagerfault.test cee8488a935e42a4a2e241e0317dc2814c997783 +F test/pagerfault.test 7285379906ab2f1108b8e82bbdf2d386cc8ff3ff F test/pagerfault2.test caf4c7facb914fd3b03a17b31ae2b180c8d6ca1f F test/pagerfault3.test 1003fcda009bf48a8e22a516e193b6ef0dd1bbd8 F test/pageropt.test 6b8f6a123a5572c195ad4ae40f2987007923bbd6 @@ -1150,7 +1150,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 090a77d97808b86d1e9f5c63c743a2b159a15f5d -R f01d2088e8545f61e859d9aad946ffb1 -U drh -Z b5ce4714b23c3d6e2db0cb8e18c5a93d +P 9efc120a1548c03f3d8aabbadf1050ff2a119c31 +R 175ad2c9f66168be6fabd0b7fdb44bd2 +U dan +Z 6e3919f2cc39eeea18a32475675bdfc0 diff --git a/manifest.uuid b/manifest.uuid index dfccdb311f..6e22de7d56 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9efc120a1548c03f3d8aabbadf1050ff2a119c31 \ No newline at end of file +f68c6c4d36481526a9348244adc571ea282dc9eb \ No newline at end of file diff --git a/src/resolve.c b/src/resolve.c index 724b8538fa..b0adb86295 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -502,16 +502,6 @@ lookupname_end: if( pExpr->op!=TK_AS ){ sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList); } - -#ifndef SQLITE_OMIT_CTE - /* If this expression reads a column value from a recursive CTE - ** reference, then this is equivalent to reading from the outermost - ** available name-context. */ - if( pMatch && pMatch->isRecursive ){ - while( pNC->pNext ) pNC = pNC->pNext; - } -#endif - /* Increment the nRef value on all name contexts from TopNC up to ** the point where the name matched. */ for(;;){ diff --git a/src/select.c b/src/select.c index 66eb4b3367..dc784b3b10 100644 --- a/src/select.c +++ b/src/select.c @@ -1791,16 +1791,6 @@ static int multiSelect( } #ifndef SQLITE_OMIT_CTE - /* If this is a recursive query, check that there is no ORDER BY or - ** LIMIT clause. Neither of these are supported. */ - assert( p->pOffset==0 || p->pLimit ); - if( (p->selFlags & SF_Recursive) && (p->pOrderBy || p->pLimit) ){ - sqlite3ErrorMsg(pParse, "%s in a recursive query is not allowed", - p->pOrderBy ? "ORDER BY" : "LIMIT" - ); - goto multi_select_end; - } - if( p->selFlags & SF_Recursive ){ SrcList *pSrc = p->pSrc; int nCol = p->pEList->nExpr; @@ -1814,6 +1804,16 @@ static int multiSelect( SelectDest tmp2dest; int i; + /* Check that there is no ORDER BY or LIMIT clause. Neither of these + ** are supported on recursive queries. */ + assert( p->pOffset==0 || p->pLimit ); + if( p->pOrderBy || p->pLimit ){ + sqlite3ErrorMsg(pParse, "%s in a recursive query is not allowed", + p->pOrderBy ? "ORDER BY" : "LIMIT" + ); + goto multi_select_end; + } + if( sqlite3AuthCheck(pParse, SQLITE_RECURSIVE, 0, 0, 0) ){ goto multi_select_end; } @@ -3581,7 +3581,7 @@ static int withExpand( pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table)); if( pTab==0 ) return WRC_Abort; pTab->nRef = 1; - pTab->zName = sqlite3MPrintf(db, "%s", pCte->zName); + pTab->zName = sqlite3DbStrDup(db, pCte->zName); pTab->iPKey = -1; pTab->nRowEst = 1048576; pTab->tabFlags |= TF_Ephemeral; diff --git a/test/pagerfault.test b/test/pagerfault.test index 1e57c93903..796f531c37 100644 --- a/test/pagerfault.test +++ b/test/pagerfault.test @@ -63,7 +63,6 @@ do_faultsim_test pagerfault-1 -prep { error "Database content appears incorrect" } } -finish_test #------------------------------------------------------------------------- # Test fault-injection while rolling back a hot-journal file with a From b290f1177553b866b806e5b987c060b9eed99758 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 17 Jan 2014 14:59:27 +0000 Subject: [PATCH 159/276] Fix some problems to do with WITH clauses and name resolution. FossilOrigin-Name: 6a549187ed8b5ed50daefa676ff666ae2ed43346 --- manifest | 21 +++++++++-------- manifest.uuid | 2 +- src/parse.y | 12 +++++----- src/select.c | 61 ++++++++++++++++++++++++------------------------- src/sqliteInt.h | 7 +++--- src/tokenize.c | 3 +-- src/walker.c | 23 ++++++++++--------- test/with2.test | 56 +++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 121 insertions(+), 64 deletions(-) create mode 100644 test/with2.test diff --git a/manifest b/manifest index 5d2226d267..586f354eac 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\ssome\scode\sfrom\sresolve.c\sthat\swas\sonly\srequired\sfor\srecursive\scte\sreferences\sin\ssub-queries.\sAlso\sa\sstray\s"finish_test"\scommand\sin\spagerfault.test. -D 2014-01-17T11:48:24.294 +C Fix\ssome\sproblems\sto\sdo\swith\sWITH\sclauses\sand\sname\sresolution. +D 2014-01-17T14:59:27.898 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -209,7 +209,7 @@ F src/os_unix.c 3a4dcb554d3c915075766162f28c3fd4cdb75968 F src/os_win.c 1b21af72c5fa6f9e519a5fcab33e80d182b1aedb F src/pager.c efa923693e958696eee69b205a20bfbc402c8480 F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428 -F src/parse.y 824eeb752c026b551bda2b66163889d7664b42e4 +F src/parse.y 475896cb883bbf4782e98abda42efbbdcbdb75f5 F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222 F src/pcache1.c 57fee9a9a617218f5037afbbe49b09da65bde56b @@ -219,12 +219,12 @@ F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c 65c13f22edfd6af04829439955c7cf5749ea4e87 +F src/select.c c77955f93121adc8b4b43a98add62fbaa2b48132 F src/shell.c 9f3bc02a658b8f61d2cbe60cfc482f660c1c6c48 F src/sqlite.h.in eed7f7d66a60daaa7b4a597dcd9bad87aad9611b F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h d49c0bea5282f15c1eb1eb9d705770f70d19c1e2 +F src/sqliteInt.h 9600eeb486c274fbdb815d040e4a7f262b7317e1 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -274,7 +274,7 @@ F src/test_thread.c 1e133a40b50e9c035b00174035b846e7eef481cb F src/test_vfs.c e72f555ef7a59080f898fcf1a233deb9eb704ea9 F src/test_vfstrace.c 3a0ab304682fecbceb689e7d9b904211fde11d78 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 -F src/tokenize.c 7dc42e9beb8c3263b79d10c195b3f5264b5f874a +F src/tokenize.c 6da2de6e12218ccb0aea5184b56727d011f4bee7 F src/trigger.c 5c1c0b899ac0ce284763dcb8fdbaa38ecf15ef98 F src/update.c c2706a6eb232a96345c35b7e1e75a188e26812bb F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 @@ -292,7 +292,7 @@ F src/vdbetrace.c 6f52bc0c51e144b7efdcfb2a8f771167a8816767 F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 -F src/walker.c e9e593d5bb798c3e67fc3893dfe7055c9e7d8d74 +F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45 F src/where.c 369b0259fabfb22644d197736ae622f762cbaba8 F src/whereInt.h 96a75c61f1d2b9d4a8e4bb17d89deb0cf7cba358 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1092,6 +1092,7 @@ F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c F test/win32lock.test 7a6bd73a5dcdee39b5bb93e92395e1773a194361 F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d F test/with1.test 90490c75e98e1914d84b7cef9e636b48917a020f +F test/with2.test 790c4b7ab3f4eb6984a3bbdae8d4ab429ebe9259 F test/withM.test 52448ce23e1c2ecba79d10e130ee49ce9f9a2a7a F test/without_rowid1.test aaa26da19d543cd8d3d2d0e686dfa255556c15c8 F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99 @@ -1150,7 +1151,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 9efc120a1548c03f3d8aabbadf1050ff2a119c31 -R 175ad2c9f66168be6fabd0b7fdb44bd2 +P f68c6c4d36481526a9348244adc571ea282dc9eb +R d73fd639096ae3d6dc6dd6a7018ffc11 U dan -Z 6e3919f2cc39eeea18a32475675bdfc0 +Z 6339477b00dd8c67441747d0ac03cfea diff --git a/manifest.uuid b/manifest.uuid index 6e22de7d56..71dd74abb9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f68c6c4d36481526a9348244adc571ea282dc9eb \ No newline at end of file +6a549187ed8b5ed50daefa676ff666ae2ed43346 \ No newline at end of file diff --git a/src/parse.y b/src/parse.y index 937669eb5c..0805407920 100644 --- a/src/parse.y +++ b/src/parse.y @@ -661,7 +661,7 @@ limit_opt(A) ::= LIMIT expr(X) COMMA expr(Y). %ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT cmd ::= with(C) DELETE FROM fullname(X) indexed_opt(I) where_opt(W) orderby_opt(O) limit_opt(L). { - sqlite3WithPush(pParse,C); + sqlite3WithPush(pParse, C, 1); sqlite3SrcListIndexedBy(pParse, X, &I); W = sqlite3LimitWhere(pParse, X, W, O, L.pLimit, L.pOffset, "DELETE"); sqlite3DeleteFrom(pParse,X,W); @@ -669,7 +669,7 @@ cmd ::= with(C) DELETE FROM fullname(X) indexed_opt(I) where_opt(W) %endif %ifndef SQLITE_ENABLE_UPDATE_DELETE_LIMIT cmd ::= with(C) DELETE FROM fullname(X) indexed_opt(I) where_opt(W). { - sqlite3WithPush(pParse,C); + sqlite3WithPush(pParse, C, 1); sqlite3SrcListIndexedBy(pParse, X, &I); sqlite3DeleteFrom(pParse,X,W); } @@ -686,7 +686,7 @@ where_opt(A) ::= WHERE expr(X). {A = X.pExpr;} %ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT cmd ::= with(C) UPDATE orconf(R) fullname(X) indexed_opt(I) SET setlist(Y) where_opt(W) orderby_opt(O) limit_opt(L). { - sqlite3WithPush(pParse, C); + sqlite3WithPush(pParse, C, 1); sqlite3SrcListIndexedBy(pParse, X, &I); sqlite3ExprListCheckLength(pParse,Y,"set list"); W = sqlite3LimitWhere(pParse, X, W, O, L.pLimit, L.pOffset, "UPDATE"); @@ -696,7 +696,7 @@ cmd ::= with(C) UPDATE orconf(R) fullname(X) indexed_opt(I) SET setlist(Y) %ifndef SQLITE_ENABLE_UPDATE_DELETE_LIMIT cmd ::= with(C) UPDATE orconf(R) fullname(X) indexed_opt(I) SET setlist(Y) where_opt(W). { - sqlite3WithPush(pParse, C); + sqlite3WithPush(pParse, C, 1); sqlite3SrcListIndexedBy(pParse, X, &I); sqlite3ExprListCheckLength(pParse,Y,"set list"); sqlite3Update(pParse,X,Y,W,R); @@ -718,12 +718,12 @@ setlist(A) ::= nm(X) EQ expr(Y). { ////////////////////////// The INSERT command ///////////////////////////////// // cmd ::= with(W) insert_cmd(R) INTO fullname(X) inscollist_opt(F) select(S). { - sqlite3WithPush(pParse, W); + sqlite3WithPush(pParse, W, 1); sqlite3Insert(pParse, X, S, F, R); } cmd ::= with(W) insert_cmd(R) INTO fullname(X) inscollist_opt(F) DEFAULT VALUES. { - sqlite3WithPush(pParse, W); + sqlite3WithPush(pParse, W, 1); sqlite3Insert(pParse, X, 0, F, R); } diff --git a/src/select.c b/src/select.c index dc784b3b10..d9625cba43 100644 --- a/src/select.c +++ b/src/select.c @@ -3527,12 +3527,19 @@ static struct Cte *searchWith(With *pWith, struct SrcList_item *pItem){ /* The code generator maintains a stack of active WITH clauses ** with the inner-most WITH clause being at the top of the stack. ** -** These routines push and pull WITH clauses on the stack. +** This routine pushes the WITH clause passed as the second argument +** onto the top of the stack. If argument bFree is true, then this +** WITH clause will never be popped from the stack. In this case it +** should be freed along with the Parse object. In other cases, when +** bFree==0, the With object will be freed along with the SELECT +** statement with which it is associated. */ -void sqlite3WithPush(Parse *pParse, With *pWith){ +void sqlite3WithPush(Parse *pParse, With *pWith, u8 bFree){ + assert( bFree==0 || pParse->pWith==0 ); if( pWith ){ pWith->pOuter = pParse->pWith; pParse->pWith = pWith; + pParse->bFreeWith = bFree; } } @@ -3649,6 +3656,19 @@ static int withExpand( } #endif +#ifndef SQLITE_OMIT_CTE +static void selectPopWith(Walker *pWalker, Select *p){ + Parse *pParse = pWalker->pParse; + if( p->pWith ){ + assert( pParse->pWith==p->pWith ); + pParse->pWith = p->pWith->pOuter; + } + return WRC_Continue; +} +#else +#define selectPopWith 0 +#endif + /* ** This routine is a Walker callback for "expanding" a SELECT statement. ** "Expanding" means to do the following: @@ -3692,6 +3712,7 @@ static int selectExpander(Walker *pWalker, Select *p){ } pTabList = p->pSrc; pEList = p->pEList; + sqlite3WithPush(pParse, p->pWith, 0); /* Make sure cursor numbers have been assigned to all entries in ** the FROM clause of the SELECT statement. @@ -3710,6 +3731,9 @@ static int selectExpander(Walker *pWalker, Select *p){ /* This statement has already been prepared. There is no need ** to go further. */ assert( i==0 ); +#ifndef SQLITE_OMIT_CTE + selectPopWith(pWalker, p); +#endif return WRC_Prune; } #ifndef SQLITE_OMIT_CTE @@ -3941,30 +3965,6 @@ static int selectExpander(Walker *pWalker, Select *p){ return WRC_Continue; } -/* -** Function (or macro) selectExpanderWith is used as the SELECT callback -** by sqlite3SelectExpand(). In builds that do not support CTEs, this -** is equivalent to the selectExpander() function. In CTE-enabled builds, -** any WITH clause associated with the SELECT statement needs to be -** pushed onto the stack before calling selectExpander(), and popped -** off again afterwards. -*/ -#ifndef SQLITE_OMIT_CTE -static int selectExpanderWith(Walker *pWalker, Select *p){ - Parse *pParse = pWalker->pParse; - int res; - sqlite3WithPush(pParse, p->pWith); - res = selectExpander(pWalker, p); - if( p->pWith ){ - assert( pParse->pWith==p->pWith ); - pParse->pWith = p->pWith->pOuter; - } - return res; -} -#else -#define selectExpanderWith selectExpander -#endif - /* ** No-op routine for the parse-tree walker. ** @@ -4001,7 +4001,8 @@ static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){ w.xSelectCallback = convertCompoundSelectToSubquery; sqlite3WalkSelect(&w, pSelect); } - w.xSelectCallback = selectExpanderWith; + w.xSelectCallback = selectExpander; + w.xSelectCallback2 = selectPopWith; sqlite3WalkSelect(&w, pSelect); } @@ -4020,7 +4021,7 @@ static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){ ** at that point because identifiers had not yet been resolved. This ** routine is called after identifier resolution. */ -static int selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){ +static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){ Parse *pParse; int i; SrcList *pTabList; @@ -4043,7 +4044,6 @@ static int selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){ } } } - return WRC_Continue; } #endif @@ -4059,10 +4059,9 @@ static void sqlite3SelectAddTypeInfo(Parse *pParse, Select *pSelect){ #ifndef SQLITE_OMIT_SUBQUERY Walker w; memset(&w, 0, sizeof(w)); - w.xSelectCallback = selectAddSubqueryTypeInfo; + w.xSelectCallback2 = selectAddSubqueryTypeInfo; w.xExprCallback = exprWalkNoop; w.pParse = pParse; - w.bSelectDepthFirst = 1; sqlite3WalkSelect(&w, pSelect); #endif } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 3f29f58d4e..1cdaf09dc7 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2371,6 +2371,7 @@ struct Parse { Table *pZombieTab; /* List of Table objects to delete after code gen */ TriggerPrg *pTriggerPrg; /* Linked list of coded triggers */ With *pWith; /* Current WITH clause, or NULL */ + u8 bFreeWith; /* True if pWith should be freed with parser */ }; /* @@ -2612,9 +2613,9 @@ struct Sqlite3Config { struct Walker { int (*xExprCallback)(Walker*, Expr*); /* Callback for expressions */ int (*xSelectCallback)(Walker*,Select*); /* Callback for SELECTs */ + void (*xSelectCallback2)(Walker*,Select*);/* Second callback for SELECTs */ Parse *pParse; /* Parser context. */ int walkerDepth; /* Number of subqueries */ - u8 bSelectDepthFirst; /* Do subqueries first */ union { /* Extra data for callback */ NameContext *pNC; /* Naming context */ int i; /* Integer value */ @@ -3354,9 +3355,9 @@ const char *sqlite3JournalModename(int); #ifndef SQLITE_OMIT_CTE With *sqlite3WithAdd(Parse*,With*,Token*,ExprList*,Select*); void sqlite3WithDelete(sqlite3*,With*); - void sqlite3WithPush(Parse*, With*); + void sqlite3WithPush(Parse*, With*, u8); #else -#define sqlite3WithPush(x,y) +#define sqlite3WithPush(x,y,z) #define sqlite3WithDelete(x,y) #endif diff --git a/src/tokenize.c b/src/tokenize.c index 3fd4f78f7a..87553e25b0 100644 --- a/src/tokenize.c +++ b/src/tokenize.c @@ -494,8 +494,7 @@ abort_parse: sqlite3DeleteTable(db, pParse->pNewTable); } - assert( pParse->pWith==0 || pParse->pWith->pOuter==0 ); - sqlite3WithDelete(db, pParse->pWith); + if( pParse->bFreeWith ) sqlite3WithDelete(db, pParse->pWith); sqlite3DeleteTrigger(db, pParse->pNewTrigger); for(i=pParse->nzVar-1; i>=0; i--) sqlite3DbFree(db, pParse->azVar[i]); sqlite3DbFree(db, pParse->azVar); diff --git a/src/walker.c b/src/walker.c index cde34ad780..016ae77a92 100644 --- a/src/walker.c +++ b/src/walker.c @@ -113,9 +113,12 @@ int sqlite3WalkSelectFrom(Walker *pWalker, Select *p){ /* ** Call sqlite3WalkExpr() for every expression in Select statement p. ** Invoke sqlite3WalkSelect() for subqueries in the FROM clause and -** on the compound select chain, p->pPrior. Invoke the xSelectCallback() -** either before or after the walk of expressions and FROM clause, depending -** on whether pWalker->bSelectDepthFirst is false or true, respectively. +** on the compound select chain, p->pPrior. +** +** If it is not NULL, the xSelectCallback() callback is invoked before +** the walk of the expressions and FROM clause. The xSelectCallback2() +** method, if it is not NULL, is invoked following the walk of the +** expressions and FROM clause. ** ** Return WRC_Continue under normal conditions. Return WRC_Abort if ** there is an abort request. @@ -125,11 +128,13 @@ int sqlite3WalkSelectFrom(Walker *pWalker, Select *p){ */ int sqlite3WalkSelect(Walker *pWalker, Select *p){ int rc; - if( p==0 || pWalker->xSelectCallback==0 ) return WRC_Continue; + if( p==0 || (pWalker->xSelectCallback==0 && pWalker->xSelectCallback2==0) ){ + return WRC_Continue; + } rc = WRC_Continue; pWalker->walkerDepth++; while( p ){ - if( !pWalker->bSelectDepthFirst ){ + if( pWalker->xSelectCallback ){ rc = pWalker->xSelectCallback(pWalker, p); if( rc ) break; } @@ -139,12 +144,8 @@ int sqlite3WalkSelect(Walker *pWalker, Select *p){ pWalker->walkerDepth--; return WRC_Abort; } - if( pWalker->bSelectDepthFirst ){ - rc = pWalker->xSelectCallback(pWalker, p); - /* Depth-first search is currently only used for - ** selectAddSubqueryTypeInfo() and that routine always returns - ** WRC_Continue (0). So the following branch is never taken. */ - if( NEVER(rc) ) break; + if( pWalker->xSelectCallback2 ){ + pWalker->xSelectCallback2(pWalker, p); } p = p->pPrior; } diff --git a/test/with2.test b/test/with2.test new file mode 100644 index 0000000000..83b3b73646 --- /dev/null +++ b/test/with2.test @@ -0,0 +1,56 @@ +# 2014 January 11 +# +# 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 WITH clause. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set ::testprefix with2 + +do_execsql_test 1.0 { + CREATE TABLE t1(a); + INSERT INTO t1 VALUES(1); + INSERT INTO t1 VALUES(2); +} + +do_execsql_test 1.1 { + WITH x1 AS (SELECT * FROM t1) + SELECT sum(a) FROM x1; +} {3} + +do_execsql_test 1.2 { + WITH x1 AS (SELECT * FROM t1) + SELECT (SELECT sum(a) FROM x1); +} {3} + +do_execsql_test 1.3 { + WITH x1 AS (SELECT * FROM t1) + SELECT (SELECT sum(a) FROM x1); +} {3} + +do_execsql_test 1.4 { + CREATE TABLE t2(i); + INSERT INTO t2 VALUES(2); + INSERT INTO t2 VALUES(3); + INSERT INTO t2 VALUES(5); + + WITH x1 AS (SELECT i FROM t2), + i(a) AS ( + SELECT min(i)-1 FROM x1 UNION SELECT a+1 FROM i WHERE a<10 + ) + SELECT a FROM i WHERE a NOT IN x1 +} {1 4 6 7 8 9 10} + +finish_test + + + From 6785bcca586fca4c1dec27ede9f2f246de5d9fa9 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 17 Jan 2014 15:27:00 +0000 Subject: [PATCH 160/276] Fix a compiler warning in selectPopWith(). FossilOrigin-Name: c8eb11635a356182611ce2ccb8f358b6c453486e --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/select.c | 1 - 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 61c516e9dd..ab69979816 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\ssupport\sfor\scommon\stable\sexpressions\s(WITH\sclauses). -D 2014-01-17T15:15:10.270 +C Fix\sa\scompiler\swarning\sin\sselectPopWith(). +D 2014-01-17T15:27:00.626 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -219,7 +219,7 @@ F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c 231079b8b07ea6f3cf4663e9c0ef2315abe2236c +F src/select.c b17dd5c3ef4647190bd80f51b56e366c7b12f6e5 F src/shell.c 9f3bc02a658b8f61d2cbe60cfc482f660c1c6c48 F src/sqlite.h.in eed7f7d66a60daaa7b4a597dcd9bad87aad9611b F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e @@ -1151,7 +1151,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 16bd54783a3f5531c55564ddefdada657c078eb0 6a549187ed8b5ed50daefa676ff666ae2ed43346 -R 3149ee3ed72aa52234b32eaa7e696309 -U dan -Z e17f48449fd6868168f4a2f61958f3af +P 0171e3bb4f663a9414b0e8b64c87b5d0683855b5 +R e6bcc1e354d62890d139633299faf33a +U drh +Z 11b7b8a08f3ff8f2c5eec014f3cfaffd diff --git a/manifest.uuid b/manifest.uuid index 5d482e8fa7..7b5cce4842 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0171e3bb4f663a9414b0e8b64c87b5d0683855b5 \ No newline at end of file +c8eb11635a356182611ce2ccb8f358b6c453486e \ No newline at end of file diff --git a/src/select.c b/src/select.c index b3a6daf170..956015840c 100644 --- a/src/select.c +++ b/src/select.c @@ -3671,7 +3671,6 @@ static void selectPopWith(Walker *pWalker, Select *p){ assert( pParse->pWith==p->pWith ); pParse->pWith = p->pWith->pOuter; } - return WRC_Continue; } #else #define selectPopWith 0 From a026b98500999f34506b2c4cf0ecb727b326c619 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 17 Jan 2014 16:19:01 +0000 Subject: [PATCH 161/276] Add tests that verify that keywords WITH, WITHOUT, and RECURSIVE can still be used as table and column names. FossilOrigin-Name: 9ca18a0191db6a9b0763e2f0b3b35d23099fb71b --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/keyword1.test | 3 +++ 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index ab69979816..984a0a27fe 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\scompiler\swarning\sin\sselectPopWith(). -D 2014-01-17T15:27:00.626 +C Add\stests\sthat\sverify\sthat\skeywords\sWITH,\sWITHOUT,\sand\sRECURSIVE\scan\sstill\nbe\sused\sas\stable\sand\scolumn\snames. +D 2014-01-17T16:19:01.842 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -643,7 +643,7 @@ F test/journal3.test ff8af941f9e06161d3db1b46bb9f965ff0e7f307 F test/jrnlmode.test 9ee3a78f53d52cca737db69293d15dc41c0cbd36 F test/jrnlmode2.test 81610545a4e6ed239ea8fa661891893385e23a1d F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa -F test/keyword1.test a2400977a2e4fde43bf33754c2929fda34dbca05 +F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63 F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200 F test/like.test e191e536d0fcd722a6b965e7cd1ee0bfd12a5991 @@ -1151,7 +1151,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 0171e3bb4f663a9414b0e8b64c87b5d0683855b5 -R e6bcc1e354d62890d139633299faf33a +P c8eb11635a356182611ce2ccb8f358b6c453486e +R c791b577950f1652718e7fda0d0264df U drh -Z 11b7b8a08f3ff8f2c5eec014f3cfaffd +Z 3da1c453f8a3e6f09e0b3d8bdad77daa diff --git a/manifest.uuid b/manifest.uuid index 7b5cce4842..4cfd423b13 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c8eb11635a356182611ce2ccb8f358b6c453486e \ No newline at end of file +9ca18a0191db6a9b0763e2f0b3b35d23099fb71b \ No newline at end of file diff --git a/test/keyword1.test b/test/keyword1.test index 94831201ce..2bc1ff5494 100644 --- a/test/keyword1.test +++ b/test/keyword1.test @@ -65,6 +65,7 @@ set kwlist { pragma query raise + recursive regexp reindex release @@ -80,6 +81,8 @@ set kwlist { vacuum view virtual + with + without }; set exprkw { cast From 98f45e53a74e4522f129c11d03993b3d17785559 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 17 Jan 2014 17:40:46 +0000 Subject: [PATCH 162/276] Resolve table names within CTEs in the context in which the CTE is declared, not the context in which it is used. FossilOrigin-Name: a7323838bbd354a1c2f339e5e0f164f0eada47b3 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/select.c | 30 ++++++++++++++++++++++-------- test/with2.test | 21 +++++++++++++++++++-- 4 files changed, 50 insertions(+), 19 deletions(-) diff --git a/manifest b/manifest index 984a0a27fe..7dbf068c5b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stests\sthat\sverify\sthat\skeywords\sWITH,\sWITHOUT,\sand\sRECURSIVE\scan\sstill\nbe\sused\sas\stable\sand\scolumn\snames. -D 2014-01-17T16:19:01.842 +C Resolve\stable\snames\swithin\sCTEs\sin\sthe\scontext\sin\swhich\sthe\sCTE\sis\sdeclared,\snot\sthe\scontext\sin\swhich\sit\sis\sused. +D 2014-01-17T17:40:46.168 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -219,7 +219,7 @@ F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c b17dd5c3ef4647190bd80f51b56e366c7b12f6e5 +F src/select.c a13cf4a450534bcbdf1cc840d695e259cd4a1409 F src/shell.c 9f3bc02a658b8f61d2cbe60cfc482f660c1c6c48 F src/sqlite.h.in eed7f7d66a60daaa7b4a597dcd9bad87aad9611b F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e @@ -1092,7 +1092,7 @@ F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c F test/win32lock.test 7a6bd73a5dcdee39b5bb93e92395e1773a194361 F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d F test/with1.test 90490c75e98e1914d84b7cef9e636b48917a020f -F test/with2.test 790c4b7ab3f4eb6984a3bbdae8d4ab429ebe9259 +F test/with2.test 21057990b59eb652a0a30c6a421fac9daad4412d F test/withM.test 52448ce23e1c2ecba79d10e130ee49ce9f9a2a7a F test/without_rowid1.test aaa26da19d543cd8d3d2d0e686dfa255556c15c8 F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99 @@ -1151,7 +1151,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P c8eb11635a356182611ce2ccb8f358b6c453486e -R c791b577950f1652718e7fda0d0264df -U drh -Z 3da1c453f8a3e6f09e0b3d8bdad77daa +P 9ca18a0191db6a9b0763e2f0b3b35d23099fb71b +R b5a3302763f84d4efb48b14faba25e2d +U dan +Z c42b677f74f4986c260cd54897199c85 diff --git a/manifest.uuid b/manifest.uuid index 4cfd423b13..6be4f2395e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9ca18a0191db6a9b0763e2f0b3b35d23099fb71b \ No newline at end of file +a7323838bbd354a1c2f339e5e0f164f0eada47b3 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 956015840c..b3f16e6113 100644 --- a/src/select.c +++ b/src/select.c @@ -3507,8 +3507,15 @@ static int convertCompoundSelectToSubquery(Walker *pWalker, Select *p){ ** FROM clause element pItem is really a common-table-expression (CTE) ** then return a pointer to the CTE definition for that table. Otherwise ** return NULL. +** +** If a non-NULL value is returned, set *ppContext to point to the With +** object that the returned CTE belongs to. */ -static struct Cte *searchWith(With *pWith, struct SrcList_item *pItem){ +static struct Cte *searchWith( + With *pWith, /* Current outermost WITH clause */ + struct SrcList_item *pItem, /* FROM clause element to resolve */ + With **ppContext /* OUT: WITH clause return value belongs to */ +){ const char *zName; if( pItem->zDatabase==0 && (zName = pItem->zName)!=0 ){ With *p; @@ -3516,6 +3523,7 @@ static struct Cte *searchWith(With *pWith, struct SrcList_item *pItem){ int i; for(i=0; inCte; i++){ if( sqlite3StrICmp(zName, p->a[i].zName)==0 ){ + *ppContext = p; return &p->a[i]; } } @@ -3562,19 +3570,21 @@ static int withExpand( Walker *pWalker, struct SrcList_item *pFrom ){ - Table *pTab; Parse *pParse = pWalker->pParse; sqlite3 *db = pParse->db; - struct Cte *pCte; + struct Cte *pCte; /* Matched CTE (or NULL if no match) */ + With *pWith; /* WITH clause that pCte belongs to */ assert( pFrom->pTab==0 ); - pCte = searchWith(pParse->pWith, pFrom); + pCte = searchWith(pParse->pWith, pFrom, &pWith); if( pCte ){ + Table *pTab; ExprList *pEList; Select *pSel; Select *pLeft; /* Left-most SELECT statement */ int bMayRecursive; /* True if compound joined by UNION [ALL] */ + With *pSavedWith; /* Initial value of pParse->pWith */ /* If pCte->zErr is non-NULL at this point, then this is an illegal ** recursive reference to CTE pCte. Leave an error in pParse and return @@ -3582,7 +3592,7 @@ static int withExpand( ** In this case, proceed. */ if( pCte->zErr ){ sqlite3ErrorMsg(pParse, pCte->zErr, pCte->zName); - return WRC_Abort; + return SQLITE_ERROR; } pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table)); @@ -3621,11 +3631,13 @@ static int withExpand( sqlite3ErrorMsg( pParse, "multiple references to recursive table: %s", pCte->zName ); - return WRC_Abort; + return SQLITE_ERROR; } assert( pTab->nRef==1 || ((pSel->selFlags&SF_Recursive) && pTab->nRef==2 )); pCte->zErr = "circular reference: %s"; + pSavedWith = pParse->pWith; + pParse->pWith = pWith; sqlite3WalkSelect(pWalker, bMayRecursive ? pSel->pPrior : pSel); for(pLeft=pSel; pLeft->pPrior; pLeft=pLeft->pPrior); @@ -3635,12 +3647,13 @@ static int withExpand( sqlite3ErrorMsg(pParse, "table %s has %d values for %d columns", pCte->zName, pEList->nExpr, pCte->pCols->nExpr ); - return WRC_Abort; + pParse->pWith = pSavedWith; + return SQLITE_ERROR; } pEList = pCte->pCols; } - selectColumnsFromExprList(pParse, pEList, &pTab->nCol, &pTab->aCol); + selectColumnsFromExprList(pParse, pEList, &pTab->nCol, &pTab->aCol); if( bMayRecursive ){ if( pSel->selFlags & SF_Recursive ){ pCte->zErr = "multiple recursive references: %s"; @@ -3650,6 +3663,7 @@ static int withExpand( sqlite3WalkSelect(pWalker, pSel); } pCte->zErr = 0; + pParse->pWith = pSavedWith; } return SQLITE_OK; diff --git a/test/with2.test b/test/with2.test index 83b3b73646..08ef7bf6f7 100644 --- a/test/with2.test +++ b/test/with2.test @@ -50,7 +50,24 @@ do_execsql_test 1.4 { SELECT a FROM i WHERE a NOT IN x1 } {1 4 6 7 8 9 10} +do_execsql_test 1.5 { + WITH x1 AS (SELECT a FROM t1), + x2 AS (SELECT i FROM t2), + x3 AS (SELECT * FROM x1, x2 WHERE x1.a IN x2 AND x2.i IN x1) + SELECT * FROM x3 +} {2 2} + +do_execsql_test 1.6 { + CREATE TABLE t3 AS SELECT 3 AS x; + CREATE TABLE t4 AS SELECT 4 AS x; + + WITH x1 AS (SELECT * FROM t3), + x2 AS ( + WITH t3 AS (SELECT * FROM t4) + SELECT * FROM x1 + ) + SELECT * FROM x2; +} {3} + finish_test - - From c59731c4aebeb878b45ad598537eed220363c4b9 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 17 Jan 2014 18:34:28 +0000 Subject: [PATCH 163/276] Minor simplification of error message text for a couple of errors associated with WITH clause processing. FossilOrigin-Name: 2031004d960526d6426d50d7b732f37b281534e2 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/select.c | 2 +- test/with1.test | 4 ++-- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 7dbf068c5b..f0167a7f8a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Resolve\stable\snames\swithin\sCTEs\sin\sthe\scontext\sin\swhich\sthe\sCTE\sis\sdeclared,\snot\sthe\scontext\sin\swhich\sit\sis\sused. -D 2014-01-17T17:40:46.168 +C Minor\ssimplification\sof\serror\smessage\stext\sfor\sa\scouple\sof\serrors\sassociated\nwith\sWITH\sclause\sprocessing. +D 2014-01-17T18:34:28.795 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -219,7 +219,7 @@ F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c a13cf4a450534bcbdf1cc840d695e259cd4a1409 +F src/select.c 170a9f9e2c89b3d336d8c39d67690f3c7a06aaaf F src/shell.c 9f3bc02a658b8f61d2cbe60cfc482f660c1c6c48 F src/sqlite.h.in eed7f7d66a60daaa7b4a597dcd9bad87aad9611b F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e @@ -1091,7 +1091,7 @@ F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c F test/win32lock.test 7a6bd73a5dcdee39b5bb93e92395e1773a194361 F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d -F test/with1.test 90490c75e98e1914d84b7cef9e636b48917a020f +F test/with1.test 6e49c7841abb5603425f8f1316ab077f6a9bbb49 F test/with2.test 21057990b59eb652a0a30c6a421fac9daad4412d F test/withM.test 52448ce23e1c2ecba79d10e130ee49ce9f9a2a7a F test/without_rowid1.test aaa26da19d543cd8d3d2d0e686dfa255556c15c8 @@ -1151,7 +1151,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 9ca18a0191db6a9b0763e2f0b3b35d23099fb71b -R b5a3302763f84d4efb48b14faba25e2d -U dan -Z c42b677f74f4986c260cd54897199c85 +P a7323838bbd354a1c2f339e5e0f164f0eada47b3 +R eb3aa3bb26890774162c9a927560c5c6 +U drh +Z f6f02c349d009e02c31d866af981661b diff --git a/manifest.uuid b/manifest.uuid index 6be4f2395e..86d2f4327b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a7323838bbd354a1c2f339e5e0f164f0eada47b3 \ No newline at end of file +2031004d960526d6426d50d7b732f37b281534e2 \ No newline at end of file diff --git a/src/select.c b/src/select.c index b3f16e6113..0ac13ea0a0 100644 --- a/src/select.c +++ b/src/select.c @@ -1808,7 +1808,7 @@ static int multiSelect( ** are supported on recursive queries. */ assert( p->pOffset==0 || p->pLimit ); if( p->pOrderBy || p->pLimit ){ - sqlite3ErrorMsg(pParse, "%s in a recursive query is not allowed", + sqlite3ErrorMsg(pParse, "%s in a recursive query", p->pOrderBy ? "ORDER BY" : "LIMIT" ); goto multi_select_end; diff --git a/test/with1.test b/test/with1.test index db0d7bc36e..d5b86209e6 100644 --- a/test/with1.test +++ b/test/with1.test @@ -152,12 +152,12 @@ do_execsql_test 5.1 { do_catchsql_test 5.2 { WITH i(x) AS ( VALUES(1) UNION ALL SELECT x+1 FROM i ORDER BY 1) SELECT x FROM i LIMIT 10; -} {1 {ORDER BY in a recursive query is not allowed}} +} {1 {ORDER BY in a recursive query}} do_catchsql_test 5.3 { WITH i(x) AS ( VALUES(1) UNION ALL SELECT x+1 FROM i LIMIT 10 ) SELECT x FROM i LIMIT 10; -} {1 {LIMIT in a recursive query is not allowed}} +} {1 {LIMIT in a recursive query}} do_execsql_test 5.4 { WITH i(x) AS ( VALUES(1) UNION ALL SELECT (x+1)%10 FROM i) From 7c82932723fc9e7d7531408db34f8ce67c2bbe81 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 17 Jan 2014 20:36:17 +0000 Subject: [PATCH 164/276] Add extra tests to with2.test. FossilOrigin-Name: eecc325afd72e37d7d565787c8cea68aad6d7a5c --- manifest | 14 +++---- manifest.uuid | 2 +- test/with2.test | 106 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 114 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index f0167a7f8a..1e4ac0fde0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\ssimplification\sof\serror\smessage\stext\sfor\sa\scouple\sof\serrors\sassociated\nwith\sWITH\sclause\sprocessing. -D 2014-01-17T18:34:28.795 +C Add\sextra\stests\sto\swith2.test. +D 2014-01-17T20:36:17.628 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -1092,7 +1092,7 @@ F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c F test/win32lock.test 7a6bd73a5dcdee39b5bb93e92395e1773a194361 F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d F test/with1.test 6e49c7841abb5603425f8f1316ab077f6a9bbb49 -F test/with2.test 21057990b59eb652a0a30c6a421fac9daad4412d +F test/with2.test eaafa54aa7aec8dd824de7d166a2452a63156737 F test/withM.test 52448ce23e1c2ecba79d10e130ee49ce9f9a2a7a F test/without_rowid1.test aaa26da19d543cd8d3d2d0e686dfa255556c15c8 F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99 @@ -1151,7 +1151,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P a7323838bbd354a1c2f339e5e0f164f0eada47b3 -R eb3aa3bb26890774162c9a927560c5c6 -U drh -Z f6f02c349d009e02c31d866af981661b +P 2031004d960526d6426d50d7b732f37b281534e2 +R 18aca364b17ce09cd2d25269185d295f +U dan +Z d7942df5ea7f32fd101e4ac65d1e6fab diff --git a/manifest.uuid b/manifest.uuid index 86d2f4327b..317857e6c4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2031004d960526d6426d50d7b732f37b281534e2 \ No newline at end of file +eecc325afd72e37d7d565787c8cea68aad6d7a5c \ No newline at end of file diff --git a/test/with2.test b/test/with2.test index 08ef7bf6f7..6035ee2b36 100644 --- a/test/with2.test +++ b/test/with2.test @@ -69,5 +69,111 @@ do_execsql_test 1.6 { SELECT * FROM x2; } {3} +do_execsql_test 1.7 { + WITH x1 AS (SELECT * FROM t1) + SELECT (SELECT sum(a) FROM x1), (SELECT max(a) FROM x1); +} {3 2} + +do_execsql_test 1.8 { + WITH x1 AS (SELECT * FROM t1) + SELECT (SELECT sum(a) FROM x1), (SELECT max(a) FROM x1), a FROM x1; +} {3 2 1 3 2 2} + +do_execsql_test 1.9 { + WITH + i(x) AS ( + WITH + j(x) AS ( SELECT * FROM i ), + i(x) AS ( SELECT * FROM t1 ) + SELECT * FROM j + ) + SELECT * FROM i; +} {1 2} + +#--------------------------------------------------------------------------- +# Check that variables can be used in CTEs. +# +set ::min [expr 3] +set ::max [expr 9] +do_execsql_test 2.1 { + WITH i(x) AS ( + VALUES($min) UNION ALL SELECT x+1 FROM i WHERE x < $max + ) + SELECT * FROM i; +} {3 4 5 6 7 8 9} + +do_execsql_test 2.2 { + WITH i(x) AS ( + VALUES($min) UNION ALL SELECT x+1 FROM i WHERE x < $max + ) + SELECT x FROM i JOIN i AS j USING (x); +} {3 4 5 6 7 8 9} + +#--------------------------------------------------------------------------- +# Check that circular references are rejected. +# +do_catchsql_test 3.1 { + WITH i(x, y) AS ( VALUES(1, (SELECT x FROM i)) ) + SELECT * FROM i; +} {1 {circular reference: i}} + +do_catchsql_test 3.2 { + WITH + i(x) AS ( SELECT * FROM j ), + j(x) AS ( SELECT * FROM k ), + k(x) AS ( SELECT * FROM i ) + SELECT * FROM i; +} {1 {circular reference: i}} + +do_catchsql_test 3.3 { + WITH + i(x) AS ( SELECT * FROM (SELECT * FROM j) ), + j(x) AS ( SELECT * FROM (SELECT * FROM i) ) + SELECT * FROM i; +} {1 {circular reference: i}} + +do_catchsql_test 3.4 { + WITH + i(x) AS ( SELECT * FROM (SELECT * FROM j) ), + j(x) AS ( SELECT * FROM (SELECT * FROM i) ) + SELECT * FROM j; +} {1 {circular reference: j}} + +do_catchsql_test 3.5 { + WITH + i(x) AS ( + WITH j(x) AS ( SELECT * FROM i ) + SELECT * FROM j + ) + SELECT * FROM i; +} {1 {circular reference: i}} + +#--------------------------------------------------------------------------- +# Try empty and very long column lists. +# +do_catchsql_test 4.1 { + WITH x() AS ( SELECT 1,2,3 ) + SELECT * FROM x; +} {1 {near ")": syntax error}} + +proc genstmt {n} { + for {set i 1} {$i<=$n} {incr i} { + lappend cols "c$i" + lappend vals $i + } + return " + WITH x([join $cols ,]) AS (SELECT [join $vals ,]) + SELECT (c$n == $n) FROM x + " +} + +do_execsql_test 4.2 [genstmt 10] 1 +do_execsql_test 4.3 [genstmt 100] 1 +do_execsql_test 4.4 [genstmt 255] 1 +set nLimit [sqlite3_limit db SQLITE_LIMIT_COLUMN -1] +do_execsql_test 4.5 [genstmt [expr $nLimit-1]] 1 +do_execsql_test 4.6 [genstmt $nLimit] 1 +do_catchsql_test 4.7 [genstmt [expr $nLimit+1]] {1 {too many columns in index}} + finish_test From ebbf08a012317c757808ae48e85ffd93a0a9953c Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 18 Jan 2014 08:27:02 +0000 Subject: [PATCH 165/276] Avoid spurious "no such table" errors in statements of the form "INSERT INTO tbl WITH xxx AS (...) SELECT * FROM xxx". FossilOrigin-Name: cccff8a0b427feb05cc8952a765b829e731394fd --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/insert.c | 9 +++++++-- test/with2.test | 35 +++++++++++++++++++++++++++++++++++ 4 files changed, 50 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 1e4ac0fde0..efb724704c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sextra\stests\sto\swith2.test. -D 2014-01-17T20:36:17.628 +C Avoid\sspurious\s"no\ssuch\stable"\serrors\sin\sstatements\sof\sthe\sform\s"INSERT\sINTO\stbl\sWITH\sxxx\sAS\s(...)\sSELECT\s*\sFROM\sxxx". +D 2014-01-18T08:27:02.507 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -183,7 +183,7 @@ F src/global.c 1d7bb7ea8254ae6a68ed9bfaf65fcb3d1690b486 F src/hash.c ac3470bbf1ca4ae4e306a8ecb0fdf1731810ffe4 F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c cb4c8ad02b6feb95d34614d94a3c68e0116fbf07 +F src/insert.c a4450f0c46a9f221622e6551ab0953b03c4f8ee8 F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b @@ -1092,7 +1092,7 @@ F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c F test/win32lock.test 7a6bd73a5dcdee39b5bb93e92395e1773a194361 F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d F test/with1.test 6e49c7841abb5603425f8f1316ab077f6a9bbb49 -F test/with2.test eaafa54aa7aec8dd824de7d166a2452a63156737 +F test/with2.test 5f7ea3453c998a6b9ed3456f251c80d94722f22a F test/withM.test 52448ce23e1c2ecba79d10e130ee49ce9f9a2a7a F test/without_rowid1.test aaa26da19d543cd8d3d2d0e686dfa255556c15c8 F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99 @@ -1151,7 +1151,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 2031004d960526d6426d50d7b732f37b281534e2 -R 18aca364b17ce09cd2d25269185d295f +P eecc325afd72e37d7d565787c8cea68aad6d7a5c +R 2a1f6d87654c7bd1758f1648d991f83e U dan -Z d7942df5ea7f32fd101e4ac65d1e6fab +Z bdd16ade1b5f6c0b188978b71304d4f1 diff --git a/manifest.uuid b/manifest.uuid index 317857e6c4..b0c2aeeecb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -eecc325afd72e37d7d565787c8cea68aad6d7a5c \ No newline at end of file +cccff8a0b427feb05cc8952a765b829e731394fd \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index b4bd6b7160..a2366360c7 100644 --- a/src/insert.c +++ b/src/insert.c @@ -667,8 +667,7 @@ void sqlite3Insert( ** ** This is the 2nd template. */ - if( pColumn==0 && pParse->pWith==0 - && xferOptimization(pParse, pTab, pSelect, onError, iDb) ){ + if( pColumn==0 && xferOptimization(pParse, pTab, pSelect, onError, iDb) ){ assert( !pTrigger ); assert( pList==0 ); goto insert_end; @@ -1859,6 +1858,12 @@ static int xferOptimization( if( pSelect==0 ){ return 0; /* Must be of the form INSERT INTO ... SELECT ... */ } + if( pParse->pWith || pSelect->pWith ){ + /* Do not attempt to process this query if there are an WITH clauses + ** attached to it. Proceeding may generate a false "no such table: xxx" + ** error if pSelect reads from a CTE named "xxx". */ + return 0; + } if( sqlite3TriggerList(pParse, pDest) ){ return 0; /* tab1 must not have triggers */ } diff --git a/test/with2.test b/test/with2.test index 6035ee2b36..de199c2e4b 100644 --- a/test/with2.test +++ b/test/with2.test @@ -175,5 +175,40 @@ do_execsql_test 4.5 [genstmt [expr $nLimit-1]] 1 do_execsql_test 4.6 [genstmt $nLimit] 1 do_catchsql_test 4.7 [genstmt [expr $nLimit+1]] {1 {too many columns in index}} +#--------------------------------------------------------------------------- +# Check that adding a WITH clause to an INSERT disables the xfer +# optimization. +# +proc do_xfer_test {tn bXfer sql {res {}}} { + set ::sqlite3_xferopt_count 0 + uplevel [list do_test $tn [subst -nocommands { + set dres [db eval {$sql}] + list [set ::sqlite3_xferopt_count] [set dres] + }] [list $bXfer $res]] +} + +do_execsql_test 5.1 { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t2; + CREATE TABLE t1(a, b); + CREATE TABLE t2(a, b); +} + +do_xfer_test 5.2 1 { INSERT INTO t1 SELECT * FROM t2 } +do_xfer_test 5.3 0 { INSERT INTO t1 SELECT a, b FROM t2 } +do_xfer_test 5.4 0 { INSERT INTO t1 SELECT b, a FROM t2 } +do_xfer_test 5.5 0 { + WITH x AS (SELECT a, b FROM t2) INSERT INTO t1 SELECT * FROM x +} +do_xfer_test 5.6 0 { + WITH x AS (SELECT a, b FROM t2) INSERT INTO t1 SELECT * FROM t2 +} +do_xfer_test 5.7 0 { + INSERT INTO t1 WITH x AS ( SELECT * FROM t2 ) SELECT * FROM x +} +do_xfer_test 5.8 0 { + INSERT INTO t1 WITH x(a,b) AS ( SELECT * FROM t2 ) SELECT * FROM x +} + finish_test From 75303a2c683fff538603e9f8a69263d2db4c0c5f Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 18 Jan 2014 15:22:53 +0000 Subject: [PATCH 166/276] Add asserts() for a couple of unreachable conditions. Add the Mandelbrot Set query as a test case. FossilOrigin-Name: 2ad4583c0cc7988f0dfe78fd0a2eb0fdb92d835a --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/expr.c | 2 +- src/vdbe.c | 3 ++- test/with1.test | 43 ++++++++++++++++++++++++++++++++++++++++++- 5 files changed, 55 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index efb724704c..f3a6dea836 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sspurious\s"no\ssuch\stable"\serrors\sin\sstatements\sof\sthe\sform\s"INSERT\sINTO\stbl\sWITH\sxxx\sAS\s(...)\sSELECT\s*\sFROM\sxxx". -D 2014-01-18T08:27:02.507 +C Add\sasserts()\sfor\sa\scouple\sof\sunreachable\sconditions.\s\sAdd\sthe\sMandelbrot\sSet\nquery\sas\sa\stest\scase. +D 2014-01-18T15:22:53.229 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -175,7 +175,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 F src/delete.c 91e1321021db5dc266360531b8b6550009d771ff -F src/expr.c e239763d8b43356fa1f46f1cf41d62a076f7f72e +F src/expr.c 8c7e482bc8f7982333f046851a610ccdb8a1ba94 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 2ab0f5384b70594468ef3ac5c7ed8ca24bfd17d5 F src/func.c 6325ac2ec10833ccf4d5c36d323709221d37ea19 @@ -280,7 +280,7 @@ F src/update.c c2706a6eb232a96345c35b7e1e75a188e26812bb F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c e71f19b272f05c8695cf747b4bac1732685f9e5c F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c ccc8594e89751966022642464ec2b5c5fa7840a2 +F src/vdbe.c 98d96d04d9a2bef78ca850be1053dc91d031338a F src/vdbe.h e6c4c610fcabad4fa80ebb1efc6822a9367e2b26 F src/vdbeInt.h 42db251e9f863401ff847b90d5fe1614c89a6a56 F src/vdbeapi.c ce4e68ea4842cc6081046f533d088dcf01d247ad @@ -1091,7 +1091,7 @@ F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c F test/win32lock.test 7a6bd73a5dcdee39b5bb93e92395e1773a194361 F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d -F test/with1.test 6e49c7841abb5603425f8f1316ab077f6a9bbb49 +F test/with1.test be21f7efdc08fe6ad182dc943d42704300f0fcdb F test/with2.test 5f7ea3453c998a6b9ed3456f251c80d94722f22a F test/withM.test 52448ce23e1c2ecba79d10e130ee49ce9f9a2a7a F test/without_rowid1.test aaa26da19d543cd8d3d2d0e686dfa255556c15c8 @@ -1151,7 +1151,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P eecc325afd72e37d7d565787c8cea68aad6d7a5c -R 2a1f6d87654c7bd1758f1648d991f83e -U dan -Z bdd16ade1b5f6c0b188978b71304d4f1 +P cccff8a0b427feb05cc8952a765b829e731394fd +R 538a9377a8d02c8e21002b1bc024f5ac +U drh +Z 8baad4729759494d05074bc32769b912 diff --git a/manifest.uuid b/manifest.uuid index b0c2aeeecb..34f13530bf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cccff8a0b427feb05cc8952a765b829e731394fd \ No newline at end of file +2ad4583c0cc7988f0dfe78fd0a2eb0fdb92d835a \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 0614be1cf5..5f11dec420 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1584,7 +1584,7 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){ iCol = (i16)pExpr->iColumn; /* Code an OP_VerifyCookie and OP_TableLock for
    . */ - if( pTab->pSchema ){ + if( ALWAYS(pTab->pSchema) ){ iDb = sqlite3SchemaToIndex(db, pTab->pSchema); sqlite3CodeVerifySchema(pParse, iDb); sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); diff --git a/src/vdbe.c b/src/vdbe.c index 9af4a62d7e..86aae3c65d 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3390,7 +3390,8 @@ case OP_SwapCursors: { p->apCsr[pOp->p1] = p->apCsr[pOp->p2]; p->apCsr[pOp->p2] = pTmp; - rc = sqlite3BtreeClearTable(pTmp->pBt, MASTER_ROOT + !pTmp->isTable, 0); + assert( pTmp->isTable ); + rc = sqlite3BtreeClearTable(pTmp->pBt, MASTER_ROOT, 0); break; } #endif /* ifndef SQLITE_OMIT_CTE */ diff --git a/test/with1.test b/test/with1.test index d5b86209e6..54e0f0aa91 100644 --- a/test/with1.test +++ b/test/with1.test @@ -324,6 +324,47 @@ do_catchsql_test 7.6 { SELECT id FROM t; } {1 {circular reference: t}} - +# Compute the mandelbrot set using a recursive query +# +do_execsql_test 8.1 { + WITH RECURSIVE + xaxis(x) AS (VALUES(-2.0) UNION ALL SELECT x+0.05 FROM xaxis WHERE x<1.2), + yaxis(y) AS (VALUES(-1.0) UNION ALL SELECT y+0.1 FROM yaxis WHERE y<1.0), + m(iter, cx, cy, x, y) AS ( + SELECT 0, x, y, 0.0, 0.0 FROM xaxis, yaxis + UNION ALL + SELECT iter+1, cx, cy, x*x-y*y + cx, 2.0*x*y + cy FROM m + WHERE (x*x + y*y) < 4.0 AND iter<28 + ), + m2(iter, cx, cy) AS ( + SELECT max(iter), cx, cy FROM m GROUP BY cx, cy + ), + a(t) AS ( + SELECT group_concat( substr(' .+*#', 1+min(iter/7,4), 1), '') + FROM m2 GROUP BY cy + ) + SELECT group_concat(rtrim(t),x'0a') FROM a; +} {{ ....# + ..#*.. + ..+####+. + .......+####.... + + ..##+*##########+.++++ + .+.##################+. + .............+###################+.+ + ..++..#.....*#####################+. + ...+#######++#######################. + ....+*################################. + #############################################... + ....+*################################. + ...+#######++#######################. + ..++..#.....*#####################+. + .............+###################+.+ + .+.##################+. + ..##+*##########+.++++ + .......+####.... + + ..+####+. + ..#*.. + ....# + +.}} finish_test From 1fe3c4b52668f261a893a9abe05829e40cad5d1e Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 18 Jan 2014 15:59:35 +0000 Subject: [PATCH 167/276] Add extra test cases. No changes to code. FossilOrigin-Name: d38d485e581dab99a3ee6b348da8ddaf9b379ff2 --- manifest | 16 ++--- manifest.uuid | 2 +- test/with2.test | 176 +++++++++++++++++++++++++++++++++++++++++++++++- test/withM.test | 16 +++++ 4 files changed, 199 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index f3a6dea836..522f30a10d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sasserts()\sfor\sa\scouple\sof\sunreachable\sconditions.\s\sAdd\sthe\sMandelbrot\sSet\nquery\sas\sa\stest\scase. -D 2014-01-18T15:22:53.229 +C Add\sextra\stest\scases.\sNo\schanges\sto\scode. +D 2014-01-18T15:59:35.958 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -1092,8 +1092,8 @@ F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c F test/win32lock.test 7a6bd73a5dcdee39b5bb93e92395e1773a194361 F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d F test/with1.test be21f7efdc08fe6ad182dc943d42704300f0fcdb -F test/with2.test 5f7ea3453c998a6b9ed3456f251c80d94722f22a -F test/withM.test 52448ce23e1c2ecba79d10e130ee49ce9f9a2a7a +F test/with2.test 67a3347f2d78618db9434a248fb5003af8f04bc1 +F test/withM.test e97f2a8c506ab3ea9eab94e6f6072f6cc924c991 F test/without_rowid1.test aaa26da19d543cd8d3d2d0e686dfa255556c15c8 F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99 F test/without_rowid3.test eac3d5c8a1924725b58503a368f2cbd24fd6c8a0 @@ -1151,7 +1151,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P cccff8a0b427feb05cc8952a765b829e731394fd -R 538a9377a8d02c8e21002b1bc024f5ac -U drh -Z 8baad4729759494d05074bc32769b912 +P 2ad4583c0cc7988f0dfe78fd0a2eb0fdb92d835a +R 71fcd9d8c24b81a08237ce7106794f40 +U dan +Z 1a2b2ad5eb21bdc784c4eae4f3f812b5 diff --git a/manifest.uuid b/manifest.uuid index 34f13530bf..e5d4cbf4df 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2ad4583c0cc7988f0dfe78fd0a2eb0fdb92d835a \ No newline at end of file +d38d485e581dab99a3ee6b348da8ddaf9b379ff2 \ No newline at end of file diff --git a/test/with2.test b/test/with2.test index de199c2e4b..90a64a4755 100644 --- a/test/with2.test +++ b/test/with2.test @@ -70,16 +70,32 @@ do_execsql_test 1.6 { } {3} do_execsql_test 1.7 { + WITH x2 AS ( + WITH t3 AS (SELECT * FROM t4) + SELECT * FROM t3 + ) + SELECT * FROM x2; +} {4} + +do_execsql_test 1.8 { + WITH x2 AS ( + WITH t3 AS (SELECT * FROM t4) + SELECT * FROM main.t3 + ) + SELECT * FROM x2; +} {3} + +do_execsql_test 1.9 { WITH x1 AS (SELECT * FROM t1) SELECT (SELECT sum(a) FROM x1), (SELECT max(a) FROM x1); } {3 2} -do_execsql_test 1.8 { +do_execsql_test 1.10 { WITH x1 AS (SELECT * FROM t1) SELECT (SELECT sum(a) FROM x1), (SELECT max(a) FROM x1), a FROM x1; } {3 2 1 3 2 2} -do_execsql_test 1.9 { +do_execsql_test 1.11 { WITH i(x) AS ( WITH @@ -90,6 +106,62 @@ do_execsql_test 1.9 { SELECT * FROM i; } {1 2} +do_execsql_test 1.12 { + WITH r(i) AS ( + VALUES('.') + UNION ALL + SELECT i || '.' FROM r, ( + SELECT x FROM x INTERSECT SELECT y FROM y + ) WHERE length(i) < 10 + ), + x(x) AS ( VALUES(1) UNION ALL VALUES(2) UNION ALL VALUES(3) ), + y(y) AS ( VALUES(2) UNION ALL VALUES(4) UNION ALL VALUES(6) ) + + SELECT * FROM r; +} {. .. ... .... ..... ...... ....... ........ ......... ..........} + +do_execsql_test 1.13 { + WITH r(i) AS ( + VALUES('.') + UNION ALL + SELECT i || '.' FROM r, ( SELECT x FROM x WHERE x=2 ) WHERE length(i) < 10 + ), + x(x) AS ( VALUES(1) UNION ALL VALUES(2) UNION ALL VALUES(3) ) + + SELECT * FROM r ORDER BY length(i) DESC; +} {.......... ......... ........ ....... ...... ..... .... ... .. .} + +do_execsql_test 1.14 { + WITH + t4(x) AS ( + VALUES(4) + UNION ALL + SELECT x+1 FROM t4 WHERE x<10 + ) + SELECT * FROM t4; +} {4 5 6 7 8 9 10} + +do_execsql_test 1.15 { + WITH + t4(x) AS ( + VALUES(4) + UNION ALL + SELECT x+1 FROM main.t4 WHERE x<10 + ) + SELECT * FROM t4; +} {4 5} + +do_catchsql_test 1.16 { + WITH + t4(x) AS ( + VALUES(4) + UNION ALL + SELECT x+1 FROM t4, main.t4, t4 WHERE x<10 + ) + SELECT * FROM t4; +} {1 {multiple references to recursive table: t4}} + + #--------------------------------------------------------------------------- # Check that variables can be used in CTEs. # @@ -210,5 +282,105 @@ do_xfer_test 5.8 0 { INSERT INTO t1 WITH x(a,b) AS ( SELECT * FROM t2 ) SELECT * FROM x } +#--------------------------------------------------------------------------- +# Check that syntax (and other) errors in statements with WITH clauses +# attached to them do not cause problems (e.g. memory leaks). +# +do_execsql_test 6.1 { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t2; + CREATE TABLE t1(a, b); + CREATE TABLE t2(a, b); +} + +do_catchsql_test 6.2 { + WITH x AS (SELECT * FROM t1) + INSERT INTO t2 VALUES(1, 2,); +} {1 {near ")": syntax error}} + +do_catchsql_test 6.3 { + WITH x AS (SELECT * FROM t1) + INSERT INTO t2 SELECT a, b, FROM t1; +} {1 {near "FROM": syntax error}} + +do_catchsql_test 6.3 { + WITH x AS (SELECT * FROM t1) + INSERT INTO t2 SELECT a, b FROM abc; +} {1 {no such table: abc}} + +do_catchsql_test 6.4 { + WITH x AS (SELECT * FROM t1) + INSERT INTO t2 SELECT a, b, FROM t1 a a a; +} {1 {near "FROM": syntax error}} + +do_catchsql_test 6.5 { + WITH x AS (SELECT * FROM t1) + DELETE FROM t2 WHERE; +} {1 {near ";": syntax error}} + +do_catchsql_test 6.6 { + WITH x AS (SELECT * FROM t1) DELETE FROM t2 WHERE +} {/1 {near .* syntax error}/} + +do_catchsql_test 6.7 { + WITH x AS (SELECT * FROM t1) DELETE FROM t2 WHRE 1; +} {/1 {near .* syntax error}/} + +do_catchsql_test 6.8 { + WITH x AS (SELECT * FROM t1) UPDATE t2 SET a = 10, b = ; +} {/1 {near .* syntax error}/} + +do_catchsql_test 6.9 { + WITH x AS (SELECT * FROM t1) UPDATE t2 SET a = 10, b = 1 WHERE a===b; +} {/1 {near .* syntax error}/} + +do_catchsql_test 6.10 { + WITH x(a,b) AS ( + SELECT 1, 1 + UNION ALL + SELECT a*b,a+b FROM x WHERE c=2 + ) + SELECT * FROM x +} {1 {no such column: c}} + +#------------------------------------------------------------------------- +# Recursive queries in IN(...) expressions. +# +do_execsql_test 7.1 { + CREATE TABLE t5(x INTEGER); + CREATE TABLE t6(y INTEGER); + + WITH s(x) AS ( VALUES(7) UNION ALL SELECT x+7 FROM s WHERE x<49 ) + INSERT INTO t5 + SELECT * FROM s; + + INSERT INTO t6 + WITH s(x) AS ( VALUES(2) UNION ALL SELECT x+2 FROM s WHERE x<49 ) + SELECT * FROM s; +} + +do_execsql_test 7.2 { + SELECT * FROM t6 WHERE y IN (SELECT x FROM t5) +} {14 28 42} + +do_execsql_test 7.3 { + WITH ss AS (SELECT x FROM t5) + SELECT * FROM t6 WHERE y IN (SELECT x FROM ss) +} {14 28 42} + +do_execsql_test 7.4 { + WITH ss(x) AS ( VALUES(7) UNION ALL SELECT x+7 FROM ss WHERE x<49 ) + SELECT * FROM t6 WHERE y IN (SELECT x FROM ss) +} {14 28 42} + +do_execsql_test 7.5 { + SELECT * FROM t6 WHERE y IN ( + WITH ss(x) AS ( VALUES(7) UNION ALL SELECT x+7 FROM ss WHERE x<49 ) + SELECT x FROM ss + ) +} {14 28 42} + + + finish_test diff --git a/test/withM.test b/test/withM.test index 9bf7ceed3f..c1650d9576 100644 --- a/test/withM.test +++ b/test/withM.test @@ -55,6 +55,22 @@ do_faultsim_test withM-1.2 -prep { db close } +do_faultsim_test withM-1.3 -prep { + sqlite3 db test.db +} -body { + execsql { + WITH w1(a,b) AS ( + SELECT 1, 1 + UNION ALL + SELECT a+1, b + 2*a + 1 FROM w1 + ) + SELECT * FROM w1 LIMIT 5; + } +} -test { + faultsim_test_result {0 {1 1 2 4 3 9 4 16 5 25}} + db close +} + finish_test From 717c09c4a94406e27148dc75f18afd02e023b845 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 18 Jan 2014 18:33:44 +0000 Subject: [PATCH 168/276] Add a sudoku solver to the recursive query tests in with1.test. FossilOrigin-Name: 679eff8759aa25368b977c0d26b78a9fcd9486f5 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/with1.test | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 522f30a10d..7463d67494 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sextra\stest\scases.\sNo\schanges\sto\scode. -D 2014-01-18T15:59:35.958 +C Add\sa\ssudoku\ssolver\sto\sthe\srecursive\squery\stests\sin\swith1.test. +D 2014-01-18T18:33:44.994 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -1091,7 +1091,7 @@ F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c F test/win32lock.test 7a6bd73a5dcdee39b5bb93e92395e1773a194361 F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d -F test/with1.test be21f7efdc08fe6ad182dc943d42704300f0fcdb +F test/with1.test cec63b56797a70842afa8929c241dfdb3d864283 F test/with2.test 67a3347f2d78618db9434a248fb5003af8f04bc1 F test/withM.test e97f2a8c506ab3ea9eab94e6f6072f6cc924c991 F test/without_rowid1.test aaa26da19d543cd8d3d2d0e686dfa255556c15c8 @@ -1151,7 +1151,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 2ad4583c0cc7988f0dfe78fd0a2eb0fdb92d835a -R 71fcd9d8c24b81a08237ce7106794f40 -U dan -Z 1a2b2ad5eb21bdc784c4eae4f3f812b5 +P d38d485e581dab99a3ee6b348da8ddaf9b379ff2 +R 65511deacff317a7a6d96d8a97a06cc3 +U drh +Z 1781cdebe197572ff0a729675feb42d9 diff --git a/manifest.uuid b/manifest.uuid index e5d4cbf4df..8e6cce16db 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d38d485e581dab99a3ee6b348da8ddaf9b379ff2 \ No newline at end of file +679eff8759aa25368b977c0d26b78a9fcd9486f5 \ No newline at end of file diff --git a/test/with1.test b/test/with1.test index 54e0f0aa91..fcf59267f2 100644 --- a/test/with1.test +++ b/test/with1.test @@ -367,4 +367,41 @@ do_execsql_test 8.1 { ....# +.}} +# Solve a sudoku puzzle using a recursive query +# +do_execsql_test 8.2 { + WITH RECURSIVE + input(sud) AS ( + VALUES('53..7....6..195....98....6.8...6...34..8.3..17...2...6.6....28....419..5....8..79') + ), + + /* A table filled with digits 1..9, inclusive. */ + digits(z, lp) AS ( + VALUES('1', 1) + UNION ALL SELECT + CAST(lp+1 AS TEXT), lp+1 FROM digits WHERE lp<9 + ), + + /* The tricky bit. */ + x(s, ind) AS ( + SELECT sud, instr(sud, '.') FROM input + UNION ALL + SELECT + substr(s, 1, ind-1) || z || substr(s, ind+1), + instr( substr(s, 1, ind-1) || z || substr(s, ind+1), '.' ) + FROM x, digits AS z + WHERE ind>0 + AND NOT EXISTS ( + SELECT 1 + FROM digits AS lp + WHERE z.z = substr(s, ((ind-1)/9)*9 + lp, 1) + OR z.z = substr(s, ((ind-1)%9) + (lp-1)*9 + 1, 1) + OR z.z = substr(s, (((ind-1)/3) % 3) * 3 + + ((ind-1)/27) * 27 + lp + + ((lp-1) / 3) * 6, 1) + ) + ) + SELECT s FROM x WHERE ind=0; +} {534678912672195348198342567859761423426853791713924856961537284287419635345286179} + finish_test From 7f3068aa83c4593dead9ee0827b2413d5a1f1bb6 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 20 Jan 2014 14:17:08 +0000 Subject: [PATCH 169/276] Do not run the tests in with2.test with SQLITE_OMIT_CTE builds. FossilOrigin-Name: 8a973912e98c9b1bb9d3f914527d35c1e7f2011a --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/with2.test | 5 +++++ 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 7463d67494..39ddd14f77 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\ssudoku\ssolver\sto\sthe\srecursive\squery\stests\sin\swith1.test. -D 2014-01-18T18:33:44.994 +C Do\snot\srun\sthe\stests\sin\swith2.test\swith\sSQLITE_OMIT_CTE\sbuilds. +D 2014-01-20T14:17:08.203 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -1092,7 +1092,7 @@ F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c F test/win32lock.test 7a6bd73a5dcdee39b5bb93e92395e1773a194361 F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d F test/with1.test cec63b56797a70842afa8929c241dfdb3d864283 -F test/with2.test 67a3347f2d78618db9434a248fb5003af8f04bc1 +F test/with2.test 2fe78fcd8deef2a0f9cfc49bfc755911d0b3fd64 F test/withM.test e97f2a8c506ab3ea9eab94e6f6072f6cc924c991 F test/without_rowid1.test aaa26da19d543cd8d3d2d0e686dfa255556c15c8 F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99 @@ -1151,7 +1151,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P d38d485e581dab99a3ee6b348da8ddaf9b379ff2 -R 65511deacff317a7a6d96d8a97a06cc3 -U drh -Z 1781cdebe197572ff0a729675feb42d9 +P 679eff8759aa25368b977c0d26b78a9fcd9486f5 +R 4f2132a97fe1dbb0dda85feb1706370a +U dan +Z 185238e927f243f40ec02c5fcc28d90b diff --git a/manifest.uuid b/manifest.uuid index 8e6cce16db..8f8eb075b5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -679eff8759aa25368b977c0d26b78a9fcd9486f5 \ No newline at end of file +8a973912e98c9b1bb9d3f914527d35c1e7f2011a \ No newline at end of file diff --git a/test/with2.test b/test/with2.test index 90a64a4755..d702f8c962 100644 --- a/test/with2.test +++ b/test/with2.test @@ -16,6 +16,11 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl set ::testprefix with2 +ifcapable {!cte} { + finish_test + return +} + do_execsql_test 1.0 { CREATE TABLE t1(a); INSERT INTO t1 VALUES(1); From c25e2ebc01a94bb18959d61237a47a758c17d267 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 20 Jan 2014 14:58:55 +0000 Subject: [PATCH 170/276] Remove an unused #define and add an assert(), both associated with WITH logic. FossilOrigin-Name: a06235e0f6aa1e8fefa3f2873ee035eac9dac750 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/select.c | 1 + src/sqliteInt.h | 1 - 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 39ddd14f77..6691d6c5ff 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\srun\sthe\stests\sin\swith2.test\swith\sSQLITE_OMIT_CTE\sbuilds. -D 2014-01-20T14:17:08.203 +C Remove\san\sunused\s#define\sand\sadd\san\sassert(),\sboth\sassociated\swith\sWITH\slogic. +D 2014-01-20T14:58:55.056 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -219,12 +219,12 @@ F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c 170a9f9e2c89b3d336d8c39d67690f3c7a06aaaf +F src/select.c a27ac21844df3123b7c1e89d79cd7034d4eb0e8e F src/shell.c 9f3bc02a658b8f61d2cbe60cfc482f660c1c6c48 F src/sqlite.h.in eed7f7d66a60daaa7b4a597dcd9bad87aad9611b F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h 9600eeb486c274fbdb815d040e4a7f262b7317e1 +F src/sqliteInt.h 99fd628541e420b98fc52072635e8ba431706250 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -1151,7 +1151,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 679eff8759aa25368b977c0d26b78a9fcd9486f5 -R 4f2132a97fe1dbb0dda85feb1706370a -U dan -Z 185238e927f243f40ec02c5fcc28d90b +P 8a973912e98c9b1bb9d3f914527d35c1e7f2011a +R bcd03400ea7bd2e959020317f5125b8b +U drh +Z f5ee43186682e26d4e29624d49787797 diff --git a/manifest.uuid b/manifest.uuid index 8f8eb075b5..9e604f5cb8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8a973912e98c9b1bb9d3f914527d35c1e7f2011a \ No newline at end of file +a06235e0f6aa1e8fefa3f2873ee035eac9dac750 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 0ac13ea0a0..dd58ed22e6 100644 --- a/src/select.c +++ b/src/select.c @@ -3595,6 +3595,7 @@ static int withExpand( return SQLITE_ERROR; } + assert( pFrom->pTab==0 ); pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table)); if( pTab==0 ) return WRC_Abort; pTab->nRef = 1; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 1cdaf09dc7..317e9eb227 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1437,7 +1437,6 @@ struct Table { #define TF_Autoincrement 0x08 /* Integer primary key is autoincrement */ #define TF_Virtual 0x10 /* Is a virtual table */ #define TF_WithoutRowid 0x20 /* No rowid used. PRIMARY KEY is the key */ -#define TF_Recursive 0x40 /* Recursive reference within CTE */ /* From 7df42aba12a1ef6607ed8718202eb434ddc514c1 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 20 Jan 2014 18:25:44 +0000 Subject: [PATCH 171/276] Handle a few obscure problems that could manifest if a database corrupted in a certain way was written by a connection in the middle of a SELECT statement on the same db. FossilOrigin-Name: eba8a564e62f84a9620008beead80081fe90a1b7 --- manifest | 15 ++--- manifest.uuid | 2 +- src/btree.c | 35 +++++------ test/corruptH.test | 150 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 176 insertions(+), 26 deletions(-) create mode 100644 test/corruptH.test diff --git a/manifest b/manifest index 6691d6c5ff..23358e38e5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunused\s#define\sand\sadd\san\sassert(),\sboth\sassociated\swith\sWITH\slogic. -D 2014-01-20T14:58:55.056 +C Handle\sa\sfew\sobscure\sproblems\sthat\scould\smanifest\sif\sa\sdatabase\scorrupted\sin\sa\scertain\sway\swas\swritten\sby\sa\sconnection\sin\sthe\smiddle\sof\sa\sSELECT\sstatement\son\sthe\ssame\sdb. +D 2014-01-20T18:25:44.841 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,7 +166,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c a729e63cf5cd1829507cb7b8e89f99b95141bb53 F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c c15e1722696b66c4029c487acfb830b0985bf142 +F src/btree.c 02e1a4e71d8fc37e9fd5216c15d989d148a77c87 F src/btree.h a61ddebc78c66795a2b93181321a116746302cc9 F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0 F src/build.c 7e6c275ab1731510d6f793d0f88373ab3e858e69 @@ -406,6 +406,7 @@ F test/corruptD.test b3c205fac7952b1de645ce44bb02335cd9e3e040 F test/corruptE.test 193b4ca4e927e77c1d5f4f56203ddc998432a7ee F test/corruptF.test be9fde98e4c93648f1ba52b74e5318edc8f59fe4 F test/corruptG.test c150f156dace653c00a121ad0f5772a0568c41ba +F test/corruptH.test 0a247f3dc8a8f3578db5f639d86c6bb4d520207f F test/count.test 42a251178e32f617eda33f76236a7f79825a50b5 F test/coveridxscan.test cdb47d01acc4a634a34fd25abe85189e0d0f1e62 F test/crash.test fb9dc4a02dcba30d4aa5c2c226f98b220b2b959f @@ -1151,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 8a973912e98c9b1bb9d3f914527d35c1e7f2011a -R bcd03400ea7bd2e959020317f5125b8b -U drh -Z f5ee43186682e26d4e29624d49787797 +P a06235e0f6aa1e8fefa3f2873ee035eac9dac750 +R 05b4cba80caa92c648883df94b9ec5d5 +U dan +Z 37a297a819c7d62ae4b0e647e3e25c85 diff --git a/manifest.uuid b/manifest.uuid index 9e604f5cb8..ad1f20fbcf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a06235e0f6aa1e8fefa3f2873ee035eac9dac750 \ No newline at end of file +eba8a564e62f84a9620008beead80081fe90a1b7 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index e28a97c846..032f3d8c78 100644 --- a/src/btree.c +++ b/src/btree.c @@ -3754,7 +3754,7 @@ int sqlite3BtreeCloseCursor(BtCursor *pCur){ int iPage = pCur->iPage; memset(&info, 0, sizeof(info)); btreeParseCell(pCur->apPage[iPage], pCur->aiIdx[iPage], &info); - assert( memcmp(&info, &pCur->info, sizeof(info))==0 ); + assert( CORRUPT_DB || memcmp(&info, &pCur->info, sizeof(info))==0 ); } #else #define assertCellInfo(x) @@ -4390,26 +4390,24 @@ static int moveToRoot(BtCursor *pCur){ return rc; } pCur->iPage = 0; - - /* If pCur->pKeyInfo is not NULL, then the caller that opened this cursor - ** expected to open it on an index b-tree. Otherwise, if pKeyInfo is - ** NULL, the caller expects a table b-tree. If this is not the case, - ** return an SQLITE_CORRUPT error. */ - assert( pCur->apPage[0]->intKey==1 || pCur->apPage[0]->intKey==0 ); - if( (pCur->pKeyInfo==0)!=pCur->apPage[0]->intKey ){ - return SQLITE_CORRUPT_BKPT; - } } - - /* Assert that the root page is of the correct type. This must be the - ** case as the call to this function that loaded the root-page (either - ** this call or a previous invocation) would have detected corruption - ** if the assumption were not true, and it is not possible for the flags - ** byte to have been modified while this cursor is holding a reference - ** to the page. */ pRoot = pCur->apPage[0]; assert( pRoot->pgno==pCur->pgnoRoot ); - assert( pRoot->isInit && (pCur->pKeyInfo==0)==pRoot->intKey ); + + /* If pCur->pKeyInfo is not NULL, then the caller that opened this cursor + ** expected to open it on an index b-tree. Otherwise, if pKeyInfo is + ** NULL, the caller expects a table b-tree. If this is not the case, + ** return an SQLITE_CORRUPT error. + ** + ** Earlier versions of SQLite assumed that this test could not fail + ** if the root page was already loaded when this function was called (i.e. + ** if pCur->iPage>=0). But this is not so if the database is corrupted + ** in such a way that page pRoot is linked into a second b-tree table + ** (or the freelist). */ + assert( pRoot->intKey==1 || pRoot->intKey==0 ); + if( pRoot->isInit==0 || (pCur->pKeyInfo==0)!=pRoot->intKey ){ + return SQLITE_CORRUPT_BKPT; + } pCur->aiIdx[0] = 0; pCur->info.nSize = 0; @@ -5251,6 +5249,7 @@ end_allocate_page: if( rc==SQLITE_OK ){ if( sqlite3PagerPageRefcount((*ppPage)->pDbPage)>1 ){ releasePage(*ppPage); + *ppPage = 0; return SQLITE_CORRUPT_BKPT; } (*ppPage)->isInit = 0; diff --git a/test/corruptH.test b/test/corruptH.test new file mode 100644 index 0000000000..23f80632b1 --- /dev/null +++ b/test/corruptH.test @@ -0,0 +1,150 @@ +# 2014-01-20 +# +# 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. +# +#*********************************************************************** +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix corruptH + +# Do not use a codec for tests in this file, as the database file is +# manipulated directly using tcl scripts (using the [hexio_write] command). +# +do_not_use_codec +database_may_be_corrupt + +# Initialize the database. +# +do_execsql_test 1.1 { + PRAGMA page_size=1024; + + CREATE TABLE t1(a INTEGER PRIMARY KEY, b); + INSERT INTO t1 VALUES(1, 'one'); + INSERT INTO t1 VALUES(2, 'two'); + + CREATE TABLE t2(x); + INSERT INTO t2 VALUES(randomblob(200)); + INSERT INTO t2 SELECT randomblob(200) FROM t2; + INSERT INTO t2 SELECT randomblob(200) FROM t2; + INSERT INTO t2 SELECT randomblob(200) FROM t2; + INSERT INTO t2 SELECT randomblob(200) FROM t2; + INSERT INTO t2 SELECT randomblob(200) FROM t2; + INSERT INTO t2 SELECT randomblob(200) FROM t2; +} {} + +# Corrupt the file so that the root page of t1 is also linked into t2 as +# a leaf page. +# +do_test 1.2 { + db eval { SELECT name, rootpage FROM sqlite_master } { + set r($name) $rootpage + } + db close + hexio_write test.db [expr {($r(t2)-1)*1024 + 11}] [format %.2X $r(t1)] + sqlite3 db test.db +} {} + +do_test 1.3 { + db eval { PRAGMA secure_delete=1 } + list [catch { + db eval { SELECT * FROM t1 WHERE a IN (1, 2) } { + db eval { DELETE FROM t2 } + } + } msg] $msg +} {1 {database disk image is malformed}} + +#------------------------------------------------------------------------- +reset_db + +# Initialize the database. +# +do_execsql_test 2.1 { + PRAGMA page_size=1024; + + CREATE TABLE t1(a INTEGER PRIMARY KEY, b); + INSERT INTO t1 VALUES(1, 'one'); + INSERT INTO t1 VALUES(2, 'two'); + + CREATE TABLE t3(x); + + CREATE TABLE t2(x PRIMARY KEY) WITHOUT ROWID; + INSERT INTO t2 VALUES(randomblob(100)); + + DROP TABLE t3; +} {} + +do_test 2.2 { + db eval { SELECT name, rootpage FROM sqlite_master } { + set r($name) $rootpage + } + db close + set fl [hexio_get_int [hexio_read test.db 32 4]] + + hexio_write test.db [expr {($fl-1) * 1024 + 0}] 00000000 + hexio_write test.db [expr {($fl-1) * 1024 + 4}] 00000001 + hexio_write test.db [expr {($fl-1) * 1024 + 8}] [format %.8X $r(t1)] + hexio_write test.db 36 00000002 + + sqlite3 db test.db +} {} + +do_test 2.3 { + list [catch { + db eval { SELECT * FROM t1 WHERE a IN (1, 2) } { + db eval { + INSERT INTO t2 SELECT randomblob(100) FROM t2; + INSERT INTO t2 SELECT randomblob(100) FROM t2; + INSERT INTO t2 SELECT randomblob(100) FROM t2; + INSERT INTO t2 SELECT randomblob(100) FROM t2; + INSERT INTO t2 SELECT randomblob(100) FROM t2; + } + } + } msg] $msg +} {1 {database disk image is malformed}} + +#------------------------------------------------------------------------- +reset_db + +# Initialize the database. +# +do_execsql_test 3.1 { + PRAGMA page_size=1024; + + CREATE TABLE t1(a INTEGER PRIMARY KEY, b); + INSERT INTO t1 VALUES(1, 'one'); + INSERT INTO t1 VALUES(2, 'two'); + + CREATE TABLE t2(c INTEGER PRAGMA KEY, d); + INSERT INTO t2 VALUES(1, randomblob(1100)); +} {} + +do_test 3.2 { + db eval { SELECT name, rootpage FROM sqlite_master } { + set r($name) $rootpage + } + db close + + hexio_write test.db [expr {($r(t2)-1) * 1024 + 1020}] 00000002 + + sqlite3 db test.db +} {} + +do_test 3.3 { + list [catch { + db eval { SELECT * FROM t1 WHERE a IN (1, 2) } { + db eval { + DELETE FROM t2 WHERE c=1; + } + } + } msg] $msg +} {1 {database disk image is malformed}} + +finish_test + From a4ff825095456e0fe12dd4d9c848043fd6b91697 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 20 Jan 2014 19:55:33 +0000 Subject: [PATCH 172/276] In where.c, do not allocate space in sqlite3_index_info structures for the internal WHERE clause "terms" generated to record column equivalencies. FossilOrigin-Name: 7d9e22187daaa3160b875a1df17b924969bf718e --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 6 ++++-- test/vtab1.test | 19 +++++++++++++++++++ 4 files changed, 31 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 23358e38e5..7c7eeb389c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Handle\sa\sfew\sobscure\sproblems\sthat\scould\smanifest\sif\sa\sdatabase\scorrupted\sin\sa\scertain\sway\swas\swritten\sby\sa\sconnection\sin\sthe\smiddle\sof\sa\sSELECT\sstatement\son\sthe\ssame\sdb. -D 2014-01-20T18:25:44.841 +C In\swhere.c,\sdo\snot\sallocate\sspace\sin\ssqlite3_index_info\sstructures\sfor\sthe\sinternal\sWHERE\sclause\s"terms"\sgenerated\sto\srecord\scolumn\sequivalencies. +D 2014-01-20T19:55:33.120 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -293,7 +293,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45 -F src/where.c 5e11de480a94e6ff8f9922e3a04a31b56d5f33b5 +F src/where.c 56f85486bc8d0cb57fc15e5db2a58d1dfa1114cf F src/whereInt.h 96a75c61f1d2b9d4a8e4bb17d89deb0cf7cba358 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1027,7 +1027,7 @@ F test/vacuum4.test d3f8ecff345f166911568f397d2432c16d2867d9 F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102 F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661 F test/view.test 4057630287bfa5955628fe90a13d4c225d1c7352 -F test/vtab1.test 45ddde57764659c0ec90874bcb6c4831f1004c06 +F test/vtab1.test b631d147b198cfd7903ab5fed028eb2a3d321dc6 F test/vtab2.test 7bcffc050da5c68f4f312e49e443063e2d391c0d F test/vtab3.test baad99fd27217f5d6db10660522e0b7192446de1 F test/vtab4.test 942f8b8280b3ea8a41dae20e7822d065ca1cb275 @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P a06235e0f6aa1e8fefa3f2873ee035eac9dac750 -R 05b4cba80caa92c648883df94b9ec5d5 +P eba8a564e62f84a9620008beead80081fe90a1b7 +R c774305f58a7e7fff71d714265811a28 U dan -Z 37a297a819c7d62ae4b0e647e3e25c85 +Z 8e05aa582afc8018a3754b6d40d97300 diff --git a/manifest.uuid b/manifest.uuid index ad1f20fbcf..1199189ccc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -eba8a564e62f84a9620008beead80081fe90a1b7 \ No newline at end of file +7d9e22187daaa3160b875a1df17b924969bf718e \ No newline at end of file diff --git a/src/where.c b/src/where.c index 30c8597408..86376c4955 100644 --- a/src/where.c +++ b/src/where.c @@ -1751,7 +1751,8 @@ static sqlite3_index_info *allocateIndexInfo( assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) ); testcase( pTerm->eOperator & WO_IN ); testcase( pTerm->eOperator & WO_ISNULL ); - if( pTerm->eOperator & (WO_ISNULL) ) continue; + testcase( pTerm->eOperator & WO_ALL ); + if( (pTerm->eOperator & ~(WO_ISNULL|WO_EQUIV))==0 ) continue; if( pTerm->wtFlags & TERM_VNULL ) continue; nTerm++; } @@ -1803,7 +1804,8 @@ static sqlite3_index_info *allocateIndexInfo( assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) ); testcase( pTerm->eOperator & WO_IN ); testcase( pTerm->eOperator & WO_ISNULL ); - if( pTerm->eOperator & (WO_ISNULL) ) continue; + testcase( pTerm->eOperator & WO_ALL ); + if( (pTerm->eOperator & ~(WO_ISNULL|WO_EQUIV))==0 ) continue; if( pTerm->wtFlags & TERM_VNULL ) continue; pIdxCons[j].iColumn = pTerm->u.leftColumn; pIdxCons[j].iTermOffset = i; diff --git a/test/vtab1.test b/test/vtab1.test index 3eb37357d9..0542ee6fdd 100644 --- a/test/vtab1.test +++ b/test/vtab1.test @@ -1376,4 +1376,23 @@ do_execsql_test 20.4 { ORDER BY 1, 2; } {5 5 6 6 11 11 12 12} +#------------------------------------------------------------------------- +# +do_execsql_test 21.1 { + CREATE TABLE t9(a,b,c); + CREATE VIRTUAL TABLE t9v USING echo(t9); + + INSERT INTO t9 VALUES(1,2,3); + INSERT INTO t9 VALUES(3,2,1); + INSERT INTO t9 VALUES(2,2,2); +} + +do_execsql_test 21.2 { + SELECT * FROM t9v WHERE a Date: Tue, 21 Jan 2014 15:04:47 +0000 Subject: [PATCH 173/276] Remove the undocumented requirement for applications that use an SQLITE_ENABLE_SQLLOG build to define a sqlite3_init_sqllog() function. FossilOrigin-Name: 5e43bf013253921e4dfbe71de11ee7ed4b3e7eae --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/main.c | 7 ------- 3 files changed, 7 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 7c7eeb389c..9793a62dd6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\swhere.c,\sdo\snot\sallocate\sspace\sin\ssqlite3_index_info\sstructures\sfor\sthe\sinternal\sWHERE\sclause\s"terms"\sgenerated\sto\srecord\scolumn\sequivalencies. -D 2014-01-20T19:55:33.120 +C Remove\sthe\sundocumented\srequirement\sfor\sapplications\sthat\suse\san\sSQLITE_ENABLE_SQLLOG\sbuild\sto\sdefine\sa\ssqlite3_init_sqllog()\sfunction. +D 2014-01-21T15:04:47.807 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -188,7 +188,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b F src/loadext.c 867c7b330b740c6c917af9956b13b81d0a048303 -F src/main.c 37f55de2000f6c882414ad3e1bcdb751c531fddd +F src/main.c 4a05a9706579c7649d7eebb0094586728eb53fcb F src/malloc.c 0203ebce9152c6a0e5de520140b8ba65187350be F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c0c990fcaddff810ea277b4fb5d9138603dd5d4b @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P eba8a564e62f84a9620008beead80081fe90a1b7 -R c774305f58a7e7fff71d714265811a28 +P 7d9e22187daaa3160b875a1df17b924969bf718e +R 72db5d0300da6235ddfc19ebd0af857f U dan -Z 8e05aa582afc8018a3754b6d40d97300 +Z 21763f37f81635b2fe9a520f9fd3a652 diff --git a/manifest.uuid b/manifest.uuid index 1199189ccc..89ddacefff 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7d9e22187daaa3160b875a1df17b924969bf718e \ No newline at end of file +5e43bf013253921e4dfbe71de11ee7ed4b3e7eae \ No newline at end of file diff --git a/src/main.c b/src/main.c index 13ad2b9081..98579105c7 100644 --- a/src/main.c +++ b/src/main.c @@ -135,13 +135,6 @@ int sqlite3_initialize(void){ */ if( sqlite3GlobalConfig.isInit ) return SQLITE_OK; -#ifdef SQLITE_ENABLE_SQLLOG - { - extern void sqlite3_init_sqllog(void); - sqlite3_init_sqllog(); - } -#endif - /* Make sure the mutex subsystem is initialized. If unable to ** initialize the mutex subsystem, return early with the error. ** If the system is so sick that we are unable to allocate a mutex, From e73f059093bbf6710688d90bc854358be27bade8 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 21 Jan 2014 22:25:45 +0000 Subject: [PATCH 174/276] Change the recursive common table expression algorithm to use a queue instead of a pair of tables. Runs about 25% faster on the sudoku solver query. The OP_SwapCursors opcode is no longer required. The current implementation uses just a fifo, but the plan is to change it into a queue that will support ORDER BY and LIMIT in a recursive query. FossilOrigin-Name: b2671e1133d2f1fbd36e7cd4b86d6cc7b528aa97 --- manifest | 23 +++++++------ manifest.uuid | 2 +- src/select.c | 91 +++++++++++++++++++++++++++++---------------------- src/shell.c | 6 ++-- src/vdbe.c | 28 ---------------- src/where.c | 12 ++++--- 6 files changed, 76 insertions(+), 86 deletions(-) diff --git a/manifest b/manifest index 9793a62dd6..955bc3f8a9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sthe\sundocumented\srequirement\sfor\sapplications\sthat\suse\san\sSQLITE_ENABLE_SQLLOG\sbuild\sto\sdefine\sa\ssqlite3_init_sqllog()\sfunction. -D 2014-01-21T15:04:47.807 +C Change\sthe\srecursive\scommon\stable\sexpression\salgorithm\sto\suse\sa\squeue\sinstead\nof\sa\spair\sof\stables.\s\sRuns\sabout\s25%\sfaster\son\sthe\ssudoku\ssolver\squery.\s\nThe\sOP_SwapCursors\sopcode\sis\sno\slonger\srequired.\s\sThe\scurrent\simplementation\nuses\sjust\sa\sfifo,\sbut\sthe\splan\sis\sto\schange\sit\sinto\sa\squeue\sthat\swill\ssupport\s\nORDER\sBY\sand\sLIMIT\sin\sa\srecursive\squery. +D 2014-01-21T22:25:45.721 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -219,8 +219,8 @@ F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c a27ac21844df3123b7c1e89d79cd7034d4eb0e8e -F src/shell.c 9f3bc02a658b8f61d2cbe60cfc482f660c1c6c48 +F src/select.c f7b1558aae71d4f6ff48ad91122185d065730ba6 +F src/shell.c 24722d24d4ea8ca93db35e44db7308de786767ca F src/sqlite.h.in eed7f7d66a60daaa7b4a597dcd9bad87aad9611b F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc @@ -280,7 +280,7 @@ F src/update.c c2706a6eb232a96345c35b7e1e75a188e26812bb F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c e71f19b272f05c8695cf747b4bac1732685f9e5c F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c 98d96d04d9a2bef78ca850be1053dc91d031338a +F src/vdbe.c dede894c2990329f8bc5a70da7de44ce8c3c6bf5 F src/vdbe.h e6c4c610fcabad4fa80ebb1efc6822a9367e2b26 F src/vdbeInt.h 42db251e9f863401ff847b90d5fe1614c89a6a56 F src/vdbeapi.c ce4e68ea4842cc6081046f533d088dcf01d247ad @@ -293,7 +293,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45 -F src/where.c 56f85486bc8d0cb57fc15e5db2a58d1dfa1114cf +F src/where.c d908f4e9e45b567e87a890959ebef01187fab46f F src/whereInt.h 96a75c61f1d2b9d4a8e4bb17d89deb0cf7cba358 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1152,7 +1152,10 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 7d9e22187daaa3160b875a1df17b924969bf718e -R 72db5d0300da6235ddfc19ebd0af857f -U dan -Z 21763f37f81635b2fe9a520f9fd3a652 +P 5e43bf013253921e4dfbe71de11ee7ed4b3e7eae +R ead1532b7d5d88209851a3d527991f22 +T *branch * cte-via-queue +T *sym-cte-via-queue * +T -sym-trunk * +U drh +Z 386bc5602f3047b62d7a78b288244cbd diff --git a/manifest.uuid b/manifest.uuid index 89ddacefff..76656dfd03 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5e43bf013253921e4dfbe71de11ee7ed4b3e7eae \ No newline at end of file +b2671e1133d2f1fbd36e7cd4b86d6cc7b528aa97 \ No newline at end of file diff --git a/src/select.c b/src/select.c index dd58ed22e6..e6dd0e7a0a 100644 --- a/src/select.c +++ b/src/select.c @@ -1792,20 +1792,21 @@ static int multiSelect( #ifndef SQLITE_OMIT_CTE if( p->selFlags & SF_Recursive ){ - SrcList *pSrc = p->pSrc; - int nCol = p->pEList->nExpr; - int addrNext; - int addrSwap; - int iCont, iBreak; - int tmp1; /* Intermediate table */ - int tmp2; /* Next intermediate table */ - int tmp3 = 0; /* To ensure unique results if UNION */ - int eDest = SRT_Table; - SelectDest tmp2dest; - int i; + SrcList *pSrc = p->pSrc; /* The FROM clause of the recursive query */ + int nCol = p->pEList->nExpr; /* Number of columns in the CTE */ + int addrTop; /* Top of the loop */ + int addrCont, addrBreak; /* CONTINUE and BREAK addresses */ + int iCurrent; /* The Current table */ + int regCurrent; /* Register holding Current table */ + int iQueue; /* The Queue table */ + int iDistinct; /* To ensure unique results if UNION */ + int eDest; /* How to write to Queue */ + SelectDest destQueue; /* SelectDest targetting the Queue table */ + int i; /* Loop counter */ /* Check that there is no ORDER BY or LIMIT clause. Neither of these - ** are supported on recursive queries. */ + ** are currently supported on recursive queries. + */ assert( p->pOffset==0 || p->pLimit ); if( p->pOrderBy || p->pLimit ){ sqlite3ErrorMsg(pParse, "%s in a recursive query", @@ -1817,56 +1818,66 @@ static int multiSelect( if( sqlite3AuthCheck(pParse, SQLITE_RECURSIVE, 0, 0, 0) ){ goto multi_select_end; } - iBreak = sqlite3VdbeMakeLabel(v); - iCont = sqlite3VdbeMakeLabel(v); + addrBreak = sqlite3VdbeMakeLabel(v); + addrCont = sqlite3VdbeMakeLabel(v); + /* Locate the cursor number of the Current table */ for(i=0; ALWAYS(inSrc); i++){ if( pSrc->a[i].isRecursive ){ - tmp1 = pSrc->a[i].iCursor; + iCurrent = pSrc->a[i].iCursor; break; } } - tmp2 = pParse->nTab++; + /* Allocate cursors for Queue and Distinct. The cursor number for + ** the Distinct table must be exactly one greater than Queue in order + ** for the SRT_DistTable destination to work. */ + iQueue = pParse->nTab++; if( p->op==TK_UNION ){ eDest = SRT_DistTable; - tmp3 = pParse->nTab++; + iDistinct = pParse->nTab++; + }else{ + eDest = SRT_Table; + iDistinct = 0; } - sqlite3SelectDestInit(&tmp2dest, eDest, tmp2); + sqlite3SelectDestInit(&destQueue, eDest, iQueue); - sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tmp1, nCol); - sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tmp2, nCol); - if( tmp3 ){ - p->addrOpenEphm[0] = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tmp3, 0); + /* Allocate cursors for Current, Queue, and iDistinct. */ + regCurrent = ++pParse->nMem; + sqlite3VdbeAddOp3(v, OP_OpenPseudo, iCurrent, regCurrent, nCol); + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iQueue, nCol); + if( iDistinct ){ + p->addrOpenEphm[0] = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iDistinct, 0); p->selFlags |= SF_UsesEphemeral; } - /* Store the results of the initial SELECT in tmp2. */ - rc = sqlite3Select(pParse, pPrior, &tmp2dest); + /* Store the results of the initial SELECT in Queue. */ + rc = sqlite3Select(pParse, pPrior, &destQueue); if( rc ) goto multi_select_end; - /* Clear tmp1. Then switch the contents of tmp1 and tmp2. Then return - ** the contents of tmp1 to the caller. Or, if tmp1 is empty at this - ** point, the recursive query has finished - jump to address iBreak. */ - addrSwap = sqlite3VdbeAddOp2(v, OP_SwapCursors, tmp1, tmp2); - sqlite3VdbeAddOp2(v, OP_Rewind, tmp1, iBreak); - addrNext = sqlite3VdbeCurrentAddr(v); - selectInnerLoop(pParse, p, p->pEList, tmp1, p->pEList->nExpr, - 0, 0, &dest, iCont, iBreak); - sqlite3VdbeResolveLabel(v, iCont); - sqlite3VdbeAddOp2(v, OP_Next, tmp1, addrNext); + /* Find the next row in the Queue and output that row */ + addrTop = sqlite3VdbeAddOp2(v, OP_Rewind, iQueue, addrBreak); + selectInnerLoop(pParse, p, p->pEList, iQueue, p->pEList->nExpr, + 0, 0, &dest, addrCont, addrBreak); + sqlite3VdbeResolveLabel(v, addrCont); - /* Execute the recursive SELECT. Store the results in tmp2. While this - ** SELECT is running, the contents of tmp1 are read by recursive - ** references to the current CTE. */ + /* Transfer the next row in Queue over to Current */ + sqlite3VdbeAddOp1(v, OP_NullRow, iCurrent); /* To reset column cache */ + sqlite3VdbeAddOp2(v, OP_RowData, iQueue, regCurrent); + sqlite3VdbeAddOp1(v, OP_Delete, iQueue); + + /* Execute the recursive SELECT taking the single row in Current as + ** the value for the CTE. Store the results in the Queue. + */ p->pPrior = 0; - rc = sqlite3Select(pParse, p, &tmp2dest); + rc = sqlite3Select(pParse, p, &destQueue); assert( p->pPrior==0 ); p->pPrior = pPrior; if( rc ) goto multi_select_end; - sqlite3VdbeAddOp2(v, OP_Goto, 0, addrSwap); - sqlite3VdbeResolveLabel(v, iBreak); + /* Keep running the loop until the Queue is empty */ + sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop); + sqlite3VdbeResolveLabel(v, addrBreak); }else #endif diff --git a/src/shell.c b/src/shell.c index b5ce90208c..1c4c4ad3e3 100644 --- a/src/shell.c +++ b/src/shell.c @@ -1177,7 +1177,7 @@ static int str_in_array(const char *zStr, const char **azArray){ ** ** * For each "Goto", if the jump destination is earlier in the program ** and ends on one of: -** Yield SeekGt SeekLt RowSetRead +** Yield SeekGt SeekLt RowSetRead Rewind ** then indent all opcodes between the earlier instruction ** and "Goto" by 2 spaces. */ @@ -1189,7 +1189,7 @@ static void explain_data_prepare(struct callback_data *p, sqlite3_stmt *pSql){ int iOp; /* Index of operation in p->aiIndent[] */ const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext", 0 }; - const char *azYield[] = { "Yield", "SeekLt", "SeekGt", "RowSetRead", 0 }; + const char *azYield[] = { "Yield", "SeekLt", "SeekGt", "RowSetRead", "Rewind", 0 }; const char *azGoto[] = { "Goto", 0 }; /* Try to figure out if this is really an EXPLAIN statement. If this @@ -1226,7 +1226,7 @@ static void explain_data_prepare(struct callback_data *p, sqlite3_stmt *pSql){ for(i=p2op; iaiIndent[i] += 2; } if( str_in_array(zOp, azGoto) && p2opnIndent && abYield[p2op] ){ - for(i=p2op; iaiIndent[i] += 2; + for(i=p2op+1; iaiIndent[i] += 2; } } diff --git a/src/vdbe.c b/src/vdbe.c index 86aae3c65d..10a70750e3 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3369,33 +3369,6 @@ case OP_OpenEphemeral: { break; } -#ifndef SQLITE_OMIT_CTE -/* Opcode: SwapCursors P1 P2 * * * -** -** Parameters P1 and P2 are both cursors opened by the OpenEphemeral -** opcode. This opcode deletes the contents of epheremal table P1, -** then renames P2 to P1 and P1 to P2. In other words, following this -** opcode cursor P2 is open on an empty table and P1 is open on the -** table that was initially accessed by P2. -*/ -case OP_SwapCursors: { - Mem tmp; - VdbeCursor *pTmp; - - tmp = p->aMem[p->nMem - pOp->p1]; - p->aMem[p->nMem - pOp->p1] = p->aMem[p->nMem - pOp->p2]; - p->aMem[p->nMem - pOp->p2] = tmp; - - pTmp = p->apCsr[pOp->p1]; - p->apCsr[pOp->p1] = p->apCsr[pOp->p2]; - p->apCsr[pOp->p2] = pTmp; - - assert( pTmp->isTable ); - rc = sqlite3BtreeClearTable(pTmp->pBt, MASTER_ROOT, 0); - break; -} -#endif /* ifndef SQLITE_OMIT_CTE */ - /* Opcode: SorterOpen P1 * * P4 * ** ** This opcode works like OP_OpenEphemeral except that it opens @@ -4393,7 +4366,6 @@ case OP_NullRow: { pC->nullRow = 1; pC->rowidIsValid = 0; pC->cacheStatus = CACHE_STALE; - assert( pC->pCursor || pC->pVtabCursor ); if( pC->pCursor ){ sqlite3BtreeClearCursor(pC->pCursor); } diff --git a/src/where.c b/src/where.c index 86376c4955..f2d72760d3 100644 --- a/src/where.c +++ b/src/where.c @@ -3410,10 +3410,14 @@ static Bitmask codeOneLoopStart( static const u8 aStep[] = { OP_Next, OP_Prev }; static const u8 aStart[] = { OP_Rewind, OP_Last }; assert( bRev==0 || bRev==1 ); - pLevel->op = aStep[bRev]; - pLevel->p1 = iCur; - pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrBrk); - pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP; + if( pTabItem->isRecursive ){ + pLevel->op = OP_Noop; + }else{ + pLevel->op = aStep[bRev]; + pLevel->p1 = iCur; + pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrBrk); + pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP; + } } /* Insert code to test every subexpression that can be completely From 340309fd69aecc620dcd23a396a0f75d1bd5da0b Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 22 Jan 2014 00:23:49 +0000 Subject: [PATCH 175/276] Remove an unnecessary parameter from selectInnerLoop(). Clean up comments. FossilOrigin-Name: 5e6c4a55f6df30da9dbaa8170f3223613cc86f65 --- manifest | 19 ++++----- manifest.uuid | 2 +- src/select.c | 110 +++++++++++++----------------------------------- src/sqliteInt.h | 54 +++++++++++++++++++++++- src/where.c | 2 + 5 files changed, 93 insertions(+), 94 deletions(-) diff --git a/manifest b/manifest index 955bc3f8a9..744daa026d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\srecursive\scommon\stable\sexpression\salgorithm\sto\suse\sa\squeue\sinstead\nof\sa\spair\sof\stables.\s\sRuns\sabout\s25%\sfaster\son\sthe\ssudoku\ssolver\squery.\s\nThe\sOP_SwapCursors\sopcode\sis\sno\slonger\srequired.\s\sThe\scurrent\simplementation\nuses\sjust\sa\sfifo,\sbut\sthe\splan\sis\sto\schange\sit\sinto\sa\squeue\sthat\swill\ssupport\s\nORDER\sBY\sand\sLIMIT\sin\sa\srecursive\squery. -D 2014-01-21T22:25:45.721 +C Remove\san\sunnecessary\sparameter\sfrom\sselectInnerLoop().\s\sClean\sup\scomments. +D 2014-01-22T00:23:49.966 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -219,12 +219,12 @@ F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c f7b1558aae71d4f6ff48ad91122185d065730ba6 +F src/select.c c2021c75911362ac2fa4d9390741c889101bca65 F src/shell.c 24722d24d4ea8ca93db35e44db7308de786767ca F src/sqlite.h.in eed7f7d66a60daaa7b4a597dcd9bad87aad9611b F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h 99fd628541e420b98fc52072635e8ba431706250 +F src/sqliteInt.h 73074ee596a978bc4431746c417527d03a3bb510 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -293,7 +293,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45 -F src/where.c d908f4e9e45b567e87a890959ebef01187fab46f +F src/where.c 943bb821042c8775672f2d0021d963b7243e53a9 F src/whereInt.h 96a75c61f1d2b9d4a8e4bb17d89deb0cf7cba358 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1152,10 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 5e43bf013253921e4dfbe71de11ee7ed4b3e7eae -R ead1532b7d5d88209851a3d527991f22 -T *branch * cte-via-queue -T *sym-cte-via-queue * -T -sym-trunk * +P b2671e1133d2f1fbd36e7cd4b86d6cc7b528aa97 +R 8aa16044970c1d470244a1583e8ab6b5 U drh -Z 386bc5602f3047b62d7a78b288244cbd +Z 0567013342859692eded4e80186919d9 diff --git a/manifest.uuid b/manifest.uuid index 76656dfd03..06282ce842 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b2671e1133d2f1fbd36e7cd4b86d6cc7b528aa97 \ No newline at end of file +5e6c4a55f6df30da9dbaa8170f3223613cc86f65 \ No newline at end of file diff --git a/src/select.c b/src/select.c index e6dd0e7a0a..a6eee2735d 100644 --- a/src/select.c +++ b/src/select.c @@ -543,17 +543,16 @@ struct DistinctCtx { ** This routine generates the code for the inside of the inner loop ** of a SELECT. ** -** If srcTab and nColumn are both zero, then the pEList expressions -** are evaluated in order to get the data for this row. If nColumn>0 -** then data is pulled from srcTab and pEList is used only to get the -** datatypes for each column. +** If srcTab is negative, then the pEList expressions +** are evaluated in order to get the data for this row. If srcTab is +** zero or more, then data is pulled from srcTab and pEList is used only +** to get number columns and the datatype for each column. */ static void selectInnerLoop( Parse *pParse, /* The parser context */ Select *p, /* The complete select statement being coded */ ExprList *pEList, /* List of values being extracted */ int srcTab, /* Pull data from this table */ - int nColumn, /* Number of columns in the source table */ ExprList *pOrderBy, /* If not NULL, sort results using this key */ DistinctCtx *pDistinct, /* If not NULL, info on how to process DISTINCT */ SelectDest *pDest, /* How to dispose of the results */ @@ -569,7 +568,6 @@ static void selectInnerLoop( int nResultCol; /* Number of result columns */ assert( v ); - if( NEVER(v==0) ) return; assert( pEList!=0 ); hasDistinct = pDistinct ? pDistinct->eTnctType : WHERE_DISTINCT_NOOP; if( pOrderBy==0 && !hasDistinct ){ @@ -578,11 +576,7 @@ static void selectInnerLoop( /* Pull the requested columns. */ - if( nColumn>0 ){ - nResultCol = nColumn; - }else{ - nResultCol = pEList->nExpr; - } + nResultCol = pEList->nExpr; if( pDest->iSdst==0 ){ pDest->iSdst = pParse->nMem+1; pDest->nSdst = nResultCol; @@ -591,9 +585,10 @@ static void selectInnerLoop( assert( pDest->nSdst==nResultCol ); } regResult = pDest->iSdst; - if( nColumn>0 ){ - for(i=0; i=0 ){ + for(i=0; ia[i].zName)); } }else if( eDest!=SRT_Exists ){ /* If the destination is an EXISTS(...) expression, the actual @@ -602,15 +597,12 @@ static void selectInnerLoop( sqlite3ExprCodeExprList(pParse, pEList, regResult, (eDest==SRT_Output)?SQLITE_ECEL_DUP:0); } - nColumn = nResultCol; /* If the DISTINCT keyword was present on the SELECT statement ** and this row has been seen before, then do not make this row ** part of the result. */ if( hasDistinct ){ - assert( pEList!=0 ); - assert( pEList->nExpr==nColumn ); switch( pDistinct->eTnctType ){ case WHERE_DISTINCT_ORDERED: { VdbeOp *pOp; /* No longer required OpenEphemeral instr. */ @@ -619,7 +611,7 @@ static void selectInnerLoop( /* Allocate space for the previous row */ regPrev = pParse->nMem+1; - pParse->nMem += nColumn; + pParse->nMem += nResultCol; /* Change the OP_OpenEphemeral coded earlier to an OP_Null ** sets the MEM_Cleared bit on the first register of the @@ -633,10 +625,10 @@ static void selectInnerLoop( pOp->p1 = 1; pOp->p2 = regPrev; - iJump = sqlite3VdbeCurrentAddr(v) + nColumn; - for(i=0; ia[i].pExpr); - if( ieTnctType==WHERE_DISTINCT_UNORDERED ); - codeDistinct(pParse, pDistinct->tabTnct, iContinue, nColumn, regResult); + codeDistinct(pParse, pDistinct->tabTnct, iContinue, nResultCol, regResult); break; } } @@ -673,7 +665,7 @@ static void selectInnerLoop( case SRT_Union: { int r1; r1 = sqlite3GetTempReg(pParse); - sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nColumn, r1); + sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1); sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1); sqlite3ReleaseTempReg(pParse, r1); break; @@ -684,7 +676,7 @@ static void selectInnerLoop( ** the temporary table iParm. */ case SRT_Except: { - sqlite3VdbeAddOp3(v, OP_IdxDelete, iParm, regResult, nColumn); + sqlite3VdbeAddOp3(v, OP_IdxDelete, iParm, regResult, nResultCol); break; } #endif @@ -697,7 +689,7 @@ static void selectInnerLoop( int r1 = sqlite3GetTempReg(pParse); testcase( eDest==SRT_Table ); testcase( eDest==SRT_EphemTab ); - sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nColumn, r1); + sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1); #ifndef SQLITE_OMIT_CTE if( eDest==SRT_DistTable ){ /* If the destination is DistTable, then cursor (iParm+1) is open @@ -730,7 +722,7 @@ static void selectInnerLoop( ** item into the set table with bogus data. */ case SRT_Set: { - assert( nColumn==1 ); + assert( nResultCol==1 ); pDest->affSdst = sqlite3CompareAffinity(pEList->a[0].pExpr, pDest->affSdst); if( pOrderBy ){ @@ -762,7 +754,7 @@ static void selectInnerLoop( ** of the scan loop. */ case SRT_Mem: { - assert( nColumn==1 ); + assert( nResultCol==1 ); if( pOrderBy ){ pushOntoSorter(pParse, pOrderBy, p, regResult); }else{ @@ -783,14 +775,14 @@ static void selectInnerLoop( testcase( eDest==SRT_Output ); if( pOrderBy ){ int r1 = sqlite3GetTempReg(pParse); - sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nColumn, r1); + sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1); pushOntoSorter(pParse, pOrderBy, p, r1); sqlite3ReleaseTempReg(pParse, r1); }else if( eDest==SRT_Coroutine ){ sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm); }else{ - sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, nColumn); - sqlite3ExprCacheAffinityChange(pParse, regResult, nColumn); + sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, nResultCol); + sqlite3ExprCacheAffinityChange(pParse, regResult, nResultCol); } break; } @@ -1857,7 +1849,7 @@ static int multiSelect( /* Find the next row in the Queue and output that row */ addrTop = sqlite3VdbeAddOp2(v, OP_Rewind, iQueue, addrBreak); - selectInnerLoop(pParse, p, p->pEList, iQueue, p->pEList->nExpr, + selectInnerLoop(pParse, p, p->pEList, iQueue, 0, 0, &dest, addrCont, addrBreak); sqlite3VdbeResolveLabel(v, addrCont); @@ -2020,7 +2012,7 @@ static int multiSelect( computeLimitRegisters(pParse, p, iBreak); sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak); iStart = sqlite3VdbeCurrentAddr(v); - selectInnerLoop(pParse, p, p->pEList, unionTab, p->pEList->nExpr, + selectInnerLoop(pParse, p, p->pEList, unionTab, 0, 0, &dest, iCont, iBreak); sqlite3VdbeResolveLabel(v, iCont); sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart); @@ -2098,7 +2090,7 @@ static int multiSelect( iStart = sqlite3VdbeAddOp2(v, OP_RowKey, tab1, r1); sqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0); sqlite3ReleaseTempReg(pParse, r1); - selectInnerLoop(pParse, p, p->pEList, tab1, p->pEList->nExpr, + selectInnerLoop(pParse, p, p->pEList, tab1, 0, 0, &dest, iCont, iBreak); sqlite3VdbeResolveLabel(v, iCont); sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart); @@ -4299,50 +4291,8 @@ static void explainSimpleCount( /* ** Generate code for the SELECT statement given in the p argument. ** -** The results are distributed in various ways depending on the -** contents of the SelectDest structure pointed to by argument pDest -** as follows: -** -** pDest->eDest Result -** ------------ ------------------------------------------- -** SRT_Output Generate a row of output (using the OP_ResultRow -** opcode) for each row in the result set. -** -** SRT_Mem Only valid if the result is a single column. -** Store the first column of the first result row -** in register pDest->iSDParm then abandon the rest -** of the query. This destination implies "LIMIT 1". -** -** SRT_Set The result must be a single column. Store each -** row of result as the key in table pDest->iSDParm. -** Apply the affinity pDest->affSdst before storing -** results. Used to implement "IN (SELECT ...)". -** -** SRT_Union Store results as a key in a temporary table -** identified by pDest->iSDParm. -** -** SRT_Except Remove results from the temporary table pDest->iSDParm. -** -** SRT_Table Store results in temporary table pDest->iSDParm. -** This is like SRT_EphemTab except that the table -** is assumed to already be open. -** -** SRT_EphemTab Create an temporary table pDest->iSDParm and store -** the result there. The cursor is left open after -** returning. This is like SRT_Table except that -** this destination uses OP_OpenEphemeral to create -** the table first. -** -** SRT_Coroutine Generate a co-routine that returns a new row of -** results each time it is invoked. The entry point -** of the co-routine is stored in register pDest->iSDParm. -** -** SRT_Exists Store a 1 in memory cell pDest->iSDParm if the result -** set is not empty. -** -** SRT_Discard Throw the results away. This is used by SELECT -** statements within triggers whose only purpose is -** the side-effects of functions. +** The results are returned according to the SelectDest structure. +** See comments in sqliteInt.h for further information. ** ** This routine returns the number of errors. If any errors are ** encountered, then an appropriate error message is left in @@ -4683,7 +4633,7 @@ int sqlite3Select( } /* Use the standard inner loop. */ - selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, &sDistinct, pDest, + selectInnerLoop(pParse, p, pEList, -1, pOrderBy, &sDistinct, pDest, sqlite3WhereContinueLabel(pWInfo), sqlite3WhereBreakLabel(pWInfo)); @@ -4955,7 +4905,7 @@ int sqlite3Select( sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); finalizeAggFunctions(pParse, &sAggInfo); sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL); - selectInnerLoop(pParse, p, p->pEList, 0, 0, pOrderBy, + selectInnerLoop(pParse, p, p->pEList, -1, pOrderBy, &sDistinct, pDest, addrOutputRow+1, addrSetAbort); sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); @@ -5098,7 +5048,7 @@ int sqlite3Select( pOrderBy = 0; sqlite3ExprIfFalse(pParse, pHaving, addrEnd, SQLITE_JUMPIFNULL); - selectInnerLoop(pParse, p, p->pEList, 0, 0, 0, 0, + selectInnerLoop(pParse, p, p->pEList, -1, 0, 0, pDest, addrEnd, addrEnd); sqlite3ExprListDelete(db, pDel); } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 317e9eb227..f2c08ad296 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2167,8 +2167,58 @@ struct Select { /* -** The results of a select can be distributed in several ways. The -** "SRT" prefix means "SELECT Result Type". +** The results of a SELECT can be distributed in several ways, as defined +** by one of the following macros. The "SRT" prefix means "SELECT Result +** Type". +** +** SRT_Union Store results as a key in a temporary index +** identified by pDest->iSDParm. +** +** SRT_Except Remove results from the temporary index pDest->iSDParm. +** +** SRT_Exists Store a 1 in memory cell pDest->iSDParm if the result +** set is not empty. +** +** SRT_Discard Throw the results away. This is used by SELECT +** statements within triggers whose only purpose is +** the side-effects of functions. +** +** All of the above are free to ignore their ORDER BY clause. Those that +** follow must honor the ORDER BY clause. +** +** SRT_Output Generate a row of output (using the OP_ResultRow +** opcode) for each row in the result set. +** +** SRT_Mem Only valid if the result is a single column. +** Store the first column of the first result row +** in register pDest->iSDParm then abandon the rest +** of the query. This destination implies "LIMIT 1". +** +** SRT_Set The result must be a single column. Store each +** row of result as the key in table pDest->iSDParm. +** Apply the affinity pDest->affSdst before storing +** results. Used to implement "IN (SELECT ...)". +** +** SRT_Table Store results in temporary table pDest->iSDParm. +** This is like SRT_EphemTab except that the table +** is assumed to already be open. +** +** SRT_EphemTab Create an temporary table pDest->iSDParm and store +** the result there. The cursor is left open after +** returning. This is like SRT_Table except that +** this destination uses OP_OpenEphemeral to create +** the table first. +** +** SRT_Coroutine Generate a co-routine that returns a new row of +** results each time it is invoked. The entry point +** of the co-routine is stored in register pDest->iSDParm +** and the result row is stored in pDest->nDest registers +** starting with pDest->iSdst. +** +** SRT_DistTable Store results in a temporary table pDest->iSDParm. +** But also use temporary table pDest->iSDParm+1 as +** a record of all prior results and ignore any duplicate +** rows. Name means: "Distinct Table". */ #define SRT_Union 1 /* Store result as keys in an index */ #define SRT_Except 2 /* Remove result from a UNION index */ diff --git a/src/where.c b/src/where.c index f2d72760d3..51223aaa93 100644 --- a/src/where.c +++ b/src/where.c @@ -3411,6 +3411,8 @@ static Bitmask codeOneLoopStart( static const u8 aStart[] = { OP_Rewind, OP_Last }; assert( bRev==0 || bRev==1 ); if( pTabItem->isRecursive ){ + /* Tables marked isRecursive have only a single row that is stored in + ** a pseudo-cursor. Need need to Rewind or Next such cursors. */ pLevel->op = OP_Noop; }else{ pLevel->op = aStep[bRev]; From 41028151beebfc5dcb1e936f797a141abd7ab11c Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 22 Jan 2014 10:22:25 +0000 Subject: [PATCH 176/276] Fix a typo in a comment. No changes to code or tests. FossilOrigin-Name: cceacc0e79c4e54682daddf2056c6bb8e88d9484 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 744daa026d..bd186f12e4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunnecessary\sparameter\sfrom\sselectInnerLoop().\s\sClean\sup\scomments. -D 2014-01-22T00:23:49.966 +C Fix\sa\stypo\sin\sa\scomment.\sNo\schanges\sto\scode\sor\stests. +D 2014-01-22T10:22:25.214 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -293,7 +293,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45 -F src/where.c 943bb821042c8775672f2d0021d963b7243e53a9 +F src/where.c 67ae3b5e97ecff36c70cb61ccc7d74cf228f1596 F src/whereInt.h 96a75c61f1d2b9d4a8e4bb17d89deb0cf7cba358 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P b2671e1133d2f1fbd36e7cd4b86d6cc7b528aa97 -R 8aa16044970c1d470244a1583e8ab6b5 -U drh -Z 0567013342859692eded4e80186919d9 +P 5e6c4a55f6df30da9dbaa8170f3223613cc86f65 +R d64224deb212538f78a2f080c518a12f +U dan +Z 6bf281c516c82d71cce682fb71803759 diff --git a/manifest.uuid b/manifest.uuid index 06282ce842..bcd373500c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5e6c4a55f6df30da9dbaa8170f3223613cc86f65 \ No newline at end of file +cceacc0e79c4e54682daddf2056c6bb8e88d9484 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 51223aaa93..6fac5e5ed1 100644 --- a/src/where.c +++ b/src/where.c @@ -3412,7 +3412,7 @@ static Bitmask codeOneLoopStart( assert( bRev==0 || bRev==1 ); if( pTabItem->isRecursive ){ /* Tables marked isRecursive have only a single row that is stored in - ** a pseudo-cursor. Need need to Rewind or Next such cursors. */ + ** a pseudo-cursor. No need to Rewind or Next such cursors. */ pLevel->op = OP_Noop; }else{ pLevel->op = aStep[bRev]; From 781def29c7e5fec282f4b69d94a4508b93e4891f Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 22 Jan 2014 13:35:53 +0000 Subject: [PATCH 177/276] Add new SelectDest codes, SRT_Queue and SRT_DistQueue in anticipation of adding ORDER BY support on recursive queries. Factor out the recursive query code generator into a separate procedure. FossilOrigin-Name: 3eb5f9f8d6ac1ee145cb4119087c516f66fe1456 --- manifest | 16 ++-- manifest.uuid | 2 +- src/select.c | 245 +++++++++++++++++++++++++++++++----------------- src/sqliteInt.h | 26 +++-- 4 files changed, 184 insertions(+), 105 deletions(-) diff --git a/manifest b/manifest index bd186f12e4..1f03409943 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\stypo\sin\sa\scomment.\sNo\schanges\sto\scode\sor\stests. -D 2014-01-22T10:22:25.214 +C Add\snew\sSelectDest\scodes,\sSRT_Queue\sand\sSRT_DistQueue\sin\santicipation\sof\sadding\nORDER\sBY\ssupport\son\srecursive\squeries.\s\sFactor\sout\sthe\srecursive\squery\ncode\sgenerator\sinto\sa\sseparate\sprocedure. +D 2014-01-22T13:35:53.476 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -219,12 +219,12 @@ F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c c2021c75911362ac2fa4d9390741c889101bca65 +F src/select.c 11c02c82a6f3cb8a491452fc7474a568a48c64ef F src/shell.c 24722d24d4ea8ca93db35e44db7308de786767ca F src/sqlite.h.in eed7f7d66a60daaa7b4a597dcd9bad87aad9611b F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h 73074ee596a978bc4431746c417527d03a3bb510 +F src/sqliteInt.h 16c73326604e5603c3c10c97ac1e63473590d4ff F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 5e6c4a55f6df30da9dbaa8170f3223613cc86f65 -R d64224deb212538f78a2f080c518a12f -U dan -Z 6bf281c516c82d71cce682fb71803759 +P cceacc0e79c4e54682daddf2056c6bb8e88d9484 +R 3e53ba84b5d9e416a6e5f351b0fd4313 +U drh +Z aa06559c4dc503939fd80ca5aa152df9 diff --git a/manifest.uuid b/manifest.uuid index bcd373500c..2b7addbf9a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cceacc0e79c4e54682daddf2056c6bb8e88d9484 \ No newline at end of file +3eb5f9f8d6ac1ee145cb4119087c516f66fe1456 \ No newline at end of file diff --git a/src/select.c b/src/select.c index a6eee2735d..0152db8b25 100644 --- a/src/select.c +++ b/src/select.c @@ -581,8 +581,10 @@ static void selectInnerLoop( pDest->iSdst = pParse->nMem+1; pDest->nSdst = nResultCol; pParse->nMem += nResultCol; + if( eDest==SRT_Queue ) pParse->nMem++; }else{ assert( pDest->nSdst==nResultCol ); + assert( eDest!=SRT_Queue ); } regResult = pDest->iSdst; if( srcTab>=0 ){ @@ -662,10 +664,30 @@ static void selectInnerLoop( ** table iParm. */ #ifndef SQLITE_OMIT_COMPOUND_SELECT +#ifndef SQLITE_OMIT_CTE + case SRT_Queue: { + sqlite3VdbeAddOp2(v, OP_Sequence, iParm, regResult+nResultCol); + nResultCol++; + /* Fall through into SRT_Union */ + } + case SRT_DistQueue: +#endif /* SQLITE_OMIT_CTE */ case SRT_Union: { int r1; r1 = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1); +#ifndef SQLITE_OMIT_CTE + if( eDest==SRT_DistQueue ){ + /* If the destination is DistQueue, then cursor (iParm+1) is open + ** on a second ephemeral index that holds all values every previously + ** added to the queue. Only add this new value if it has never before + ** been added */ + int addr = sqlite3VdbeCurrentAddr(v) + 3; + sqlite3VdbeAddOp4Int(v, OP_Found, iParm+1, addr, r1, 0); + sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm+1, r1); + assert( pOrderBy==0 ); + } +#endif /* SQLITE_OMIT_CTE */ sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1); sqlite3ReleaseTempReg(pParse, r1); break; @@ -679,7 +701,7 @@ static void selectInnerLoop( sqlite3VdbeAddOp3(v, OP_IdxDelete, iParm, regResult, nResultCol); break; } -#endif +#endif /* SQLITE_OMIT_COMPOUND_SELECT */ /* Store the result as data using a unique key. */ @@ -1676,7 +1698,139 @@ static CollSeq *multiSelectCollSeq(Parse *pParse, Select *p, int iCol){ } #endif /* SQLITE_OMIT_COMPOUND_SELECT */ -/* Forward reference */ +#ifndef SQLITE_OMIT_CTE +/* +** This routine generates VDBE code to compute the content of a WITH RECURSIVE +** query of the form: +** +** AS ( UNION [ALL] ) +** \___________/ \_______________/ +** p->pPrior p +** +** +** There is exactly one reference to the recursive-table in the FROM clause +** of recursive-query, marked with the SrcList->a[].isRecursive flag. +** +** The setup-query runs once to generate an initial set of rows that go +** into a Queue table. Rows are extracted from the Queue table one by +** one. Each row extracted from iQueue is output to pDest. Then the single +** extracted row (now the iCurrent table) becomes the content of the +** recursive-table and recursive-query is run. The output of the recursive-query +** is added back into the Queue table. Then another row is extracted from Queue +** and the iteration continues until the Queue table is empty. +** +** If the compound query operator is UNION then no duplicate rows are ever +** inserted into the Queue table. The iDistinct table keeps a copy of all rows +** that have ever been inserted into Queue and causes duplicates to be +** discarded. If the operator is UNION ALL, then duplicates are allowed. +** +** If the query has an ORDER BY, then entries in the Queue table are kept in +** ORDER BY order and the first entry is extracted for each cycle. Without +** an ORDER BY, the Queue table is just a FIFO. +** +** If a LIMIT clause is provided, then the iteration stops after LIMIT rows +** have been output to pDest. A LIMIT of zero means to output no rows and a +** negative LIMIT means to output all rows. If there is also an OFFSET clause +** with a positive value, then the first OFFSET outputs are discarded rather +** than being sent to pDest. The LIMIT count does not begin until after OFFSET +** rows have been skipped. +*/ +static void generateWithRecursiveQuery( + Parse *pParse, /* Parsing context */ + Select *p, /* The recursive SELECT to be coded */ + SelectDest *pDest /* What to do with query results */ +){ + SrcList *pSrc = p->pSrc; /* The FROM clause of the recursive query */ + int nCol = p->pEList->nExpr; /* Number of columns in the recursive table */ + Vdbe *v = pParse->pVdbe; /* The prepared statement under construction */ + Select *pSetup = p->pPrior; /* The setup query */ + int addrTop; /* Top of the loop */ + int addrCont, addrBreak; /* CONTINUE and BREAK addresses */ + int iCurrent; /* The Current table */ + int regCurrent; /* Register holding Current table */ + int iQueue; /* The Queue table */ + int iDistinct = 0; /* To ensure unique results if UNION */ + int eDest = SRT_Table; /* How to write to Queue */ + SelectDest destQueue; /* SelectDest targetting the Queue table */ + int i; /* Loop counter */ + int rc; /* Result code */ + + /* Obtain authorization to do a recursive query */ + if( sqlite3AuthCheck(pParse, SQLITE_RECURSIVE, 0, 0, 0) ) return; + addrBreak = sqlite3VdbeMakeLabel(v); + addrCont = sqlite3VdbeMakeLabel(v); + + + /* Check that there is no ORDER BY or LIMIT clause. Neither of these + ** are currently supported on recursive queries. + */ + assert( p->pOffset==0 || p->pLimit ); + if( p->pOrderBy || p->pLimit ){ + sqlite3ErrorMsg(pParse, "%s in a recursive query", + p->pOrderBy ? "ORDER BY" : "LIMIT" + ); + return; + } + + /* Locate the cursor number of the Current table */ + for(i=0; ALWAYS(inSrc); i++){ + if( pSrc->a[i].isRecursive ){ + iCurrent = pSrc->a[i].iCursor; + break; + } + } + + /* Allocate cursors for Queue and Distinct. The cursor number for + ** the Distinct table must be exactly one greater than Queue in order + ** for the SRT_DistTable destination to work. */ + iQueue = pParse->nTab++; + if( p->op==TK_UNION ){ + assert( SRT_Table+1==SRT_DistTable ); + assert( SRT_Queue+1==SRT_DistQueue ); + eDest++; + iDistinct = pParse->nTab++; + } + sqlite3SelectDestInit(&destQueue, eDest, iQueue); + + /* Allocate cursors for Current, Queue, and Distinct. */ + regCurrent = ++pParse->nMem; + sqlite3VdbeAddOp3(v, OP_OpenPseudo, iCurrent, regCurrent, nCol); + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iQueue, nCol); + if( iDistinct ){ + p->addrOpenEphm[0] = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iDistinct, 0); + p->selFlags |= SF_UsesEphemeral; + } + + /* Store the results of the setup-query in Queue. */ + rc = sqlite3Select(pParse, pSetup, &destQueue); + if( rc ) return; + + /* Find the next row in the Queue and output that row */ + addrTop = sqlite3VdbeAddOp2(v, OP_Rewind, iQueue, addrBreak); + selectInnerLoop(pParse, p, p->pEList, iQueue, + 0, 0, pDest, addrCont, addrBreak); + sqlite3VdbeResolveLabel(v, addrCont); + + /* Transfer the next row in Queue over to Current */ + sqlite3VdbeAddOp1(v, OP_NullRow, iCurrent); /* To reset column cache */ + sqlite3VdbeAddOp2(v, OP_RowData, iQueue, regCurrent); + sqlite3VdbeAddOp1(v, OP_Delete, iQueue); + + /* Execute the recursive SELECT taking the single row in Current as + ** the value for the recursive-table. Store the results in the Queue. + */ + p->pPrior = 0; + sqlite3Select(pParse, p, &destQueue); + assert( p->pPrior==0 ); + p->pPrior = pSetup; + + /* Keep running the loop until the Queue is empty */ + sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop); + sqlite3VdbeResolveLabel(v, addrBreak); +} +#endif + +/* Forward references */ static int multiSelectOrderBy( Parse *pParse, /* Parsing context */ Select *p, /* The right-most of SELECTs to be coded */ @@ -1784,92 +1938,7 @@ static int multiSelect( #ifndef SQLITE_OMIT_CTE if( p->selFlags & SF_Recursive ){ - SrcList *pSrc = p->pSrc; /* The FROM clause of the recursive query */ - int nCol = p->pEList->nExpr; /* Number of columns in the CTE */ - int addrTop; /* Top of the loop */ - int addrCont, addrBreak; /* CONTINUE and BREAK addresses */ - int iCurrent; /* The Current table */ - int regCurrent; /* Register holding Current table */ - int iQueue; /* The Queue table */ - int iDistinct; /* To ensure unique results if UNION */ - int eDest; /* How to write to Queue */ - SelectDest destQueue; /* SelectDest targetting the Queue table */ - int i; /* Loop counter */ - - /* Check that there is no ORDER BY or LIMIT clause. Neither of these - ** are currently supported on recursive queries. - */ - assert( p->pOffset==0 || p->pLimit ); - if( p->pOrderBy || p->pLimit ){ - sqlite3ErrorMsg(pParse, "%s in a recursive query", - p->pOrderBy ? "ORDER BY" : "LIMIT" - ); - goto multi_select_end; - } - - if( sqlite3AuthCheck(pParse, SQLITE_RECURSIVE, 0, 0, 0) ){ - goto multi_select_end; - } - addrBreak = sqlite3VdbeMakeLabel(v); - addrCont = sqlite3VdbeMakeLabel(v); - - /* Locate the cursor number of the Current table */ - for(i=0; ALWAYS(inSrc); i++){ - if( pSrc->a[i].isRecursive ){ - iCurrent = pSrc->a[i].iCursor; - break; - } - } - - /* Allocate cursors for Queue and Distinct. The cursor number for - ** the Distinct table must be exactly one greater than Queue in order - ** for the SRT_DistTable destination to work. */ - iQueue = pParse->nTab++; - if( p->op==TK_UNION ){ - eDest = SRT_DistTable; - iDistinct = pParse->nTab++; - }else{ - eDest = SRT_Table; - iDistinct = 0; - } - sqlite3SelectDestInit(&destQueue, eDest, iQueue); - - /* Allocate cursors for Current, Queue, and iDistinct. */ - regCurrent = ++pParse->nMem; - sqlite3VdbeAddOp3(v, OP_OpenPseudo, iCurrent, regCurrent, nCol); - sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iQueue, nCol); - if( iDistinct ){ - p->addrOpenEphm[0] = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iDistinct, 0); - p->selFlags |= SF_UsesEphemeral; - } - - /* Store the results of the initial SELECT in Queue. */ - rc = sqlite3Select(pParse, pPrior, &destQueue); - if( rc ) goto multi_select_end; - - /* Find the next row in the Queue and output that row */ - addrTop = sqlite3VdbeAddOp2(v, OP_Rewind, iQueue, addrBreak); - selectInnerLoop(pParse, p, p->pEList, iQueue, - 0, 0, &dest, addrCont, addrBreak); - sqlite3VdbeResolveLabel(v, addrCont); - - /* Transfer the next row in Queue over to Current */ - sqlite3VdbeAddOp1(v, OP_NullRow, iCurrent); /* To reset column cache */ - sqlite3VdbeAddOp2(v, OP_RowData, iQueue, regCurrent); - sqlite3VdbeAddOp1(v, OP_Delete, iQueue); - - /* Execute the recursive SELECT taking the single row in Current as - ** the value for the CTE. Store the results in the Queue. - */ - p->pPrior = 0; - rc = sqlite3Select(pParse, p, &destQueue); - assert( p->pPrior==0 ); - p->pPrior = pPrior; - if( rc ) goto multi_select_end; - - /* Keep running the loop until the Queue is empty */ - sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop); - sqlite3VdbeResolveLabel(v, addrBreak); + generateWithRecursiveQuery(pParse, p, &dest); }else #endif diff --git a/src/sqliteInt.h b/src/sqliteInt.h index f2c08ad296..ac48291d80 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2199,10 +2199,6 @@ struct Select { ** Apply the affinity pDest->affSdst before storing ** results. Used to implement "IN (SELECT ...)". ** -** SRT_Table Store results in temporary table pDest->iSDParm. -** This is like SRT_EphemTab except that the table -** is assumed to already be open. -** ** SRT_EphemTab Create an temporary table pDest->iSDParm and store ** the result there. The cursor is left open after ** returning. This is like SRT_Table except that @@ -2215,10 +2211,22 @@ struct Select { ** and the result row is stored in pDest->nDest registers ** starting with pDest->iSdst. ** +** SRT_Table Store results in temporary table pDest->iSDParm. +** This is like SRT_EphemTab except that the table +** is assumed to already be open. +** ** SRT_DistTable Store results in a temporary table pDest->iSDParm. ** But also use temporary table pDest->iSDParm+1 as ** a record of all prior results and ignore any duplicate ** rows. Name means: "Distinct Table". +** +** SRT_Queue Store results in priority queue pDest->iSDParm (really +** an index). Append a sequence number so that all entries +** are distinct. +** +** SRT_DistQueue Store results in priority queue pDest->iSDParm only if +** the same record has never been stored before. The +** index at pDest->iSDParm+1 hold all prior stores. */ #define SRT_Union 1 /* Store result as keys in an index */ #define SRT_Except 2 /* Remove result from a UNION index */ @@ -2231,10 +2239,12 @@ struct Select { #define SRT_Output 5 /* Output each row of result */ #define SRT_Mem 6 /* Store result in a memory cell */ #define SRT_Set 7 /* Store results as keys in an index */ -#define SRT_Table 8 /* Store result as data with an automatic rowid */ -#define SRT_EphemTab 9 /* Create transient tab and store like SRT_Table */ -#define SRT_Coroutine 10 /* Generate a single row of result */ -#define SRT_DistTable 11 /* Like SRT_TABLE, but unique results only */ +#define SRT_EphemTab 8 /* Create transient tab and store like SRT_Table */ +#define SRT_Coroutine 9 /* Generate a single row of result */ +#define SRT_Table 10 /* Store result as data with an automatic rowid */ +#define SRT_DistTable 11 /* Like SRT_Table, but unique results only */ +#define SRT_Queue 12 /* Store result in an queue */ +#define SRT_DistQueue 13 /* Like SRT_Queue, but unique results only */ /* ** An instance of this object describes where to put of the results of From fe1c6bb9c291e2a670236b2d33fb74b587bf8b16 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 22 Jan 2014 17:28:35 +0000 Subject: [PATCH 178/276] Get ORDER BY working for recursive queries. FossilOrigin-Name: 37b343b01841b338954ddfa9b76d92aa50037aec --- manifest | 16 +++--- manifest.uuid | 2 +- src/select.c | 135 ++++++++++++++++++++++++++++++++---------------- src/sqliteInt.h | 11 ++-- test/with1.test | 39 +++++++++++++- 5 files changed, 143 insertions(+), 60 deletions(-) diff --git a/manifest b/manifest index 1f03409943..896f5cf947 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\snew\sSelectDest\scodes,\sSRT_Queue\sand\sSRT_DistQueue\sin\santicipation\sof\sadding\nORDER\sBY\ssupport\son\srecursive\squeries.\s\sFactor\sout\sthe\srecursive\squery\ncode\sgenerator\sinto\sa\sseparate\sprocedure. -D 2014-01-22T13:35:53.476 +C Get\sORDER\sBY\sworking\sfor\srecursive\squeries. +D 2014-01-22T17:28:35.279 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -219,12 +219,12 @@ F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c 11c02c82a6f3cb8a491452fc7474a568a48c64ef +F src/select.c b5430b99c0339dcfe9d06a4c251548e650e386e0 F src/shell.c 24722d24d4ea8ca93db35e44db7308de786767ca F src/sqlite.h.in eed7f7d66a60daaa7b4a597dcd9bad87aad9611b F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h 16c73326604e5603c3c10c97ac1e63473590d4ff +F src/sqliteInt.h 87a90ad4818ac5d68d3463eb7fe3ed96e5209b25 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -1092,7 +1092,7 @@ F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c F test/win32lock.test 7a6bd73a5dcdee39b5bb93e92395e1773a194361 F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d -F test/with1.test cec63b56797a70842afa8929c241dfdb3d864283 +F test/with1.test f4aa699a3712207e02f13945cd2b67d01a9d9f57 F test/with2.test 2fe78fcd8deef2a0f9cfc49bfc755911d0b3fd64 F test/withM.test e97f2a8c506ab3ea9eab94e6f6072f6cc924c991 F test/without_rowid1.test aaa26da19d543cd8d3d2d0e686dfa255556c15c8 @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P cceacc0e79c4e54682daddf2056c6bb8e88d9484 -R 3e53ba84b5d9e416a6e5f351b0fd4313 +P 3eb5f9f8d6ac1ee145cb4119087c516f66fe1456 +R a615c5dcec438a7db4f9b5a3e0983f82 U drh -Z aa06559c4dc503939fd80ca5aa152df9 +Z 4ad026d26a172a85d439a21b0ddb47e4 diff --git a/manifest.uuid b/manifest.uuid index 2b7addbf9a..87e23ab961 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3eb5f9f8d6ac1ee145cb4119087c516f66fe1456 \ No newline at end of file +37b343b01841b338954ddfa9b76d92aa50037aec \ No newline at end of file diff --git a/src/select.c b/src/select.c index 0152db8b25..13e9562ba2 100644 --- a/src/select.c +++ b/src/select.c @@ -581,10 +581,8 @@ static void selectInnerLoop( pDest->iSdst = pParse->nMem+1; pDest->nSdst = nResultCol; pParse->nMem += nResultCol; - if( eDest==SRT_Queue ) pParse->nMem++; }else{ assert( pDest->nSdst==nResultCol ); - assert( eDest!=SRT_Queue ); } regResult = pDest->iSdst; if( srcTab>=0 ){ @@ -664,30 +662,10 @@ static void selectInnerLoop( ** table iParm. */ #ifndef SQLITE_OMIT_COMPOUND_SELECT -#ifndef SQLITE_OMIT_CTE - case SRT_Queue: { - sqlite3VdbeAddOp2(v, OP_Sequence, iParm, regResult+nResultCol); - nResultCol++; - /* Fall through into SRT_Union */ - } - case SRT_DistQueue: -#endif /* SQLITE_OMIT_CTE */ case SRT_Union: { int r1; r1 = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1); -#ifndef SQLITE_OMIT_CTE - if( eDest==SRT_DistQueue ){ - /* If the destination is DistQueue, then cursor (iParm+1) is open - ** on a second ephemeral index that holds all values every previously - ** added to the queue. Only add this new value if it has never before - ** been added */ - int addr = sqlite3VdbeCurrentAddr(v) + 3; - sqlite3VdbeAddOp4Int(v, OP_Found, iParm+1, addr, r1, 0); - sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm+1, r1); - assert( pOrderBy==0 ); - } -#endif /* SQLITE_OMIT_CTE */ sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1); sqlite3ReleaseTempReg(pParse, r1); break; @@ -809,6 +787,51 @@ static void selectInnerLoop( break; } +#ifndef SQLITE_OMIT_CTE + /* Write the results into a priority queue that is order according to + ** pDest->pOrderBy (in pSO). pDest->iSDParm (in iParm) is the cursor for an + ** index with pSO->nExpr+2 columns. Build a key using pSO for the first + ** pSO->nExpr columns, then make sure all keys are unique by adding a + ** final OP_Sequence column. The last column is the record as a blob. + */ + case SRT_DistQueue: + case SRT_Queue: { + int nKey; + int r1, r2, r3; + int addrTest = 0; + ExprList *pSO; + pSO = pDest->pOrderBy; + assert( pSO ); + nKey = pSO->nExpr; + r1 = sqlite3GetTempReg(pParse); + r2 = sqlite3GetTempRange(pParse, nKey+2); + r3 = r2+nKey+1; + sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r3); + if( eDest==SRT_DistQueue ){ + /* If the destination is DistQueue, then cursor (iParm+1) is open + ** on a second ephemeral index that holds all values every previously + ** added to the queue. Only add this new value if it has never before + ** been added */ + addrTest = sqlite3VdbeAddOp4Int(v, OP_Found, iParm+1, 0, r3, 0); + sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm+1, r3); + } + for(i=0; ia[i].u.x.iOrderByCol - 1, + r2+i); + } + sqlite3VdbeAddOp2(v, OP_Sequence, iParm, r2+nKey); + sqlite3VdbeAddOp3(v, OP_MakeRecord, r2, nKey+2, r1); + sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1); + if( addrTest ) sqlite3VdbeJumpHere(v, addrTest); + sqlite3ReleaseTempReg(pParse, r1); + sqlite3ReleaseTempRange(pParse, r2, nKey+2); + break; + } +#endif /* SQLITE_OMIT_CTE */ + + + #if !defined(SQLITE_OMIT_TRIGGER) /* Discard the results. This is used for SELECT statements inside ** the body of a TRIGGER. The purpose of such selects is to call @@ -897,7 +920,7 @@ int sqlite3KeyInfoIsWriteable(KeyInfo *p){ return p->nRef==1; } ** function is responsible for seeing that this structure is eventually ** freed. */ -static KeyInfo *keyInfoFromExprList(Parse *pParse, ExprList *pList){ +static KeyInfo *keyInfoFromExprList(Parse *pParse, ExprList *pList, int nExtra){ int nExpr; KeyInfo *pInfo; struct ExprList_item *pItem; @@ -905,7 +928,7 @@ static KeyInfo *keyInfoFromExprList(Parse *pParse, ExprList *pList){ int i; nExpr = pList->nExpr; - pInfo = sqlite3KeyInfoAlloc(db, nExpr, 1); + pInfo = sqlite3KeyInfoAlloc(db, nExpr+nExtra, 1); if( pInfo ){ assert( sqlite3KeyInfoIsWriteable(pInfo) ); for(i=0, pItem=pList->a; ipOffset==0 || p->pLimit ); - if( p->pOrderBy || p->pLimit ){ + if( /*p->pOrderBy ||*/ p->pLimit ){ sqlite3ErrorMsg(pParse, "%s in a recursive query", p->pOrderBy ? "ORDER BY" : "LIMIT" ); @@ -1780,22 +1802,34 @@ static void generateWithRecursiveQuery( } } - /* Allocate cursors for Queue and Distinct. The cursor number for + /* Detach the ORDER BY clause from the compound SELECT */ + pOrderBy = p->pOrderBy; + p->pOrderBy = 0; + + /* Allocate cursors numbers for Queue and Distinct. The cursor number for ** the Distinct table must be exactly one greater than Queue in order - ** for the SRT_DistTable destination to work. */ + ** for the SRT_DistTable and SRT_DistQueue destinations to work. */ iQueue = pParse->nTab++; if( p->op==TK_UNION ){ - assert( SRT_Table+1==SRT_DistTable ); - assert( SRT_Queue+1==SRT_DistQueue ); - eDest++; + eDest = pOrderBy ? SRT_DistQueue : SRT_DistTable; iDistinct = pParse->nTab++; + }else{ + eDest = pOrderBy ? SRT_Queue : SRT_Table; } sqlite3SelectDestInit(&destQueue, eDest, iQueue); /* Allocate cursors for Current, Queue, and Distinct. */ regCurrent = ++pParse->nMem; sqlite3VdbeAddOp3(v, OP_OpenPseudo, iCurrent, regCurrent, nCol); - sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iQueue, nCol); + if( pOrderBy ){ + KeyInfo *pKeyInfo = keyInfoFromExprList(pParse, pOrderBy, 1); + sqlite3VdbeAddOp4(v, OP_OpenEphemeral, iQueue, pOrderBy->nExpr+2, 0, + (char*)pKeyInfo, P4_KEYINFO); + destQueue.pOrderBy = pOrderBy; + }else{ + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iQueue, nCol); + } + VdbeComment((v, "Queue table")); if( iDistinct ){ p->addrOpenEphm[0] = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iDistinct, 0); p->selFlags |= SF_UsesEphemeral; @@ -1803,19 +1837,26 @@ static void generateWithRecursiveQuery( /* Store the results of the setup-query in Queue. */ rc = sqlite3Select(pParse, pSetup, &destQueue); - if( rc ) return; + if( rc ) goto end_of_recursive_query; /* Find the next row in the Queue and output that row */ addrTop = sqlite3VdbeAddOp2(v, OP_Rewind, iQueue, addrBreak); - selectInnerLoop(pParse, p, p->pEList, iQueue, - 0, 0, pDest, addrCont, addrBreak); - sqlite3VdbeResolveLabel(v, addrCont); /* Transfer the next row in Queue over to Current */ sqlite3VdbeAddOp1(v, OP_NullRow, iCurrent); /* To reset column cache */ - sqlite3VdbeAddOp2(v, OP_RowData, iQueue, regCurrent); + if( pOrderBy ){ + sqlite3VdbeAddOp3(v, OP_Column, iQueue, pOrderBy->nExpr+1, regCurrent); + }else{ + sqlite3VdbeAddOp2(v, OP_RowData, iQueue, regCurrent); + } sqlite3VdbeAddOp1(v, OP_Delete, iQueue); + /* Output the single row in Current */ + addrCont = sqlite3VdbeMakeLabel(v); + selectInnerLoop(pParse, p, p->pEList, iCurrent, + 0, 0, pDest, addrCont, addrBreak); + sqlite3VdbeResolveLabel(v, addrCont); + /* Execute the recursive SELECT taking the single row in Current as ** the value for the recursive-table. Store the results in the Queue. */ @@ -1827,6 +1868,10 @@ static void generateWithRecursiveQuery( /* Keep running the loop until the Queue is empty */ sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop); sqlite3VdbeResolveLabel(v, addrBreak); + +end_of_recursive_query: + p->pOrderBy = pOrderBy; + return; } #endif @@ -4227,7 +4272,7 @@ static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){ "argument"); pFunc->iDistinct = -1; }else{ - KeyInfo *pKeyInfo = keyInfoFromExprList(pParse, pE->x.pList); + KeyInfo *pKeyInfo = keyInfoFromExprList(pParse, pE->x.pList, 0); sqlite3VdbeAddOp4(v, OP_OpenEphemeral, pFunc->iDistinct, 0, 0, (char*)pKeyInfo, P4_KEYINFO); } @@ -4636,7 +4681,7 @@ int sqlite3Select( */ if( pOrderBy ){ KeyInfo *pKeyInfo; - pKeyInfo = keyInfoFromExprList(pParse, pOrderBy); + pKeyInfo = keyInfoFromExprList(pParse, pOrderBy, 0); pOrderBy->iECursor = pParse->nTab++; p->addrOpenEphm[2] = addrSortIndex = sqlite3VdbeAddOp4(v, OP_OpenEphemeral, @@ -4668,7 +4713,7 @@ int sqlite3Select( sDistinct.tabTnct = pParse->nTab++; sDistinct.addrTnct = sqlite3VdbeAddOp4(v, OP_OpenEphemeral, sDistinct.tabTnct, 0, 0, - (char*)keyInfoFromExprList(pParse, p->pEList), + (char*)keyInfoFromExprList(pParse, p->pEList, 0), P4_KEYINFO); sqlite3VdbeChangeP5(v, BTREE_UNORDERED); sDistinct.eTnctType = WHERE_DISTINCT_UNORDERED; @@ -4792,7 +4837,7 @@ int sqlite3Select( ** will be converted into a Noop. */ sAggInfo.sortingIdx = pParse->nTab++; - pKeyInfo = keyInfoFromExprList(pParse, pGroupBy); + pKeyInfo = keyInfoFromExprList(pParse, pGroupBy, 0); addrSortingIdx = sqlite3VdbeAddOp4(v, OP_SorterOpen, sAggInfo.sortingIdx, sAggInfo.nSortingColumn, 0, (char*)pKeyInfo, P4_KEYINFO); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index ac48291d80..c1fa7b69ad 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2251,11 +2251,12 @@ struct Select { ** a SELECT statement. */ struct SelectDest { - u8 eDest; /* How to dispose of the results. On of SRT_* above. */ - char affSdst; /* Affinity used when eDest==SRT_Set */ - int iSDParm; /* A parameter used by the eDest disposal method */ - int iSdst; /* Base register where results are written */ - int nSdst; /* Number of registers allocated */ + u8 eDest; /* How to dispose of the results. On of SRT_* above. */ + char affSdst; /* Affinity used when eDest==SRT_Set */ + int iSDParm; /* A parameter used by the eDest disposal method */ + int iSdst; /* Base register where results are written */ + int nSdst; /* Number of registers allocated */ + ExprList *pOrderBy; /* Key columns for SRT_Queue and SRT_DistQueue */ }; /* diff --git a/test/with1.test b/test/with1.test index fcf59267f2..0895312b0c 100644 --- a/test/with1.test +++ b/test/with1.test @@ -152,7 +152,44 @@ do_execsql_test 5.1 { do_catchsql_test 5.2 { WITH i(x) AS ( VALUES(1) UNION ALL SELECT x+1 FROM i ORDER BY 1) SELECT x FROM i LIMIT 10; -} {1 {ORDER BY in a recursive query}} +} {0 {1 2 3 4 5 6 7 8 9 10}} + +do_execsql_test 5.2.1 { + CREATE TABLE edge(xfrom, xto, seq, PRIMARY KEY(xfrom, xto)) WITHOUT ROWID; + INSERT INTO edge VALUES(0, 1, 10); + INSERT INTO edge VALUES(1, 2, 20); + INSERT INTO edge VALUES(0, 3, 30); + INSERT INTO edge VALUES(2, 4, 40); + INSERT INTO edge VALUES(3, 4, 40); + INSERT INTO edge VALUES(2, 5, 50); + INSERT INTO edge VALUES(3, 6, 60); + INSERT INTO edge VALUES(5, 7, 70); + INSERT INTO edge VALUES(3, 7, 70); + INSERT INTO edge VALUES(4, 8, 80); + INSERT INTO edge VALUES(7, 8, 80); + INSERT INTO edge VALUES(8, 9, 90); + + WITH RECURSIVE + ancest(id, mtime) AS + (VALUES(0, 0) + UNION + SELECT edge.xto, edge.seq FROM edge, ancest + WHERE edge.xfrom=ancest.id + ORDER BY 2 + ) + SELECT * FROM ancest; +} {0 0 1 10 2 20 3 30 4 40 5 50 6 60 7 70 8 80 9 90} +do_execsql_test 5.2.2 { + WITH RECURSIVE + ancest(id, mtime) AS + (VALUES(0, 0) + UNION ALL + SELECT edge.xto, edge.seq FROM edge, ancest + WHERE edge.xfrom=ancest.id + ORDER BY 2 + ) + SELECT * FROM ancest; +} {0 0 1 10 2 20 3 30 4 40 4 40 5 50 6 60 7 70 7 70 8 80 8 80 8 80 8 80 9 90 9 90 9 90 9 90} do_catchsql_test 5.3 { WITH i(x) AS ( VALUES(1) UNION ALL SELECT x+1 FROM i LIMIT 10 ) From a8a0617e06534c751e4079f0b9c5a47fc4ca07af Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 22 Jan 2014 17:43:16 +0000 Subject: [PATCH 179/276] =?UTF-8?q?Update=20the=20spellfix=20virtual=20tab?= =?UTF-8?q?le=20to=20optimize=20queries=20of=20the=20form=20"SELECT=20...?= =?UTF-8?q?=20FROM=20tbl=20WHERE=20rowid=3D=3F".?= FossilOrigin-Name: a0ba55ff0596c5f15e9cdb254c68ef50df2dfaad --- ext/misc/spellfix.c | 32 ++++++++++++++++++++++++++++---- manifest | 14 +++++++------- manifest.uuid | 2 +- test/spellfix.test | 45 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 81 insertions(+), 12 deletions(-) diff --git a/ext/misc/spellfix.c b/ext/misc/spellfix.c index 768ea5753c..4be73bb39e 100644 --- a/ext/misc/spellfix.c +++ b/ext/misc/spellfix.c @@ -2051,6 +2051,7 @@ static int spellfix1Close(sqlite3_vtab_cursor *cur){ ** (D) scope = $scope ** (E) distance < $distance ** (F) distance <= $distance +** (G) rowid = $rowid ** ** The plan number is a bit mask formed with these bits: ** @@ -2060,8 +2061,9 @@ static int spellfix1Close(sqlite3_vtab_cursor *cur){ ** 0x08 (D) is found ** 0x10 (E) is found ** 0x20 (F) is found +** 0x40 (G) is found ** -** filter.argv[*] values contains $str, $langid, $top, and $scope, +** filter.argv[*] values contains $str, $langid, $top, $scope and $rowid ** if specified and in that order. */ static int spellfix1BestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ @@ -2070,6 +2072,7 @@ static int spellfix1BestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ int iTopTerm = -1; int iScopeTerm = -1; int iDistTerm = -1; + int iRowidTerm = -1; int i; const struct sqlite3_index_constraint *pConstraint; pConstraint = pIdxInfo->aConstraint; @@ -2122,6 +2125,15 @@ static int spellfix1BestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ iPlan |= pConstraint->op==SQLITE_INDEX_CONSTRAINT_LT ? 16 : 32; iDistTerm = i; } + + /* Terms of the form: distance < $dist or distance <= $dist */ + if( (iPlan & 64)==0 + && pConstraint->iColumn<0 + && pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ + ){ + iPlan |= 64; + iRowidTerm = i; + } } if( iPlan&1 ){ int idx = 2; @@ -2149,6 +2161,11 @@ static int spellfix1BestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ pIdxInfo->aConstraintUsage[iDistTerm].omit = 1; } pIdxInfo->estimatedCost = 1e5; + }else if( (iPlan & 64) ){ + pIdxInfo->idxNum = 64; + pIdxInfo->aConstraintUsage[iRowidTerm].argvIndex = 1; + pIdxInfo->aConstraintUsage[iRowidTerm].omit = 1; + pIdxInfo->estimatedCost = 5; }else{ pIdxInfo->idxNum = 0; pIdxInfo->estimatedCost = 1e50; @@ -2465,16 +2482,23 @@ static int spellfix1FilterForFullScan( int argc, sqlite3_value **argv ){ - int rc; + int rc = SQLITE_OK; char *zSql; spellfix1_vtab *pVTab = pCur->pVTab; spellfix1ResetCursor(pCur); + assert( idxNum==0 || idxNum==64 ); zSql = sqlite3_mprintf( - "SELECT word, rank, NULL, langid, id FROM \"%w\".\"%w_vocab\"", - pVTab->zDbName, pVTab->zTableName); + "SELECT word, rank, NULL, langid, id FROM \"%w\".\"%w_vocab\"%s", + pVTab->zDbName, pVTab->zTableName, + ((idxNum & 64) ? " WHERE rowid=?" : "") + ); if( zSql==0 ) return SQLITE_NOMEM; rc = sqlite3_prepare_v2(pVTab->db, zSql, -1, &pCur->pFullScan, 0); sqlite3_free(zSql); + if( rc==SQLITE_OK && (idxNum & 64) ){ + assert( argc==1 ); + rc = sqlite3_bind_value(pCur->pFullScan, 1, argv[0]); + } pCur->nRow = pCur->iRow = 0; if( rc==SQLITE_OK ){ rc = sqlite3_step(pCur->pFullScan); diff --git a/manifest b/manifest index 9793a62dd6..336d04f480 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sthe\sundocumented\srequirement\sfor\sapplications\sthat\suse\san\sSQLITE_ENABLE_SQLLOG\sbuild\sto\sdefine\sa\ssqlite3_init_sqllog()\sfunction. -D 2014-01-21T15:04:47.807 +C Update\sthe\sspellfix\svirtual\stable\sto\soptimize\squeries\sof\sthe\sform\s"SELECT\s...\sFROM\stbl\sWHERE\srowid=?". +D 2014-01-22T17:43:16.604 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -114,7 +114,7 @@ F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342 F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63 F ext/misc/regexp.c af92cdaa5058fcec1451e49becc7ba44dba023dc F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a -F ext/misc/spellfix.c 76578f2c56ceaa23d22032338d90db79c68490fb +F ext/misc/spellfix.c adfc569fafef7a1eb8f21528e5277686b358c3ce F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512 F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95 F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e @@ -825,7 +825,7 @@ F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b F test/speedtest1.c 7130d2cb6db45baa553a4ab2f715116c71c2d9f4 -F test/spellfix.test 8c40b169b104086d8795781f670ba3c786d6d8be +F test/spellfix.test 674db5da8b16d2b54939b68ccc0ac31ca53d9977 F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298 F test/stat.test 76fd746b85459e812a0193410fb599f0531f22de F test/stmt.test 25d64e3dbf9a3ce89558667d7f39d966fe2a71b9 @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 7d9e22187daaa3160b875a1df17b924969bf718e -R 72db5d0300da6235ddfc19ebd0af857f +P 5e43bf013253921e4dfbe71de11ee7ed4b3e7eae +R d2ae80bd066cad79603d23bc83a10a19 U dan -Z 21763f37f81635b2fe9a520f9fd3a652 +Z 90dc7fd11fe48035054a3857f5aa405e diff --git a/manifest.uuid b/manifest.uuid index 89ddacefff..3b856a138c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5e43bf013253921e4dfbe71de11ee7ed4b3e7eae \ No newline at end of file +a0ba55ff0596c5f15e9cdb254c68ef50df2dfaad \ No newline at end of file diff --git a/test/spellfix.test b/test/spellfix.test index 9eb7a45f5d..3e6fdf7eec 100644 --- a/test/spellfix.test +++ b/test/spellfix.test @@ -221,6 +221,51 @@ foreach {tn word res} { } $res } +#------------------------------------------------------------------------- +# Try some queries by rowid. +# +do_execsql_test 6.1.1 { + SELECT word FROM t3 WHERE rowid = 10; +} {keener} +do_execsql_test 6.1.2 { + SELECT word, distance FROM t3 WHERE rowid = 10; +} {keener {}} +do_execsql_test 6.1.3 { + SELECT word, distance FROM t3 WHERE rowid = 10 AND word MATCH 'kiiner'; +} {keener 300} + +proc trace_callback {sql} { + if {[string range $sql 0 2] == "-- "} { + lappend ::trace [string range $sql 3 end] + } +} + +proc do_tracesql_test {tn sql {res {}}} { + set ::trace [list] + uplevel [list do_test $tn [subst -nocommands { + set vals [execsql {$sql}] + concat [set vals] [set ::trace] + }] [list {*}$res]] +} + +db trace trace_callback +do_tracesql_test 6.2.1 { + SELECT word FROM t3 WHERE rowid = 10; +} {keener + {SELECT word, rank, NULL, langid, id FROM "main"."t3_vocab" WHERE rowid=?} +} +do_tracesql_test 6.2.2 { + SELECT word, distance FROM t3 WHERE rowid = 10; +} {keener {} + {SELECT word, rank, NULL, langid, id FROM "main"."t3_vocab" WHERE rowid=?} +} +do_tracesql_test 6.2.3 { + SELECT word, distance FROM t3 WHERE rowid = 10 AND word MATCH 'kiiner'; +} {keener 300 + {SELECT id, word, rank, k1 FROM "main"."t3_vocab" WHERE langid=0 AND k2>=?1 AND k2 Date: Wed, 22 Jan 2014 18:07:04 +0000 Subject: [PATCH 180/276] Add support for LIMIT and OFFSET in a recursive query. FossilOrigin-Name: 1945484e6b9769c1943f750f5b09860417fb190a --- manifest | 14 ++++++------- manifest.uuid | 2 +- src/select.c | 55 ++++++++++++++++++++++++++++--------------------- test/with1.test | 17 ++++++++++++--- 4 files changed, 54 insertions(+), 34 deletions(-) diff --git a/manifest b/manifest index 896f5cf947..aa1a8aadb5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Get\sORDER\sBY\sworking\sfor\srecursive\squeries. -D 2014-01-22T17:28:35.279 +C Add\ssupport\sfor\sLIMIT\sand\sOFFSET\sin\sa\srecursive\squery. +D 2014-01-22T18:07:04.473 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -219,7 +219,7 @@ F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c b5430b99c0339dcfe9d06a4c251548e650e386e0 +F src/select.c f6d84f3a109d3e43d38089da6a4f131a5ce4c6ef F src/shell.c 24722d24d4ea8ca93db35e44db7308de786767ca F src/sqlite.h.in eed7f7d66a60daaa7b4a597dcd9bad87aad9611b F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e @@ -1092,7 +1092,7 @@ F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c F test/win32lock.test 7a6bd73a5dcdee39b5bb93e92395e1773a194361 F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d -F test/with1.test f4aa699a3712207e02f13945cd2b67d01a9d9f57 +F test/with1.test 97166cc72de5327bbae782aece707c45ee40e41b F test/with2.test 2fe78fcd8deef2a0f9cfc49bfc755911d0b3fd64 F test/withM.test e97f2a8c506ab3ea9eab94e6f6072f6cc924c991 F test/without_rowid1.test aaa26da19d543cd8d3d2d0e686dfa255556c15c8 @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 3eb5f9f8d6ac1ee145cb4119087c516f66fe1456 -R a615c5dcec438a7db4f9b5a3e0983f82 +P 37b343b01841b338954ddfa9b76d92aa50037aec +R f6fa1b44c6431db29f11962241b14895 U drh -Z 4ad026d26a172a85d439a21b0ddb47e4 +Z a802989c6813792648a40d2b5db727ef diff --git a/manifest.uuid b/manifest.uuid index 87e23ab961..adee55d513 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -37b343b01841b338954ddfa9b76d92aa50037aec \ No newline at end of file +1945484e6b9769c1943f750f5b09860417fb190a \ No newline at end of file diff --git a/src/select.c b/src/select.c index 13e9562ba2..891bbf7604 100644 --- a/src/select.c +++ b/src/select.c @@ -462,13 +462,13 @@ static void pushOntoSorter( */ static void codeOffset( Vdbe *v, /* Generate code into this VM */ - Select *p, /* The SELECT statement being coded */ + int iOffset, /* Register holding the offset counter */ int iContinue /* Jump here to skip the current record */ ){ - if( p->iOffset && iContinue!=0 ){ + if( iOffset>0 && iContinue!=0 ){ int addr; - sqlite3VdbeAddOp2(v, OP_AddImm, p->iOffset, -1); - addr = sqlite3VdbeAddOp1(v, OP_IfNeg, p->iOffset); + sqlite3VdbeAddOp2(v, OP_AddImm, iOffset, -1); + addr = sqlite3VdbeAddOp1(v, OP_IfNeg, iOffset); sqlite3VdbeAddOp2(v, OP_Goto, 0, iContinue); VdbeComment((v, "skip OFFSET records")); sqlite3VdbeJumpHere(v, addr); @@ -571,7 +571,7 @@ static void selectInnerLoop( assert( pEList!=0 ); hasDistinct = pDistinct ? pDistinct->eTnctType : WHERE_DISTINCT_NOOP; if( pOrderBy==0 && !hasDistinct ){ - codeOffset(v, p, iContinue); + codeOffset(v, p->iOffset, iContinue); } /* Pull the requested columns. @@ -653,7 +653,7 @@ static void selectInnerLoop( } } if( pOrderBy==0 ){ - codeOffset(v, p, iContinue); + codeOffset(v, p->iOffset, iContinue); } } @@ -1069,13 +1069,13 @@ static void generateSortTail( int ptab2 = pParse->nTab++; sqlite3VdbeAddOp3(v, OP_OpenPseudo, ptab2, regSortOut, pOrderBy->nExpr+2); addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak); - codeOffset(v, p, addrContinue); + codeOffset(v, p->iOffset, addrContinue); sqlite3VdbeAddOp2(v, OP_SorterData, iTab, regSortOut); sqlite3VdbeAddOp3(v, OP_Column, ptab2, pOrderBy->nExpr+1, regRow); sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE); }else{ addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak); - codeOffset(v, p, addrContinue); + codeOffset(v, p->iOffset, addrContinue); sqlite3VdbeAddOp3(v, OP_Column, iTab, pOrderBy->nExpr+1, regRow); } switch( eDest ){ @@ -1639,8 +1639,13 @@ Vdbe *sqlite3GetVdbe(Parse *pParse){ ** ** This routine changes the values of iLimit and iOffset only if ** a limit or offset is defined by pLimit and pOffset. iLimit and -** iOffset should have been preset to appropriate default values -** (usually but not always -1) prior to calling this routine. +** iOffset should have been preset to appropriate default values (zero) +** prior to calling this routine. +** +** The iOffset register (if it exists) is initialized to the value +** of the OFFSET. The iLimit register is initialized to LIMIT. Register +** iOffset+1 is initialized to LIMIT+OFFSET. +** ** Only if pLimit!=0 or pOffset!=0 do the limit registers get ** redefined. The UNION ALL operator uses this property to force ** the reuse of the same limit and offset registers across multiple @@ -1664,7 +1669,7 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){ if( p->pLimit ){ p->iLimit = iLimit = ++pParse->nMem; v = sqlite3GetVdbe(pParse); - if( NEVER(v==0) ) return; /* VDBE should have already been allocated */ + assert( v!=0 ); if( sqlite3ExprIsInteger(p->pLimit, &n) ){ sqlite3VdbeAddOp2(v, OP_Integer, n, iLimit); VdbeComment((v, "LIMIT counter")); @@ -1778,21 +1783,21 @@ static void generateWithRecursiveQuery( int i; /* Loop counter */ int rc; /* Result code */ ExprList *pOrderBy; /* The ORDER BY clause */ + Expr *pLimit, *pOffset; /* Saved LIMIT and OFFSET */ + int regLimit, regOffset; /* Registers used by LIMIT and OFFSET */ /* Obtain authorization to do a recursive query */ if( sqlite3AuthCheck(pParse, SQLITE_RECURSIVE, 0, 0, 0) ) return; - addrBreak = sqlite3VdbeMakeLabel(v); - /* Check that there is no ORDER BY or LIMIT clause. Neither of these - ** are currently supported on recursive queries. - */ - assert( p->pOffset==0 || p->pLimit ); - if( /*p->pOrderBy ||*/ p->pLimit ){ - sqlite3ErrorMsg(pParse, "%s in a recursive query", - p->pOrderBy ? "ORDER BY" : "LIMIT" - ); - return; - } + /* Process the LIMIT and OFFSET clauses, if they exist */ + addrBreak = sqlite3VdbeMakeLabel(v); + computeLimitRegisters(pParse, p, addrBreak); + pLimit = p->pLimit; + pOffset = p->pOffset; + regLimit = p->iLimit; + regOffset = p->iOffset; + p->pLimit = p->pOffset = 0; + p->iLimit = p->iOffset = 0; /* Locate the cursor number of the Current table */ for(i=0; ALWAYS(inSrc); i++){ @@ -1853,8 +1858,10 @@ static void generateWithRecursiveQuery( /* Output the single row in Current */ addrCont = sqlite3VdbeMakeLabel(v); + codeOffset(v, regOffset, addrCont); selectInnerLoop(pParse, p, p->pEList, iCurrent, 0, 0, pDest, addrCont, addrBreak); + if( regLimit ) sqlite3VdbeAddOp3(v, OP_IfZero, regLimit, addrBreak, -1); sqlite3VdbeResolveLabel(v, addrCont); /* Execute the recursive SELECT taking the single row in Current as @@ -1871,6 +1878,8 @@ static void generateWithRecursiveQuery( end_of_recursive_query: p->pOrderBy = pOrderBy; + p->pLimit = pLimit; + p->pOffset = pOffset; return; } #endif @@ -2326,7 +2335,7 @@ static int generateOutputSubroutine( /* Suppress the first OFFSET entries if there is an OFFSET clause */ - codeOffset(v, p, iContinue); + codeOffset(v, p->iOffset, iContinue); switch( pDest->eDest ){ /* Store the result as data using a unique key. diff --git a/test/with1.test b/test/with1.test index 0895312b0c..fcd1929277 100644 --- a/test/with1.test +++ b/test/with1.test @@ -190,11 +190,22 @@ do_execsql_test 5.2.2 { ) SELECT * FROM ancest; } {0 0 1 10 2 20 3 30 4 40 4 40 5 50 6 60 7 70 7 70 8 80 8 80 8 80 8 80 9 90 9 90 9 90 9 90} +do_execsql_test 5.2.3 { + WITH RECURSIVE + ancest(id, mtime) AS + (VALUES(0, 0) + UNION ALL + SELECT edge.xto, edge.seq FROM edge, ancest + WHERE edge.xfrom=ancest.id + ORDER BY 2 LIMIT 4 OFFSET 2 + ) + SELECT * FROM ancest; +} {2 20 3 30 4 40 4 40} do_catchsql_test 5.3 { - WITH i(x) AS ( VALUES(1) UNION ALL SELECT x+1 FROM i LIMIT 10 ) - SELECT x FROM i LIMIT 10; -} {1 {LIMIT in a recursive query}} + WITH i(x) AS ( VALUES(1) UNION ALL SELECT x+1 FROM i LIMIT 5) + SELECT x FROM i; +} {0 {1 2 3 4 5}} do_execsql_test 5.4 { WITH i(x) AS ( VALUES(1) UNION ALL SELECT (x+1)%10 FROM i) From edf83d1e3d13058d0b3ea87e88817a73ef35ee84 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 22 Jan 2014 18:31:27 +0000 Subject: [PATCH 181/276] Fix harmless compiler warnings. FossilOrigin-Name: dea2ca6a159d5dcfd8deceedf1c2a73fb4ac1cfc --- manifest | 17 ++++++++--------- manifest.uuid | 2 +- src/expr.c | 8 +++----- src/parse.y | 2 +- src/select.c | 6 +++--- 5 files changed, 16 insertions(+), 19 deletions(-) diff --git a/manifest b/manifest index 1fd0e675c0..5418051033 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\sWITH\sRECURSIVE\simplementation\sto\suse\sa\squeue\sinstead\sof\sa\spair\sof\ntables.\s\sAdd\ssupport\sfor\sORDER\sBY,\sLIMIT,\sand\sOFFSET\son\srecursive\squeries. -D 2014-01-22T18:16:27.891 +C Fix\sharmless\scompiler\swarnings. +D 2014-01-22T18:31:27.905 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -175,7 +175,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 F src/delete.c 91e1321021db5dc266360531b8b6550009d771ff -F src/expr.c 8c7e482bc8f7982333f046851a610ccdb8a1ba94 +F src/expr.c 61f9105820d6702d7153dfb6ca3d58e751a5e95a F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 2ab0f5384b70594468ef3ac5c7ed8ca24bfd17d5 F src/func.c 6325ac2ec10833ccf4d5c36d323709221d37ea19 @@ -209,7 +209,7 @@ F src/os_unix.c 3a4dcb554d3c915075766162f28c3fd4cdb75968 F src/os_win.c 1b21af72c5fa6f9e519a5fcab33e80d182b1aedb F src/pager.c efa923693e958696eee69b205a20bfbc402c8480 F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428 -F src/parse.y 475896cb883bbf4782e98abda42efbbdcbdb75f5 +F src/parse.y bd51bc17cbfe7549adb4ca3747b1c3d384645065 F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222 F src/pcache1.c 57fee9a9a617218f5037afbbe49b09da65bde56b @@ -219,7 +219,7 @@ F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c f6d84f3a109d3e43d38089da6a4f131a5ce4c6ef +F src/select.c a4ac380e9c07135b4613f9021c93e9252a1586d8 F src/shell.c 24722d24d4ea8ca93db35e44db7308de786767ca F src/sqlite.h.in eed7f7d66a60daaa7b4a597dcd9bad87aad9611b F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e @@ -1152,8 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P a0ba55ff0596c5f15e9cdb254c68ef50df2dfaad 1945484e6b9769c1943f750f5b09860417fb190a -R 0105f6ff7a9dec4a544ebd63835ab3ca -T +closed 1945484e6b9769c1943f750f5b09860417fb190a +P b6cea42006910d590373e8f9e296d7672edb114b +R 1ba001345e8bb7e9c10a92447c5b79e1 U drh -Z c6c3dc0c740728b9edf5697c95361334 +Z 3fb7fa817c3bd22cb870eb237b846ff7 diff --git a/manifest.uuid b/manifest.uuid index 6b5e670c10..ef71cf8a80 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b6cea42006910d590373e8f9e296d7672edb114b \ No newline at end of file +dea2ca6a159d5dcfd8deceedf1c2a73fb4ac1cfc \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 5f11dec420..2e8079eb8f 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1584,11 +1584,9 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){ iCol = (i16)pExpr->iColumn; /* Code an OP_VerifyCookie and OP_TableLock for
    . */ - if( ALWAYS(pTab->pSchema) ){ - iDb = sqlite3SchemaToIndex(db, pTab->pSchema); - sqlite3CodeVerifySchema(pParse, iDb); - sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); - } + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + sqlite3CodeVerifySchema(pParse, iDb); + sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); /* This function is only called from two places. In both cases the vdbe ** has already been allocated. So assume sqlite3GetVdbe() is always diff --git a/src/parse.y b/src/parse.y index 0805407920..d0ec821d7a 100644 --- a/src/parse.y +++ b/src/parse.y @@ -397,7 +397,7 @@ cmd ::= DROP VIEW ifexists(E) fullname(X). { //////////////////////// The SELECT statement ///////////////////////////////// // cmd ::= select(X). { - SelectDest dest = {SRT_Output, 0, 0, 0, 0}; + SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0}; sqlite3Select(pParse, X, &dest); sqlite3ExplainBegin(pParse->pVdbe); sqlite3ExplainSelect(pParse->pVdbe, X); diff --git a/src/select.c b/src/select.c index 891bbf7604..0fb1cf8362 100644 --- a/src/select.c +++ b/src/select.c @@ -1774,7 +1774,7 @@ static void generateWithRecursiveQuery( Select *pSetup = p->pPrior; /* The setup query */ int addrTop; /* Top of the loop */ int addrCont, addrBreak; /* CONTINUE and BREAK addresses */ - int iCurrent; /* The Current table */ + int iCurrent = 0; /* The Current table */ int regCurrent; /* Register holding Current table */ int iQueue; /* The Queue table */ int iDistinct = 0; /* To ensure unique results if UNION */ @@ -1936,8 +1936,8 @@ static int multiSelect( Select *pDelete = 0; /* Chain of simple selects to delete */ sqlite3 *db; /* Database connection */ #ifndef SQLITE_OMIT_EXPLAIN - int iSub1; /* EQP id of left-hand query */ - int iSub2; /* EQP id of right-hand query */ + int iSub1 = 0; /* EQP id of left-hand query */ + int iSub2 = 0; /* EQP id of right-hand query */ #endif /* Make sure there is no ORDER BY or LIMIT clause on prior SELECTs. Only From cfe24586a8866fcbe1bb9d9f45b267fdb23a8207 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 22 Jan 2014 19:23:30 +0000 Subject: [PATCH 182/276] Avoid an extra seek when inserting records into the epheremal index used to ensure that rows returned by UNION recursive queries are unique. FossilOrigin-Name: 72c4b3f07a3faacb5b62d5bc374b4e125a0bd8b3 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/select.c | 1 + 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 5418051033..0452c399e9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings. -D 2014-01-22T18:31:27.905 +C Avoid\san\sextra\sseek\swhen\sinserting\srecords\sinto\sthe\sepheremal\sindex\sused\sto\sensure\sthat\srows\sreturned\sby\sUNION\srecursive\squeries\sare\sunique. +D 2014-01-22T19:23:30.685 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -219,7 +219,7 @@ F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c a4ac380e9c07135b4613f9021c93e9252a1586d8 +F src/select.c 93764e0d81946c070e2c7f1127f35e21efabbcc3 F src/shell.c 24722d24d4ea8ca93db35e44db7308de786767ca F src/sqlite.h.in eed7f7d66a60daaa7b4a597dcd9bad87aad9611b F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P b6cea42006910d590373e8f9e296d7672edb114b -R 1ba001345e8bb7e9c10a92447c5b79e1 -U drh -Z 3fb7fa817c3bd22cb870eb237b846ff7 +P dea2ca6a159d5dcfd8deceedf1c2a73fb4ac1cfc +R 94fca679783d65c2e2622ed1059ebe94 +U dan +Z f354f4f3e5d1356fcb7db559f2782a7e diff --git a/manifest.uuid b/manifest.uuid index ef71cf8a80..93493f97eb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dea2ca6a159d5dcfd8deceedf1c2a73fb4ac1cfc \ No newline at end of file +72c4b3f07a3faacb5b62d5bc374b4e125a0bd8b3 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 0fb1cf8362..98ed526e08 100644 --- a/src/select.c +++ b/src/select.c @@ -814,6 +814,7 @@ static void selectInnerLoop( ** been added */ addrTest = sqlite3VdbeAddOp4Int(v, OP_Found, iParm+1, 0, r3, 0); sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm+1, r3); + sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); } for(i=0; i Date: Thu, 23 Jan 2014 14:44:08 +0000 Subject: [PATCH 183/276] Modifications to test files to omit any tests that intentionally access out-of-bounds locations in clang -fsanitize=address builds. FossilOrigin-Name: f4a701d55f5c4e1e62ed64b779ad4fff89dd31b7 --- manifest | 24 ++++++++-------- manifest.uuid | 2 +- src/test1.c | 24 +++++++++++++++- test/capi3.test | 42 ++++++++++++++++------------ test/capi3c.test | 36 ++++++++++++++---------- test/e_fkey.test | 71 ++++++++++++++++++++++++++--------------------- test/misc7.test | 8 ++++-- test/misuse.test | 61 +++++++++++++++++++++------------------- test/select7.test | 30 ++++++++++---------- 9 files changed, 173 insertions(+), 125 deletions(-) diff --git a/manifest b/manifest index 0452c399e9..eff8df8471 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\san\sextra\sseek\swhen\sinserting\srecords\sinto\sthe\sepheremal\sindex\sused\sto\sensure\sthat\srows\sreturned\sby\sUNION\srecursive\squeries\sare\sunique. -D 2014-01-22T19:23:30.685 +C Modifications\sto\stest\sfiles\sto\somit\sany\stests\sthat\sintentionally\saccess\sout-of-bounds\slocations\sin\sclang\s-fsanitize=address\sbuilds. +D 2014-01-23T14:44:08.207 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -229,7 +229,7 @@ F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e F src/tclsqlite.c 46073db71011b6542fde1f234c56a076d5ff23f9 -F src/test1.c db16ba651453b15001c7f2838c446284dde4ecaf +F src/test1.c 2401eee14a4309a7cfe2aeb2f30ad517a1d9c299 F src/test2.c 7355101c085304b90024f2261e056cdff13c6c35 F src/test3.c 1c0e5d6f080b8e33c1ce8b3078e7013fdbcd560c F src/test4.c 9b32d22f5f150abe23c1830e2057c4037c45b3df @@ -364,9 +364,9 @@ F test/btreefault.test c2bcb542685eea44621275cfedbd8a13f65201e3 F test/busy.test 76b4887f8b9160ba903c1ac22e8ff406ad6ae2f0 F test/cache.test 13bc046b26210471ca6f2889aceb1ea52dc717de F test/capi2.test 011c16da245fdc0106a2785035de6b242c05e738 -F test/capi3.test 56ab450125ead38846cbae7e5b6a216686c3cffa +F test/capi3.test 6cdd49656bd62a296924f4d2fcfd05cd2a298369 F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4 -F test/capi3c.test 93d24621c9ff84da9da060f30431e0453db1cdb0 +F test/capi3c.test a21869e4d50d5dbb7e566e328fc0bc7c2efa6a32 F test/capi3d.test 6d0fc0a86d73f42dd19a7d8b7761ab9bc02277d0 F test/capi3e.test ad90088b18b0367125ff2d4b5400153fd2f99aab F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3 @@ -439,7 +439,7 @@ F test/e_delete.test d5186e2f5478b659f16a2c8b66c09892823e542a F test/e_droptrigger.test 3cd080807622c13e5bbb61fc9a57bd7754da2412 F test/e_dropview.test 0c9f7f60989164a70a67a9d9c26d1083bc808306 F test/e_expr.test 5c71d183fbf519a4769fd2e2124afdc70b5b1f42 -F test/e_fkey.test d83a04478bb9c02d2c513518548a69f818869f41 +F test/e_fkey.test 630597377549af579d34faaf64c6959a5a68ef76 F test/e_fts3.test 5c02288842e4f941896fd44afdef564dd5fc1459 F test/e_insert.test 1e44f84d2abe44d66e4fbf198be4b20e3cc724a0 F test/e_reindex.test 396b7b4f0a66863b4e95116a67d93b227193e589 @@ -700,8 +700,8 @@ F test/misc3.test cf3dda47d5dda3e53fc5804a100d3c82be736c9d F test/misc4.test 9c078510fbfff05a9869a0b6d8b86a623ad2c4f6 F test/misc5.test 528468b26d03303b1f047146e5eefc941b9069f5 F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91 -F test/misc7.test 1265eb98c2e22a446a13fdef754118b272716684 -F test/misuse.test ba4fb5d1a6101d1c171ea38b3c613d0661c83054 +F test/misc7.test edd0b63e2ee29a256900b0514f6fff27e19e9bb2 +F test/misuse.test 3c34719944ba045cc6c188a4852ba04680728912 F test/mmap1.test 93d167b328255cbe6679fe1e1a23be1b1197d07b F test/mmap2.test 9d6dd9ddb4ad2379f29cc78f38ce1e63ed418022 F test/mmap3.test c92273e16eb8d23c1d55c9815b446bb72ef0512e @@ -783,7 +783,7 @@ F test/select3.test 2ce595f8fb8e2ac10071d3b4e424cadd4634a054 F test/select4.test 00179be44e531fe04c1c3f15df216439dff2519d F test/select5.test e758b8ef94f69b111df4cb819008856655dcd535 F test/select6.test e76bd10a56988f15726c097a5d5a7966fe82d3b2 -F test/select7.test dad6f00f0d49728a879d6eb6451d4752db0b0abe +F test/select7.test 7fd2ef598cfabb6b9ff6ac13973b91d0527df49d F test/select8.test 391de11bdd52339c30580dabbbbe97e3e9a3c79d F test/select9.test aebc2bb0c3bc44606125033cbcaac2c8d1f33a95 F test/selectA.test 99cf21df033b93033ea4f34aba14a500f48f04fe @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P dea2ca6a159d5dcfd8deceedf1c2a73fb4ac1cfc -R 94fca679783d65c2e2622ed1059ebe94 +P 72c4b3f07a3faacb5b62d5bc374b4e125a0bd8b3 +R 1a965aa9944d1df45f2b3d9d29de01da U dan -Z f354f4f3e5d1356fcb7db559f2782a7e +Z 5e3d3ac89b5b8048d3858093fe9eb7e9 diff --git a/manifest.uuid b/manifest.uuid index 93493f97eb..d96db9705f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -72c4b3f07a3faacb5b62d5bc374b4e125a0bd8b3 \ No newline at end of file +f4a701d55f5c4e1e62ed64b779ad4fff89dd31b7 \ No newline at end of file diff --git a/src/test1.c b/src/test1.c index 109f90143f..3000288c7d 100644 --- a/src/test1.c +++ b/src/test1.c @@ -242,7 +242,28 @@ static int test_io_trace( return TCL_OK; } - +/* +** Usage: clang_sanitize_address +** +** Returns true if the program was compiled using clang with the +** -fsanitize=address switch on the command line. False otherwise. +*/ +static int clang_sanitize_address( + void *NotUsed, + Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ + int argc, /* Number of arguments */ + char **argv /* Text of each argument */ +){ + int res = 0; +#if defined(__has_feature) +# if __has_feature(address_sanitizer) + res = 1; +# endif +#endif + Tcl_SetObjResult(interp, Tcl_NewIntObj(res)); + return TCL_OK; +} + /* ** Usage: sqlite3_exec_printf DB FORMAT STRING ** @@ -6323,6 +6344,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ { "sqlite3_busy_timeout", (Tcl_CmdProc*)test_busy_timeout }, { "printf", (Tcl_CmdProc*)test_printf }, { "sqlite3IoTrace", (Tcl_CmdProc*)test_io_trace }, + { "clang_sanitize_address", (Tcl_CmdProc*)clang_sanitize_address }, }; static struct { char *zName; diff --git a/test/capi3.test b/test/capi3.test index 9d7434d25d..f0234e8897 100644 --- a/test/capi3.test +++ b/test/capi3.test @@ -179,16 +179,18 @@ do_test capi3-3.4 { do_test capi3-3.5 { sqlite3_close $db2 } {SQLITE_OK} -do_test capi3-3.6.1-misuse { - sqlite3_close $db2 -} {SQLITE_MISUSE} -do_test capi3-3.6.2-misuse { - sqlite3_errmsg $db2 -} {library routine called out of sequence} -ifcapable {utf16} { - do_test capi3-3.6.3-misuse { - utf8 [sqlite3_errmsg16 $db2] +if {[clang_sanitize_address]==0} { + do_test capi3-3.6.1-misuse { + sqlite3_close $db2 + } {SQLITE_MISUSE} + do_test capi3-3.6.2-misuse { + sqlite3_errmsg $db2 } {library routine called out of sequence} + ifcapable {utf16} { + do_test capi3-3.6.3-misuse { + utf8 [sqlite3_errmsg16 $db2] + } {library routine called out of sequence} + } } do_test capi3-3.7 { @@ -661,10 +663,12 @@ do_test capi3-6.3 { sqlite3_finalize $STMT } {SQLITE_OK} -do_test capi3-6.4-misuse { - db cache flush - sqlite3_close $DB -} {SQLITE_OK} +if {[clang_sanitize_address]==0} { + do_test capi3-6.4-misuse { + db cache flush + sqlite3_close $DB + } {SQLITE_OK} +} db close # This procedure sets the value of the file-format in file 'test.db' @@ -1060,11 +1064,13 @@ if {[llength [info commands sqlite3_sleep]]>0} { } # Ticket #1219: Make sure binding APIs can handle a NULL pointer. -# -do_test capi3-14.1-misuse { - set rc [catch {sqlite3_bind_text 0 1 hello 5} msg] - lappend rc $msg -} {1 SQLITE_MISUSE} +# +if {[clang_sanitize_address]==0} { + do_test capi3-14.1-misuse { + set rc [catch {sqlite3_bind_text 0 1 hello 5} msg] + lappend rc $msg + } {1 SQLITE_MISUSE} +} # Ticket #1650: Honor the nBytes parameter to sqlite3_prepare. # diff --git a/test/capi3c.test b/test/capi3c.test index 14545c0a68..6388717e00 100644 --- a/test/capi3c.test +++ b/test/capi3c.test @@ -169,16 +169,18 @@ do_test capi3c-3.4 { do_test capi3c-3.5 { sqlite3_close $db2 } {SQLITE_OK} -do_test capi3c-3.6.1-misuse { - sqlite3_close $db2 -} {SQLITE_MISUSE} -do_test capi3c-3.6.2-misuse { - sqlite3_errmsg $db2 -} {library routine called out of sequence} -ifcapable {utf16} { - do_test capi3c-3.6.3-misuse { - utf8 [sqlite3_errmsg16 $db2] +if {[clang_sanitize_address]==0} { + do_test capi3c-3.6.1-misuse { + sqlite3_close $db2 + } {SQLITE_MISUSE} + do_test capi3c-3.6.2-misuse { + sqlite3_errmsg $db2 } {library routine called out of sequence} + ifcapable {utf16} { + do_test capi3c-3.6.3-misuse { + utf8 [sqlite3_errmsg16 $db2] + } {library routine called out of sequence} + } } # rename sqlite3_open "" @@ -627,13 +629,17 @@ check_data $STMT capi3c-6.3 {INTEGER} {1} {1.0} {1} do_test capi3c-6.3 { sqlite3_finalize $STMT } {SQLITE_OK} -do_test capi3c-6.4 { - db cache flush - sqlite3_close $DB -} {SQLITE_OK} -do_test capi3c-6.99-misuse { +if {[clang_sanitize_address]==0} { + do_test capi3c-6.4 { + db cache flush + sqlite3_close $DB + } {SQLITE_OK} + do_test capi3c-6.99-misuse { + db close + } {} +} else { db close -} {} +} # This procedure sets the value of the file-format in file 'test.db' # to $newval. Also, the schema cookie is incremented. diff --git a/test/e_fkey.test b/test/e_fkey.test index 022611695d..921e967176 100644 --- a/test/e_fkey.test +++ b/test/e_fkey.test @@ -2946,38 +2946,45 @@ proc test_on_update_recursion {limit} { " } -do_test e_fkey-63.1.1 { - test_on_delete_recursion $SQLITE_MAX_TRIGGER_DEPTH -} {0 0} -do_test e_fkey-63.1.2 { - test_on_delete_recursion [expr $SQLITE_MAX_TRIGGER_DEPTH+1] -} {1 {too many levels of trigger recursion}} -do_test e_fkey-63.1.3 { - sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH 5 - test_on_delete_recursion 5 -} {0 0} -do_test e_fkey-63.1.4 { - test_on_delete_recursion 6 -} {1 {too many levels of trigger recursion}} -do_test e_fkey-63.1.5 { - sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH 1000000 -} {5} -do_test e_fkey-63.2.1 { - test_on_update_recursion $SQLITE_MAX_TRIGGER_DEPTH -} {0 0} -do_test e_fkey-63.2.2 { - test_on_update_recursion [expr $SQLITE_MAX_TRIGGER_DEPTH+1] -} {1 {too many levels of trigger recursion}} -do_test e_fkey-63.2.3 { - sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH 5 - test_on_update_recursion 5 -} {0 0} -do_test e_fkey-63.2.4 { - test_on_update_recursion 6 -} {1 {too many levels of trigger recursion}} -do_test e_fkey-63.2.5 { - sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH 1000000 -} {5} +# If the current build was created using clang with the -fsanitize=address +# switch, then the library uses considerably more stack space than usual. +# So much more, that some of the following tests cause stack overflows +# if they are run under this configuration. +# +if {[clang_sanitize_address]==0} { + do_test e_fkey-63.1.1 { + test_on_delete_recursion $SQLITE_MAX_TRIGGER_DEPTH + } {0 0} + do_test e_fkey-63.1.2 { + test_on_delete_recursion [expr $SQLITE_MAX_TRIGGER_DEPTH+1] + } {1 {too many levels of trigger recursion}} + do_test e_fkey-63.1.3 { + sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH 5 + test_on_delete_recursion 5 + } {0 0} + do_test e_fkey-63.1.4 { + test_on_delete_recursion 6 + } {1 {too many levels of trigger recursion}} + do_test e_fkey-63.1.5 { + sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH 1000000 + } {5} + do_test e_fkey-63.2.1 { + test_on_update_recursion $SQLITE_MAX_TRIGGER_DEPTH + } {0 0} + do_test e_fkey-63.2.2 { + test_on_update_recursion [expr $SQLITE_MAX_TRIGGER_DEPTH+1] + } {1 {too many levels of trigger recursion}} + do_test e_fkey-63.2.3 { + sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH 5 + test_on_update_recursion 5 + } {0 0} + do_test e_fkey-63.2.4 { + test_on_update_recursion 6 + } {1 {too many levels of trigger recursion}} + do_test e_fkey-63.2.5 { + sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH 1000000 + } {5} +} #------------------------------------------------------------------------- # The setting of the recursive_triggers pragma does not affect foreign diff --git a/test/misc7.test b/test/misc7.test index ec042ff0ee..8fd5fe7546 100644 --- a/test/misc7.test +++ b/test/misc7.test @@ -15,9 +15,11 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl -do_test misc7-1-misuse { - c_misuse_test -} {} +if {[clang_sanitize_address]==0} { + do_test misc7-1-misuse { + c_misuse_test + } {} +} do_test misc7-2 { c_realloc_test diff --git a/test/misuse.test b/test/misuse.test index 71ee0118c8..d5d836cbfb 100644 --- a/test/misuse.test +++ b/test/misuse.test @@ -171,37 +171,40 @@ do_test misuse-4.3 { } msg] lappend v $msg $r } {0 {} SQLITE_BUSY} -do_test misuse-4.4 { + +if {[clang_sanitize_address]==0} { + do_test misuse-4.4 { # Flush the TCL statement cache here, otherwise the sqlite3_close() will # fail because there are still un-finalized() VDBEs. - db cache flush - sqlite3_close $::DB - catchsql2 {SELECT * FROM t1} -} {1 {library routine called out of sequence}} -do_test misuse-4.5 { - catchsql { - SELECT * FROM t1 - } -} {1 {library routine called out of sequence}} + db cache flush + sqlite3_close $::DB + catchsql2 {SELECT * FROM t1} + } {1 {library routine called out of sequence}} + do_test misuse-4.5 { + catchsql { + SELECT * FROM t1 + } + } {1 {library routine called out of sequence}} -# Attempt to use a database after it has been closed. -# -do_test misuse-5.1 { - db close - sqlite3 db test2.db; set ::DB [sqlite3_connection_pointer db] - execsql { - SELECT * FROM t1 - } -} {1 2} -do_test misuse-5.2 { - catchsql2 {SELECT * FROM t1} -} {0 {a b 1 2}} -do_test misuse-5.3 { - db close - set r [catch { - sqlite3_prepare $::DB {SELECT * FROM t1} -1 TAIL - } msg] - lappend r $msg -} {1 {(21) library routine called out of sequence}} + # Attempt to use a database after it has been closed. + # + do_test misuse-5.1 { + db close + sqlite3 db test2.db; set ::DB [sqlite3_connection_pointer db] + execsql { + SELECT * FROM t1 + } + } {1 2} + do_test misuse-5.2 { + catchsql2 {SELECT * FROM t1} + } {0 {a b 1 2}} + do_test misuse-5.3 { + db close + set r [catch { + sqlite3_prepare $::DB {SELECT * FROM t1} -1 TAIL + } msg] + lappend r $msg + } {1 {(21) library routine called out of sequence}} +} finish_test diff --git a/test/select7.test b/test/select7.test index e8fc440006..6816b9fcb9 100644 --- a/test/select7.test +++ b/test/select7.test @@ -138,21 +138,23 @@ ifcapable {subquery && compound} { # Verify that an error occurs if you have too many terms on a # compound select statement. # -ifcapable compound { - if {$SQLITE_MAX_COMPOUND_SELECT>0} { - set sql {SELECT 0} - set result 0 - for {set i 1} {$i<$SQLITE_MAX_COMPOUND_SELECT} {incr i} { - append sql " UNION ALL SELECT $i" - lappend result $i +if {[clang_sanitize_address]==0} { + ifcapable compound { + if {$SQLITE_MAX_COMPOUND_SELECT>0} { + set sql {SELECT 0} + set result 0 + for {set i 1} {$i<$SQLITE_MAX_COMPOUND_SELECT} {incr i} { + append sql " UNION ALL SELECT $i" + lappend result $i + } + do_test select7-6.1 { + catchsql $sql + } [list 0 $result] + append sql { UNION ALL SELECT 99999999} + do_test select7-6.2 { + catchsql $sql + } {1 {too many terms in compound SELECT}} } - do_test select7-6.1 { - catchsql $sql - } [list 0 $result] - append sql { UNION ALL SELECT 99999999} - do_test select7-6.2 { - catchsql $sql - } {1 {too many terms in compound SELECT}} } } From b090352b5a46884806d1c1d99dbcd336b103fe67 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 24 Jan 2014 11:16:01 +0000 Subject: [PATCH 184/276] Add test cases showing the use of ORDER BY on a recursive query to control depth-first versus breath-first search of a tree. FossilOrigin-Name: 83b0b2916589db0184435dbd4c304387f393ed60 --- manifest | 14 +++--- manifest.uuid | 2 +- test/with1.test | 123 +++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 129 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index eff8df8471..fb401ca29f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Modifications\sto\stest\sfiles\sto\somit\sany\stests\sthat\sintentionally\saccess\sout-of-bounds\slocations\sin\sclang\s-fsanitize=address\sbuilds. -D 2014-01-23T14:44:08.207 +C Add\stest\scases\sshowing\sthe\suse\sof\sORDER\sBY\son\sa\srecursive\squery\sto\scontrol\ndepth-first\sversus\sbreath-first\ssearch\sof\sa\stree. +D 2014-01-24T11:16:01.884 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -1092,7 +1092,7 @@ F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c F test/win32lock.test 7a6bd73a5dcdee39b5bb93e92395e1773a194361 F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d -F test/with1.test 97166cc72de5327bbae782aece707c45ee40e41b +F test/with1.test 9d3537372c8cf6d5e0a5e9af037a52f3375fb704 F test/with2.test 2fe78fcd8deef2a0f9cfc49bfc755911d0b3fd64 F test/withM.test e97f2a8c506ab3ea9eab94e6f6072f6cc924c991 F test/without_rowid1.test aaa26da19d543cd8d3d2d0e686dfa255556c15c8 @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 72c4b3f07a3faacb5b62d5bc374b4e125a0bd8b3 -R 1a965aa9944d1df45f2b3d9d29de01da -U dan -Z 5e3d3ac89b5b8048d3858093fe9eb7e9 +P f4a701d55f5c4e1e62ed64b779ad4fff89dd31b7 +R 15c1d48ec007e0818a79a87f9c81fe3d +U drh +Z a61c87789af8810b68d544f76885410e diff --git a/manifest.uuid b/manifest.uuid index d96db9705f..1c78fab271 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f4a701d55f5c4e1e62ed64b779ad4fff89dd31b7 \ No newline at end of file +83b0b2916589db0184435dbd4c304387f393ed60 \ No newline at end of file diff --git a/test/with1.test b/test/with1.test index fcd1929277..6dd67d1690 100644 --- a/test/with1.test +++ b/test/with1.test @@ -374,7 +374,7 @@ do_catchsql_test 7.6 { # Compute the mandelbrot set using a recursive query # -do_execsql_test 8.1 { +do_execsql_test 8.1-mandelbrot { WITH RECURSIVE xaxis(x) AS (VALUES(-2.0) UNION ALL SELECT x+0.05 FROM xaxis WHERE x<1.2), yaxis(y) AS (VALUES(-1.0) UNION ALL SELECT y+0.1 FROM yaxis WHERE y<1.0), @@ -417,7 +417,7 @@ do_execsql_test 8.1 { # Solve a sudoku puzzle using a recursive query # -do_execsql_test 8.2 { +do_execsql_test 8.2-soduko { WITH RECURSIVE input(sud) AS ( VALUES('53..7....6..195....98....6.8...6...34..8.3..17...2...6.6....28....419..5....8..79') @@ -452,4 +452,123 @@ do_execsql_test 8.2 { SELECT s FROM x WHERE ind=0; } {534678912672195348198342567859761423426853791713924856961537284287419635345286179} + +# Test cases to illustrate on the ORDER BY clause on a recursive query can be +# used to control depth-first versus breath-first search in a tree. +# +do_execsql_test 9.1 { + CREATE TABLE org( + name TEXT PRIMARY KEY, + boss TEXT REFERENCES org + ) WITHOUT ROWID; + INSERT INTO org VALUES('Alice',NULL); + INSERT INTO org VALUES('Bob','Alice'); + INSERT INTO org VALUES('Cindy','Alice'); + INSERT INTO org VALUES('Dave','Bob'); + INSERT INTO org VALUES('Emma','Bob'); + INSERT INTO org VALUES('Fred','Cindy'); + INSERT INTO org VALUES('Gail','Cindy'); + INSERT INTO org VALUES('Harry','Dave'); + INSERT INTO org VALUES('Ingrid','Dave'); + INSERT INTO org VALUES('Jim','Emma'); + INSERT INTO org VALUES('Kate','Emma'); + INSERT INTO org VALUES('Lanny','Fred'); + INSERT INTO org VALUES('Mary','Fred'); + INSERT INTO org VALUES('Noland','Gail'); + INSERT INTO org VALUES('Olivia','Gail'); + -- The above are all under Alice. Add a few more records for people + -- not in Alice's group, just to prove that they won't be selected. + INSERT INTO org VALUES('Xaviar',NULL); + INSERT INTO org VALUES('Xia','Xaviar'); + INSERT INTO org VALUES('Xerxes','Xaviar'); + INSERT INTO org VALUES('Xena','Xia'); + -- Find all members of Alice's group, breath-first order + WITH RECURSIVE + under_alice(name,level) AS ( + VALUES('Alice','0') + UNION ALL + SELECT org.name, under_alice.level+1 + FROM org, under_alice + WHERE org.boss=under_alice.name + ORDER BY 2 + ) + SELECT group_concat(substr('...............',1,level*3) || name,x'0a') + FROM under_alice; +} {{Alice +...Bob +...Cindy +......Dave +......Emma +......Fred +......Gail +.........Harry +.........Ingrid +.........Jim +.........Kate +.........Lanny +.........Mary +.........Noland +.........Olivia}} + +# The previous query used "ORDER BY level" to yield a breath-first search. +# Change that to "ORDER BY level DESC" for a depth-first search. +# +do_execsql_test 9.2 { + WITH RECURSIVE + under_alice(name,level) AS ( + VALUES('Alice','0') + UNION ALL + SELECT org.name, under_alice.level+1 + FROM org, under_alice + WHERE org.boss=under_alice.name + ORDER BY 2 DESC + ) + SELECT group_concat(substr('...............',1,level*3) || name,x'0a') + FROM under_alice; +} {{Alice +...Bob +......Dave +.........Harry +.........Ingrid +......Emma +.........Jim +.........Kate +...Cindy +......Fred +.........Lanny +.........Mary +......Gail +.........Noland +.........Olivia}} + +# Without an ORDER BY clause, the recursive query should use a FIFO, +# resulting in a breath-first search. +# +do_execsql_test 9.3 { + WITH RECURSIVE + under_alice(name,level) AS ( + VALUES('Alice','0') + UNION ALL + SELECT org.name, under_alice.level+1 + FROM org, under_alice + WHERE org.boss=under_alice.name + ) + SELECT group_concat(substr('...............',1,level*3) || name,x'0a') + FROM under_alice; +} {{Alice +...Bob +...Cindy +......Dave +......Emma +......Fred +......Gail +.........Harry +.........Ingrid +.........Jim +.........Kate +.........Lanny +.........Mary +.........Noland +.........Olivia}} + finish_test From 3c2aeae16e04c903ec6393cb940f23f80c769442 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 24 Jan 2014 14:37:44 +0000 Subject: [PATCH 185/276] Add test cases that compare the performance of the transitive_closure virtual table again common table expressions for walking a tree. FossilOrigin-Name: 9a23f020e8ed0e7a1ad227b4ab379fdf5e2de222 --- manifest | 14 ++++++------- manifest.uuid | 2 +- test/closure01.test | 48 +++++++++++++++++++++++++-------------------- test/tester.tcl | 14 +++++++++++++ 4 files changed, 49 insertions(+), 29 deletions(-) diff --git a/manifest b/manifest index fb401ca29f..2336aab937 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stest\scases\sshowing\sthe\suse\sof\sORDER\sBY\son\sa\srecursive\squery\sto\scontrol\ndepth-first\sversus\sbreath-first\ssearch\sof\sa\stree. -D 2014-01-24T11:16:01.884 +C Add\stest\scases\sthat\scompare\sthe\sperformance\sof\sthe\stransitive_closure\nvirtual\stable\sagain\scommon\stable\sexpressions\sfor\swalking\sa\stree. +D 2014-01-24T14:37:44.938 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -372,7 +372,7 @@ F test/capi3e.test ad90088b18b0367125ff2d4b5400153fd2f99aab F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3 F test/check.test 5831ddb6f2c687782eaf2e1a07b6e17f24c4f763 F test/close.test 340bd24cc58b16c6bc01967402755027c37eb815 -F test/closure01.test dbb28f1ea9eeaf0a53ec5bc0fed352e479def8c7 +F test/closure01.test 52036bd5f5d1734f41ba708e9038198aa274156a F test/coalesce.test cee0dccb9fbd2d494b77234bccf9dc6c6786eb91 F test/collate1.test 73b91005f264b7c403e2d63a6708d150679ac99a F test/collate2.test 9aaa410a00734e48bcb27f3872617d6f69b2a621 @@ -844,7 +844,7 @@ F test/tclsqlite.test 37a61c2da7e3bfe3b8c1a2867199f6b860df5d43 F test/tempdb.test 19d0f66e2e3eeffd68661a11c83ba5e6ace9128c F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30 F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1 -F test/tester.tcl 08e9f317afe60d398fa900993503ecaef3295bad +F test/tester.tcl 9bd04481b8b0ef1f2049ad01f28e175ee9a14f7b F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5 F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58 F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7 @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P f4a701d55f5c4e1e62ed64b779ad4fff89dd31b7 -R 15c1d48ec007e0818a79a87f9c81fe3d +P 83b0b2916589db0184435dbd4c304387f393ed60 +R f85f8ae6263bf3d6f45ffff44c95c74a U drh -Z a61c87789af8810b68d544f76885410e +Z be990f0e27dcbfb4abd20beb041780d7 diff --git a/manifest.uuid b/manifest.uuid index 1c78fab271..cc3b6b6830 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -83b0b2916589db0184435dbd4c304387f393ed60 \ No newline at end of file +9a23f020e8ed0e7a1ad227b4ab379fdf5e2de222 \ No newline at end of file diff --git a/test/closure01.test b/test/closure01.test index 5dac87a0ce..346ea76e8c 100644 --- a/test/closure01.test +++ b/test/closure01.test @@ -15,41 +15,36 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix closure01 -ifcapable !vtab { finish_test ; return } +ifcapable !vtab||!cte { finish_test ; return } load_static_extension db closure do_execsql_test 1.0 { BEGIN; CREATE TABLE t1(x INTEGER PRIMARY KEY, y INTEGER); + WITH RECURSIVE + cnt(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM cnt LIMIT 131072) + INSERT INTO t1(x, y) SELECT i, nullif(i,1)/2 FROM cnt; CREATE INDEX t1y ON t1(y); - INSERT INTO t1(x) VALUES(1),(2); - INSERT INTO t1(x) SELECT x+2 FROM t1; - INSERT INTO t1(x) SELECT x+4 FROM t1; - INSERT INTO t1(x) SELECT x+8 FROM t1; - INSERT INTO t1(x) SELECT x+16 FROM t1; - INSERT INTO t1(x) SELECT x+32 FROM t1; - INSERT INTO t1(x) SELECT x+64 FROM t1; - INSERT INTO t1(x) SELECT x+128 FROM t1; - INSERT INTO t1(x) SELECT x+256 FROM t1; - INSERT INTO t1(x) SELECT x+512 FROM t1; - INSERT INTO t1(x) SELECT x+1024 FROM t1; - INSERT INTO t1(x) SELECT x+2048 FROM t1; - INSERT INTO t1(x) SELECT x+4096 FROM t1; - INSERT INTO t1(x) SELECT x+8192 FROM t1; - INSERT INTO t1(x) SELECT x+16384 FROM t1; - INSERT INTO t1(x) SELECT x+32768 FROM t1; - INSERT INTO t1(x) SELECT x+65536 FROM t1; - UPDATE t1 SET y=x/2 WHERE x>1; COMMIT; CREATE VIRTUAL TABLE cx USING transitive_closure(tablename=t1, idcolumn=x, parentcolumn=y); } {} # The entire table -do_execsql_test 1.1 { +do_timed_execsql_test 1.1 { SELECT count(*), depth FROM cx WHERE root=1 GROUP BY depth ORDER BY 1; } {/1 0 1 17 2 1 4 2 8 3 16 4 .* 65536 16/} +do_timed_execsql_test 1.1-cte { + WITH RECURSIVE + below(id,depth) AS ( + VALUES(1,0) + UNION ALL + SELECT t1.x, below.depth+1 + FROM t1 JOIN below on t1.y=below.id + ) + SELECT count(*), depth FROM below GROUP BY depth ORDER BY 1; +} {/1 0 1 17 2 1 4 2 8 3 16 4 .* 65536 16/} # descendents of 32768 do_execsql_test 1.2 { @@ -57,9 +52,20 @@ do_execsql_test 1.2 { } {32768 0 65536 1 65537 1 131072 2} # descendents of 16384 -do_execsql_test 1.3 { +do_timed_execsql_test 1.3 { SELECT * FROM cx WHERE root=16384 AND depth<=2 ORDER BY id; } {16384 0 32768 1 32769 1 65536 2 65537 2 65538 2 65539 2} +do_timed_execsql_test 1.3-cte { + WITH RECURSIVE + below(id,depth) AS ( + VALUES(16384,0) + UNION ALL + SELECT t1.x, below.depth+1 + FROM t1 JOIN below on t1.y=below.id + WHERE below.depth<2 + ) + SELECT id, depth FROM below ORDER BY id; +} {16384 0 32768 1 32769 1 65536 2 65537 2 65538 2 65539 2} # children of 16384 do_execsql_test 1.4 { diff --git a/test/tester.tcl b/test/tester.tcl index 109fb310a9..fefd5e8a8f 100644 --- a/test/tester.tcl +++ b/test/tester.tcl @@ -59,6 +59,7 @@ # do_test TESTNAME SCRIPT EXPECTED # do_execsql_test TESTNAME SQL EXPECTED # do_catchsql_test TESTNAME SQL EXPECTED +# do_timed_execsql_test TESTNAME SQL EXPECTED # # Commands providing a lower level interface to the global test counters: # @@ -717,6 +718,11 @@ proc do_catchsql_test {testname sql result} { fix_testname testname uplevel do_test [list $testname] [list "catchsql {$sql}"] [list $result] } +proc do_timed_execsql_test {testname sql {result {}}} { + fix_testname testname + uplevel do_test [list $testname] [list "execsql_timed {$sql}"]\ + [list [list {*}$result]] +} proc do_eqp_test {name sql res} { uplevel do_execsql_test $name [list "EXPLAIN QUERY PLAN $sql"] [list $res] } @@ -1013,6 +1019,14 @@ proc execsql {sql {db db}} { # puts "SQL = $sql" uplevel [list $db eval $sql] } +proc execsql_timed {sql {db db}} { + set tm [time { + set x [uplevel [list $db eval $sql]] + } 1] + set tm [lindex $tm 0] + puts -nonewline " ([expr {$tm*0.001}]ms) " + set x +} # Execute SQL and catch exceptions. # From 9e2c7ae1b0ce1b88a0bba91f7bdde4ce3e6bc1c4 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 24 Jan 2014 15:42:51 +0000 Subject: [PATCH 186/276] Add a few more CTE test cases to closure.test. FossilOrigin-Name: 1b6405d9788c1bb89761b2bcdce560a5020ff503 --- manifest | 12 +++++------ manifest.uuid | 2 +- test/closure01.test | 52 +++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 55 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 2336aab937..275452cb28 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stest\scases\sthat\scompare\sthe\sperformance\sof\sthe\stransitive_closure\nvirtual\stable\sagain\scommon\stable\sexpressions\sfor\swalking\sa\stree. -D 2014-01-24T14:37:44.938 +C Add\sa\sfew\smore\sCTE\stest\scases\sto\sclosure.test. +D 2014-01-24T15:42:51.397 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -372,7 +372,7 @@ F test/capi3e.test ad90088b18b0367125ff2d4b5400153fd2f99aab F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3 F test/check.test 5831ddb6f2c687782eaf2e1a07b6e17f24c4f763 F test/close.test 340bd24cc58b16c6bc01967402755027c37eb815 -F test/closure01.test 52036bd5f5d1734f41ba708e9038198aa274156a +F test/closure01.test b1703ba40639cfc9b295cf478d70739415eec6a4 F test/coalesce.test cee0dccb9fbd2d494b77234bccf9dc6c6786eb91 F test/collate1.test 73b91005f264b7c403e2d63a6708d150679ac99a F test/collate2.test 9aaa410a00734e48bcb27f3872617d6f69b2a621 @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 83b0b2916589db0184435dbd4c304387f393ed60 -R f85f8ae6263bf3d6f45ffff44c95c74a +P 9a23f020e8ed0e7a1ad227b4ab379fdf5e2de222 +R f2060716c43f1dee6a2c1f879c1129f5 U drh -Z be990f0e27dcbfb4abd20beb041780d7 +Z 7914ad8fe58314f1f17f9965f9b13c5e diff --git a/manifest.uuid b/manifest.uuid index cc3b6b6830..6ca0ece42c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9a23f020e8ed0e7a1ad227b4ab379fdf5e2de222 \ No newline at end of file +1b6405d9788c1bb89761b2bcdce560a5020ff503 \ No newline at end of file diff --git a/test/closure01.test b/test/closure01.test index 346ea76e8c..213ef4e966 100644 --- a/test/closure01.test +++ b/test/closure01.test @@ -47,9 +47,20 @@ do_timed_execsql_test 1.1-cte { } {/1 0 1 17 2 1 4 2 8 3 16 4 .* 65536 16/} # descendents of 32768 -do_execsql_test 1.2 { +do_timed_execsql_test 1.2 { SELECT * FROM cx WHERE root=32768 ORDER BY id; } {32768 0 65536 1 65537 1 131072 2} +do_timed_execsql_test 1.2-cte { + WITH RECURSIVE + below(id,depth) AS ( + VALUES(32768,0) + UNION ALL + SELECT t1.x, below.depth+1 + FROM t1 JOIN below on t1.y=below.id + WHERE below.depth<2 + ) + SELECT id, depth FROM below ORDER BY id; +} {32768 0 65536 1 65537 1 131072 2} # descendents of 16384 do_timed_execsql_test 1.3 { @@ -76,19 +87,41 @@ do_execsql_test 1.4 { } {32768 1 {} t1 x y 32769 1 {} t1 x y} # great-grandparent of 16384 -do_execsql_test 1.5 { +do_timed_execsql_test 1.5 { SELECT id, depth, root, tablename, idcolumn, parentcolumn FROM cx WHERE root=16384 AND depth=3 AND idcolumn='Y' AND parentcolumn='X'; } {2048 3 {} t1 Y X} +do_timed_execsql_test 1.5-cte { + WITH RECURSIVE + above(id,depth) AS ( + VALUES(16384,0) + UNION ALL + SELECT t1.y, above.depth+1 + FROM t1 JOIN above ON t1.x=above.id + WHERE above.depth<3 + ) + SELECT id FROM above WHERE depth=3; +} {2048} # depth<5 -do_execsql_test 1.6 { +do_timed_execsql_test 1.6 { SELECT count(*), depth FROM cx WHERE root=1 AND depth<5 GROUP BY depth ORDER BY 1; } {1 0 2 1 4 2 8 3 16 4} +do_timed_execsql_test 1.6-cte { + WITH RECURSIVE + below(id,depth) AS ( + VALUES(1,0) + UNION ALL + SELECT t1.x, below.depth+1 + FROM t1 JOIN below ON t1.y=below.id + WHERE below.depth<4 + ) + SELECT count(*), depth FROM below GROUP BY depth ORDER BY 1; +} {1 0 2 1 4 2 8 3 16 4} # depth<=5 do_execsql_test 1.7 { @@ -109,9 +142,20 @@ do_execsql_test 1.9 { } {8 3 16 4 32 5} # depth==5 with min() and max() -do_execsql_test 1.10 { +do_timed_execsql_test 1.10 { SELECT count(*), min(id), max(id) FROM cx WHERE root=1 AND depth=5; } {32 32 63} +do_timed_execsql_test 1.10-cte { + WITH RECURSIVE + below(id,depth) AS ( + VALUES(1,0) + UNION ALL + SELECT t1.x, below.depth+1 + FROM t1 JOIN below ON t1.y=below.id + WHERE below.depth<5 + ) + SELECT count(*), min(id), max(id) FROM below WHERE depth=5; +} {32 32 63} # Create a much smaller table t2 with only 32 elements db eval { From dc3bb0deb2f4d3328d796ee60597bb6adf769546 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 24 Jan 2014 16:36:18 +0000 Subject: [PATCH 187/276] Use an unsigned integer to accumulate the string hash. Avoids compiler warnings. FossilOrigin-Name: b1824344ea4918a13abbda4a3b7134d35fd867c4 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/hash.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 275452cb28..e446313c60 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\sfew\smore\sCTE\stest\scases\sto\sclosure.test. -D 2014-01-24T15:42:51.397 +C Use\san\sunsigned\sinteger\sto\saccumulate\sthe\sstring\shash.\s\sAvoids\scompiler\nwarnings. +D 2014-01-24T16:36:18.370 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -180,7 +180,7 @@ F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 2ab0f5384b70594468ef3ac5c7ed8ca24bfd17d5 F src/func.c 6325ac2ec10833ccf4d5c36d323709221d37ea19 F src/global.c 1d7bb7ea8254ae6a68ed9bfaf65fcb3d1690b486 -F src/hash.c ac3470bbf1ca4ae4e306a8ecb0fdf1731810ffe4 +F src/hash.c d139319967164f139c8d1bb8a11b14db9c4ba3cd F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 F src/insert.c a4450f0c46a9f221622e6551ab0953b03c4f8ee8 @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 9a23f020e8ed0e7a1ad227b4ab379fdf5e2de222 -R f2060716c43f1dee6a2c1f879c1129f5 +P 1b6405d9788c1bb89761b2bcdce560a5020ff503 +R f7e02965abaaba2b2c591f1141f3d7cf U drh -Z 7914ad8fe58314f1f17f9965f9b13c5e +Z 197e448152d1aa82b77763ec048456c7 diff --git a/manifest.uuid b/manifest.uuid index 6ca0ece42c..710b1dce96 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1b6405d9788c1bb89761b2bcdce560a5020ff503 \ No newline at end of file +b1824344ea4918a13abbda4a3b7134d35fd867c4 \ No newline at end of file diff --git a/src/hash.c b/src/hash.c index e81dcf95e4..f9901fee8f 100644 --- a/src/hash.c +++ b/src/hash.c @@ -53,7 +53,7 @@ void sqlite3HashClear(Hash *pH){ ** The hashing function. */ static unsigned int strHash(const char *z, int nKey){ - int h = 0; + unsigned int h = 0; assert( nKey>=0 ); while( nKey > 0 ){ h = (h<<3) ^ h ^ sqlite3UpperToLower[(unsigned char)*z++]; From 05d3dc29c5fa8f5e404079493e7e02fc8b033da1 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 24 Jan 2014 16:57:42 +0000 Subject: [PATCH 188/276] Add test cases for LIMIT and ORDER BY on recursive CTEs. FossilOrigin-Name: 67d6c42d44cb191368ce20f553b32fcb14bfc4d7 --- manifest | 14 ++--- manifest.uuid | 2 +- test/with1.test | 161 +++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 166 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index e446313c60..f46cfae2f5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Use\san\sunsigned\sinteger\sto\saccumulate\sthe\sstring\shash.\s\sAvoids\scompiler\nwarnings. -D 2014-01-24T16:36:18.370 +C Add\stest\scases\sfor\sLIMIT\sand\sORDER\sBY\son\srecursive\sCTEs. +D 2014-01-24T16:57:42.837 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -1092,7 +1092,7 @@ F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c F test/win32lock.test 7a6bd73a5dcdee39b5bb93e92395e1773a194361 F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d -F test/with1.test 9d3537372c8cf6d5e0a5e9af037a52f3375fb704 +F test/with1.test 6c9c27b76e320d0ae3a3fc9ff6b236018201470d F test/with2.test 2fe78fcd8deef2a0f9cfc49bfc755911d0b3fd64 F test/withM.test e97f2a8c506ab3ea9eab94e6f6072f6cc924c991 F test/without_rowid1.test aaa26da19d543cd8d3d2d0e686dfa255556c15c8 @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 1b6405d9788c1bb89761b2bcdce560a5020ff503 -R f7e02965abaaba2b2c591f1141f3d7cf -U drh -Z 197e448152d1aa82b77763ec048456c7 +P b1824344ea4918a13abbda4a3b7134d35fd867c4 +R 9a46b9863f9dd82900d571672109f9d1 +U dan +Z c5f919f56b9fa0112bb7211064a506d1 diff --git a/manifest.uuid b/manifest.uuid index 710b1dce96..44c9c799f8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b1824344ea4918a13abbda4a3b7134d35fd867c4 \ No newline at end of file +67d6c42d44cb191368ce20f553b32fcb14bfc4d7 \ No newline at end of file diff --git a/test/with1.test b/test/with1.test index 6dd67d1690..486f025c64 100644 --- a/test/with1.test +++ b/test/with1.test @@ -452,11 +452,165 @@ do_execsql_test 8.2-soduko { SELECT s FROM x WHERE ind=0; } {534678912672195348198342567859761423426853791713924856961537284287419635345286179} +#-------------------------------------------------------------------------- +# Some tests that use LIMIT and OFFSET in the definition of recursive CTEs. +# +set I [list 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20] +proc limit_test {tn iLimit iOffset} { + if {$iOffset < 0} { set iOffset 0 } + if {$iLimit < 0 } { + set result [lrange $::I $iOffset end] + } else { + set result [lrange $::I $iOffset [expr $iLimit+$iOffset-1]] + } + uplevel [list do_execsql_test $tn [subst -nocommands { + WITH ii(a) AS ( + VALUES(1) + UNION ALL + SELECT a+1 FROM ii WHERE a<20 + LIMIT $iLimit OFFSET $iOffset + ) + SELECT * FROM ii + }] $result] +} + +limit_test 9.1 20 0 +limit_test 9.2 0 0 +limit_test 9.3 19 1 +limit_test 9.4 20 -1 +limit_test 9.5 5 5 +limit_test 9.6 0 -1 +limit_test 9.7 40 -1 +limit_test 9.8 -1 -1 +limit_test 9.9 -1 -1 + +#-------------------------------------------------------------------------- +# Test the ORDER BY clause on recursive tables. +# + +do_execsql_test 10.1 { + DROP TABLE IF EXISTS tree; + CREATE TABLE tree(id INTEGER PRIMARY KEY, parentid, payload); +} + +proc insert_into_tree {L} { + db eval { DELETE FROM tree } + foreach key $L { + unset -nocomplain parentid + foreach seg [split $key /] { + if {$seg==""} continue + set id [db one { + SELECT id FROM tree WHERE parentid IS $parentid AND payload=$seg + }] + if {$id==""} { + db eval { INSERT INTO tree VALUES(NULL, $parentid, $seg) } + set parentid [db last_insert_rowid] + } else { + set parentid $id + } + } + } +} + +insert_into_tree { + /a/a/a + /a/b/c + /a/b/c/d + /a/b/d +} +do_execsql_test 10.2 { + WITH flat(fid, p) AS ( + SELECT id, '/' || payload FROM tree WHERE parentid IS NULL + UNION ALL + SELECT id, p || '/' || payload FROM flat, tree WHERE parentid=fid + ) + SELECT p FROM flat ORDER BY p; +} { + /a /a/a /a/a/a + /a/b /a/b/c /a/b/c/d + /a/b/d +} + +# Scan the tree-structure currently stored in table tree. Return a list +# of nodes visited. +# +proc scan_tree {bDepthFirst bReverse} { + + set order "ORDER BY " + if {$bDepthFirst==0} { append order "2 ASC," } + if {$bReverse==0} { + append order " 3 ASC" + } else { + append order " 3 DESC" + } + + db eval " + WITH flat(fid, depth, p) AS ( + SELECT id, 1, '/' || payload FROM tree WHERE parentid IS NULL + UNION ALL + SELECT id, depth+1, p||'/'||payload FROM flat, tree WHERE parentid=fid + $order + ) + SELECT p FROM flat; + " +} + +insert_into_tree { + /a/b + /a/b/c + /a/d + /a/d/e + /a/d/f + /g/h +} + +# Breadth first, siblings in ascending order. +# +do_test 10.3 { + scan_tree 0 0 +} [list {*}{ + /a /g + /a/b /a/d /g/h + /a/b/c /a/d/e /a/d/f +}] + +# Depth first, siblings in ascending order. +# +do_test 10.4 { + scan_tree 1 0 +} [list {*}{ + /a /a/b /a/b/c + /a/d /a/d/e + /a/d/f + /g /g/h +}] + +# Breadth first, siblings in descending order. +# +do_test 10.5 { + scan_tree 0 1 +} [list {*}{ + /g /a + /g/h /a/d /a/b + /a/d/f /a/d/e /a/b/c +}] + +# Depth first, siblings in ascending order. +# +do_test 10.6 { + scan_tree 1 1 +} [list {*}{ + /g /g/h + /a /a/d /a/d/f + /a/d/e + /a/b /a/b/c +}] + # Test cases to illustrate on the ORDER BY clause on a recursive query can be # used to control depth-first versus breath-first search in a tree. # -do_execsql_test 9.1 { +do_execsql_test 11.1 { CREATE TABLE org( name TEXT PRIMARY KEY, boss TEXT REFERENCES org @@ -513,7 +667,7 @@ do_execsql_test 9.1 { # The previous query used "ORDER BY level" to yield a breath-first search. # Change that to "ORDER BY level DESC" for a depth-first search. # -do_execsql_test 9.2 { +do_execsql_test 11.2 { WITH RECURSIVE under_alice(name,level) AS ( VALUES('Alice','0') @@ -544,7 +698,7 @@ do_execsql_test 9.2 { # Without an ORDER BY clause, the recursive query should use a FIFO, # resulting in a breath-first search. # -do_execsql_test 9.3 { +do_execsql_test 11.3 { WITH RECURSIVE under_alice(name,level) AS ( VALUES('Alice','0') @@ -572,3 +726,4 @@ do_execsql_test 9.3 { .........Olivia}} finish_test + From 6ef5e12e1f8af8458cd7fd0623f36554b03580ec Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 24 Jan 2014 17:03:55 +0000 Subject: [PATCH 189/276] Fix harmless compiler warnings in the Tcl interface. FossilOrigin-Name: 35bc81f5ad4503c0db03127ba3c2ee4ce5227448 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/tclsqlite.c | 16 ++++++++-------- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index f46cfae2f5..d3ca0de3ef 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stest\scases\sfor\sLIMIT\sand\sORDER\sBY\son\srecursive\sCTEs. -D 2014-01-24T16:57:42.837 +C Fix\sharmless\scompiler\swarnings\sin\sthe\sTcl\sinterface. +D 2014-01-24T17:03:55.776 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -228,7 +228,7 @@ F src/sqliteInt.h 87a90ad4818ac5d68d3463eb7fe3ed96e5209b25 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e -F src/tclsqlite.c 46073db71011b6542fde1f234c56a076d5ff23f9 +F src/tclsqlite.c 21ca0043d7c48cde5dabed5c1116eee1be692f62 F src/test1.c 2401eee14a4309a7cfe2aeb2f30ad517a1d9c299 F src/test2.c 7355101c085304b90024f2261e056cdff13c6c35 F src/test3.c 1c0e5d6f080b8e33c1ce8b3078e7013fdbcd560c @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P b1824344ea4918a13abbda4a3b7134d35fd867c4 -R 9a46b9863f9dd82900d571672109f9d1 -U dan -Z c5f919f56b9fa0112bb7211064a506d1 +P 67d6c42d44cb191368ce20f553b32fcb14bfc4d7 +R 4c6f56cfb9673c8d50f2c5c8d045a419 +U mistachkin +Z 1e8effcea2fae186977e2dc88d96ee04 diff --git a/manifest.uuid b/manifest.uuid index 44c9c799f8..6840f3457c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -67d6c42d44cb191368ce20f553b32fcb14bfc4d7 \ No newline at end of file +35bc81f5ad4503c0db03127ba3c2ee4ce5227448 \ No newline at end of file diff --git a/src/tclsqlite.c b/src/tclsqlite.c index 1e81912526..969a83ad45 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -873,7 +873,7 @@ static int auth_callback( const char *zArg3, const char *zArg4 ){ - char *zCode; + const char *zCode; Tcl_DString str; int rc; const char *zReply; @@ -999,7 +999,7 @@ static int DbTransPostCmd( Tcl_Interp *interp, /* Tcl interpreter */ int result /* Result of evaluating SCRIPT */ ){ - static const char *azEnd[] = { + static const char *const azEnd[] = { "RELEASE _tcl_transaction", /* rc==TCL_ERROR, nTransaction!=0 */ "COMMIT", /* rc!=TCL_ERROR, nTransaction==0 */ "ROLLBACK TO _tcl_transaction ; RELEASE _tcl_transaction", @@ -1937,7 +1937,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ Tcl_AppendResult(interp, pDb->zCommit, 0); } }else{ - char *zCommit; + const char *zCommit; int len; if( pDb->zCommit ){ Tcl_Free(pDb->zCommit); @@ -2010,14 +2010,14 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ char *zSql; /* An SQL statement */ char *zLine; /* A single line of input from the file */ char **azCol; /* zLine[] broken up into columns */ - char *zCommit; /* How to commit changes */ + const char *zCommit; /* How to commit changes */ FILE *in; /* The input file */ int lineno = 0; /* Line number of input file */ char zLineNum[80]; /* Line number print buffer */ Tcl_Obj *pResult; /* interp result */ - char *zSep; - char *zNull; + const char *zSep; + const char *zNull; if( objc<5 || objc>7 ){ Tcl_WrongNumArgs(interp, 2, objv, "CONFLICT-ALGORITHM TABLE FILENAME ?SEPARATOR? ?NULLINDICATOR?"); @@ -2935,7 +2935,7 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ if( objc==2 ){ zArg = Tcl_GetStringFromObj(objv[1], 0); if( strcmp(zArg,"-version")==0 ){ - Tcl_AppendResult(interp,sqlite3_version,0); + Tcl_AppendResult(interp,sqlite3_libversion(),0); return TCL_OK; } if( strcmp(zArg,"-has-codec")==0 ){ @@ -3017,7 +3017,7 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ zErrMsg = 0; p = (SqliteDb*)Tcl_Alloc( sizeof(*p) ); if( p==0 ){ - Tcl_SetResult(interp, "malloc failed", TCL_STATIC); + Tcl_SetResult(interp, (char *)"malloc failed", TCL_STATIC); return TCL_ERROR; } memset(p, 0, sizeof(*p)); From 53bed45ecb66ba6ddd835a448adebdb61c2a81dc Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 24 Jan 2014 20:37:18 +0000 Subject: [PATCH 190/276] Select collation sequences for ORDER BY expressions attached to recursive CTEs in the same way as they are selected for other compound SELECT statements. FossilOrigin-Name: 9554519c126c5e714421a82fd2e8aa9b19e11493 --- manifest | 16 ++++----- manifest.uuid | 2 +- src/select.c | 67 +++++++++++++++++++++++------------- test/with1.test | 91 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 144 insertions(+), 32 deletions(-) diff --git a/manifest b/manifest index d3ca0de3ef..ebef0b5e83 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings\sin\sthe\sTcl\sinterface. -D 2014-01-24T17:03:55.776 +C Select\scollation\ssequences\sfor\sORDER\sBY\sexpressions\sattached\sto\srecursive\sCTEs\sin\sthe\ssame\sway\sas\sthey\sare\sselected\sfor\sother\scompound\sSELECT\sstatements. +D 2014-01-24T20:37:18.933 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -219,7 +219,7 @@ F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c 93764e0d81946c070e2c7f1127f35e21efabbcc3 +F src/select.c d88d739b7af398b8d5b6856d1d479b42d15c419d F src/shell.c 24722d24d4ea8ca93db35e44db7308de786767ca F src/sqlite.h.in eed7f7d66a60daaa7b4a597dcd9bad87aad9611b F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e @@ -1092,7 +1092,7 @@ F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c F test/win32lock.test 7a6bd73a5dcdee39b5bb93e92395e1773a194361 F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d -F test/with1.test 6c9c27b76e320d0ae3a3fc9ff6b236018201470d +F test/with1.test ce15d69d34a2576b0e47d78c244d1ba2a31679d1 F test/with2.test 2fe78fcd8deef2a0f9cfc49bfc755911d0b3fd64 F test/withM.test e97f2a8c506ab3ea9eab94e6f6072f6cc924c991 F test/without_rowid1.test aaa26da19d543cd8d3d2d0e686dfa255556c15c8 @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 67d6c42d44cb191368ce20f553b32fcb14bfc4d7 -R 4c6f56cfb9673c8d50f2c5c8d045a419 -U mistachkin -Z 1e8effcea2fae186977e2dc88d96ee04 +P 35bc81f5ad4503c0db03127ba3c2ee4ce5227448 +R c1a71fcb2b287542b440975ad8562a1c +U dan +Z 0004644f36087f5d68980e2ae5cf51c5 diff --git a/manifest.uuid b/manifest.uuid index 6840f3457c..7673b5df8f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -35bc81f5ad4503c0db03127ba3c2ee4ce5227448 \ No newline at end of file +9554519c126c5e714421a82fd2e8aa9b19e11493 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 98ed526e08..9efa822a8c 100644 --- a/src/select.c +++ b/src/select.c @@ -1725,6 +1725,44 @@ static CollSeq *multiSelectCollSeq(Parse *pParse, Select *p, int iCol){ } return pRet; } + +/* +** The select statement passed as the second parameter is a compound SELECT +** with an ORDER BY clause. This function allocates and returns a KeyInfo +** structure suitable for implementing the ORDER BY. +** +** Space to hold the KeyInfo structure is obtained from malloc. The calling +** function is responsible for ensuring that this structure is eventually +** freed. +*/ +static KeyInfo *multiSelectOrderByKeyInfo(Parse *pParse, Select *p, int nExtra){ + ExprList *pOrderBy = p->pOrderBy; + int nOrderBy = p->pOrderBy->nExpr; + sqlite3 *db = pParse->db; + KeyInfo *pRet = sqlite3KeyInfoAlloc(db, nOrderBy+nExtra, 1); + if( pRet ){ + int i; + for(i=0; ia[i]; + Expr *pTerm = pItem->pExpr; + CollSeq *pColl; + + if( pTerm->flags & EP_Collate ){ + pColl = sqlite3ExprCollSeq(pParse, pTerm); + }else{ + pColl = multiSelectCollSeq(pParse, p, pItem->u.x.iOrderByCol-1); + if( pColl==0 ) pColl = db->pDfltColl; + pOrderBy->a[i].pExpr = + sqlite3ExprAddCollateString(pParse, pTerm, pColl->zName); + } + assert( sqlite3KeyInfoIsWriteable(pRet) ); + pRet->aColl[i] = pColl; + pRet->aSortOrder[i] = pOrderBy->a[i].sortOrder; + } + } + + return pRet; +} #endif /* SQLITE_OMIT_COMPOUND_SELECT */ #ifndef SQLITE_OMIT_CTE @@ -1799,6 +1837,7 @@ static void generateWithRecursiveQuery( regOffset = p->iOffset; p->pLimit = p->pOffset = 0; p->iLimit = p->iOffset = 0; + pOrderBy = p->pOrderBy; /* Locate the cursor number of the Current table */ for(i=0; ALWAYS(inSrc); i++){ @@ -1808,10 +1847,6 @@ static void generateWithRecursiveQuery( } } - /* Detach the ORDER BY clause from the compound SELECT */ - pOrderBy = p->pOrderBy; - p->pOrderBy = 0; - /* Allocate cursors numbers for Queue and Distinct. The cursor number for ** the Distinct table must be exactly one greater than Queue in order ** for the SRT_DistTable and SRT_DistQueue destinations to work. */ @@ -1828,7 +1863,7 @@ static void generateWithRecursiveQuery( regCurrent = ++pParse->nMem; sqlite3VdbeAddOp3(v, OP_OpenPseudo, iCurrent, regCurrent, nCol); if( pOrderBy ){ - KeyInfo *pKeyInfo = keyInfoFromExprList(pParse, pOrderBy, 1); + KeyInfo *pKeyInfo = multiSelectOrderByKeyInfo(pParse, p, 1); sqlite3VdbeAddOp4(v, OP_OpenEphemeral, iQueue, pOrderBy->nExpr+2, 0, (char*)pKeyInfo, P4_KEYINFO); destQueue.pOrderBy = pOrderBy; @@ -1841,6 +1876,9 @@ static void generateWithRecursiveQuery( p->selFlags |= SF_UsesEphemeral; } + /* Detach the ORDER BY clause from the compound SELECT */ + p->pOrderBy = 0; + /* Store the results of the setup-query in Queue. */ rc = sqlite3Select(pParse, pSetup, &destQueue); if( rc ) goto end_of_recursive_query; @@ -2625,24 +2663,7 @@ static int multiSelectOrderBy( && pItem->u.x.iOrderByCol<=p->pEList->nExpr ); aPermute[i] = pItem->u.x.iOrderByCol - 1; } - pKeyMerge = sqlite3KeyInfoAlloc(db, nOrderBy, 1); - if( pKeyMerge ){ - for(i=0; ia[i].pExpr; - if( pTerm->flags & EP_Collate ){ - pColl = sqlite3ExprCollSeq(pParse, pTerm); - }else{ - pColl = multiSelectCollSeq(pParse, p, aPermute[i]); - if( pColl==0 ) pColl = db->pDfltColl; - pOrderBy->a[i].pExpr = - sqlite3ExprAddCollateString(pParse, pTerm, pColl->zName); - } - assert( sqlite3KeyInfoIsWriteable(pKeyMerge) ); - pKeyMerge->aColl[i] = pColl; - pKeyMerge->aSortOrder[i] = pOrderBy->a[i].sortOrder; - } - } + pKeyMerge = multiSelectOrderByKeyInfo(pParse, p, 1); }else{ pKeyMerge = 0; } diff --git a/test/with1.test b/test/with1.test index 486f025c64..2fca12817f 100644 --- a/test/with1.test +++ b/test/with1.test @@ -607,6 +607,97 @@ do_test 10.6 { }] +# Test name resolution in ORDER BY clauses. +# +do_catchsql_test 10.7.1 { + WITH t(a) AS ( + SELECT 1 AS b UNION ALL SELECT a+1 AS c FROM t WHERE a<5 ORDER BY a + ) + SELECT * FROM t +} {1 {1st ORDER BY term does not match any column in the result set}} +do_execsql_test 10.7.2 { + WITH t(a) AS ( + SELECT 1 AS b UNION ALL SELECT a+1 AS c FROM t WHERE a<5 ORDER BY b + ) + SELECT * FROM t +} {1 2 3 4 5} +do_execsql_test 10.7.3 { + WITH t(a) AS ( + SELECT 1 AS b UNION ALL SELECT a+1 AS c FROM t WHERE a<5 ORDER BY c + ) + SELECT * FROM t +} {1 2 3 4 5} + +# Test COLLATE clauses attached to ORDER BY. +# +insert_into_tree { + /a/b + /a/C + /a/d + /B/e + /B/F + /B/g + /c/h + /c/I + /c/j +} + +do_execsql_test 10.8.1 { + WITH flat(fid, depth, p) AS ( + SELECT id, 1, '/' || payload FROM tree WHERE parentid IS NULL + UNION ALL + SELECT id, depth+1, p||'/'||payload FROM flat, tree WHERE parentid=fid + ORDER BY 2, 3 COLLATE nocase + ) + SELECT p FROM flat; +} { + /a /B /c + /a/b /a/C /a/d /B/e /B/F /B/g /c/h /c/I /c/j +} +do_execsql_test 10.8.2 { + WITH flat(fid, depth, p) AS ( + SELECT id, 1, ('/' || payload) COLLATE nocase + FROM tree WHERE parentid IS NULL + UNION ALL + SELECT id, depth+1, (p||'/'||payload) + FROM flat, tree WHERE parentid=fid + ORDER BY 2, 3 + ) + SELECT p FROM flat; +} { + /a /B /c + /a/b /a/C /a/d /B/e /B/F /B/g /c/h /c/I /c/j +} + +do_execsql_test 10.8.3 { + WITH flat(fid, depth, p) AS ( + SELECT id, 1, ('/' || payload) + FROM tree WHERE parentid IS NULL + UNION ALL + SELECT id, depth+1, (p||'/'||payload) COLLATE nocase + FROM flat, tree WHERE parentid=fid + ORDER BY 2, 3 + ) + SELECT p FROM flat; +} { + /a /B /c + /a/b /a/C /a/d /B/e /B/F /B/g /c/h /c/I /c/j +} + +do_execsql_test 10.8.4.1 { + CREATE TABLE tst(a,b); + INSERT INTO tst VALUES('a', 'A'); + INSERT INTO tst VALUES('b', 'B'); + INSERT INTO tst VALUES('c', 'C'); + SELECT a COLLATE nocase FROM tst UNION ALL SELECT b FROM tst ORDER BY 1; +} {a A b B c C} +do_execsql_test 10.8.4.2 { + SELECT a FROM tst UNION ALL SELECT b COLLATE nocase FROM tst ORDER BY 1; +} {A B C a b c} +do_execsql_test 10.8.4.3 { + SELECT a||'' FROM tst UNION ALL SELECT b COLLATE nocase FROM tst ORDER BY 1; +} {a A b B c C} + # Test cases to illustrate on the ORDER BY clause on a recursive query can be # used to control depth-first versus breath-first search in a tree. # From 693e671936cd7053e874186228b9b0454a643893 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 24 Jan 2014 22:58:00 +0000 Subject: [PATCH 191/276] Fixes for various clang warnings. FossilOrigin-Name: 87bf60637e5863c54c5e2d05aaaca0835b7aace8 --- ext/fts3/fts3_hash.c | 4 ++-- manifest | 38 +++++++++++++++++++------------------- manifest.uuid | 2 +- src/delete.c | 3 ++- src/expr.c | 5 +++-- src/func.c | 2 +- src/os_unix.c | 2 +- src/pcache1.c | 3 ++- src/sqliteInt.h | 1 + src/test8.c | 2 +- src/update.c | 5 +++-- src/util.c | 3 ++- src/vdbe.c | 2 +- src/vdbeaux.c | 26 +++++++++++++++----------- src/vdbemem.c | 2 +- 15 files changed, 55 insertions(+), 45 deletions(-) diff --git a/ext/fts3/fts3_hash.c b/ext/fts3/fts3_hash.c index 57c59b587a..1a32a537b4 100644 --- a/ext/fts3/fts3_hash.c +++ b/ext/fts3/fts3_hash.c @@ -96,13 +96,13 @@ void sqlite3Fts3HashClear(Fts3Hash *pH){ */ static int fts3StrHash(const void *pKey, int nKey){ const char *z = (const char *)pKey; - int h = 0; + unsigned h = 0; if( nKey<=0 ) nKey = (int) strlen(z); while( nKey > 0 ){ h = (h<<3) ^ h ^ *z++; nKey--; } - return h & 0x7fffffff; + return (int)(h & 0x7fffffff); } static int fts3StrCompare(const void *pKey1, int n1, const void *pKey2, int n2){ if( n1!=n2 ) return 1; diff --git a/manifest b/manifest index ebef0b5e83..4866e9a371 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Select\scollation\ssequences\sfor\sORDER\sBY\sexpressions\sattached\sto\srecursive\sCTEs\sin\sthe\ssame\sway\sas\sthey\sare\sselected\sfor\sother\scompound\sSELECT\sstatements. -D 2014-01-24T20:37:18.933 +C Fixes\sfor\svarious\sclang\swarnings. +D 2014-01-24T22:58:00.303 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -83,7 +83,7 @@ F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe F ext/fts3/fts3Int.h eb5f8029589f3d8f1dc7fd50c773326a640388b1 F ext/fts3/fts3_aux.c 5c211e17a64885faeb16b9ba7772f9d5445c2365 F ext/fts3/fts3_expr.c 5165c365cb5a035f5be8bb296f7aa3211d43e4ac -F ext/fts3/fts3_hash.c 8dd2d06b66c72c628c2732555a32bc0943114914 +F ext/fts3/fts3_hash.c 29b986e43f4e9dd40110eafa377dc0d63c422c60 F ext/fts3/fts3_hash.h 39cf6874dc239d6b4e30479b1975fe5b22a3caaf F ext/fts3/fts3_icu.c e319e108661147bcca8dd511cd562f33a1ba81b5 F ext/fts3/fts3_porter.c 7f8b4bf5af7c0f20f73b8e87e14fa9298f52e290 @@ -174,11 +174,11 @@ F src/callback.c 174e3c8656bc29f91d710ab61550d16eea34be98 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 -F src/delete.c 91e1321021db5dc266360531b8b6550009d771ff -F src/expr.c 61f9105820d6702d7153dfb6ca3d58e751a5e95a +F src/delete.c 22e54756c08b194a29d51cd6552922028b3e21a9 +F src/expr.c 96f00a262308f3f97d2afd8519c7a284e25829f3 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 2ab0f5384b70594468ef3ac5c7ed8ca24bfd17d5 -F src/func.c 6325ac2ec10833ccf4d5c36d323709221d37ea19 +F src/func.c f4499b39d66b71825514334ce67b32ff14bd19f5 F src/global.c 1d7bb7ea8254ae6a68ed9bfaf65fcb3d1690b486 F src/hash.c d139319967164f139c8d1bb8a11b14db9c4ba3cd F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22 @@ -205,14 +205,14 @@ F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30 F src/os.c 1b147e4cf7cc39e618115c14a086aed44bc91ace F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 -F src/os_unix.c 3a4dcb554d3c915075766162f28c3fd4cdb75968 +F src/os_unix.c f3ed0e406cbf9c820565b2118232d0796346130f F src/os_win.c 1b21af72c5fa6f9e519a5fcab33e80d182b1aedb F src/pager.c efa923693e958696eee69b205a20bfbc402c8480 F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428 F src/parse.y bd51bc17cbfe7549adb4ca3747b1c3d384645065 F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222 -F src/pcache1.c 57fee9a9a617218f5037afbbe49b09da65bde56b +F src/pcache1.c 102e6f5a2fbc646154463eb856d1fd716867b64c F src/pragma.c ed409ce4104cf4d9de6ead40ace70974f124853b F src/prepare.c 677521ab7132615a8a26107a1d1c3132f44ae337 F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 @@ -224,7 +224,7 @@ F src/shell.c 24722d24d4ea8ca93db35e44db7308de786767ca F src/sqlite.h.in eed7f7d66a60daaa7b4a597dcd9bad87aad9611b F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h 87a90ad4818ac5d68d3463eb7fe3ed96e5209b25 +F src/sqliteInt.h 22c8f7112f2fa8e778bbd9d331cbebff8c645574 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -236,7 +236,7 @@ F src/test4.c 9b32d22f5f150abe23c1830e2057c4037c45b3df F src/test5.c a6d1ac55ac054d0b2b8f37b5e655b6c92645a013 F src/test6.c 41cacf3b0dd180823919bf9e1fbab287c9266723 F src/test7.c 72b732baa5642f795655ba1126ea032af46ecfd2 -F src/test8.c c7aab1d9fbbf54fc33d43b73aa24aa55f9eaf534 +F src/test8.c 54ccd7b1df5062f0ecbf50a8f7b618f8b1f13b20 F src/test9.c bea1e8cf52aa93695487badedd6e1886c321ea60 F src/test_async.c 21e11293a2f72080eda70e1124e9102044531cd8 F src/test_autoext.c dea8a01a7153b9adc97bd26161e4226329546e12 @@ -276,17 +276,17 @@ F src/test_vfstrace.c 3a0ab304682fecbceb689e7d9b904211fde11d78 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/tokenize.c 6da2de6e12218ccb0aea5184b56727d011f4bee7 F src/trigger.c 5c1c0b899ac0ce284763dcb8fdbaa38ecf15ef98 -F src/update.c c2706a6eb232a96345c35b7e1e75a188e26812bb +F src/update.c a7df6fffce6bfedc578fda6136dd33e34a63f8ee F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 -F src/util.c e71f19b272f05c8695cf747b4bac1732685f9e5c +F src/util.c 15ac2627f548f5481d0d7e6c4eb67be673027695 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c dede894c2990329f8bc5a70da7de44ce8c3c6bf5 +F src/vdbe.c 5fe94e13fa56c50edb75263706b6fbcc860a3980 F src/vdbe.h e6c4c610fcabad4fa80ebb1efc6822a9367e2b26 F src/vdbeInt.h 42db251e9f863401ff847b90d5fe1614c89a6a56 F src/vdbeapi.c ce4e68ea4842cc6081046f533d088dcf01d247ad -F src/vdbeaux.c 9f4bfc52672acbb0bb4493d6a03603dc5a595ac1 +F src/vdbeaux.c f228f45f5edc8a4cf97e965236519cdcb6baf99b F src/vdbeblob.c bc40f98f256f0b34116d6a44b114da4a81a15d33 -F src/vdbemem.c 0e69351b2c6ff7d8b638688c0ae336a26befa6b2 +F src/vdbemem.c 23cdc14ed43e0aafa57bd72b9bf3d5b1641afa91 F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147 F src/vdbetrace.c 6f52bc0c51e144b7efdcfb2a8f771167a8816767 F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 35bc81f5ad4503c0db03127ba3c2ee4ce5227448 -R c1a71fcb2b287542b440975ad8562a1c -U dan -Z 0004644f36087f5d68980e2ae5cf51c5 +P 9554519c126c5e714421a82fd2e8aa9b19e11493 +R c581db3b6e5511f2dddae190976cfffb +U drh +Z 8b12a1dace1d4f79f17e9cd04b2cccdf diff --git a/manifest.uuid b/manifest.uuid index 7673b5df8f..d7e5fe4225 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9554519c126c5e714421a82fd2e8aa9b19e11493 \ No newline at end of file +87bf60637e5863c54c5e2d05aaaca0835b7aace8 \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index e448e47b02..ecf850cf8e 100644 --- a/src/delete.c +++ b/src/delete.c @@ -636,7 +636,8 @@ void sqlite3GenerateRowDelete( ** used by any BEFORE and AFTER triggers that exist. */ sqlite3VdbeAddOp2(v, OP_Copy, iPk, iOld); for(iCol=0; iColnCol; iCol++){ - if( mask==0xffffffff || mask&(1<a[i].pExpr) ){ - constMask |= (1<funcFlags & SQLITE_FUNC_NEEDCOLL)!=0 && !pColl ){ pColl = sqlite3ExprCollSeq(pParse, pFarg->a[i].pExpr); diff --git a/src/func.c b/src/func.c index 1d6ec9f6ee..e657558ba2 100644 --- a/src/func.c +++ b/src/func.c @@ -137,7 +137,7 @@ static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ case SQLITE_INTEGER: { i64 iVal = sqlite3_value_int64(argv[0]); if( iVal<0 ){ - if( (iVal<<1)==0 ){ + if( iVal==SMALLEST_INT64 ){ /* IMP: R-31676-45509 If X is the integer -9223372036854775808 ** then abs(X) throws an integer overflow error since there is no ** equivalent positive 64-bit two complement value. */ diff --git a/src/os_unix.c b/src/os_unix.c index 96cd5e6191..b539550220 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -4097,7 +4097,7 @@ static int unixShmSystemLock( #ifdef SQLITE_DEBUG { u16 mask; OSTRACE(("SHM-LOCK ")); - mask = ofst>31 ? 0xffffffff : (1<<(ofst+n)) - (1<31 ? 0xffff : (1<<(ofst+n)) - (1<bPurgeable || createFlag!=1 ); assert( pCache->bPurgeable || pCache->nMin==0 ); assert( pCache->bPurgeable==0 || pCache->nMin==10 ); @@ -825,7 +826,7 @@ fetch_out: pCache->iMaxKey = iKey; } pcache1LeaveMutex(pGroup); - return &pPage->page; + return (sqlite3_pcache_page*)pPage; } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index c1fa7b69ad..f58d826788 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1982,6 +1982,7 @@ typedef u64 Bitmask; ** A bit in a Bitmask */ #define MASKBIT(n) (((Bitmask)1)<<(n)) +#define MASKBIT32(n) (((unsigned int)1)<<(n)) /* ** The following structure describes the FROM clause of a SELECT statement. diff --git a/src/test8.c b/src/test8.c index 9b8b545fa6..8bc835d638 100644 --- a/src/test8.c +++ b/src/test8.c @@ -892,7 +892,7 @@ static int echoBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ pIdxInfo->estimatedCost = cost; }else if( useIdx ){ /* Approximation of log2(nRow). */ - for( ii=0; ii<(sizeof(int)*8); ii++ ){ + for( ii=0; ii<(sizeof(int)*8)-1; ii++ ){ if( nRow & (1<estimatedCost = (double)ii; } diff --git a/src/update.c b/src/update.c index d62d0d3245..a7da4ce71f 100644 --- a/src/update.c +++ b/src/update.c @@ -467,9 +467,10 @@ void sqlite3Update( ); for(i=0; inCol; i++){ if( oldmask==0xffffffff - || (i<32 && (oldmask & (1<aCol[i].colFlags & COLFLAG_PRIMKEY)!=0 ){ + testcase( oldmask!=0xffffffff && i==31 ); sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, regOld+i); }else{ sqlite3VdbeAddOp2(v, OP_Null, 0, regOld+i); @@ -504,7 +505,7 @@ void sqlite3Update( j = aXRef[i]; if( j>=0 ){ sqlite3ExprCode(pParse, pChanges->a[j].pExpr, regNew+i); - }else if( 0==(tmask&TRIGGER_BEFORE) || i>31 || (newmask&(1<31 || (newmask & MASKBIT32(i)) ){ /* This branch loads the value of a column that will not be changed ** into a register. This is done if there are no BEFORE triggers, or ** if there are one or more BEFORE triggers that use this value via diff --git a/src/util.c b/src/util.c index 362a5d8970..3f3a9649e0 100644 --- a/src/util.c +++ b/src/util.c @@ -1001,7 +1001,8 @@ int sqlite3VarintLen(u64 v){ ** Read or write a four-byte big-endian integer value. */ u32 sqlite3Get4byte(const u8 *p){ - return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3]; + testcase( p[0]&0x80 ); + return ((unsigned)p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3]; } void sqlite3Put4byte(unsigned char *p, u32 v){ p[0] = (u8)(v>>24); diff --git a/src/vdbe.c b/src/vdbe.c index 10a70750e3..30c9269ea4 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -6174,7 +6174,7 @@ case OP_Trace: { if( zTrace ){ int i; for(i=0; inDb; i++){ - if( ((1<btreeMask)==0 ) continue; + if( MASKBIT(i) & p->btreeMask)==0 ) continue; sqlite3_file_control(db, db->aDb[i].zName, SQLITE_FCNTL_TRACE, zTrace); } } diff --git a/src/vdbeaux.c b/src/vdbeaux.c index faabaf75d7..e06f091aed 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2615,8 +2615,9 @@ void sqlite3VdbeDeleteAuxData(Vdbe *pVdbe, int iOp, int mask){ while( *pp ){ AuxData *pAux = *pp; if( (iOp<0) - || (pAux->iOp==iOp && (pAux->iArg>31 || !(mask & ((u32)1<iArg)))) + || (pAux->iOp==iOp && (pAux->iArg>31 || !(mask & MASKBIT32(pAux->iArg)))) ){ + testcase( pAux->iArg==31 ); if( pAux->xDelete ){ pAux->xDelete(pAux->pAux); } @@ -2931,6 +2932,9 @@ u32 sqlite3VdbeSerialGet( u32 serial_type, /* Serial type to deserialize */ Mem *pMem /* Memory cell to write value into */ ){ + u64 x; + u32 y; + int i; switch( serial_type ){ case 10: /* Reserved for future use */ case 11: /* Reserved for future use */ @@ -2944,23 +2948,26 @@ u32 sqlite3VdbeSerialGet( return 1; } case 2: { /* 2-byte signed integer */ - pMem->u.i = (((signed char)buf[0])<<8) | buf[1]; + i = 256*(signed char)buf[0] | buf[1]; + pMem->u.i = (i64)i; pMem->flags = MEM_Int; return 2; } case 3: { /* 3-byte signed integer */ - pMem->u.i = (((signed char)buf[0])<<16) | (buf[1]<<8) | buf[2]; + i = 65536*(signed char)buf[0] | (buf[1]<<8) | buf[2]; + pMem->u.i = (i64)i; pMem->flags = MEM_Int; return 3; } case 4: { /* 4-byte signed integer */ - pMem->u.i = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3]; + y = ((unsigned)buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3]; + pMem->u.i = (i64)*(int*)&y; pMem->flags = MEM_Int; return 4; } case 5: { /* 6-byte signed integer */ - u64 x = (((signed char)buf[0])<<8) | buf[1]; - u32 y = (buf[2]<<24) | (buf[3]<<16) | (buf[4]<<8) | buf[5]; + u64 x = 256*(signed char)buf[0] + buf[1]; + u32 y = ((unsigned)buf[2]<<24) | (buf[3]<<16) | (buf[4]<<8) | buf[5]; x = (x<<32) | y; pMem->u.i = *(i64*)&x; pMem->flags = MEM_Int; @@ -2968,8 +2975,6 @@ u32 sqlite3VdbeSerialGet( } case 6: /* 8-byte signed integer */ case 7: { /* IEEE floating point */ - u64 x; - u32 y; #if !defined(NDEBUG) && !defined(SQLITE_OMIT_FLOATING_POINT) /* Verify that integers and floating point values use the same ** byte order. Or, that if SQLITE_MIXED_ENDIAN_64BIT_FLOAT is @@ -2982,9 +2987,8 @@ u32 sqlite3VdbeSerialGet( swapMixedEndianFloat(t2); assert( sizeof(r1)==sizeof(t2) && memcmp(&r1, &t2, sizeof(r1))==0 ); #endif - - x = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3]; - y = (buf[4]<<24) | (buf[5]<<16) | (buf[6]<<8) | buf[7]; + x = ((unsigned)buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3]; + y = ((unsigned)buf[4]<<24) | (buf[5]<<16) | (buf[6]<<8) | buf[7]; x = (x<<32) | y; if( serial_type==6 ){ pMem->u.i = *(i64*)&x; diff --git a/src/vdbemem.c b/src/vdbemem.c index 3beccd92db..9a621d1f73 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -598,7 +598,7 @@ void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){ /* ** Size of struct Mem not including the Mem.zMalloc member. */ -#define MEMCELLSIZE (size_t)(&(((Mem *)0)->zMalloc)) +#define MEMCELLSIZE offsetof(Mem,zMalloc) /* ** Make an shallow copy of pFrom into pTo. Prior contents of From b68b97789ec4851015f3bb05444088e68cc7cf20 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 25 Jan 2014 12:16:53 +0000 Subject: [PATCH 192/276] Fix a problem causing SQLITE_OMIT_COMPOUND_SELECT builds to fail. FossilOrigin-Name: b30db0ac3096b43d55a6da40cafc7de569082bf8 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/select.c | 4 +--- tool/omittest.tcl | 1 + 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 4866e9a371..1a65c31de1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fixes\sfor\svarious\sclang\swarnings. -D 2014-01-24T22:58:00.303 +C Fix\sa\sproblem\scausing\sSQLITE_OMIT_COMPOUND_SELECT\sbuilds\sto\sfail. +D 2014-01-25T12:16:53.164 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -219,7 +219,7 @@ F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c d88d739b7af398b8d5b6856d1d479b42d15c419d +F src/select.c a421f3fb7f52a3c0b37f5caeabd27799e8a9ae58 F src/shell.c 24722d24d4ea8ca93db35e44db7308de786767ca F src/sqlite.h.in eed7f7d66a60daaa7b4a597dcd9bad87aad9611b F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e @@ -1127,7 +1127,7 @@ F tool/mksqlite3h.tcl ba24038056f51fde07c0079c41885ab85e2cff12 F tool/mksqlite3internalh.tcl 3dca7bb5374cee003379b8cbac73714f610ef795 F tool/mkvsix.tcl 6477fb9dab838b7eea1eed50658ff1cda04850b5 F tool/offsets.c fe4262fdfa378e8f5499a42136d17bf3b98f6091 -F tool/omittest.tcl 4665982e95a6e5c1bd806cf7bc3dea95be422d77 +F tool/omittest.tcl 34d7ac01fe4fd18e3637f64abe12c40eca0f6b97 F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c F tool/pagesig.c ff0ca355fd3c2398e933da5e22439bbff89b803b F tool/restore_jrnl.tcl 6957a34f8f1f0f8285e07536225ec3b292a9024a @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 9554519c126c5e714421a82fd2e8aa9b19e11493 -R c581db3b6e5511f2dddae190976cfffb -U drh -Z 8b12a1dace1d4f79f17e9cd04b2cccdf +P 87bf60637e5863c54c5e2d05aaaca0835b7aace8 +R 69ab88b9bb0a730071944ebfada4d77f +U dan +Z d44703c5b70f5ed4164d3c8bc064c718 diff --git a/manifest.uuid b/manifest.uuid index d7e5fe4225..ceaaffde0a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -87bf60637e5863c54c5e2d05aaaca0835b7aace8 \ No newline at end of file +b30db0ac3096b43d55a6da40cafc7de569082bf8 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 9efa822a8c..c78d997806 100644 --- a/src/select.c +++ b/src/select.c @@ -1763,7 +1763,6 @@ static KeyInfo *multiSelectOrderByKeyInfo(Parse *pParse, Select *p, int nExtra){ return pRet; } -#endif /* SQLITE_OMIT_COMPOUND_SELECT */ #ifndef SQLITE_OMIT_CTE /* @@ -1921,7 +1920,7 @@ end_of_recursive_query: p->pOffset = pOffset; return; } -#endif +#endif /* SQLITE_OMIT_CTE */ /* Forward references */ static int multiSelectOrderBy( @@ -1931,7 +1930,6 @@ static int multiSelectOrderBy( ); -#ifndef SQLITE_OMIT_COMPOUND_SELECT /* ** This routine is called to process a compound query form from ** two or more separate queries using UNION, UNION ALL, EXCEPT, or diff --git a/tool/omittest.tcl b/tool/omittest.tcl index 3351b96b32..5437f2eb01 100644 --- a/tool/omittest.tcl +++ b/tool/omittest.tcl @@ -190,6 +190,7 @@ proc main {argv} { SQLITE_OMIT_COMPILEOPTION_DIAGS \ SQLITE_OMIT_COMPLETE \ SQLITE_OMIT_COMPOUND_SELECT \ + SQLITE_OMIT_CTE \ SQLITE_OMIT_DATETIME_FUNCS \ SQLITE_OMIT_DECLTYPE \ SQLITE_OMIT_DEPRECATED \ From abfe034692ad10d6b96c2e80975fec1c1568eee8 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 27 Jan 2014 08:48:10 +0000 Subject: [PATCH 193/276] Fix some problems in test scripts. No code changes. FossilOrigin-Name: 08acfc65877e207f1a62d31a14afb4add20c4c35 --- manifest | 14 +++++------ manifest.uuid | 2 +- test/corruptH.test | 1 + test/spellfix.test | 58 ++++++++++++++++++++++++---------------------- 4 files changed, 39 insertions(+), 36 deletions(-) diff --git a/manifest b/manifest index 1a65c31de1..ef413f44a3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\scausing\sSQLITE_OMIT_COMPOUND_SELECT\sbuilds\sto\sfail. -D 2014-01-25T12:16:53.164 +C Fix\ssome\sproblems\sin\stest\sscripts.\sNo\scode\schanges. +D 2014-01-27T08:48:10.724 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -406,7 +406,7 @@ F test/corruptD.test b3c205fac7952b1de645ce44bb02335cd9e3e040 F test/corruptE.test 193b4ca4e927e77c1d5f4f56203ddc998432a7ee F test/corruptF.test be9fde98e4c93648f1ba52b74e5318edc8f59fe4 F test/corruptG.test c150f156dace653c00a121ad0f5772a0568c41ba -F test/corruptH.test 0a247f3dc8a8f3578db5f639d86c6bb4d520207f +F test/corruptH.test 7c02f5d928499bc1b68ed4610bfc2c3f12565a35 F test/count.test 42a251178e32f617eda33f76236a7f79825a50b5 F test/coveridxscan.test cdb47d01acc4a634a34fd25abe85189e0d0f1e62 F test/crash.test fb9dc4a02dcba30d4aa5c2c226f98b220b2b959f @@ -825,7 +825,7 @@ F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b F test/speedtest1.c 7130d2cb6db45baa553a4ab2f715116c71c2d9f4 -F test/spellfix.test 674db5da8b16d2b54939b68ccc0ac31ca53d9977 +F test/spellfix.test 61309f5efbec53603b3f86457d34a504f80abafe F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298 F test/stat.test 76fd746b85459e812a0193410fb599f0531f22de F test/stmt.test 25d64e3dbf9a3ce89558667d7f39d966fe2a71b9 @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 87bf60637e5863c54c5e2d05aaaca0835b7aace8 -R 69ab88b9bb0a730071944ebfada4d77f +P b30db0ac3096b43d55a6da40cafc7de569082bf8 +R c469588e2189e74bc2d9214e1aed9609 U dan -Z d44703c5b70f5ed4164d3c8bc064c718 +Z 7abd7bfcd6752912e65623c5ee39477d diff --git a/manifest.uuid b/manifest.uuid index ceaaffde0a..081ba3ceea 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b30db0ac3096b43d55a6da40cafc7de569082bf8 \ No newline at end of file +08acfc65877e207f1a62d31a14afb4add20c4c35 \ No newline at end of file diff --git a/test/corruptH.test b/test/corruptH.test index 23f80632b1..875a92f504 100644 --- a/test/corruptH.test +++ b/test/corruptH.test @@ -66,6 +66,7 @@ reset_db # Initialize the database. # do_execsql_test 2.1 { + PRAGMA auto_vacuum=0; PRAGMA page_size=1024; CREATE TABLE t1(a INTEGER PRIMARY KEY, b); diff --git a/test/spellfix.test b/test/spellfix.test index 3e6fdf7eec..21383c2d33 100644 --- a/test/spellfix.test +++ b/test/spellfix.test @@ -234,35 +234,37 @@ do_execsql_test 6.1.3 { SELECT word, distance FROM t3 WHERE rowid = 10 AND word MATCH 'kiiner'; } {keener 300} -proc trace_callback {sql} { - if {[string range $sql 0 2] == "-- "} { - lappend ::trace [string range $sql 3 end] +ifcapable trace { + proc trace_callback {sql} { + if {[string range $sql 0 2] == "-- "} { + lappend ::trace [string range $sql 3 end] + } + } + + proc do_tracesql_test {tn sql {res {}}} { + set ::trace [list] + uplevel [list do_test $tn [subst -nocommands { + set vals [execsql {$sql}] + concat [set vals] [set ::trace] + }] [list {*}$res]] + } + + db trace trace_callback + do_tracesql_test 6.2.1 { + SELECT word FROM t3 WHERE rowid = 10; + } {keener + {SELECT word, rank, NULL, langid, id FROM "main"."t3_vocab" WHERE rowid=?} + } + do_tracesql_test 6.2.2 { + SELECT word, distance FROM t3 WHERE rowid = 10; + } {keener {} + {SELECT word, rank, NULL, langid, id FROM "main"."t3_vocab" WHERE rowid=?} + } + do_tracesql_test 6.2.3 { + SELECT word, distance FROM t3 WHERE rowid = 10 AND word MATCH 'kiiner'; + } {keener 300 + {SELECT id, word, rank, k1 FROM "main"."t3_vocab" WHERE langid=0 AND k2>=?1 AND k2=?1 AND k2 Date: Mon, 27 Jan 2014 13:58:58 +0000 Subject: [PATCH 194/276] Fix (harmless) duplicate variable declaration. FossilOrigin-Name: 94ed9bc4207873e0f3f8114009002f56d5aff359 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbeaux.c | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index ef413f44a3..e7e1dcb4a5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\ssome\sproblems\sin\stest\sscripts.\sNo\scode\schanges. -D 2014-01-27T08:48:10.724 +C Fix\s(harmless)\sduplicate\svariable\sdeclaration. +D 2014-01-27T13:58:58.483 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -284,7 +284,7 @@ F src/vdbe.c 5fe94e13fa56c50edb75263706b6fbcc860a3980 F src/vdbe.h e6c4c610fcabad4fa80ebb1efc6822a9367e2b26 F src/vdbeInt.h 42db251e9f863401ff847b90d5fe1614c89a6a56 F src/vdbeapi.c ce4e68ea4842cc6081046f533d088dcf01d247ad -F src/vdbeaux.c f228f45f5edc8a4cf97e965236519cdcb6baf99b +F src/vdbeaux.c a3327afa8cfcc5bb3d38f2b2a599bac5fb63c6be F src/vdbeblob.c bc40f98f256f0b34116d6a44b114da4a81a15d33 F src/vdbemem.c 23cdc14ed43e0aafa57bd72b9bf3d5b1641afa91 F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147 @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P b30db0ac3096b43d55a6da40cafc7de569082bf8 -R c469588e2189e74bc2d9214e1aed9609 -U dan -Z 7abd7bfcd6752912e65623c5ee39477d +P 08acfc65877e207f1a62d31a14afb4add20c4c35 +R 56b35e8471481c78f01b8967b6b0512c +U drh +Z cff646eb741caa60bf91c3c7dcaf59ea diff --git a/manifest.uuid b/manifest.uuid index 081ba3ceea..6180eadb1e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -08acfc65877e207f1a62d31a14afb4add20c4c35 \ No newline at end of file +94ed9bc4207873e0f3f8114009002f56d5aff359 \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index e06f091aed..69611622af 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2966,8 +2966,8 @@ u32 sqlite3VdbeSerialGet( return 4; } case 5: { /* 6-byte signed integer */ - u64 x = 256*(signed char)buf[0] + buf[1]; - u32 y = ((unsigned)buf[2]<<24) | (buf[3]<<16) | (buf[4]<<8) | buf[5]; + x = 256*(signed char)buf[0] + buf[1]; + y = ((unsigned)buf[2]<<24) | (buf[3]<<16) | (buf[4]<<8) | buf[5]; x = (x<<32) | y; pMem->u.i = *(i64*)&x; pMem->flags = MEM_Int; From d0879bad420fcfe1106b2bbcf71e27af1208055e Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 27 Jan 2014 14:19:22 +0000 Subject: [PATCH 195/276] Fix a problem in pagerfault.test causing an assert() to fail. FossilOrigin-Name: ba8d2d507f82e2baaceadcf7ac6d71bb91f7e06b --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/pagerfault.test | 1 + 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index e7e1dcb4a5..a94442148e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\s(harmless)\sduplicate\svariable\sdeclaration. -D 2014-01-27T13:58:58.483 +C Fix\sa\sproblem\sin\spagerfault.test\scausing\san\sassert()\sto\sfail. +D 2014-01-27T14:19:22.594 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -729,7 +729,7 @@ F test/pager1.test 1acbdb14c5952a72dd43129cabdbf69aaa3ed1fa F test/pager2.test 67b8f40ae98112bcdba1f2b2d03ea83266418c71 F test/pager3.test 3856d9c80839be0668efee1b74811b1b7f7fc95f F test/pager4.test b40ecb4cc7dff957ee7916e41ab21d1ed702a642 -F test/pagerfault.test 7285379906ab2f1108b8e82bbdf2d386cc8ff3ff +F test/pagerfault.test ae9ee0db5a30aecda9db8290ce3dd12e5f7bbaa1 F test/pagerfault2.test caf4c7facb914fd3b03a17b31ae2b180c8d6ca1f F test/pagerfault3.test 1003fcda009bf48a8e22a516e193b6ef0dd1bbd8 F test/pageropt.test 6b8f6a123a5572c195ad4ae40f2987007923bbd6 @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 08acfc65877e207f1a62d31a14afb4add20c4c35 -R 56b35e8471481c78f01b8967b6b0512c -U drh -Z cff646eb741caa60bf91c3c7dcaf59ea +P 94ed9bc4207873e0f3f8114009002f56d5aff359 +R 0be44d42254ead49d986d7d5578b5723 +U dan +Z 0a8e95fd0596f45df583df2ebdde1bb1 diff --git a/manifest.uuid b/manifest.uuid index 6180eadb1e..6a6b134850 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -94ed9bc4207873e0f3f8114009002f56d5aff359 \ No newline at end of file +ba8d2d507f82e2baaceadcf7ac6d71bb91f7e06b \ No newline at end of file diff --git a/test/pagerfault.test b/test/pagerfault.test index 796f531c37..c0f5de69ac 100644 --- a/test/pagerfault.test +++ b/test/pagerfault.test @@ -1544,5 +1544,6 @@ do_faultsim_test pagerfault-36 -prep { sqlite3_shutdown sqlite3_config_uri 0 +sqlite3_initialize finish_test From a820c05aa03d5a7c643af73f35da3f2743bf85f4 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 27 Jan 2014 15:02:07 +0000 Subject: [PATCH 196/276] Update some requirements marks to conform with improvements in the documentation. FossilOrigin-Name: be1acb610f7e594b417dd8409b7a7aa8f3af5f77 --- manifest | 18 +++++++------- manifest.uuid | 2 +- test/e_select.test | 58 ++++++++++++++++++++++----------------------- test/e_select2.test | 30 +++++++++++------------ test/printf2.test | 2 +- 5 files changed, 54 insertions(+), 56 deletions(-) diff --git a/manifest b/manifest index a94442148e..dfa2b5a9f9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\sin\spagerfault.test\scausing\san\sassert()\sto\sfail. -D 2014-01-27T14:19:22.594 +C Update\ssome\srequirements\smarks\sto\sconform\swith\simprovements\nin\sthe\sdocumentation. +D 2014-01-27T15:02:07.424 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -444,8 +444,8 @@ F test/e_fts3.test 5c02288842e4f941896fd44afdef564dd5fc1459 F test/e_insert.test 1e44f84d2abe44d66e4fbf198be4b20e3cc724a0 F test/e_reindex.test 396b7b4f0a66863b4e95116a67d93b227193e589 F test/e_resolve.test dcce9308fb13b934ce29591105d031d3e14fbba6 -F test/e_select.test d3226cb94fae4af3f198e68e71f655e106d0be47 -F test/e_select2.test 22c660a7becf0712c95e1ca1b2d9e716a1261460 +F test/e_select.test 51c062a9bda16e0ae1bbeed50806bedbd040b282 +F test/e_select2.test aceb80ab927d46fba5ce7586ebabf23e2bb0604f F test/e_update.test 312cb8f5ccfe41515a6bb092f8ea562a9bd54d52 F test/e_uri.test a2c92d80093a7efdcfbb11093651cbea87097b6b F test/e_vacuum.test 5bfbdc21b65c0abf24398d0ba31dc88d93ca77a9 @@ -741,7 +741,7 @@ F test/permutations.test af3278cbea3a19e025d5169be8193ff48dc3f862 F test/pragma.test e882183ecd21d064cec5c7aaea174fbd36293429 F test/pragma2.test aea7b3d82c76034a2df2b38a13745172ddc0bc13 F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552 -F test/printf2.test 414fcba6d6c10e0a5e58efd213811e5ead4635a0 +F test/printf2.test bed79b4c3e5da08ba88ad637c0bf62586843cfb1 F test/progress.test a282973d1d17f08071bc58a77d6b80f2a81c354d F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc F test/queryonly.test 5f653159e0f552f0552d43259890c1089391dcca @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 94ed9bc4207873e0f3f8114009002f56d5aff359 -R 0be44d42254ead49d986d7d5578b5723 -U dan -Z 0a8e95fd0596f45df583df2ebdde1bb1 +P ba8d2d507f82e2baaceadcf7ac6d71bb91f7e06b +R 21ce223091709a0563d8c91470de6542 +U drh +Z c5e028d1cb73bb521efada71d2fc02fb diff --git a/manifest.uuid b/manifest.uuid index 6a6b134850..eeb83b19fe 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ba8d2d507f82e2baaceadcf7ac6d71bb91f7e06b \ No newline at end of file +be1acb610f7e594b417dd8409b7a7aa8f3af5f77 \ No newline at end of file diff --git a/test/e_select.test b/test/e_select.test index 61646a2a31..58b8987ba6 100644 --- a/test/e_select.test +++ b/test/e_select.test @@ -333,9 +333,9 @@ do_select_tests e_select-1.1 { 6 "SELECT count(*) WHERE 1" {1} } -# EVIDENCE-OF: R-48114-33255 If there is only a single table in the -# join-source following the FROM clause, then the input data used by the -# SELECT statement is the contents of the named table. +# EVIDENCE-OF: R-45424-07352 If there is only a single table or subquery +# in the FROM clause, then the input data used by the SELECT statement +# is the contents of the named table. # # The results of the SELECT queries suggest that they are operating on the # contents of the table 'xx'. @@ -357,10 +357,10 @@ do_select_tests e_select-1.2 { 3 "SELECT sum(x), sum(y) FROM xx" {-17.89 -16.87} } -# EVIDENCE-OF: R-23593-12456 If there is more than one table specified -# as part of the join-source following the FROM keyword, then the -# contents of each named table are joined into a single dataset for the -# simple SELECT statement to operate on. +# EVIDENCE-OF: R-28355-09804 If there is more than one table or subquery +# in FROM clause then the contents of all tables and/or subqueries are +# joined into a single dataset for the simple SELECT statement to +# operate on. # # There are more detailed tests for subsequent requirements that add # more detail to this idea. We just add a single test that shows that @@ -383,10 +383,10 @@ do_select_tests e_select-1.3 { # of cartesian joins in the SELECT documentation is consistent with SQLite. # In doing so, we test the following three requirements as a side-effect: # -# EVIDENCE-OF: R-46122-14930 If the join-op is "CROSS JOIN", "INNER -# JOIN", "JOIN" or a comma (",") and there is no ON or USING clause, -# then the result of the join is simply the cartesian product of the -# left and right-hand datasets. +# EVIDENCE-OF: R-49872-03192 If the join-operator is "CROSS JOIN", +# "INNER JOIN", "JOIN" or a comma (",") and there is no ON or USING +# clause, then the result of the join is simply the cartesian product of +# the left and right-hand datasets. # # The tests are built on this assertion. Really, they test that the output # of a CROSS JOIN, JOIN, INNER JOIN or "," join matches the expected result @@ -513,11 +513,10 @@ do_select_tests e_select-1.4.5 [list \ 4 { SELECT * FROM t1 AS y INNER JOIN t1 AS x } $t1_cross_t1 \ ] - -# EVIDENCE-OF: R-22775-56496 If there is an ON clause specified, then -# the ON expression is evaluated for each row of the cartesian product -# as a boolean expression. All rows for which the expression evaluates -# to false are excluded from the dataset. +# EVIDENCE-OF: R-38465-03616 If there is an ON clause then the ON +# expression is evaluated for each row of the cartesian product as a +# boolean expression. Only rows for which the expression evaluates to +# true are included from the dataset. # foreach {tn select res} [list \ 1 { SELECT * FROM t1 %JOIN% t2 ON (1) } $t1_cross_t2 \ @@ -540,9 +539,9 @@ foreach {tn select res} [list \ do_join_test e_select-1.3.$tn $select $res } -# EVIDENCE-OF: R-63358-54862 If there is a USING clause specified as -# part of the join-constraint, then each of the column names specified -# must exist in the datasets to both the left and right of the join-op. +# EVIDENCE-OF: R-49933-05137 If there is a USING clause then each of the +# column names specified must exist in the datasets to both the left and +# right of the join-operator. # do_select_tests e_select-1.4 -error { cannot join using column %s - column not present in both tables @@ -552,10 +551,10 @@ do_select_tests e_select-1.4 -error { 3 { SELECT * FROM t3, (SELECT a AS b, b AS c FROM t1) USING (a) } "a" } -# EVIDENCE-OF: R-55987-04584 For each pair of namesake columns, the +# EVIDENCE-OF: R-22776-52830 For each pair of named columns, the # expression "lhs.X = rhs.X" is evaluated for each row of the cartesian -# product as a boolean expression. All rows for which one or more of the -# expressions evaluates to false are excluded from the result set. +# product as a boolean expression. Only rows for which all such +# expressions evaluates to true are included from the result set. # do_select_tests e_select-1.5 { 1 { SELECT * FROM t1, t3 USING (a) } {a one 1 b two 2} @@ -566,8 +565,8 @@ do_select_tests e_select-1.5 { # USING clause, the normal rules for handling affinities, collation # sequences and NULL values in comparisons apply. # -# EVIDENCE-OF: R-35466-18578 The column from the dataset on the -# left-hand side of the join operator is considered to be on the +# EVIDENCE-OF: R-38422-04402 The column from the dataset on the +# left-hand side of the join-operator is considered to be on the # left-hand side of the comparison operator (=) for the purposes of # collation sequence and affinity precedence. # @@ -622,10 +621,9 @@ foreach {tn select res} { } { do_join_test e_select-1.7.$tn $select $res } - -# EVIDENCE-OF: R-41434-12448 If the join-op is a "LEFT JOIN" or "LEFT -# OUTER JOIN", then after the ON or USING filtering clauses have been -# applied, an extra row is added to the output for each row in the +# EVIDENCE-OF: R-42531-52874 If the join-operator is a "LEFT JOIN" or +# "LEFT OUTER JOIN", then after the ON or USING filtering clauses have +# been applied, an extra row is added to the output for each row in the # original left-hand input dataset that corresponds to no rows at all in # the composite dataset (if any). # @@ -660,8 +658,8 @@ do_select_tests e_select-1.9 { 2b "SELECT * FROM t7 LEFT JOIN t8 USING (a)" {x ex 24 abc 24 y why 25 {} {}} } -# EVIDENCE-OF: R-01809-52134 If the NATURAL keyword is added to any of -# the join-ops, then an implicit USING clause is added to the +# EVIDENCE-OF: R-04932-55942 If the NATURAL keyword is in the +# join-operator then an implicit USING clause is added to the # join-constraints. The implicit USING clause contains each of the # column names that appear in both the left and right-hand input # datasets. diff --git a/test/e_select2.test b/test/e_select2.test index a2a32a0503..8330894428 100644 --- a/test/e_select2.test +++ b/test/e_select2.test @@ -344,10 +344,10 @@ foreach {tn indexes} { catchsql { DROP INDEX i3 } execsql $indexes - # EVIDENCE-OF: R-46122-14930 If the join-op is "CROSS JOIN", "INNER - # JOIN", "JOIN" or a comma (",") and there is no ON or USING clause, - # then the result of the join is simply the cartesian product of the - # left and right-hand datasets. + # EVIDENCE-OF: R-49872-03192 If the join-operator is "CROSS JOIN", + # "INNER JOIN", "JOIN" or a comma (",") and there is no ON or USING + # clause, then the result of the join is simply the cartesian product of + # the left and right-hand datasets. # # EVIDENCE-OF: R-46256-57243 There is no difference between the "INNER # JOIN", "JOIN" and "," join operators. @@ -368,10 +368,10 @@ foreach {tn indexes} { test_join $tn.1.11 "t2 CROSS JOIN t2 AS x" {t2 t2} test_join $tn.1.12 "t2 JOIN t2 AS x" {t2 t2} - # EVIDENCE-OF: R-22775-56496 If there is an ON clause specified, then - # the ON expression is evaluated for each row of the cartesian product - # as a boolean expression. All rows for which the expression evaluates - # to false are excluded from the dataset. + # EVIDENCE-OF: R-38465-03616 If there is an ON clause then the ON + # expression is evaluated for each row of the cartesian product as a + # boolean expression. Only rows for which the expression evaluates to + # true are included from the dataset. # test_join $tn.2.1 "t1, t2 ON (t1.a=t2.a)" {t1 t2 -on {te_equals a a}} test_join $tn.2.2 "t2, t1 ON (t1.a=t2.a)" {t2 t1 -on {te_equals a a}} @@ -504,14 +504,14 @@ do_execsql_test e_select-2.2.0 { INSERT INTO t5 VALUES(2, 'two'); } {} -# EVIDENCE-OF: R-55824-40976 A sub-select specified in the join-source -# following the FROM clause in a simple SELECT statement is handled as -# if it was a table containing the data returned by executing the -# sub-select statement. +# EVIDENCE-OF: R-59237-46742 A subquery specified in the +# table-or-subquery following the FROM clause in a simple SELECT +# statement is handled as if it was a table containing the data returned +# by executing the subquery statement. # -# EVIDENCE-OF: R-42612-06757 Each column of the sub-select dataset -# inherits the collation sequence and affinity of the corresponding -# expression in the sub-select statement. +# EVIDENCE-OF: R-27438-53558 Each column of the subquery has the +# collation sequence and affinity of the corresponding expression in the +# subquery statement. # foreach {tn subselect select spec} { 1 "SELECT * FROM t2" "SELECT * FROM t1 JOIN %ss%" diff --git a/test/printf2.test b/test/printf2.test index 8985d083cf..4cb1783bfb 100644 --- a/test/printf2.test +++ b/test/printf2.test @@ -59,7 +59,7 @@ do_execsql_test printf2-1.11 { SELECT printf('%lld%n',314159.2653,'hi'); } {314159} -# EVIDENCE-OF: R-20555-31089 The %z format is interchangable with %s. +# EVIDENCE-OF: R-17002-27534 The %z format is interchangeable with %s. # do_execsql_test printf2-1.12 { SELECT printf('%.*z',5,'abcdefghijklmnop'); From 705a48758a30d07d6a9b8792bd7b91bf2154b2a0 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 27 Jan 2014 16:35:15 +0000 Subject: [PATCH 197/276] Fix a couple of problems with new test scripts causing the permutations test to fail. FossilOrigin-Name: 48d736c0ee1ac0879bd12d2f1901f208e87e538a --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- test/corruptH.test | 27 ++++++++++++++++++++++++++- test/pager4.test | 7 ++++++- 4 files changed, 41 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index dfa2b5a9f9..295364ab48 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\ssome\srequirements\smarks\sto\sconform\swith\simprovements\nin\sthe\sdocumentation. -D 2014-01-27T15:02:07.424 +C Fix\sa\scouple\sof\sproblems\swith\snew\stest\sscripts\scausing\sthe\spermutations\stest\sto\sfail. +D 2014-01-27T16:35:15.028 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -406,7 +406,7 @@ F test/corruptD.test b3c205fac7952b1de645ce44bb02335cd9e3e040 F test/corruptE.test 193b4ca4e927e77c1d5f4f56203ddc998432a7ee F test/corruptF.test be9fde98e4c93648f1ba52b74e5318edc8f59fe4 F test/corruptG.test c150f156dace653c00a121ad0f5772a0568c41ba -F test/corruptH.test 7c02f5d928499bc1b68ed4610bfc2c3f12565a35 +F test/corruptH.test 9d8186f6f8751efdfd445d8546fd98f073499039 F test/count.test 42a251178e32f617eda33f76236a7f79825a50b5 F test/coveridxscan.test cdb47d01acc4a634a34fd25abe85189e0d0f1e62 F test/crash.test fb9dc4a02dcba30d4aa5c2c226f98b220b2b959f @@ -728,7 +728,7 @@ F test/oserror.test 50417780d0e0d7cd23cf12a8277bb44024765df3 F test/pager1.test 1acbdb14c5952a72dd43129cabdbf69aaa3ed1fa F test/pager2.test 67b8f40ae98112bcdba1f2b2d03ea83266418c71 F test/pager3.test 3856d9c80839be0668efee1b74811b1b7f7fc95f -F test/pager4.test b40ecb4cc7dff957ee7916e41ab21d1ed702a642 +F test/pager4.test a122e9e6925d5b23b31e3dfef8c6a44bbf19590e F test/pagerfault.test ae9ee0db5a30aecda9db8290ce3dd12e5f7bbaa1 F test/pagerfault2.test caf4c7facb914fd3b03a17b31ae2b180c8d6ca1f F test/pagerfault3.test 1003fcda009bf48a8e22a516e193b6ef0dd1bbd8 @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P ba8d2d507f82e2baaceadcf7ac6d71bb91f7e06b -R 21ce223091709a0563d8c91470de6542 -U drh -Z c5e028d1cb73bb521efada71d2fc02fb +P be1acb610f7e594b417dd8409b7a7aa8f3af5f77 +R a3dad1261990ae79a41c0830e9dec218 +U dan +Z bcec9d735db62477dd1be5e976533ffa diff --git a/manifest.uuid b/manifest.uuid index eeb83b19fe..fc234874ae 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -be1acb610f7e594b417dd8409b7a7aa8f3af5f77 \ No newline at end of file +48d736c0ee1ac0879bd12d2f1901f208e87e538a \ No newline at end of file diff --git a/test/corruptH.test b/test/corruptH.test index 875a92f504..775c30d2a1 100644 --- a/test/corruptH.test +++ b/test/corruptH.test @@ -96,8 +96,31 @@ do_test 2.2 { sqlite3 db test.db } {} + +# The corruption migration caused by the test case below does not +# cause corruption to be detected in mmap mode. +# +# The trick here is that the root page of the tree scanned by the outer +# query is also currently on the free-list. So while the first seek on +# the table (for a==1) works, by the time the second is attempted The +# "INSERT INTO t2..." statements have recycled the root page of t1 and +# used it as an index leaf. Normally, BtreeMovetoUnpacked() detects +# that the PgHdr object associated with said root page does not match +# the cursor (as it is now marked with PgHdr.intKey==0) and returns +# SQLITE_CORRUPT. +# +# However, in mmap mode, the outer query and the inner queries use +# different PgHdr objects (same data, but different PgHdr container +# objects). And so the corruption is not detected. Instead, the second +# seek fails to find anything and only a single row is returned. +# +set res23 {1 {database disk image is malformed}} +if {[permutation]=="mmap"} { + set res23 {0 one} +} do_test 2.3 { list [catch { + set res [list] db eval { SELECT * FROM t1 WHERE a IN (1, 2) } { db eval { INSERT INTO t2 SELECT randomblob(100) FROM t2; @@ -106,9 +129,11 @@ do_test 2.3 { INSERT INTO t2 SELECT randomblob(100) FROM t2; INSERT INTO t2 SELECT randomblob(100) FROM t2; } + lappend res $b } + set res } msg] $msg -} {1 {database disk image is malformed}} +} $res23 #------------------------------------------------------------------------- reset_db diff --git a/test/pager4.test b/test/pager4.test index edfd2660c2..2cf73d1b17 100644 --- a/test/pager4.test +++ b/test/pager4.test @@ -9,7 +9,7 @@ # #*********************************************************************** # -# Tests for the SQLITE_IOERR_NODB error condition: the database file file +# Tests for the SQLITE_READONLY_DBMOVED error condition: the database file # is unlinked or renamed out from under SQLite. # @@ -18,6 +18,11 @@ if {$tcl_platform(platform)!="unix"} return set testdir [file dirname $argv0] source $testdir/tester.tcl +if {[permutation]=="inmemory_journal"} { + finish_test + return +} + # Create a database file for testing # do_execsql_test pager4-1.1 { From 9c2552f2e856ca7ebab74192dcc6de1493514854 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 28 Jan 2014 17:49:13 +0000 Subject: [PATCH 198/276] Minor bugfix in main.c so that the library builds with SQLITE_OMIT_WSD defined. FossilOrigin-Name: 5e3b9ecc7b2b2e50952de819b99bafdb7b9ff59e --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/main.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 295364ab48..55d11eedcb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\scouple\sof\sproblems\swith\snew\stest\sscripts\scausing\sthe\spermutations\stest\sto\sfail. -D 2014-01-27T16:35:15.028 +C Minor\sbugfix\sin\smain.c\sso\sthat\sthe\slibrary\sbuilds\swith\sSQLITE_OMIT_WSD\sdefined. +D 2014-01-28T17:49:13.545 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -188,7 +188,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b F src/loadext.c 867c7b330b740c6c917af9956b13b81d0a048303 -F src/main.c 4a05a9706579c7649d7eebb0094586728eb53fcb +F src/main.c 07225af6a00be0b7f34ac52e60f99cf5cbb2a475 F src/malloc.c 0203ebce9152c6a0e5de520140b8ba65187350be F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c0c990fcaddff810ea277b4fb5d9138603dd5d4b @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P be1acb610f7e594b417dd8409b7a7aa8f3af5f77 -R a3dad1261990ae79a41c0830e9dec218 +P 48d736c0ee1ac0879bd12d2f1901f208e87e538a +R 2cc45274993cd572752bb3138d773ec9 U dan -Z bcec9d735db62477dd1be5e976533ffa +Z efd313d0ce443bf7542f8c0ae313a99a diff --git a/manifest.uuid b/manifest.uuid index fc234874ae..5b9b68c635 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -48d736c0ee1ac0879bd12d2f1901f208e87e538a \ No newline at end of file +5e3b9ecc7b2b2e50952de819b99bafdb7b9ff59e \ No newline at end of file diff --git a/src/main.c b/src/main.c index 98579105c7..45e31a8076 100644 --- a/src/main.c +++ b/src/main.c @@ -3303,7 +3303,7 @@ int sqlite3_test_control(int op, ...){ ** that demonstrat invariants on well-formed database files. */ case SQLITE_TESTCTRL_NEVER_CORRUPT: { - sqlite3Config.neverCorrupt = va_arg(ap, int); + sqlite3GlobalConfig.neverCorrupt = va_arg(ap, int); break; } From 4d06798e56aaaa1b61b2826acfff9a29829aa6fc Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 28 Jan 2014 18:53:29 +0000 Subject: [PATCH 199/276] Fix a potential over-size and hence undefined shift operation. FossilOrigin-Name: 6379b0729521146bc4ec27a9924492c7dc1d8a31 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/delete.c | 3 ++- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 55d11eedcb..d7f9b6bdb6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\sbugfix\sin\smain.c\sso\sthat\sthe\slibrary\sbuilds\swith\sSQLITE_OMIT_WSD\sdefined. -D 2014-01-28T17:49:13.545 +C Fix\sa\spotential\sover-size\sand\shence\sundefined\sshift\soperation. +D 2014-01-28T18:53:29.749 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -174,7 +174,7 @@ F src/callback.c 174e3c8656bc29f91d710ab61550d16eea34be98 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 -F src/delete.c 22e54756c08b194a29d51cd6552922028b3e21a9 +F src/delete.c d784e2ee2c6e90fbbd9dcf88a2030c9e12a9318d F src/expr.c 96f00a262308f3f97d2afd8519c7a284e25829f3 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 2ab0f5384b70594468ef3ac5c7ed8ca24bfd17d5 @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 48d736c0ee1ac0879bd12d2f1901f208e87e538a -R 2cc45274993cd572752bb3138d773ec9 -U dan -Z efd313d0ce443bf7542f8c0ae313a99a +P 5e3b9ecc7b2b2e50952de819b99bafdb7b9ff59e +R 706dcce3a402caa9db92672703e679ae +U drh +Z e7afb21bdb8343de7138a61b1fa9482c diff --git a/manifest.uuid b/manifest.uuid index 5b9b68c635..7c8d73272d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5e3b9ecc7b2b2e50952de819b99bafdb7b9ff59e \ No newline at end of file +6379b0729521146bc4ec27a9924492c7dc1d8a31 \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index ecf850cf8e..e98ad6d604 100644 --- a/src/delete.c +++ b/src/delete.c @@ -637,7 +637,8 @@ void sqlite3GenerateRowDelete( sqlite3VdbeAddOp2(v, OP_Copy, iPk, iOld); for(iCol=0; iColnCol; iCol++){ testcase( mask!=0xffffffff && iCol==31 ); - if( mask==0xffffffff || (mask & MASKBIT32(iCol))!=0 ){ + testcase( mask!=0xffffffff && iCol==32 ); + if( mask==0xffffffff || (iCol<=31 && (mask & MASKBIT32(iCol))!=0) ){ sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, iCol, iOld+iCol+1); } } From db718d8a3b7e336451afe73707644aae30c6aefe Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 28 Jan 2014 20:36:22 +0000 Subject: [PATCH 200/276] Fix harmless compiler warnings in the showdb utility program. FossilOrigin-Name: 27c27daa3324b7c9323acfb972330367630bb64e --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/showdb.c | 11 +++++------ 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index d7f9b6bdb6..0863208836 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\spotential\sover-size\sand\shence\sundefined\sshift\soperation. -D 2014-01-28T18:53:29.749 +C Fix\sharmless\scompiler\swarnings\sin\sthe\sshowdb\sutility\sprogram. +D 2014-01-28T20:36:22.236 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -1132,7 +1132,7 @@ F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c F tool/pagesig.c ff0ca355fd3c2398e933da5e22439bbff89b803b F tool/restore_jrnl.tcl 6957a34f8f1f0f8285e07536225ec3b292a9024a F tool/rollback-test.c 9fc98427d1e23e84429d7e6d07d9094fbdec65a5 -F tool/showdb.c 525ecc443578647703051308ad50a93de6ba2c4b +F tool/showdb.c 1f3fe634d6f690b8d39ab1b9fd34583d468921e1 F tool/showjournal.c b62cecaab86a4053d944c276bb5232e4d17ece02 F tool/showwal.c 3f7f7da5ec0cba51b1449a75f700493377da57b5 F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 5e3b9ecc7b2b2e50952de819b99bafdb7b9ff59e -R 706dcce3a402caa9db92672703e679ae +P 6379b0729521146bc4ec27a9924492c7dc1d8a31 +R d624107de1307ff82acc1c4254272e47 U drh -Z e7afb21bdb8343de7138a61b1fa9482c +Z ce78bc9f9aa25be3c31879ef495a76f2 diff --git a/manifest.uuid b/manifest.uuid index 7c8d73272d..4b5c72332f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6379b0729521146bc4ec27a9924492c7dc1d8a31 \ No newline at end of file +27c27daa3324b7c9323acfb972330367630bb64e \ No newline at end of file diff --git a/tool/showdb.c b/tool/showdb.c index 27424e0920..4d274a7aac 100644 --- a/tool/showdb.c +++ b/tool/showdb.c @@ -119,7 +119,7 @@ static unsigned char *print_byte_range( /* ** Print an entire page of content as hex */ -static print_page(int iPg){ +static void print_page(int iPg){ int iStart; unsigned char *aData; iStart = (iPg-1)*pagesize; @@ -131,7 +131,7 @@ static print_page(int iPg){ /* Print a line of decode output showing a 4-byte integer. */ -static print_decode_line( +static void print_decode_line( unsigned char *aData, /* Content being decoded */ int ofst, int nByte, /* Start and size of decode */ const char *zMsg /* Message to append */ @@ -428,7 +428,7 @@ static void decode_trunk_page( int detail, /* Show leaf pages if true */ int recursive /* Follow the trunk change if true */ ){ - int n, i, k; + int n, i; unsigned char *a; while( pgno>0 ){ a = getContent((pgno-1)*pagesize, pagesize); @@ -495,7 +495,6 @@ static void page_usage_cell( int cellno /* Index of the cell on the page */ ){ int i; - int nDesc = 0; int n = 0; i64 nPayload; i64 rowid; @@ -677,7 +676,7 @@ static void page_usage_report(const char *zDbName){ if( rc==SQLITE_OK ){ while( sqlite3_step(pStmt)==SQLITE_ROW ){ int pgno = sqlite3_column_int(pStmt, 2); - page_usage_btree(pgno, 0, 0, sqlite3_column_text(pStmt, 1)); + page_usage_btree(pgno, 0, 0, (const char*)sqlite3_column_text(pStmt,1)); } }else{ printf("ERROR: cannot query database: %s\n", sqlite3_errmsg(db)); @@ -835,7 +834,6 @@ int main(int argc, char **argv){ free(a); continue; }else if( zLeft && zLeft[0]=='t' ){ - unsigned char *a; int detail = 0; int recursive = 0; int i; @@ -861,4 +859,5 @@ int main(int argc, char **argv){ } } close(db); + return 0; } From ec2da854122bce8fadfa4480c14d0902dbf2eeff Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 29 Jan 2014 01:46:12 +0000 Subject: [PATCH 201/276] Make sure that sqlite3SelectDup() initializes the nSelectRow of the duplicate Select object. FossilOrigin-Name: 5bb29b82109224a2ad02920658fabd8fb0f27b3f --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 0863208836..1cd51063f2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings\sin\sthe\sshowdb\sutility\sprogram. -D 2014-01-28T20:36:22.236 +C Make\ssure\sthat\ssqlite3SelectDup()\sinitializes\sthe\snSelectRow\sof\sthe\nduplicate\sSelect\sobject. +D 2014-01-29T01:46:12.389 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -175,7 +175,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 F src/delete.c d784e2ee2c6e90fbbd9dcf88a2030c9e12a9318d -F src/expr.c 96f00a262308f3f97d2afd8519c7a284e25829f3 +F src/expr.c e3e09af908b968305d4efeda8dc3499a087ee7d2 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 2ab0f5384b70594468ef3ac5c7ed8ca24bfd17d5 F src/func.c f4499b39d66b71825514334ce67b32ff14bd19f5 @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 6379b0729521146bc4ec27a9924492c7dc1d8a31 -R d624107de1307ff82acc1c4254272e47 +P 27c27daa3324b7c9323acfb972330367630bb64e +R f049cadfe79d3cfbcc34d51b06338c39 U drh -Z ce78bc9f9aa25be3c31879ef495a76f2 +Z 40ce23bc9f3b9d3c5fa7bebae22e1b10 diff --git a/manifest.uuid b/manifest.uuid index 4b5c72332f..a9b235c6f0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -27c27daa3324b7c9323acfb972330367630bb64e \ No newline at end of file +5bb29b82109224a2ad02920658fabd8fb0f27b3f \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index a48a31f932..7323e5d4f7 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1064,6 +1064,7 @@ Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){ pNew->addrOpenEphm[0] = -1; pNew->addrOpenEphm[1] = -1; pNew->addrOpenEphm[2] = -1; + pNew->nSelectRow = p->nSelectRow; pNew->pWith = withDup(db, p->pWith); return pNew; } From b04275121cfd750191011012773aa8509e7d5f47 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Thu, 30 Jan 2014 11:12:52 +0000 Subject: [PATCH 202/276] Enhance the MSVC makefile for better debugging symbol support. FossilOrigin-Name: c723ec2784d6b60c9781a435c84800b2bc7818d5 --- Makefile.msc | 31 +++++++++++++++++++++---------- manifest | 17 ++++++++++------- manifest.uuid | 2 +- 3 files changed, 32 insertions(+), 18 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index 94cd38d0ae..8dce52b5bc 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -270,6 +270,17 @@ TCC = $(TCC) -I$(TOP)\ext\rtree RCC = $(RCC) -I$(TOP)\ext\rtree !ENDIF +# The mksqlite3c.tcl script accepts some options on the command +# line. When compiling with debugging enabled, some of these +# options are necessary in order to allow debugging symbols to +# work correctly with Visual Studio when using the amalgamation. +# +!IF $(DEBUG)>0 +MKSQLITE3C_ARGS = --linemacros +!ELSE +MKSQLITE3C_ARGS = +!ENDIF + # Define -DNDEBUG to compile without debugging (i.e., for production usage) # Omitting the define will cause extra debugging code to be inserted and # includes extra comments when "EXPLAIN stmt" is used. @@ -916,7 +927,7 @@ mptester.exe: $(TOP)\mptest\mptest.c libsqlite3.lib $(LIBRESOBJS) sqlite3.h echo > .target_source sqlite3.c: .target_source $(TOP)\tool\mksqlite3c.tcl - $(TCLSH_CMD) $(TOP)\tool\mksqlite3c.tcl + $(TCLSH_CMD) $(TOP)\tool\mksqlite3c.tcl $(MKSQLITE3C_ARGS) copy tsrc\shell.c . copy tsrc\sqlite3ext.h . @@ -1334,17 +1345,17 @@ sqlite3_analyzer.exe: sqlite3_analyzer.c $(LIBRESOBJS) $(LTLINK) -DBUILD_sqlite -DTCLSH=2 -I$(TCLINCDIR) sqlite3_analyzer.c \ /link $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS) -showdb.exe: $(TOP)\tool\showdb.c sqlite3.c - $(LTLINK) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -o $@ \ - $(TOP)\tool\showdb.c sqlite3.c +showdb.exe: $(TOP)\tool\showdb.c $(SQLITE3C) + $(LTLINK) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \ + $(TOP)\tool\showdb.c $(SQLITE3C) -wordcount.exe: $(TOP)\test\wordcount.c sqlite3.c - $(LTLINK) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -o $@ \ - $(TOP)\test\wordcount.c sqlite3.c +wordcount.exe: $(TOP)\test\wordcount.c $(SQLITE3C) + $(LTLINK) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \ + $(TOP)\test\wordcount.c $(SQLITE3C) -speedtest1.exe: $(TOP)\test\speedtest1.c sqlite3.c - $(LTLINK) -DSQLITE_OMIT_LOAD_EXTENSION -o $@ \ - $(TOP)\test\speedtest1.c sqlite3.c +speedtest1.exe: $(TOP)\test\speedtest1.c $(SQLITE3C) + $(LTLINK) -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \ + $(TOP)\test\speedtest1.c $(SQLITE3C) clean: del /Q *.lo *.ilk *.lib *.obj *.pdb sqlite3.exe libsqlite3.lib diff --git a/manifest b/manifest index 1cd51063f2..c7699c04b5 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Make\ssure\sthat\ssqlite3SelectDup()\sinitializes\sthe\snSelectRow\sof\sthe\nduplicate\sSelect\sobject. -D 2014-01-29T01:46:12.389 +C Enhance\sthe\sMSVC\smakefile\sfor\sbetter\sdebugging\ssymbol\ssupport. +D 2014-01-30T11:12:52.221 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 -F Makefile.msc 4d4ead6b71d1bf03028fbd61da0ba0ec5e1556e1 +F Makefile.msc 6ff3ff2eef45c7dd309a8626ff7947b20bd387e7 F Makefile.vxworks db21ed42a01d5740e656b16f92cb5d8d5e5dd315 F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6 F VERSION 8ed548d87d0a27fd7d7620476f9e25f9fa742d73 @@ -1152,7 +1152,10 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 27c27daa3324b7c9323acfb972330367630bb64e -R f049cadfe79d3cfbcc34d51b06338c39 -U drh -Z 40ce23bc9f3b9d3c5fa7bebae22e1b10 +P 5bb29b82109224a2ad02920658fabd8fb0f27b3f +R e0401798681e1755ee5c5e2fa367c3e2 +T *branch * msvcDebug +T *sym-msvcDebug * +T -sym-trunk * +U mistachkin +Z 7b0fb43b6887cb799be56b64c1e1c153 diff --git a/manifest.uuid b/manifest.uuid index a9b235c6f0..3ede51f527 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5bb29b82109224a2ad02920658fabd8fb0f27b3f \ No newline at end of file +c723ec2784d6b60c9781a435c84800b2bc7818d5 \ No newline at end of file From 81a034b62b8dfbc99154173669638fcaa74af110 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 30 Jan 2014 12:16:23 +0000 Subject: [PATCH 203/276] Do not run test script mmapfault.test as part of the "inmemory_journal" permutation test. FossilOrigin-Name: b222b61a98dc1f3c2c48ea06efe7d82d9fcf4d75 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/permutations.test | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 1cd51063f2..8aafb6e35b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\sthat\ssqlite3SelectDup()\sinitializes\sthe\snSelectRow\sof\sthe\nduplicate\sSelect\sobject. -D 2014-01-29T01:46:12.389 +C Do\snot\srun\stest\sscript\smmapfault.test\sas\spart\sof\sthe\s"inmemory_journal"\spermutation\stest. +D 2014-01-30T12:16:23.545 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -737,7 +737,7 @@ F test/pagesize.test 1dd51367e752e742f58e861e65ed7390603827a0 F test/pcache.test b09104b03160aca0d968d99e8cd2c5b1921a993d F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025 F test/percentile.test b98fc868d71eb5619d42a1702e9ab91718cbed54 -F test/permutations.test af3278cbea3a19e025d5169be8193ff48dc3f862 +F test/permutations.test 40add071ba71aefe1c04f5845308cf46f7de8d04 F test/pragma.test e882183ecd21d064cec5c7aaea174fbd36293429 F test/pragma2.test aea7b3d82c76034a2df2b38a13745172ddc0bc13 F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552 @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 27c27daa3324b7c9323acfb972330367630bb64e -R f049cadfe79d3cfbcc34d51b06338c39 -U drh -Z 40ce23bc9f3b9d3c5fa7bebae22e1b10 +P 5bb29b82109224a2ad02920658fabd8fb0f27b3f +R 084406ca2af9d69eb5b38d017e1e87d2 +U dan +Z c9a3e6c7abdab10d94b6f3e5600f8eec diff --git a/manifest.uuid b/manifest.uuid index a9b235c6f0..76a05f8541 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5bb29b82109224a2ad02920658fabd8fb0f27b3f \ No newline at end of file +b222b61a98dc1f3c2c48ea06efe7d82d9fcf4d75 \ No newline at end of file diff --git a/test/permutations.test b/test/permutations.test index b72d7ad3c7..7f1485f831 100644 --- a/test/permutations.test +++ b/test/permutations.test @@ -642,7 +642,7 @@ test_suite "inmemory_journal" -description { ioerr.test ioerr2.test ioerr3.test ioerr4.test ioerr5.test vacuum3.test incrblob_err.test diskfull.test backup_ioerr.test e_fts3.test fts3cov.test fts3malloc.test fts3rnd.test - fts3snippet.test + fts3snippet.test mmapfault.test # Exclude test scripts that use tcl IO to access journal files or count # the number of fsync() calls. From a88aca5442e8849a65c256f192da2d80b0571e71 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 30 Jan 2014 14:10:00 +0000 Subject: [PATCH 204/276] Update a requirement mark and add some additional test cases to cover the requirement associated with ORDER BY and LIMIT on compound SELECT statements. FossilOrigin-Name: 8560091e85f2f99a24810648868bf2e081c32698 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/e_select.test | 14 ++++++++++++-- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 67bd849e56..d1099a7749 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\sMSVC\smakefile\sfor\sbetter\sdebugging\ssymbol\ssupport. -D 2014-01-30T12:45:32.815 +C Update\sa\srequirement\smark\sand\sadd\ssome\sadditional\stest\scases\sto\scover\nthe\srequirement\sassociated\swith\sORDER\sBY\sand\sLIMIT\son\scompound\sSELECT\nstatements. +D 2014-01-30T14:10:00.638 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -444,7 +444,7 @@ F test/e_fts3.test 5c02288842e4f941896fd44afdef564dd5fc1459 F test/e_insert.test 1e44f84d2abe44d66e4fbf198be4b20e3cc724a0 F test/e_reindex.test 396b7b4f0a66863b4e95116a67d93b227193e589 F test/e_resolve.test dcce9308fb13b934ce29591105d031d3e14fbba6 -F test/e_select.test 51c062a9bda16e0ae1bbeed50806bedbd040b282 +F test/e_select.test 5ea777ed64da80e9555c899418147545672d79e0 F test/e_select2.test aceb80ab927d46fba5ce7586ebabf23e2bb0604f F test/e_update.test 312cb8f5ccfe41515a6bb092f8ea562a9bd54d52 F test/e_uri.test a2c92d80093a7efdcfbb11093651cbea87097b6b @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P b222b61a98dc1f3c2c48ea06efe7d82d9fcf4d75 c723ec2784d6b60c9781a435c84800b2bc7818d5 -R e369e7ab83fcd9b334788d3ecd6a9d15 -U mistachkin -Z 2464332c499b43b0d44ce106a9540b46 +P c9bef0f29a5a7f04914d80e58105104babd4168c +R ae529b38795c843e83dc18ea74bfef1b +U drh +Z 79880c6c4300891d14acd2d52b2dcd6c diff --git a/manifest.uuid b/manifest.uuid index 26473fc0db..772abde600 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c9bef0f29a5a7f04914d80e58105104babd4168c \ No newline at end of file +8560091e85f2f99a24810648868bf2e081c32698 \ No newline at end of file diff --git a/test/e_select.test b/test/e_select.test index 58b8987ba6..4822df5f0b 100644 --- a/test/e_select.test +++ b/test/e_select.test @@ -1371,8 +1371,9 @@ foreach {tn select op1 op2} { do_catchsql_test e_select-7.2.$tn $select [list 1 $err] } -# EVIDENCE-OF: R-22874-32655 ORDER BY and LIMIT clauses may only occur -# at the end of the entire compound SELECT. +# EVIDENCE-OF: R-45440-25633 ORDER BY and LIMIT clauses may only occur +# at the end of the entire compound SELECT, and then only if the final +# element of the compound is not a VALUES clause. # foreach {tn select} { 1 "SELECT * FROM j1 UNION ALL SELECT * FROM j2,j3 ORDER BY a" @@ -1384,6 +1385,7 @@ foreach {tn select} { 7 "SELECT * FROM j1 UNION SELECT * FROM j2,j3 ORDER BY a" 8 "SELECT count(*) FROM j1 UNION SELECT max(e) FROM j2 ORDER BY 1" + 8b "VALUES('8b') UNION SELECT max(e) FROM j2 ORDER BY 1" 9 "SELECT count(*), * FROM j1 UNION SELECT *,* FROM j2 ORDER BY 1,2,3" 10 "SELECT * FROM j1 UNION SELECT * FROM j2,j3 LIMIT 10" 11 "SELECT * FROM j1 UNION SELECT * FROM j2,j3 LIMIT 10 OFFSET 5" @@ -1405,6 +1407,14 @@ foreach {tn select} { } { do_test e_select-7.3.$tn { catch {execsql $select} msg } 0 } +foreach {tn select} { + 50 "SELECT * FROM j1 ORDER BY 1 UNION ALL SELECT * FROM j2,j3" + 51 "SELECT * FROM j1 LIMIT 1 UNION ALL SELECT * FROM j2,j3" + 52 "SELECT count(*) FROM j1 UNION ALL VALUES(11) ORDER BY 1" + 53 "SELECT count(*) FROM j1 UNION ALL VALUES(11) LIMIT 1" +} { + do_test e_select-7.3.$tn { catch {execsql $select} msg } 1 +} # EVIDENCE-OF: R-08531-36543 A compound SELECT created using UNION ALL # operator returns all the rows from the SELECT to the left of the UNION From 9a2555f538d0c77fc1311ef18f3e7cca941ff6af Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 30 Jan 2014 15:03:50 +0000 Subject: [PATCH 205/276] Fix requirements marks only. No changes to code or tests. FossilOrigin-Name: 4a34378b9b02e463081729186dcb9b0404dbcd06 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/e_select.test | 14 +++++++------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index d1099a7749..cc818173f1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sa\srequirement\smark\sand\sadd\ssome\sadditional\stest\scases\sto\scover\nthe\srequirement\sassociated\swith\sORDER\sBY\sand\sLIMIT\son\scompound\sSELECT\nstatements. -D 2014-01-30T14:10:00.638 +C Fix\srequirements\smarks\sonly.\s\sNo\schanges\sto\scode\sor\stests. +D 2014-01-30T15:03:50.330 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -444,7 +444,7 @@ F test/e_fts3.test 5c02288842e4f941896fd44afdef564dd5fc1459 F test/e_insert.test 1e44f84d2abe44d66e4fbf198be4b20e3cc724a0 F test/e_reindex.test 396b7b4f0a66863b4e95116a67d93b227193e589 F test/e_resolve.test dcce9308fb13b934ce29591105d031d3e14fbba6 -F test/e_select.test 5ea777ed64da80e9555c899418147545672d79e0 +F test/e_select.test d159f8b9f4489e6f8ca070b2ca9979206856eb11 F test/e_select2.test aceb80ab927d46fba5ce7586ebabf23e2bb0604f F test/e_update.test 312cb8f5ccfe41515a6bb092f8ea562a9bd54d52 F test/e_uri.test a2c92d80093a7efdcfbb11093651cbea87097b6b @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P c9bef0f29a5a7f04914d80e58105104babd4168c -R ae529b38795c843e83dc18ea74bfef1b +P 8560091e85f2f99a24810648868bf2e081c32698 +R 910df673e4073912e875417aedade94a U drh -Z 79880c6c4300891d14acd2d52b2dcd6c +Z d92a31ea54cc58b07b68e352bd02fd37 diff --git a/manifest.uuid b/manifest.uuid index 772abde600..8dfcce5262 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8560091e85f2f99a24810648868bf2e081c32698 \ No newline at end of file +4a34378b9b02e463081729186dcb9b0404dbcd06 \ No newline at end of file diff --git a/test/e_select.test b/test/e_select.test index 4822df5f0b..d108f9cb7f 100644 --- a/test/e_select.test +++ b/test/e_select.test @@ -464,10 +464,10 @@ do_join_test e_select-1.4.2.1 { ] # TODO: Come back and add a few more like the above. -# EVIDENCE-OF: R-20659-43267 In other words, if the left-hand dataset -# consists of Nlhs rows of Mlhs columns, and the right-hand dataset of -# Nrhs rows of Mrhs columns, then the cartesian product is a dataset of -# Nlhs.Nrhs rows, each containing Mlhs+Mrhs columns. +# EVIDENCE-OF: R-18439-38548 In other words, if the left-hand dataset +# consists of Nleft rows of Mleft columns, and the right-hand dataset of +# Nright rows of Mright columns, then the cartesian product is a dataset +# of Nleft×Nright rows, each containing Mleft+Mright columns. # # x1, x2 (Nlhs=3, Nrhs=2) (Mlhs=2, Mrhs=3) do_join_test e_select-1.4.3.1 { @@ -732,10 +732,10 @@ do_execsql_test e_select-3.0 { INSERT INTO x2 VALUES(7, 'mistrusted', 'standardized'); } {} -# EVIDENCE-OF: R-06999-14330 If a WHERE clause is specified, the WHERE +# EVIDENCE-OF: R-60775-64916 If a WHERE clause is specified, the WHERE # expression is evaluated for each row in the input data as a boolean -# expression. All rows for which the WHERE clause expression evaluates -# to false are excluded from the dataset before continuing. +# expression. Only rows for which the WHERE clause expression evaluates +# to true are included from the dataset before continuing. # do_execsql_test e_select-3.1.1 { SELECT k FROM x1 WHERE x } {3} do_execsql_test e_select-3.1.2 { SELECT k FROM x1 WHERE y } {3 5 6} From bb44b3de399fa298100a6cd8a9d122882cb8a2a0 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 30 Jan 2014 17:47:02 +0000 Subject: [PATCH 206/276] Update evidence marks on SELECT tests. Comment changes only. No changes to code or tests. FossilOrigin-Name: 1973d80e474cb95d053e04415b22154897d4d710 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/e_select.test | 8 ++++---- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index cc818173f1..dca5ddec9b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\srequirements\smarks\sonly.\s\sNo\schanges\sto\scode\sor\stests. -D 2014-01-30T15:03:50.330 +C Update\sevidence\smarks\son\sSELECT\stests.\s\sComment\schanges\sonly.\nNo\schanges\sto\scode\sor\stests. +D 2014-01-30T17:47:02.916 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -444,7 +444,7 @@ F test/e_fts3.test 5c02288842e4f941896fd44afdef564dd5fc1459 F test/e_insert.test 1e44f84d2abe44d66e4fbf198be4b20e3cc724a0 F test/e_reindex.test 396b7b4f0a66863b4e95116a67d93b227193e589 F test/e_resolve.test dcce9308fb13b934ce29591105d031d3e14fbba6 -F test/e_select.test d159f8b9f4489e6f8ca070b2ca9979206856eb11 +F test/e_select.test 52692ff3849541e828ad4661fe3773a9b8711763 F test/e_select2.test aceb80ab927d46fba5ce7586ebabf23e2bb0604f F test/e_update.test 312cb8f5ccfe41515a6bb092f8ea562a9bd54d52 F test/e_uri.test a2c92d80093a7efdcfbb11093651cbea87097b6b @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 8560091e85f2f99a24810648868bf2e081c32698 -R 910df673e4073912e875417aedade94a +P 4a34378b9b02e463081729186dcb9b0404dbcd06 +R 449df259d7d735d626dd09fd972693fc U drh -Z d92a31ea54cc58b07b68e352bd02fd37 +Z a5152c6e4bb0fbba75e0ba888180a1b9 diff --git a/manifest.uuid b/manifest.uuid index 8dfcce5262..62176e10b3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4a34378b9b02e463081729186dcb9b0404dbcd06 \ No newline at end of file +1973d80e474cb95d053e04415b22154897d4d710 \ No newline at end of file diff --git a/test/e_select.test b/test/e_select.test index d108f9cb7f..89d61b53bc 100644 --- a/test/e_select.test +++ b/test/e_select.test @@ -813,8 +813,8 @@ do_select_tests e_select-4.1 { } } -# EVIDENCE-OF: R-61869-22578 It is an error to use a "*" or "alias.*" -# expression in any context other than than a result expression list. +# EVIDENCE-OF: R-38023-18396 It is an error to use a "*" or "alias.*" +# expression in any context other than a result expression list. # # EVIDENCE-OF: R-44324-41166 It is also an error to use a "*" or # "alias.*" expression in a simple SELECT query that does not have a @@ -1007,12 +1007,12 @@ do_execsql_test e_select-4.9.0 { INSERT INTO b3 VALUES('dEF', 'dEF'); } {} -# EVIDENCE-OF: R-57754-57109 If the SELECT statement is an aggregate +# EVIDENCE-OF: R-07284-35990 If the SELECT statement is an aggregate # query with a GROUP BY clause, then each of the expressions specified # as part of the GROUP BY clause is evaluated for each row of the # dataset. Each row is then assigned to a "group" based on the results; # rows for which the results of evaluating the GROUP BY expressions are -# the same are assigned to the same group. +# the same get assigned to the same group. # # These tests also show that the following is not untrue: # From a3fdec717215e16952e87a126f783b342053204e Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 31 Jan 2014 06:35:37 +0000 Subject: [PATCH 207/276] Minor change to TEA extension docs in an attempt to make links work correctly. FossilOrigin-Name: 492585c8208457120dde24f5fbf4db7e4e10ae73 --- autoconf/tea/doc/sqlite3.n | 4 ++-- manifest | 17 ++++++++++------- manifest.uuid | 2 +- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/autoconf/tea/doc/sqlite3.n b/autoconf/tea/doc/sqlite3.n index cee765f94c..13913e5583 100644 --- a/autoconf/tea/doc/sqlite3.n +++ b/autoconf/tea/doc/sqlite3.n @@ -11,5 +11,5 @@ SQLite3 is a self-contains, zero-configuration, transactional SQL database engine. This extension provides an easy to use interface for accessing SQLite database files from Tcl. .PP -For full documentation see http://www.sqlite.org/ and -in particular http://www.sqlite.org/tclsqlite.html. +For full documentation see \fIhttp://www.sqlite.org/\fR and +in particular \fIhttp://www.sqlite.org/tclsqlite.html\fR. diff --git a/manifest b/manifest index dca5ddec9b..aef718c827 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sevidence\smarks\son\sSELECT\stests.\s\sComment\schanges\sonly.\nNo\schanges\sto\scode\sor\stests. -D 2014-01-30T17:47:02.916 +C Minor\schange\sto\sTEA\sextension\sdocs\sin\san\sattempt\sto\smake\slinks\swork\scorrectly. +D 2014-01-31T06:35:37.211 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -27,7 +27,7 @@ F autoconf/tea/Makefile.in 5c3b0bdfb66c20d55ebff59d1718864461570ca9 F autoconf/tea/README 3e9a3c060f29a44344ab50aec506f4db903fb873 F autoconf/tea/aclocal.m4 52c47aac44ce0ddb1f918b6993e8beb8eee88f43 F autoconf/tea/configure.in e0466b881b53f31f5a4a69e7a91ad130902fb359 -F autoconf/tea/doc/sqlite3.n e268faa1691c33663d3a7faf9fa30673d14bd879 +F autoconf/tea/doc/sqlite3.n e1fe45d4f5286ee3d0ccc877aca2a0def488e9bb F autoconf/tea/license.terms 13bd403c9610fd2b76ece0ab50c4c5eda933d523 F autoconf/tea/pkgIndex.tcl.in 3ef61715cf1c7bdcff56947ffadb26bc991ca39d F autoconf/tea/tclconfig/install-sh b087e5c4b92820c60bffb74acc1d9c2d40d80b8f @@ -1152,7 +1152,10 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 4a34378b9b02e463081729186dcb9b0404dbcd06 -R 449df259d7d735d626dd09fd972693fc -U drh -Z a5152c6e4bb0fbba75e0ba888180a1b9 +P 1973d80e474cb95d053e04415b22154897d4d710 +R fbd2e2f50b97b1d4e5868ed74b607215 +T *branch * teaDoc +T *sym-teaDoc * +T -sym-trunk * +U mistachkin +Z 3240d2babdfc522d2f9c123249df16a2 diff --git a/manifest.uuid b/manifest.uuid index 62176e10b3..e3e9f01557 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1973d80e474cb95d053e04415b22154897d4d710 \ No newline at end of file +492585c8208457120dde24f5fbf4db7e4e10ae73 \ No newline at end of file From d49c545968f3a1112eb74cbc09ce1ff5cbc63d50 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 31 Jan 2014 11:50:20 +0000 Subject: [PATCH 208/276] Update the "sqlite3.1" unix manpage document. FossilOrigin-Name: 21ce9e3a53aed62fbe075b0dbed9faa00218aadc --- manifest | 12 +++---- manifest.uuid | 2 +- sqlite3.1 | 96 +++++++++++++++++++++++++++++++++++++++------------ 3 files changed, 80 insertions(+), 30 deletions(-) diff --git a/manifest b/manifest index dca5ddec9b..8f39d5d726 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sevidence\smarks\son\sSELECT\stests.\s\sComment\schanges\sonly.\nNo\schanges\sto\scode\sor\stests. -D 2014-01-30T17:47:02.916 +C Update\sthe\s"sqlite3.1"\sunix\smanpage\sdocument. +D 2014-01-31T11:50:20.694 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -157,7 +157,7 @@ F mptest/mptest.c 499a74af4be293b7c1c7c3d40f332b67227dd739 F mptest/multiwrite01.test 499ad0310da8dff8e8f98d2e272fc2a8aa741b2e F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b -F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc +F sqlite3.1 3d8b83c91651f53472ca17599dae3457b8b89494 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c 2af0330bb1b601af7a7789bf7229675fd772a083 F src/analyze.c 581d5c18ce89c6f45d4dca65914d0de5b4dad41f @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 4a34378b9b02e463081729186dcb9b0404dbcd06 -R 449df259d7d735d626dd09fd972693fc +P 1973d80e474cb95d053e04415b22154897d4d710 +R 42353486be3948c9479e543480f92b29 U drh -Z a5152c6e4bb0fbba75e0ba888180a1b9 +Z 7053d12f62aed1ad53b57dbef8a0decd diff --git a/manifest.uuid b/manifest.uuid index 62176e10b3..79ffce48d2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1973d80e474cb95d053e04415b22154897d4d710 \ No newline at end of file +21ce9e3a53aed62fbe075b0dbed9faa00218aadc \ No newline at end of file diff --git a/sqlite3.1 b/sqlite3.1 index 785995bf60..02df7f44c7 100644 --- a/sqlite3.1 +++ b/sqlite3.1 @@ -2,7 +2,7 @@ .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) -.TH SQLITE3 1 "Mon Apr 15 23:49:17 2002" +.TH SQLITE3 1 "Mon Jan 31 11:14:00 2014" .\" Please adjust this date whenever revising the manpage. .\" .\" Some roff macros, for reference: @@ -49,7 +49,7 @@ a table named "memos" and insert a couple of records into that table: $ .B sqlite3 mydata.db .br -SQLite version 3.1.3 +SQLite version 3.8.3 .br Enter ".help" for instructions .br @@ -108,15 +108,24 @@ sqlite> .B .help .nf .cc | +.backup ?DB? FILE Backup DB (default "main") to FILE +.bail ON|OFF Stop after hitting an error. Default OFF .databases List names and files of attached databases .dump ?TABLE? ... Dump the database in an SQL text format + If TABLE specified, only dump tables matching + LIKE pattern TABLE. .echo ON|OFF Turn command echo on or off .exit Exit this program -.explain ON|OFF Turn output mode suitable for EXPLAIN on or off. +.explain ?ON|OFF? Turn output mode suitable for EXPLAIN on or off. + With no args, it turns EXPLAIN on. .header(s) ON|OFF Turn display of headers on or off .help Show this message .import FILE TABLE Import data from FILE into TABLE -.indices TABLE Show names of all indices on TABLE +.indices ?TABLE? Show names of all indices + If TABLE specified, only show indices for tables + matching LIKE pattern TABLE. +.load FILE ?ENTRY? Load an extension library +.log FILE|off Turn logging on or off. FILE can be stderr/stdout .mode MODE ?TABLE? Set output mode where MODE is one of: csv Comma-separated values column Left-aligned columns. (See .width) @@ -126,46 +135,76 @@ sqlite> list Values delimited by .separator string tabs Tab-separated values tcl TCL list elements -.nullvalue STRING Print STRING in place of NULL values +.nullvalue STRING Use STRING in place of NULL values +.open ?FILENAME? Close existing database and reopen FILENAME .output FILENAME Send output to FILENAME .output stdout Send output to the screen +.print STRING... Print literal STRING .prompt MAIN CONTINUE Replace the standard prompts .quit Exit this program .read FILENAME Execute SQL in FILENAME +.restore ?DB? FILE Restore content of DB (default "main") from FILE .schema ?TABLE? Show the CREATE statements + If TABLE specified, only show tables matching + LIKE pattern TABLE. .separator STRING Change separator used by output mode and .import .show Show the current values for various settings -.tables ?PATTERN? List names of tables matching a LIKE pattern +.stats ON|OFF Turn stats on or off +.tables ?TABLE? List names of tables + If TABLE specified, only list tables matching + LIKE pattern TABLE. .timeout MS Try opening locked tables for MS milliseconds -.width NUM NUM ... Set column widths for "column" mode +.trace FILE|off Output each SQL statement as it is run +.vfsname ?AUX? Print the name of the VFS stack +.width NUM1 NUM2 ... Set column widths for "column" mode +.timer ON|OFF Turn the CPU timer measurement on or off sqlite> |cc . .sp .fi - .SH OPTIONS .B sqlite3 has the following options: .TP -.BI \-init\ file -Read and execute commands from -.I file -, which can contain a mix of SQL statements and meta-commands. +.B \-bail +Stop after hitting an error. .TP -.B \-echo -Print commands before execution. -.TP -.B \-[no]header -Turn headers on or off. +.B \-batch +Force batch I/O. .TP .B \-column Query results will be displayed in a table like form, using whitespace characters to separate the columns and align the output. .TP +.BI \-cmd\ command +run +.I command +before reading stdin +.TP +.B \-csv +Set output mode to CSV (comma separated values). +.TP +.B \-echo +Print commands before execution. +.TP +.BI \-init\ file +Read and execute commands from +.I file +, which can contain a mix of SQL statements and meta-commands. +.TP +.B \-[no]header +Turn headers on or off. +.TP +.B \-help +Show help on options and exit. +.TP .B \-html Query results will be output as simple HTML tables. .TP +.B \-interactive +Force interactive I/O. +.TP .B \-line Query results will be displayed with one value per line, rows separated by a blank line. Designed to be easily parsed by @@ -175,18 +214,28 @@ scripts or other programs Query results will be displayed with the separator (|, by default) character between each field value. The default. .TP -.BI \-separator\ separator -Set output field separator. Default is '|'. +.BI \-mmap\ N +Set default mmap size to +.I N +\. .TP .BI \-nullvalue\ string Set string used to represent NULL values. Default is '' (empty string). .TP +.BI \-separator\ separator +Set output field separator. Default is '|'. +.TP +.B \-stats +Print memory stats before each finalize. +.TP .B \-version Show SQLite version. .TP -.B \-help -Show help on options and exit. +.BI \-vfs\ name +Use +.I name +as the default VFS. .SH INIT FILE @@ -222,8 +271,9 @@ o All other command line options are processed. .SH SEE ALSO http://www.sqlite.org/ .br -The sqlite-doc package +The sqlite3-doc package. .SH AUTHOR This manual page was originally written by Andreas Rottmann , for the Debian GNU/Linux system (but may be used -by others). It was subsequently revised by Bill Bumgarner . +by others). It was subsequently revised by Bill Bumgarner and +further updated by Laszlo Boszormenyi . From 6645370e5b5f28af4d4332242a15e6a327c658f9 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 3 Feb 2014 13:52:03 +0000 Subject: [PATCH 209/276] Version 3.8.3 FossilOrigin-Name: e816dd924619db5f766de6df74ea2194f3e3b538 --- manifest | 12 +++++++----- manifest.uuid | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/manifest b/manifest index a5ad7c93cb..e648887520 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\schange\sto\sTEA\sextension\sdocs\sin\san\sattempt\sto\smake\slinks\swork\scorrectly. -D 2014-02-03T13:49:40.898 +C Version\s3.8.3 +D 2014-02-03T13:52:03.248 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -1152,8 +1152,10 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 21ce9e3a53aed62fbe075b0dbed9faa00218aadc 492585c8208457120dde24f5fbf4db7e4e10ae73 +P af3c775e5d6a399bfc985a5dae27451908766546 R d59f4c16611ef76ed43b5f579f765c07 -T +closed 492585c8208457120dde24f5fbf4db7e4e10ae73 +T +bgcolor * #d0c0ff +T +sym-release * +T +sym-version-3.8.3 * U drh -Z 2bef28b38855e6ad6cb1516abae9de60 +Z be66093eab6507921c2b573a40e5f8d7 diff --git a/manifest.uuid b/manifest.uuid index 78402db31e..514369c84f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -af3c775e5d6a399bfc985a5dae27451908766546 \ No newline at end of file +e816dd924619db5f766de6df74ea2194f3e3b538 \ No newline at end of file From e39a732ce236ae1c1baf0b2dca7dfc0f46067551 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 3 Feb 2014 14:04:11 +0000 Subject: [PATCH 210/276] Provide hints to the btree layer Next and Previous primitives to let them know if they can be no-ops if the underlying index is unique. FossilOrigin-Name: 6c643e45c274e755dc5a1a65673df79261c774be --- manifest | 22 ++++++++++------------ manifest.uuid | 2 +- src/btree.c | 22 +++++++++++++++++++++- src/vdbe.c | 23 +++++++++++++++++++---- src/where.c | 15 +++++++++------ src/whereInt.h | 3 ++- 6 files changed, 62 insertions(+), 25 deletions(-) diff --git a/manifest b/manifest index e648887520..90c123fd33 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Version\s3.8.3 -D 2014-02-03T13:52:03.248 +C Provide\shints\sto\sthe\sbtree\slayer\sNext\sand\sPrevious\sprimitives\sto\slet\sthem\s\nknow\sif\sthey\scan\sbe\sno-ops\sif\sthe\sunderlying\sindex\sis\sunique. +D 2014-02-03T14:04:11.993 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,7 +166,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c a729e63cf5cd1829507cb7b8e89f99b95141bb53 F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c 02e1a4e71d8fc37e9fd5216c15d989d148a77c87 +F src/btree.c 7b2c3cd16deedff7f4904f2e871e7b77328b9872 F src/btree.h a61ddebc78c66795a2b93181321a116746302cc9 F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0 F src/build.c 7e6c275ab1731510d6f793d0f88373ab3e858e69 @@ -280,7 +280,7 @@ F src/update.c a7df6fffce6bfedc578fda6136dd33e34a63f8ee F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c 15ac2627f548f5481d0d7e6c4eb67be673027695 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c 5fe94e13fa56c50edb75263706b6fbcc860a3980 +F src/vdbe.c e703913e9a3b56d7824f3eb8b76d99f496ff6dc1 F src/vdbe.h e6c4c610fcabad4fa80ebb1efc6822a9367e2b26 F src/vdbeInt.h 42db251e9f863401ff847b90d5fe1614c89a6a56 F src/vdbeapi.c ce4e68ea4842cc6081046f533d088dcf01d247ad @@ -293,8 +293,8 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45 -F src/where.c 67ae3b5e97ecff36c70cb61ccc7d74cf228f1596 -F src/whereInt.h 96a75c61f1d2b9d4a8e4bb17d89deb0cf7cba358 +F src/where.c bacb79fb31e082c9c599e68e5e9f161e1d5430ca +F src/whereInt.h 921f935af8b684ffb49705610bda7284db1db138 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6 @@ -1152,10 +1152,8 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P af3c775e5d6a399bfc985a5dae27451908766546 -R d59f4c16611ef76ed43b5f579f765c07 -T +bgcolor * #d0c0ff -T +sym-release * -T +sym-version-3.8.3 * +P e816dd924619db5f766de6df74ea2194f3e3b538 +Q +a2c347faf91d82cf8734621bf378a6dd68b00957 +R be5a44c31c2829557525011b36aec00e U drh -Z be66093eab6507921c2b573a40e5f8d7 +Z 23965260487a528a52632de193207045 diff --git a/manifest.uuid b/manifest.uuid index 514369c84f..243bc6de49 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e816dd924619db5f766de6df74ea2194f3e3b538 \ No newline at end of file +6c643e45c274e755dc5a1a65673df79261c774be \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 032f3d8c78..cf135b1e14 100644 --- a/src/btree.c +++ b/src/btree.c @@ -4777,6 +4777,15 @@ int sqlite3BtreeEof(BtCursor *pCur){ ** successful then set *pRes=0. If the cursor ** was already pointing to the last entry in the database before ** this routine was called, then set *pRes=1. +** +** The calling function will set *pRes to 0 or 1. The initial *pRes value +** will be 1 if the cursor being stepped corresponds to an SQL index and +** if this routine could have been skipped if that SQL index had been +** a unique index. Otherwise the caller will have set *pRes to zero. +** Zero is the common case. The btree implementation is free to use the +** initial *pRes value as a hint to improve performance, but the current +** SQLite btree implementation does not. (Note that the comdb2 btree +** implementation does use this hint, however.) */ int sqlite3BtreeNext(BtCursor *pCur, int *pRes){ int rc; @@ -4785,6 +4794,7 @@ int sqlite3BtreeNext(BtCursor *pCur, int *pRes){ assert( cursorHoldsMutex(pCur) ); assert( pRes!=0 ); + assert( *pRes==0 || *pRes==1 ); assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID ); if( pCur->eState!=CURSOR_VALID ){ rc = restoreCursorPosition(pCur); @@ -4863,6 +4873,15 @@ int sqlite3BtreeNext(BtCursor *pCur, int *pRes){ ** successful then set *pRes=0. If the cursor ** was already pointing to the first entry in the database before ** this routine was called, then set *pRes=1. +** +** The calling function will set *pRes to 0 or 1. The initial *pRes value +** will be 1 if the cursor being stepped corresponds to an SQL index and +** if this routine could have been skipped if that SQL index had been +** a unique index. Otherwise the caller will have set *pRes to zero. +** Zero is the common case. The btree implementation is free to use the +** initial *pRes value as a hint to improve performance, but the current +** SQLite btree implementation does not. (Note that the comdb2 btree +** implementation does use this hint, however.) */ int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){ int rc; @@ -4870,6 +4889,7 @@ int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){ assert( cursorHoldsMutex(pCur) ); assert( pRes!=0 ); + assert( *pRes==0 || *pRes==1 ); assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID ); pCur->atLast = 0; if( pCur->eState!=CURSOR_VALID ){ @@ -7096,7 +7116,7 @@ int sqlite3BtreeDelete(BtCursor *pCur){ ** sub-tree headed by the child page of the cell being deleted. This makes ** balancing the tree following the delete operation easier. */ if( !pPage->leaf ){ - int notUsed; + int notUsed = 0; rc = sqlite3BtreePrevious(pCur, ¬Used); if( rc ) return rc; } diff --git a/src/vdbe.c b/src/vdbe.c index 30c9269ea4..037b02f12a 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3599,6 +3599,7 @@ case OP_SeekGt: { /* jump, in3 */ #endif if( oc>=OP_SeekGe ){ assert( oc==OP_SeekGe || oc==OP_SeekGt ); if( res<0 || (res==0 && oc==OP_SeekGt) ){ + res = 0; rc = sqlite3BtreeNext(pC->pCursor, &res); if( rc!=SQLITE_OK ) goto abort_due_to_error; pC->rowidIsValid = 0; @@ -3608,6 +3609,7 @@ case OP_SeekGt: { /* jump, in3 */ }else{ assert( oc==OP_SeekLt || oc==OP_SeekLe ); if( res>0 || (res==0 && oc==OP_SeekLt) ){ + res = 0; rc = sqlite3BtreePrevious(pC->pCursor, &res); if( rc!=SQLITE_OK ) goto abort_due_to_error; pC->rowidIsValid = 0; @@ -4460,7 +4462,7 @@ case OP_Rewind: { /* jump */ break; } -/* Opcode: Next P1 P2 * * P5 +/* Opcode: Next P1 P2 P3 * P5 ** ** Advance cursor P1 so that it points to the next key/data pair in its ** table or index. If there are no more key/value pairs then fall through @@ -4470,6 +4472,11 @@ case OP_Rewind: { /* jump */ ** The P1 cursor must be for a real table, not a pseudo-table. P1 must have ** been opened prior to this opcode or the program will segfault. ** +** The P3 value is a hint to the btree implementation. If P3==1, that +** means P1 is an SQL index and that this instruction could have been +** omitted if that index had been unique. P3 is usually 0. P3 is +** always either 0 or 1. +** ** P4 is always of type P4_ADVANCE. The function pointer points to ** sqlite3BtreeNext(). ** @@ -4478,12 +4485,12 @@ case OP_Rewind: { /* jump */ ** ** See also: Prev, NextIfOpen */ -/* Opcode: NextIfOpen P1 P2 * * P5 +/* Opcode: NextIfOpen P1 P2 P3 * P5 ** ** This opcode works just like OP_Next except that if cursor P1 is not ** open it behaves a no-op. */ -/* Opcode: Prev P1 P2 * * P5 +/* Opcode: Prev P1 P2 P3 * P5 ** ** Back up cursor P1 so that it points to the previous key/data pair in its ** table or index. If there is no previous key/value pairs then fall through @@ -4493,13 +4500,18 @@ case OP_Rewind: { /* jump */ ** The P1 cursor must be for a real table, not a pseudo-table. If P1 is ** not open then the behavior is undefined. ** +** The P3 value is a hint to the btree implementation. If P3==1, that +** means P1 is an SQL index and that this instruction could have been +** omitted if that index had been unique. P3 is usually 0. P3 is +** always either 0 or 1. +** ** P4 is always of type P4_ADVANCE. The function pointer points to ** sqlite3BtreePrevious(). ** ** If P5 is positive and the jump is taken, then event counter ** number P5-1 in the prepared statement is incremented. */ -/* Opcode: PrevIfOpen P1 P2 * * P5 +/* Opcode: PrevIfOpen P1 P2 P3 * P5 ** ** This opcode works just like OP_Prev except that if cursor P1 is not ** open it behaves a no-op. @@ -4521,9 +4533,12 @@ case OP_Next: /* jump */ assert( pOp->p1>=0 && pOp->p1nCursor ); assert( pOp->p5aCounter) ); pC = p->apCsr[pOp->p1]; + res = pOp->p3; assert( pC!=0 ); assert( pC->deferredMoveto==0 ); assert( pC->pCursor ); + assert( res==0 || (res==1 && pC->isTable==0) ); + testcase( res==1 ); assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext ); assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious ); assert( pOp->opcode!=OP_NextIfOpen || pOp->p4.xAdvance==sqlite3BtreeNext ); diff --git a/src/where.c b/src/where.c index 6fac5e5ed1..a900dd0b84 100644 --- a/src/where.c +++ b/src/where.c @@ -3184,6 +3184,8 @@ static Bitmask codeOneLoopStart( pLevel->op = OP_Next; } pLevel->p1 = iIdxCur; + assert( (WHERE_UNQ_WANTED>>16)==1 ); + pLevel->p3 = (pLoop->wsFlags>>16)&1; if( (pLoop->wsFlags & WHERE_CONSTRAINT)==0 ){ pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP; }else{ @@ -3986,12 +3988,13 @@ static int whereLoopAddBtreeIndex( || nInMul==0 ); pNew->wsFlags |= WHERE_COLUMN_EQ; - if( iCol<0 - || (pProbe->onError!=OE_None && nInMul==0 - && pNew->u.btree.nEq==pProbe->nKeyCol-1) - ){ + if( iCol<0 || (nInMul==0 && pNew->u.btree.nEq==pProbe->nKeyCol-1)){ assert( (pNew->wsFlags & WHERE_COLUMN_IN)==0 || iCol<0 ); - pNew->wsFlags |= WHERE_ONEROW; + if( iCol>=0 && pProbe->onError==OE_None ){ + pNew->wsFlags |= WHERE_UNQ_WANTED; + }else{ + pNew->wsFlags |= WHERE_ONEROW; + } } pNew->u.btree.nEq++; pNew->nOut = nRowEst + nInMul; @@ -5785,7 +5788,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ pLoop = pLevel->pWLoop; sqlite3VdbeResolveLabel(v, pLevel->addrCont); if( pLevel->op!=OP_Noop ){ - sqlite3VdbeAddOp2(v, pLevel->op, pLevel->p1, pLevel->p2); + sqlite3VdbeAddOp3(v, pLevel->op, pLevel->p1, pLevel->p2, pLevel->p3); sqlite3VdbeChangeP5(v, pLevel->p5); } if( pLoop->wsFlags & WHERE_IN_ABLE && pLevel->u.in.nIn>0 ){ diff --git a/src/whereInt.h b/src/whereInt.h index 56646c55e6..23f929c461 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -70,7 +70,7 @@ struct WhereLevel { int addrFirst; /* First instruction of interior of the loop */ int addrBody; /* Beginning of the body of this loop */ u8 iFrom; /* Which entry in the FROM clause */ - u8 op, p5; /* Opcode and P5 of the opcode that ends the loop */ + u8 op, p3, p5; /* Opcode, P3 & P5 of the opcode that ends the loop */ int p1, p2; /* Operands of the opcode used to ends the loop */ union { /* Information that depends on pWLoop->wsFlags */ struct { @@ -457,3 +457,4 @@ struct WhereInfo { #define WHERE_MULTI_OR 0x00002000 /* OR using multiple indices */ #define WHERE_AUTO_INDEX 0x00004000 /* Uses an ephemeral index */ #define WHERE_SKIPSCAN 0x00008000 /* Uses the skip-scan algorithm */ +#define WHERE_UNQ_WANTED 0x00010000 /* WHERE_ONEROW would have been helpful*/ From fe21a796f7af89c7bf6c588f28a2a2d3f646218f Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 3 Feb 2014 17:04:29 +0000 Subject: [PATCH 211/276] Performance optimizations in sqlite3PcacheFetch(). FossilOrigin-Name: b60cc11ef775c23a2245d9e7a00dab34013f3ccb --- manifest | 13 ++++++------- manifest.uuid | 2 +- src/pcache.c | 34 ++++++++++++++++++++++++++-------- 3 files changed, 33 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index 90c123fd33..8ed9435be8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Provide\shints\sto\sthe\sbtree\slayer\sNext\sand\sPrevious\sprimitives\sto\slet\sthem\s\nknow\sif\sthey\scan\sbe\sno-ops\sif\sthe\sunderlying\sindex\sis\sunique. -D 2014-02-03T14:04:11.993 +C Performance\soptimizations\sin\ssqlite3PcacheFetch(). +D 2014-02-03T17:04:29.099 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -210,7 +210,7 @@ F src/os_win.c 1b21af72c5fa6f9e519a5fcab33e80d182b1aedb F src/pager.c efa923693e958696eee69b205a20bfbc402c8480 F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428 F src/parse.y bd51bc17cbfe7549adb4ca3747b1c3d384645065 -F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 +F src/pcache.c d8eafac28290d4bb80332005435db44991d07fc2 F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222 F src/pcache1.c 102e6f5a2fbc646154463eb856d1fd716867b64c F src/pragma.c ed409ce4104cf4d9de6ead40ace70974f124853b @@ -1152,8 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P e816dd924619db5f766de6df74ea2194f3e3b538 -Q +a2c347faf91d82cf8734621bf378a6dd68b00957 -R be5a44c31c2829557525011b36aec00e +P 6c643e45c274e755dc5a1a65673df79261c774be +R 8b5419aed1d20751ed2fa03b47b5e0a6 U drh -Z 23965260487a528a52632de193207045 +Z f3fb6a665960323d1a0ee233aafe4773 diff --git a/manifest.uuid b/manifest.uuid index 243bc6de49..bad810a1b8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6c643e45c274e755dc5a1a65673df79261c774be \ No newline at end of file +b60cc11ef775c23a2245d9e7a00dab34013f3ccb \ No newline at end of file diff --git a/src/pcache.c b/src/pcache.c index 482a188bee..e18bf93be0 100644 --- a/src/pcache.c +++ b/src/pcache.c @@ -23,7 +23,8 @@ struct PCache { int szCache; /* Configured cache size */ int szPage; /* Size of every page in this cache */ int szExtra; /* Size of extra space for each page */ - int bPurgeable; /* True if pages are on backing store */ + u8 bPurgeable; /* True if pages are on backing store */ + u8 eCreate; /* eCreate value for for xFetch() */ int (*xStress)(void*,PgHdr*); /* Call to try make a page clean */ void *pStress; /* Argument to xStress */ sqlite3_pcache *pCache; /* Pluggable cache module */ @@ -90,6 +91,10 @@ static void pcacheRemoveFromDirtyList(PgHdr *pPage){ }else{ assert( pPage==p->pDirty ); p->pDirty = pPage->pDirtyNext; + if( p->pDirty==0 && p->bPurgeable ){ + assert( p->eCreate==1 ); + p->eCreate = 2; + } } pPage->pDirtyNext = 0; pPage->pDirtyPrev = 0; @@ -110,6 +115,9 @@ static void pcacheAddToDirtyList(PgHdr *pPage){ if( pPage->pDirtyNext ){ assert( pPage->pDirtyNext->pDirtyPrev==0 ); pPage->pDirtyNext->pDirtyPrev = pPage; + }else if( p->bPurgeable ){ + assert( p->eCreate==2 ); + p->eCreate = 1; } p->pDirty = pPage; if( !p->pDirtyTail ){ @@ -179,6 +187,7 @@ void sqlite3PcacheOpen( p->szPage = szPage; p->szExtra = szExtra; p->bPurgeable = bPurgeable; + p->eCreate = 2; p->xStress = xStress; p->pStress = pStress; p->szCache = 100; @@ -218,7 +227,7 @@ int sqlite3PcacheFetch( int createFlag, /* If true, create page if it does not exist already */ PgHdr **ppPage /* Write the page here */ ){ - sqlite3_pcache_page *pPage = 0; + sqlite3_pcache_page *pPage; PgHdr *pPgHdr = 0; int eCreate; @@ -229,8 +238,12 @@ int sqlite3PcacheFetch( /* If the pluggable cache (sqlite3_pcache*) has not been allocated, ** allocate it now. */ - if( !pCache->pCache && createFlag ){ + if( !pCache->pCache ){ sqlite3_pcache *p; + if( !createFlag ){ + *ppPage = 0; + return SQLITE_OK; + } p = sqlite3GlobalConfig.pcache2.xCreate( pCache->szPage, pCache->szExtra + sizeof(PgHdr), pCache->bPurgeable ); @@ -241,11 +254,16 @@ int sqlite3PcacheFetch( pCache->pCache = p; } - eCreate = createFlag * (1 + (!pCache->bPurgeable || !pCache->pDirty)); - if( pCache->pCache ){ - pPage = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, eCreate); - } - + /* eCreate defines what to do if the page does not exist. + ** 0 Do not allocate a new page. (createFlag==0) + ** 1 Allocate a new page if doing so is inexpensive. + ** (createFlag==1 AND bPurgeable AND pDirty) + ** 2 Allocate a new page even it doing so is difficult. + ** (createFlag==1 AND !(bPurgeable AND pDirty) + */ + eCreate = createFlag==0 ? 0 : pCache->eCreate; + assert( (createFlag*(1+(!pCache->bPurgeable||!pCache->pDirty)))==eCreate ); + pPage = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, eCreate); if( !pPage && eCreate==1 ){ PgHdr *pPg; From 7df89c8c8a9a9e6232e602e102edfdbcbfb8f1af Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 4 Feb 2014 15:55:25 +0000 Subject: [PATCH 212/276] Rearrange fields in the Parse object for a tighter packing, resulting in an 8% size reduction on x64. FossilOrigin-Name: 3e1a3f68d7457ff708222a3448404b593f018fc2 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqliteInt.h | 18 +++++++++++------- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 8ed9435be8..be9aa406a7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\soptimizations\sin\ssqlite3PcacheFetch(). -D 2014-02-03T17:04:29.099 +C Rearrange\sfields\sin\sthe\sParse\sobject\sfor\sa\stighter\spacking,\sresulting\sin\nan\s8%\ssize\sreduction\son\sx64. +D 2014-02-04T15:55:25.100 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -224,7 +224,7 @@ F src/shell.c 24722d24d4ea8ca93db35e44db7308de786767ca F src/sqlite.h.in eed7f7d66a60daaa7b4a597dcd9bad87aad9611b F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h 22c8f7112f2fa8e778bbd9d331cbebff8c645574 +F src/sqliteInt.h ee8b7647d02470e75b4fc0e8a06b2f178d994670 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 6c643e45c274e755dc5a1a65673df79261c774be -R 8b5419aed1d20751ed2fa03b47b5e0a6 +P b60cc11ef775c23a2245d9e7a00dab34013f3ccb +R 9fefa46640582f27b969bb2001156b91 U drh -Z f3fb6a665960323d1a0ee233aafe4773 +Z b3499e6545a6347f51724280bec4401e diff --git a/manifest.uuid b/manifest.uuid index bad810a1b8..e9d58ea3e5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b60cc11ef775c23a2245d9e7a00dab34013f3ccb \ No newline at end of file +3e1a3f68d7457ff708222a3448404b593f018fc2 \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index f58d826788..0d1342a56a 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2358,22 +2358,23 @@ struct Parse { int nSet; /* Number of sets used so far */ int nOnce; /* Number of OP_Once instructions so far */ int nOpAlloc; /* Number of slots allocated for Vdbe.aOp[] */ - int nLabel; /* Number of labels used */ - int *aLabel; /* Space to hold the labels */ int iFixedOp; /* Never back out opcodes iFixedOp-1 or earlier */ int ckBase; /* Base register of data during check constraints */ int iPartIdxTab; /* Table corresponding to a partial index */ int iCacheLevel; /* ColCache valid when aColCache[].iLevel<=iCacheLevel */ int iCacheCnt; /* Counter used to generate aColCache[].lru values */ + int nLabel; /* Number of labels used */ + int *aLabel; /* Space to hold the labels */ struct yColCache { int iTable; /* Table cursor number */ - int iColumn; /* Table column number */ + i16 iColumn; /* Table column number */ u8 tempReg; /* iReg is a temp register that needs to be freed */ int iLevel; /* Nesting level */ int iReg; /* Reg with value of this column. 0 means none. */ int lru; /* Least recently used entry has the smallest value */ } aColCache[SQLITE_N_COLCACHE]; /* One for each column cache entry */ ExprList *pConstExpr;/* Constant expressions */ + Token constraintName;/* Name of the constraint currently being parsed */ yDbMask writeMask; /* Start a write transaction on these databases */ yDbMask cookieMask; /* Bitmask of schema verified databases */ int cookieGoto; /* Address of OP_Goto to cookie verifier subroutine */ @@ -2381,7 +2382,6 @@ struct Parse { int regRowid; /* Register holding rowid of CREATE TABLE entry */ int regRoot; /* Register holding root page number for new objects */ int nMaxArg; /* Max args passed to user function by sub-program */ - Token constraintName;/* Name of the constraint currently being parsed */ #ifndef SQLITE_OMIT_SHARED_CACHE int nTableLock; /* Number of locks in aTableLock */ TableLock *aTableLock; /* Required table locks for shared-cache mode */ @@ -2400,12 +2400,17 @@ struct Parse { u8 eOrconf; /* Default ON CONFLICT policy for trigger steps */ u8 disableTriggers; /* True to disable triggers */ - /* Above is constant between recursions. Below is reset before and after - ** each recursion */ + /************************************************************************ + ** Above is constant between recursions. Below is reset before and after + ** each recursion. The boundary between these two regions is determined + ** using offsetof(Parse,nVar) so the nVar field must be the first field + ** in the recursive region. + ************************************************************************/ int nVar; /* Number of '?' variables seen in the SQL so far */ int nzVar; /* Number of available slots in azVar[] */ u8 iPkSortOrder; /* ASC or DESC for INTEGER PRIMARY KEY */ + u8 bFreeWith; /* True if pWith should be freed with parser */ u8 explain; /* True if the EXPLAIN flag is found on the query */ #ifndef SQLITE_OMIT_VIRTUALTABLE u8 declareVtab; /* True if inside sqlite3_declare_vtab() */ @@ -2432,7 +2437,6 @@ struct Parse { Table *pZombieTab; /* List of Table objects to delete after code gen */ TriggerPrg *pTriggerPrg; /* Linked list of coded triggers */ With *pWith; /* Current WITH clause, or NULL */ - u8 bFreeWith; /* True if pWith should be freed with parser */ }; /* From ee06c99b49e5812403eb2b2762da4d5fee4e4d18 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 4 Feb 2014 20:46:41 +0000 Subject: [PATCH 213/276] Remove the SF_Materialize flag from the SELECT object as it does not accomplish anything useful. FossilOrigin-Name: 65d5dcddbd34dfb2733a7a908c7c652ce2d610fe --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/delete.c | 5 ----- src/select.c | 4 ++-- src/sqliteInt.h | 2 +- 5 files changed, 12 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index be9aa406a7..95aa7f83ef 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Rearrange\sfields\sin\sthe\sParse\sobject\sfor\sa\stighter\spacking,\sresulting\sin\nan\s8%\ssize\sreduction\son\sx64. -D 2014-02-04T15:55:25.100 +C Remove\sthe\sSF_Materialize\sflag\sfrom\sthe\sSELECT\sobject\sas\sit\sdoes\snot\naccomplish\sanything\suseful. +D 2014-02-04T20:46:41.282 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -174,7 +174,7 @@ F src/callback.c 174e3c8656bc29f91d710ab61550d16eea34be98 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 -F src/delete.c d784e2ee2c6e90fbbd9dcf88a2030c9e12a9318d +F src/delete.c 6765a421f08adbedc5d52d21760ec6dbe5123fd3 F src/expr.c e3e09af908b968305d4efeda8dc3499a087ee7d2 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 2ab0f5384b70594468ef3ac5c7ed8ca24bfd17d5 @@ -219,12 +219,12 @@ F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c a421f3fb7f52a3c0b37f5caeabd27799e8a9ae58 +F src/select.c b78f5e62c283aca2e38657938bc1fec1051df728 F src/shell.c 24722d24d4ea8ca93db35e44db7308de786767ca F src/sqlite.h.in eed7f7d66a60daaa7b4a597dcd9bad87aad9611b F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h ee8b7647d02470e75b4fc0e8a06b2f178d994670 +F src/sqliteInt.h fdab572b3567d587cf3096e3ca5dabcedda3fa66 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P b60cc11ef775c23a2245d9e7a00dab34013f3ccb -R 9fefa46640582f27b969bb2001156b91 +P 3e1a3f68d7457ff708222a3448404b593f018fc2 +R ade75eb85514e63b06c7a5a5e6c85df2 U drh -Z b3499e6545a6347f51724280bec4401e +Z e551af7aa0a37f40c066574f60e01273 diff --git a/manifest.uuid b/manifest.uuid index e9d58ea3e5..bb6a8f738c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3e1a3f68d7457ff708222a3448404b593f018fc2 \ No newline at end of file +65d5dcddbd34dfb2733a7a908c7c652ce2d610fe \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index e98ad6d604..936517c4a7 100644 --- a/src/delete.c +++ b/src/delete.c @@ -97,10 +97,8 @@ void sqlite3MaterializeView( SrcList *pFrom; sqlite3 *db = pParse->db; int iDb = sqlite3SchemaToIndex(db, pView->pSchema); - pWhere = sqlite3ExprDup(db, pWhere, 0); pFrom = sqlite3SrcListAppend(db, 0, 0, 0); - if( pFrom ){ assert( pFrom->nSrc==1 ); pFrom->a[0].zName = sqlite3DbStrDup(db, pView->zName); @@ -108,10 +106,7 @@ void sqlite3MaterializeView( assert( pFrom->a[0].pOn==0 ); assert( pFrom->a[0].pUsing==0 ); } - pSel = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, 0, 0, 0, 0); - if( pSel ) pSel->selFlags |= SF_Materialize; - sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur); sqlite3Select(pParse, pSel, &dest); sqlite3SelectDelete(db, pSel); diff --git a/src/select.c b/src/select.c index c78d997806..f923766c85 100644 --- a/src/select.c +++ b/src/select.c @@ -4552,8 +4552,8 @@ int sqlite3Select( p->selFlags |= SF_Aggregate; } i = -1; - }else if( pTabList->nSrc==1 && (p->selFlags & SF_Materialize)==0 - && OptimizationEnabled(db, SQLITE_SubqCoroutine) + }else if( pTabList->nSrc==1 + && OptimizationEnabled(db, SQLITE_SubqCoroutine) ){ /* Implement a co-routine that will return a single row of the result ** set on each invocation. diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 0d1342a56a..7c5e1e3ed9 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2161,7 +2161,7 @@ struct Select { #define SF_HasTypeInfo 0x0020 /* FROM subqueries have Table metadata */ #define SF_UseSorter 0x0040 /* Sort using a sorter */ #define SF_Values 0x0080 /* Synthesized from VALUES clause */ -#define SF_Materialize 0x0100 /* Force materialization of views */ +#define SF_Materialize 0x0100 /* NOT USED */ #define SF_NestedFrom 0x0200 /* Part of a parenthesized FROM clause */ #define SF_MaybeConvert 0x0400 /* Need convertCompoundSelectToSubquery() */ #define SF_Recursive 0x0800 /* The recursive part of a recursive CTE */ From e08ecad58a7f11b915920eaf0b9833b87ba02ea3 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 4 Feb 2014 23:45:45 +0000 Subject: [PATCH 214/276] Do not mark the ephemeral tables used to hold the RHS of IN clauses as unordered because the NGQP will use those ephemeral tables to help order the output. This is not an issue for standard SQLite since ephemeral tables there are always ordered, regardless of the hint. It only affects systems that substitute an alternative storage engine. FossilOrigin-Name: f2504089df0bf4011864e67825b37f6aa3d03458 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 1 - 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 95aa7f83ef..4796737c60 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sthe\sSF_Materialize\sflag\sfrom\sthe\sSELECT\sobject\sas\sit\sdoes\snot\naccomplish\sanything\suseful. -D 2014-02-04T20:46:41.282 +C Do\snot\smark\sthe\sephemeral\stables\sused\sto\shold\sthe\sRHS\sof\sIN\sclauses\sas\nunordered\sbecause\sthe\sNGQP\swill\suse\sthose\sephemeral\stables\sto\shelp\sorder\sthe\noutput.\s\sThis\sis\snot\san\sissue\sfor\sstandard\sSQLite\ssince\sephemeral\stables\nthere\sare\salways\sordered,\sregardless\sof\sthe\shint.\s\sIt\sonly\saffects\ssystems\nthat\ssubstitute\san\salternative\sstorage\sengine. +D 2014-02-04T23:45:45.488 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -175,7 +175,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 F src/delete.c 6765a421f08adbedc5d52d21760ec6dbe5123fd3 -F src/expr.c e3e09af908b968305d4efeda8dc3499a087ee7d2 +F src/expr.c 2c710c35a05486d8e2e142bff1e66bac6ed39a35 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 2ab0f5384b70594468ef3ac5c7ed8ca24bfd17d5 F src/func.c f4499b39d66b71825514334ce67b32ff14bd19f5 @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 3e1a3f68d7457ff708222a3448404b593f018fc2 -R ade75eb85514e63b06c7a5a5e6c85df2 +P 65d5dcddbd34dfb2733a7a908c7c652ce2d610fe +R 0cb9b0d02c191eb29e623ef228773cac U drh -Z e551af7aa0a37f40c066574f60e01273 +Z 4064cb60834c8d1598bb0abfd98d0dc6 diff --git a/manifest.uuid b/manifest.uuid index bb6a8f738c..bc5d6bafc7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -65d5dcddbd34dfb2733a7a908c7c652ce2d610fe \ No newline at end of file +f2504089df0bf4011864e67825b37f6aa3d03458 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 7323e5d4f7..ee9d7877ab 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1763,7 +1763,6 @@ int sqlite3CodeSubselect( */ pExpr->iTable = pParse->nTab++; addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pExpr->iTable, !isRowid); - if( rMayHaveNull==0 ) sqlite3VdbeChangeP5(v, BTREE_UNORDERED); pKeyInfo = isRowid ? 0 : sqlite3KeyInfoAlloc(pParse->db, 1, 1); if( ExprHasProperty(pExpr, EP_xIsSelect) ){ From 5dfd3d908057bef11d94145d105ec3adc80fe2f5 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Wed, 5 Feb 2014 11:05:47 +0000 Subject: [PATCH 215/276] In the Win32 VFS, the winSysInfo variable should be static. FossilOrigin-Name: 4a4dd371a72b7d475185923bebb4cd9bd83e1bd9 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/os_win.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 4796737c60..da13307c6c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\smark\sthe\sephemeral\stables\sused\sto\shold\sthe\sRHS\sof\sIN\sclauses\sas\nunordered\sbecause\sthe\sNGQP\swill\suse\sthose\sephemeral\stables\sto\shelp\sorder\sthe\noutput.\s\sThis\sis\snot\san\sissue\sfor\sstandard\sSQLite\ssince\sephemeral\stables\nthere\sare\salways\sordered,\sregardless\sof\sthe\shint.\s\sIt\sonly\saffects\ssystems\nthat\ssubstitute\san\salternative\sstorage\sengine. -D 2014-02-04T23:45:45.488 +C In\sthe\sWin32\sVFS,\sthe\swinSysInfo\svariable\sshould\sbe\sstatic. +D 2014-02-05T11:05:47.687 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -206,7 +206,7 @@ F src/os.c 1b147e4cf7cc39e618115c14a086aed44bc91ace F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_unix.c f3ed0e406cbf9c820565b2118232d0796346130f -F src/os_win.c 1b21af72c5fa6f9e519a5fcab33e80d182b1aedb +F src/os_win.c d4284f003445054a26689f1264b1b9bf7261bd1b F src/pager.c efa923693e958696eee69b205a20bfbc402c8480 F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428 F src/parse.y bd51bc17cbfe7549adb4ca3747b1c3d384645065 @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 65d5dcddbd34dfb2733a7a908c7c652ce2d610fe -R 0cb9b0d02c191eb29e623ef228773cac -U drh -Z 4064cb60834c8d1598bb0abfd98d0dc6 +P f2504089df0bf4011864e67825b37f6aa3d03458 +R f919fd88b0fe2a17b41d9c03ff44720f +U mistachkin +Z fecb65c3944a970d4d7662e030506246 diff --git a/manifest.uuid b/manifest.uuid index bc5d6bafc7..e178daa36c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f2504089df0bf4011864e67825b37f6aa3d03458 \ No newline at end of file +4a4dd371a72b7d475185923bebb4cd9bd83e1bd9 \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index 4fb4f02703..d393c0d016 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -3201,7 +3201,7 @@ static int winDeviceCharacteristics(sqlite3_file *id){ ** During sqlite3_os_init() we do a GetSystemInfo() ** to get the granularity size. */ -SYSTEM_INFO winSysInfo; +static SYSTEM_INFO winSysInfo; #ifndef SQLITE_OMIT_WAL From 3350ce95f7d754c8b8de51c926b870d06f9ee7ad Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 6 Feb 2014 00:49:12 +0000 Subject: [PATCH 216/276] Add the ".repair" command to the command-line shell. FossilOrigin-Name: d1dfadea87ecf18eeb6d2f21769deaa97473ca0e --- manifest | 14 ++-- manifest.uuid | 2 +- src/shell.c | 194 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 202 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index da13307c6c..c624ecece4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\sWin32\sVFS,\sthe\swinSysInfo\svariable\sshould\sbe\sstatic. -D 2014-02-05T11:05:47.687 +C Add\sthe\s".repair"\scommand\sto\sthe\scommand-line\sshell. +D 2014-02-06T00:49:12.328 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -220,7 +220,7 @@ F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c b78f5e62c283aca2e38657938bc1fec1051df728 -F src/shell.c 24722d24d4ea8ca93db35e44db7308de786767ca +F src/shell.c c128bf92b3ed268d8ec6f0df275a5d737edf2968 F src/sqlite.h.in eed7f7d66a60daaa7b4a597dcd9bad87aad9611b F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P f2504089df0bf4011864e67825b37f6aa3d03458 -R f919fd88b0fe2a17b41d9c03ff44720f -U mistachkin -Z fecb65c3944a970d4d7662e030506246 +P 4a4dd371a72b7d475185923bebb4cd9bd83e1bd9 +R 235c07c6649435d22d14c7aa202be2ed +U drh +Z b9d162ba79528a4d7df551b82e7b6e75 diff --git a/manifest.uuid b/manifest.uuid index e178daa36c..98d249ad3e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4a4dd371a72b7d475185923bebb4cd9bd83e1bd9 \ No newline at end of file +d1dfadea87ecf18eeb6d2f21769deaa97473ca0e \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 1c4c4ad3e3..68f2ef2afc 100644 --- a/src/shell.c +++ b/src/shell.c @@ -1581,6 +1581,7 @@ static char zHelp[] = ".prompt MAIN CONTINUE Replace the standard prompts\n" ".quit Exit this program\n" ".read FILENAME Execute SQL in FILENAME\n" + ".repair NEWDB Recover data into NEWDB from a corrupt database\n" ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n" ".schema ?TABLE? Show the CREATE statements\n" " If TABLE specified, only show tables matching\n" @@ -1896,6 +1897,195 @@ static char *csv_read_one_field(CSVReader *p){ return p->z; } +/* +** Try to transfer data for table zTable +*/ +static void tryToRepairData( + struct callback_data *p, + sqlite3 *newDb, + const char *zTable +){ + sqlite3_stmt *pQuery = 0; + sqlite3_stmt *pInsert = 0; + char *zQuery = 0; + char *zInsert = 0; + int rc; + int i, j, n; + int nTable = (int)strlen(zTable); + int k = 0; + + zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable); + rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0); + if( rc ){ + fprintf(stderr, "Error: (%d) %s on [%s]\n", + sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db), + zQuery); + goto end_data_xfer; + } + n = sqlite3_column_count(pQuery); + zInsert = sqlite3_malloc(200 + nTable + n*3); + if( zInsert==0 ){ + fprintf(stderr, "out of memory\n"); + goto end_data_xfer; + } + sqlite3_snprintf(200+nTable,zInsert, + "INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable); + i = (int)strlen(zInsert); + for(j=1; jdb, zQuery, -1, &pQuery, 0); + if( rc ){ + fprintf(stderr, "Error: (%d) %s on [%s]\n", + sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db), + zQuery); + goto end_data_xfer; + } + } /* End for(k=0...) */ + +end_data_xfer: + sqlite3_finalize(pQuery); + sqlite3_finalize(pInsert); + sqlite3_free(zQuery); + sqlite3_free(zInsert); +} + + +/* +** Try to transfer all rows of the schema that match zWhere. For +** each row, invoke xForEach() on the object defined by that row. +*/ +static void tryToRepairSchema( + struct callback_data *p, + sqlite3 *newDb, + const char *zWhere, + void (*xForEach)(struct callback_data*,sqlite3*,const char*) +){ + sqlite3_stmt *pQuery = 0; + char *zQuery = 0; + int rc; + const unsigned char *zName; + const unsigned char *zSql; + + zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master" + " WHERE %s", zWhere); + rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0); + if( rc ){ + fprintf(stderr, "Error: (%d) %s on [%s]\n", + sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db), + zQuery); + goto end_schema_xfer; + } + while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){ + zName = sqlite3_column_text(pQuery, 0); + zSql = sqlite3_column_text(pQuery, 1); + printf("%s... ", zName); fflush(stdout); + sqlite3_exec(newDb, (const char*)zSql, 0, 0, 0); + if( xForEach ){ + xForEach(p, newDb, (const char*)zName); + } + printf("done\n"); + } + if( rc!=SQLITE_DONE ){ + sqlite3_finalize(pQuery); + sqlite3_free(zQuery); + zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master" + " WHERE %s ORDER BY rowid DESC", zWhere); + rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0); + if( rc ){ + fprintf(stderr, "Error: (%d) %s on [%s]\n", + sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db), + zQuery); + goto end_schema_xfer; + } + while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){ + zName = sqlite3_column_text(pQuery, 0); + zSql = sqlite3_column_text(pQuery, 1); + printf("%s... ", zName); fflush(stdout); + sqlite3_exec(newDb, (const char*)zSql, 0, 0, 0); + if( xForEach ){ + xForEach(p, newDb, (const char*)zName); + } + printf("done\n"); + } + } +end_schema_xfer: + sqlite3_finalize(pQuery); + sqlite3_free(zQuery); +} + +/* +** Open a new database file named "zNewDb". Try to recover as much information +** as possible out of the main database (which might be corrupt) and write it +** into zNewDb. +*/ +static void tryToRepair(struct callback_data *p, const char *zNewDb){ + int rc; + sqlite3 *newDb = 0; + if( access(zNewDb,0)==0 ){ + fprintf(stderr, "File \"%s\" already exists.\n", zNewDb); + return; + } + rc = sqlite3_open(zNewDb, &newDb); + if( rc ){ + fprintf(stderr, "Cannot create output database: %s\n", + sqlite3_errmsg(newDb)); + }else{ + sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0); + tryToRepairSchema(p, newDb, "type='table'", tryToRepairData); + tryToRepairSchema(p, newDb, "type!='table'", 0); + sqlite3_exec(newDb, "COMMIT;", 0, 0, 0); + } + sqlite3_close(newDb); +} + /* ** If an input line begins with "." then invoke this routine to ** process that line. @@ -2495,6 +2685,10 @@ static int do_meta_command(char *zLine, struct callback_data *p){ } }else + if( c=='r' && strncmp(azArg[0], "repair", n)==0 && nArg>1 && nArg<3 ){ + tryToRepair(p, azArg[1]); + }else + if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 && nArg>1 && nArg<4){ const char *zSrcFile; const char *zDb; From e31ae901004bd2ec35a031b884f737c62a44c005 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Thu, 6 Feb 2014 01:15:29 +0000 Subject: [PATCH 217/276] Rename the '.repair' shell command to '.clone'. FossilOrigin-Name: 4f9d95624ae4e123f83c835b5940f64d4a47be0d --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c | 20 ++++++++++---------- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index c624ecece4..8cb9683c66 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s".repair"\scommand\sto\sthe\scommand-line\sshell. -D 2014-02-06T00:49:12.328 +C Rename\sthe\s'.repair'\sshell\scommand\sto\s'.clone'. +D 2014-02-06T01:15:29.192 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -220,7 +220,7 @@ F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c b78f5e62c283aca2e38657938bc1fec1051df728 -F src/shell.c c128bf92b3ed268d8ec6f0df275a5d737edf2968 +F src/shell.c da0a97d984a7f59441d052925f3b83189c532bf7 F src/sqlite.h.in eed7f7d66a60daaa7b4a597dcd9bad87aad9611b F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 4a4dd371a72b7d475185923bebb4cd9bd83e1bd9 -R 235c07c6649435d22d14c7aa202be2ed -U drh -Z b9d162ba79528a4d7df551b82e7b6e75 +P d1dfadea87ecf18eeb6d2f21769deaa97473ca0e +R f560d9f23cc9db65e30e7982b2e54ef7 +U mistachkin +Z 4d9ab8dffd5cac0331ab06f34b9616ca diff --git a/manifest.uuid b/manifest.uuid index 98d249ad3e..5b765640c3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d1dfadea87ecf18eeb6d2f21769deaa97473ca0e \ No newline at end of file +4f9d95624ae4e123f83c835b5940f64d4a47be0d \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 68f2ef2afc..3a583f09fc 100644 --- a/src/shell.c +++ b/src/shell.c @@ -1581,7 +1581,7 @@ static char zHelp[] = ".prompt MAIN CONTINUE Replace the standard prompts\n" ".quit Exit this program\n" ".read FILENAME Execute SQL in FILENAME\n" - ".repair NEWDB Recover data into NEWDB from a corrupt database\n" + ".clone NEWDB Clone data into NEWDB from the existing database\n" ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n" ".schema ?TABLE? Show the CREATE statements\n" " If TABLE specified, only show tables matching\n" @@ -1900,7 +1900,7 @@ static char *csv_read_one_field(CSVReader *p){ /* ** Try to transfer data for table zTable */ -static void tryToRepairData( +static void tryToCloneData( struct callback_data *p, sqlite3 *newDb, const char *zTable @@ -2002,7 +2002,7 @@ end_data_xfer: ** Try to transfer all rows of the schema that match zWhere. For ** each row, invoke xForEach() on the object defined by that row. */ -static void tryToRepairSchema( +static void tryToCloneSchema( struct callback_data *p, sqlite3 *newDb, const char *zWhere, @@ -2066,7 +2066,7 @@ end_schema_xfer: ** as possible out of the main database (which might be corrupt) and write it ** into zNewDb. */ -static void tryToRepair(struct callback_data *p, const char *zNewDb){ +static void tryToClone(struct callback_data *p, const char *zNewDb){ int rc; sqlite3 *newDb = 0; if( access(zNewDb,0)==0 ){ @@ -2079,8 +2079,8 @@ static void tryToRepair(struct callback_data *p, const char *zNewDb){ sqlite3_errmsg(newDb)); }else{ sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0); - tryToRepairSchema(p, newDb, "type='table'", tryToRepairData); - tryToRepairSchema(p, newDb, "type!='table'", 0); + tryToCloneSchema(p, newDb, "type='table'", tryToCloneData); + tryToCloneSchema(p, newDb, "type!='table'", 0); sqlite3_exec(newDb, "COMMIT;", 0, 0, 0); } sqlite3_close(newDb); @@ -2193,6 +2193,10 @@ static int do_meta_command(char *zLine, struct callback_data *p){ test_breakpoint(); }else + if( c=='c' && strncmp(azArg[0], "clone", n)==0 && nArg>1 && nArg<3 ){ + tryToClone(p, azArg[1]); + }else + if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 && nArg==1 ){ struct callback_data data; char *zErrMsg = 0; @@ -2685,10 +2689,6 @@ static int do_meta_command(char *zLine, struct callback_data *p){ } }else - if( c=='r' && strncmp(azArg[0], "repair", n)==0 && nArg>1 && nArg<3 ){ - tryToRepair(p, azArg[1]); - }else - if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 && nArg>1 && nArg<4){ const char *zSrcFile; const char *zDb; From 4bbcf10617908811dde800c114b693834b2574dd Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 6 Feb 2014 02:46:08 +0000 Subject: [PATCH 218/276] Add additional error messages and a progress spinner to the ".clone" command. FossilOrigin-Name: dd0db3f0cef1be46cea16d4e61ea3348b3b3bd3e --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c | 46 +++++++++++++++++++++++++++++++++++----------- 3 files changed, 43 insertions(+), 19 deletions(-) diff --git a/manifest b/manifest index 8cb9683c66..3a59340ec6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Rename\sthe\s'.repair'\sshell\scommand\sto\s'.clone'. -D 2014-02-06T01:15:29.192 +C Add\sadditional\serror\smessages\sand\sa\sprogress\sspinner\sto\sthe\s".clone"\scommand. +D 2014-02-06T02:46:08.164 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -220,7 +220,7 @@ F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c b78f5e62c283aca2e38657938bc1fec1051df728 -F src/shell.c da0a97d984a7f59441d052925f3b83189c532bf7 +F src/shell.c 7dedf7367ee49050b0366bf8dbc8ec2bd15b42c7 F src/sqlite.h.in eed7f7d66a60daaa7b4a597dcd9bad87aad9611b F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P d1dfadea87ecf18eeb6d2f21769deaa97473ca0e -R f560d9f23cc9db65e30e7982b2e54ef7 -U mistachkin -Z 4d9ab8dffd5cac0331ab06f34b9616ca +P 4f9d95624ae4e123f83c835b5940f64d4a47be0d +R f4dd749481e46684567e713bb83ed4e5 +U drh +Z 395514f5fdbe146277bb7612673c11cf diff --git a/manifest.uuid b/manifest.uuid index 5b765640c3..eb1eab6d72 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4f9d95624ae4e123f83c835b5940f64d4a47be0d \ No newline at end of file +dd0db3f0cef1be46cea16d4e61ea3348b3b3bd3e \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 3a583f09fc..8fa32105d9 100644 --- a/src/shell.c +++ b/src/shell.c @@ -1543,6 +1543,7 @@ static int run_schema_dump_query( static char zHelp[] = ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n" ".bail ON|OFF Stop after hitting an error. Default OFF\n" + ".clone NEWDB Clone data into NEWDB from the existing database\n" ".databases List names and files of attached databases\n" ".dump ?TABLE? ... Dump the database in an SQL text format\n" " If TABLE specified, only dump tables matching\n" @@ -1581,7 +1582,6 @@ static char zHelp[] = ".prompt MAIN CONTINUE Replace the standard prompts\n" ".quit Exit this program\n" ".read FILENAME Execute SQL in FILENAME\n" - ".clone NEWDB Clone data into NEWDB from the existing database\n" ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n" ".schema ?TABLE? Show the CREATE statements\n" " If TABLE specified, only show tables matching\n" @@ -1898,7 +1898,9 @@ static char *csv_read_one_field(CSVReader *p){ } /* -** Try to transfer data for table zTable +** Try to transfer data for table zTable. If an error is seen while +** moving forward, try to go backwards. The backwards movement won't +** work for WITHOUT ROWID tables. */ static void tryToCloneData( struct callback_data *p, @@ -1913,11 +1915,13 @@ static void tryToCloneData( int i, j, n; int nTable = (int)strlen(zTable); int k = 0; + int cnt = 0; + const int spinRate = 10000; zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable); rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0); if( rc ){ - fprintf(stderr, "Error: (%d) %s on [%s]\n", + fprintf(stderr, "Error %d: %s on [%s]\n", sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db), zQuery); goto end_data_xfer; @@ -1938,7 +1942,7 @@ static void tryToCloneData( memcpy(zInsert+i, ");", 3); rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0); if( rc ){ - fprintf(stderr, "Error: (%d) %s on [%s]\n", + fprintf(stderr, "Error %d: %s on [%s]\n", sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb), zQuery); goto end_data_xfer; @@ -1973,8 +1977,17 @@ static void tryToCloneData( } } } /* End for */ - sqlite3_step(pInsert); + rc = sqlite3_step(pInsert); + if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){ + fprintf(stderr, "Error %d: %s\n", sqlite3_extended_errcode(newDb), + sqlite3_errmsg(newDb)); + } sqlite3_reset(pInsert); + cnt++; + if( (cnt%spinRate)==0 ){ + printf("%c\b", "|/-\\"[(cnt/spinRate)%4]); + fflush(stdout); + } } /* End while */ if( rc==SQLITE_DONE ) break; sqlite3_finalize(pQuery); @@ -1983,10 +1996,8 @@ static void tryToCloneData( zTable); rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0); if( rc ){ - fprintf(stderr, "Error: (%d) %s on [%s]\n", - sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db), - zQuery); - goto end_data_xfer; + fprintf(stderr, "Warning: cannot step \"%s\" backwards", zTable); + break; } } /* End for(k=0...) */ @@ -2001,6 +2012,8 @@ end_data_xfer: /* ** Try to transfer all rows of the schema that match zWhere. For ** each row, invoke xForEach() on the object defined by that row. +** If an error is encountered while moving forward through the +** sqlite_master table, try again moving backwards. */ static void tryToCloneSchema( struct callback_data *p, @@ -2013,6 +2026,7 @@ static void tryToCloneSchema( int rc; const unsigned char *zName; const unsigned char *zSql; + char *zErrMsg = 0; zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master" " WHERE %s", zWhere); @@ -2027,7 +2041,12 @@ static void tryToCloneSchema( zName = sqlite3_column_text(pQuery, 0); zSql = sqlite3_column_text(pQuery, 1); printf("%s... ", zName); fflush(stdout); - sqlite3_exec(newDb, (const char*)zSql, 0, 0, 0); + sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg); + if( zErrMsg ){ + fprintf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql); + sqlite3_free(zErrMsg); + zErrMsg = 0; + } if( xForEach ){ xForEach(p, newDb, (const char*)zName); } @@ -2049,7 +2068,12 @@ static void tryToCloneSchema( zName = sqlite3_column_text(pQuery, 0); zSql = sqlite3_column_text(pQuery, 1); printf("%s... ", zName); fflush(stdout); - sqlite3_exec(newDb, (const char*)zSql, 0, 0, 0); + sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg); + if( zErrMsg ){ + fprintf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql); + sqlite3_free(zErrMsg); + zErrMsg = 0; + } if( xForEach ){ xForEach(p, newDb, (const char*)zName); } From 0211d8bca4ddab5a0d4a1f5299c3cb7cd6effe7d Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 6 Feb 2014 13:18:51 +0000 Subject: [PATCH 219/276] Change the spellfix1 virtual table to deterministically names its shadow tables. FossilOrigin-Name: 5219cdfc56ec3e1cd645ae6443ba72ce0df0339a --- ext/misc/spellfix.c | 6 ++---- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/ext/misc/spellfix.c b/ext/misc/spellfix.c index 4be73bb39e..d33740bf6d 100644 --- a/ext/misc/spellfix.c +++ b/ext/misc/spellfix.c @@ -1933,7 +1933,6 @@ static int spellfix1Init( #define SPELLFIX_COL_COMMAND 11 } if( rc==SQLITE_OK && isCreate ){ - sqlite3_uint64 r; spellfix1DbExec(&rc, db, "CREATE TABLE IF NOT EXISTS \"%w\".\"%w_vocab\"(\n" " id INTEGER PRIMARY KEY,\n" @@ -1945,11 +1944,10 @@ static int spellfix1Init( ");\n", zDbName, zTableName ); - sqlite3_randomness(sizeof(r), &r); spellfix1DbExec(&rc, db, - "CREATE INDEX IF NOT EXISTS \"%w\".\"%w_index_%llx\" " + "CREATE INDEX IF NOT EXISTS \"%w\".\"%w_vocab_index_langid_k2\" " "ON \"%w_vocab\"(langid,k2);", - zDbName, zModule, r, zTableName + zDbName, zModule, zTableName ); } for(i=3; rc==SQLITE_OK && i Date: Thu, 6 Feb 2014 23:56:27 +0000 Subject: [PATCH 220/276] Delete the OP_VerifySchema opcode. Enhance OP_Transaction to do the schema version checks that OP_VerifySchema used to do. FossilOrigin-Name: 2f3376ebf13df44e6acf27cb1f07172cd8b34033 --- manifest | 20 +++++----- manifest.uuid | 2 +- src/alter.c | 2 +- src/build.c | 15 ++++---- src/expr.c | 2 +- src/vdbe.c | 99 +++++++++++++++++++------------------------------- src/vdbeblob.c | 58 +++++++++++++---------------- 7 files changed, 85 insertions(+), 113 deletions(-) diff --git a/manifest b/manifest index 4697702db0..cf0f6dd247 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\sspellfix1\svirtual\stable\sto\sdeterministically\snames\sits\sshadow\ntables. -D 2014-02-06T13:18:51.466 +C Delete\sthe\sOP_VerifySchema\sopcode.\s\sEnhance\sOP_Transaction\sto\sdo\sthe\sschema\nversion\schecks\sthat\sOP_VerifySchema\sused\sto\sdo. +D 2014-02-06T23:56:27.981 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -159,7 +159,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 3d8b83c91651f53472ca17599dae3457b8b89494 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c 2af0330bb1b601af7a7789bf7229675fd772a083 +F src/alter.c d5348d0f86a5fc8fb3987727402f023953c021cf F src/analyze.c 581d5c18ce89c6f45d4dca65914d0de5b4dad41f F src/attach.c 3801129015ef59d76bf23c95ef9b0069d18a0c52 F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 @@ -169,13 +169,13 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btree.c 7b2c3cd16deedff7f4904f2e871e7b77328b9872 F src/btree.h a61ddebc78c66795a2b93181321a116746302cc9 F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0 -F src/build.c 7e6c275ab1731510d6f793d0f88373ab3e858e69 +F src/build.c 40c38ec8f10835cf68879cb12e7c00e32b8edf78 F src/callback.c 174e3c8656bc29f91d710ab61550d16eea34be98 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 F src/delete.c 6765a421f08adbedc5d52d21760ec6dbe5123fd3 -F src/expr.c 2c710c35a05486d8e2e142bff1e66bac6ed39a35 +F src/expr.c fabda9e9320e3284c2a35cdc558313d9e80ce92a F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 2ab0f5384b70594468ef3ac5c7ed8ca24bfd17d5 F src/func.c f4499b39d66b71825514334ce67b32ff14bd19f5 @@ -280,12 +280,12 @@ F src/update.c a7df6fffce6bfedc578fda6136dd33e34a63f8ee F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c 15ac2627f548f5481d0d7e6c4eb67be673027695 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c e703913e9a3b56d7824f3eb8b76d99f496ff6dc1 +F src/vdbe.c 5e3a494f6e704c65d1c1bfb71dc1d3f600a83daa F src/vdbe.h e6c4c610fcabad4fa80ebb1efc6822a9367e2b26 F src/vdbeInt.h 42db251e9f863401ff847b90d5fe1614c89a6a56 F src/vdbeapi.c ce4e68ea4842cc6081046f533d088dcf01d247ad F src/vdbeaux.c a3327afa8cfcc5bb3d38f2b2a599bac5fb63c6be -F src/vdbeblob.c bc40f98f256f0b34116d6a44b114da4a81a15d33 +F src/vdbeblob.c 9542e116c1db5ed813977581d506c176e117c0ec F src/vdbemem.c 23cdc14ed43e0aafa57bd72b9bf3d5b1641afa91 F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147 F src/vdbetrace.c 6f52bc0c51e144b7efdcfb2a8f771167a8816767 @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P dd0db3f0cef1be46cea16d4e61ea3348b3b3bd3e -R d1392d03f19b15b6d22c3ea00bdb4a28 +P 5219cdfc56ec3e1cd645ae6443ba72ce0df0339a +R cf804140230dbce93e49a96814bb11f2 U drh -Z 43f5ac71b446a3c191c2b0e127f22d0c +Z c3b911d3bee960b579ea55e50656eb54 diff --git a/manifest.uuid b/manifest.uuid index e2ca533bde..d18e4e1854 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5219cdfc56ec3e1cd645ae6443ba72ce0df0339a \ No newline at end of file +2f3376ebf13df44e6acf27cb1f07172cd8b34033 \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index 9d34b07b0c..67070a5891 100644 --- a/src/alter.c +++ b/src/alter.c @@ -469,7 +469,7 @@ void sqlite3AlterRenameTable( } #endif - /* Begin a transaction and code the VerifyCookie for database iDb. + /* Begin a transaction for database iDb. ** Then modify the schema cookie (since the ALTER TABLE modifies the ** schema). Open a statement transaction if the table is a virtual ** table. diff --git a/src/build.c b/src/build.c index fa7364c3da..afd68a8f63 100644 --- a/src/build.c +++ b/src/build.c @@ -156,13 +156,14 @@ void sqlite3FinishCoding(Parse *pParse){ for(iDb=0, mask=1; iDbnDb; mask<<=1, iDb++){ if( (mask & pParse->cookieMask)==0 ) continue; sqlite3VdbeUsesBtree(v, iDb); - sqlite3VdbeAddOp2(v,OP_Transaction, iDb, (mask & pParse->writeMask)!=0); - if( db->init.busy==0 ){ - assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); - sqlite3VdbeAddOp3(v, OP_VerifyCookie, - iDb, pParse->cookieValue[iDb], - db->aDb[iDb].pSchema->iGeneration); - } + sqlite3VdbeAddOp4Int(v, + OP_Transaction, /* Opcode */ + iDb, /* P1 */ + (mask & pParse->writeMask)!=0, /* P2 */ + pParse->cookieValue[iDb], /* P3 */ + db->aDb[iDb].pSchema->iGeneration /* P4 */ + ); + if( db->init.busy==0 ) sqlite3VdbeChangeP5(v, 1); } #ifndef SQLITE_OMIT_VIRTUALTABLE for(i=0; inVtabLock; i++){ diff --git a/src/expr.c b/src/expr.c index ee9d7877ab..e417d8aadd 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1584,7 +1584,7 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){ pExpr = p->pEList->a[0].pExpr; iCol = (i16)pExpr->iColumn; - /* Code an OP_VerifyCookie and OP_TableLock for
    . */ + /* Code an OP_Transaction and OP_TableLock for
    . */ iDb = sqlite3SchemaToIndex(db, pTab->pSchema); sqlite3CodeVerifySchema(pParse, iDb); sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); diff --git a/src/vdbe.c b/src/vdbe.c index 037b02f12a..7c8cfe13d3 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2946,7 +2946,7 @@ case OP_AutoCommit: { break; } -/* Opcode: Transaction P1 P2 * * * +/* Opcode: Transaction P1 P2 P3 P4 P5 ** ** Begin a transaction. The transaction ends when a Commit or Rollback ** opcode is encountered. Depending on the ON CONFLICT setting, the @@ -2976,9 +2976,17 @@ case OP_AutoCommit: { ** will automatically commit when the VDBE halts. ** ** If P2 is zero, then a read-lock is obtained on the database file. +** +** If P5!=0 then this opcode also checks the schema cookie against P3 +** and the schema generation counter against P4. +** The cookie changes its value whenever the database schema changes. +** This operation is used to detect when that the cookie has changed +** and that the current process needs to reread the schema. */ case OP_Transaction: { Btree *pBt; + int iMeta; + int iGen; assert( p->bIsReader ); assert( p->readOnly==0 || pOp->p2==0 ); @@ -3022,6 +3030,35 @@ case OP_Transaction: { p->nStmtDefCons = db->nDeferredCons; p->nStmtDefImmCons = db->nDeferredImmCons; } + + /* Gather the schema version number for checking */ + sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&iMeta); + iGen = db->aDb[pOp->p1].pSchema->iGeneration; + }else{ + iGen = iMeta = 0; + } + assert( pOp->p5==0 || pOp->p4type==P4_INT32 ); + if( pOp->p5 && (iMeta!=pOp->p3 || iGen!=pOp->p4.i) ){ + sqlite3DbFree(db, p->zErrMsg); + p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed"); + /* If the schema-cookie from the database file matches the cookie + ** stored with the in-memory representation of the schema, do + ** not reload the schema from the database file. + ** + ** If virtual-tables are in use, this is not just an optimization. + ** Often, v-tables store their data in other SQLite tables, which + ** are queried from within xNext() and other v-table methods using + ** prepared queries. If such a query is out-of-date, we do not want to + ** discard the database schema, as the user code implementing the + ** v-table would have to be ready for the sqlite3_vtab structure itself + ** to be invalidated whenever sqlite3_step() is called from within + ** a v-table method. + */ + if( db->aDb[pOp->p1].pSchema->schema_cookie!=iMeta ){ + sqlite3ResetOneSchema(db, pOp->p1); + } + p->expired = 1; + rc = SQLITE_SCHEMA; } break; } @@ -3096,66 +3133,6 @@ case OP_SetCookie: { /* in3 */ break; } -/* Opcode: VerifyCookie P1 P2 P3 * * -** -** Check the value of global database parameter number 0 (the -** schema version) and make sure it is equal to P2 and that the -** generation counter on the local schema parse equals P3. -** -** P1 is the database number which is 0 for the main database file -** and 1 for the file holding temporary tables and some higher number -** for auxiliary databases. -** -** The cookie changes its value whenever the database schema changes. -** This operation is used to detect when that the cookie has changed -** and that the current process needs to reread the schema. -** -** Either a transaction needs to have been started or an OP_Open needs -** to be executed (to establish a read lock) before this opcode is -** invoked. -*/ -case OP_VerifyCookie: { - int iMeta; - int iGen; - Btree *pBt; - - assert( pOp->p1>=0 && pOp->p1nDb ); - assert( (p->btreeMask & (((yDbMask)1)<p1))!=0 ); - assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) ); - assert( p->bIsReader ); - pBt = db->aDb[pOp->p1].pBt; - if( pBt ){ - sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&iMeta); - iGen = db->aDb[pOp->p1].pSchema->iGeneration; - }else{ - iGen = iMeta = 0; - } - if( iMeta!=pOp->p2 || iGen!=pOp->p3 ){ - sqlite3DbFree(db, p->zErrMsg); - p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed"); - /* If the schema-cookie from the database file matches the cookie - ** stored with the in-memory representation of the schema, do - ** not reload the schema from the database file. - ** - ** If virtual-tables are in use, this is not just an optimization. - ** Often, v-tables store their data in other SQLite tables, which - ** are queried from within xNext() and other v-table methods using - ** prepared queries. If such a query is out-of-date, we do not want to - ** discard the database schema, as the user code implementing the - ** v-table would have to be ready for the sqlite3_vtab structure itself - ** to be invalidated whenever sqlite3_step() is called from within - ** a v-table method. - */ - if( db->aDb[pOp->p1].pSchema->schema_cookie!=iMeta ){ - sqlite3ResetOneSchema(db, pOp->p1); - } - - p->expired = 1; - rc = SQLITE_SCHEMA; - } - break; -} - /* Opcode: OpenRead P1 P2 P3 P4 P5 ** Synopsis: root=P2 iDb=P3 ** diff --git a/src/vdbeblob.c b/src/vdbeblob.c index 20841c44f9..0fbc1ad477 100644 --- a/src/vdbeblob.c +++ b/src/vdbeblob.c @@ -134,21 +134,20 @@ int sqlite3_blob_open( ** transaction. */ static const VdbeOpList openBlob[] = { - {OP_Transaction, 0, 0, 0}, /* 0: Start a transaction */ - {OP_VerifyCookie, 0, 0, 0}, /* 1: Check the schema cookie */ - {OP_TableLock, 0, 0, 0}, /* 2: Acquire a read or write lock */ + /* {OP_Transaction, 0, 0, 0}, // 0: Inserted separately */ + {OP_TableLock, 0, 0, 0}, /* 1: Acquire a read or write lock */ /* One of the following two instructions is replaced by an OP_Noop. */ - {OP_OpenRead, 0, 0, 0}, /* 3: Open cursor 0 for reading */ - {OP_OpenWrite, 0, 0, 0}, /* 4: Open cursor 0 for read/write */ + {OP_OpenRead, 0, 0, 0}, /* 2: Open cursor 0 for reading */ + {OP_OpenWrite, 0, 0, 0}, /* 3: Open cursor 0 for read/write */ - {OP_Variable, 1, 1, 1}, /* 5: Push the rowid to the stack */ - {OP_NotExists, 0, 10, 1}, /* 6: Seek the cursor */ - {OP_Column, 0, 0, 1}, /* 7 */ - {OP_ResultRow, 1, 0, 0}, /* 8 */ - {OP_Goto, 0, 5, 0}, /* 9 */ - {OP_Close, 0, 0, 0}, /* 10 */ - {OP_Halt, 0, 0, 0}, /* 11 */ + {OP_Variable, 1, 1, 1}, /* 4: Push the rowid to the stack */ + {OP_NotExists, 0, 10, 1}, /* 5: Seek the cursor */ + {OP_Column, 0, 0, 1}, /* 6 */ + {OP_ResultRow, 1, 0, 0}, /* 7 */ + {OP_Goto, 0, 4, 0}, /* 8 */ + {OP_Close, 0, 0, 0}, /* 9 */ + {OP_Halt, 0, 0, 0}, /* 10 */ }; int rc = SQLITE_OK; @@ -261,36 +260,31 @@ int sqlite3_blob_open( Vdbe *v = (Vdbe *)pBlob->pStmt; int iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + + sqlite3VdbeAddOp4Int(v, OP_Transaction, iDb, flags, + pTab->pSchema->schema_cookie, + pTab->pSchema->iGeneration); + sqlite3VdbeChangeP5(v, 1); sqlite3VdbeAddOpList(v, sizeof(openBlob)/sizeof(VdbeOpList), openBlob); - - /* Configure the OP_Transaction */ - sqlite3VdbeChangeP1(v, 0, iDb); - sqlite3VdbeChangeP2(v, 0, flags); - - /* Configure the OP_VerifyCookie */ - sqlite3VdbeChangeP1(v, 1, iDb); - sqlite3VdbeChangeP2(v, 1, pTab->pSchema->schema_cookie); - sqlite3VdbeChangeP3(v, 1, pTab->pSchema->iGeneration); - /* Make sure a mutex is held on the table to be accessed */ sqlite3VdbeUsesBtree(v, iDb); /* Configure the OP_TableLock instruction */ #ifdef SQLITE_OMIT_SHARED_CACHE - sqlite3VdbeChangeToNoop(v, 2); + sqlite3VdbeChangeToNoop(v, 1); #else - sqlite3VdbeChangeP1(v, 2, iDb); - sqlite3VdbeChangeP2(v, 2, pTab->tnum); - sqlite3VdbeChangeP3(v, 2, flags); - sqlite3VdbeChangeP4(v, 2, pTab->zName, P4_TRANSIENT); + sqlite3VdbeChangeP1(v, 1, iDb); + sqlite3VdbeChangeP2(v, 1, pTab->tnum); + sqlite3VdbeChangeP3(v, 1, flags); + sqlite3VdbeChangeP4(v, 1, pTab->zName, P4_TRANSIENT); #endif /* Remove either the OP_OpenWrite or OpenRead. Set the P2 ** parameter of the other to pTab->tnum. */ - sqlite3VdbeChangeToNoop(v, 4 - flags); - sqlite3VdbeChangeP2(v, 3 + flags, pTab->tnum); - sqlite3VdbeChangeP3(v, 3 + flags, iDb); + sqlite3VdbeChangeToNoop(v, 3 - flags); + sqlite3VdbeChangeP2(v, 2 + flags, pTab->tnum); + sqlite3VdbeChangeP3(v, 2 + flags, iDb); /* Configure the number of columns. Configure the cursor to ** think that the table has one more column than it really @@ -299,8 +293,8 @@ int sqlite3_blob_open( ** we can invoke OP_Column to fill in the vdbe cursors type ** and offset cache without causing any IO. */ - sqlite3VdbeChangeP4(v, 3+flags, SQLITE_INT_TO_PTR(pTab->nCol+1),P4_INT32); - sqlite3VdbeChangeP2(v, 7, pTab->nCol); + sqlite3VdbeChangeP4(v, 2+flags, SQLITE_INT_TO_PTR(pTab->nCol+1),P4_INT32); + sqlite3VdbeChangeP2(v, 6, pTab->nCol); if( !db->mallocFailed ){ pParse->nVar = 1; pParse->nMem = 1; From 0fd613542cfa78c4c23ace6b1752b1201b25286f Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 7 Feb 2014 02:29:45 +0000 Subject: [PATCH 221/276] Update comments in vdbe.c. No changes to code. FossilOrigin-Name: 1122b410de68a3c79b4c719a3a4cc4dc6a5bb39d --- manifest | 12 ++--- manifest.uuid | 2 +- src/vdbe.c | 140 ++++++++++++++++++-------------------------------- 3 files changed, 56 insertions(+), 98 deletions(-) diff --git a/manifest b/manifest index cf0f6dd247..5ce0f954c3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Delete\sthe\sOP_VerifySchema\sopcode.\s\sEnhance\sOP_Transaction\sto\sdo\sthe\sschema\nversion\schecks\sthat\sOP_VerifySchema\sused\sto\sdo. -D 2014-02-06T23:56:27.981 +C Update\scomments\sin\svdbe.c.\s\sNo\schanges\sto\scode. +D 2014-02-07T02:29:45.685 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -280,7 +280,7 @@ F src/update.c a7df6fffce6bfedc578fda6136dd33e34a63f8ee F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c 15ac2627f548f5481d0d7e6c4eb67be673027695 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c 5e3a494f6e704c65d1c1bfb71dc1d3f600a83daa +F src/vdbe.c 962cb7aad1a89ecc2b0cb879d7021c591ddc9a31 F src/vdbe.h e6c4c610fcabad4fa80ebb1efc6822a9367e2b26 F src/vdbeInt.h 42db251e9f863401ff847b90d5fe1614c89a6a56 F src/vdbeapi.c ce4e68ea4842cc6081046f533d088dcf01d247ad @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 5219cdfc56ec3e1cd645ae6443ba72ce0df0339a -R cf804140230dbce93e49a96814bb11f2 +P 2f3376ebf13df44e6acf27cb1f07172cd8b34033 +R aa84db7692e8a0ce37f76fa70188d582 U drh -Z c3b911d3bee960b579ea55e50656eb54 +Z 06749a17929b89f5bdf09dbcde9d47c5 diff --git a/manifest.uuid b/manifest.uuid index d18e4e1854..214aabe77c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2f3376ebf13df44e6acf27cb1f07172cd8b34033 \ No newline at end of file +1122b410de68a3c79b4c719a3a4cc4dc6a5bb39d \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 7c8cfe13d3..b97d6135ad 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -9,33 +9,8 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* -** The code in this file implements execution method of the -** Virtual Database Engine (VDBE). A separate file ("vdbeaux.c") -** handles housekeeping details such as creating and deleting -** VDBE instances. This file is solely interested in executing -** the VDBE program. -** -** In the external interface, an "sqlite3_stmt*" is an opaque pointer -** to a VDBE. -** -** The SQL parser generates a program which is then executed by -** the VDBE to do the work of the SQL statement. VDBE programs are -** similar in form to assembly language. The program consists of -** a linear sequence of operations. Each operation has an opcode -** and 5 operands. Operands P1, P2, and P3 are integers. Operand P4 -** is a null-terminated string. Operand P5 is an unsigned character. -** Few opcodes use all 5 operands. -** -** Computation results are stored on a set of registers numbered beginning -** with 1 and going up to Vdbe.nMem. Each register can store -** either an integer, a null-terminated string, a floating point -** number, or the SQL "NULL" value. An implicit conversion from one -** type to the other occurs as necessary. -** -** Most of the code in this file is taken up by the sqlite3VdbeExec() -** 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. +** The code in this file implements the function that runs the +** bytecode of a prepared statement. ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting @@ -49,7 +24,11 @@ /* ** Invoke this macro on memory cells just prior to changing the ** value of the cell. This macro verifies that shallow copies are -** not misused. +** not misused. A shallow copy of a string or blob just copies a +** pointer to the string or blob, not the content. If the original +** is changed while the copy is still in use, the string or blob might +** be changed out from under the copy. This macro verifies that nothing +** like that every happens. */ #ifdef SQLITE_DEBUG # define memAboutToChange(P,M) sqlite3VdbeMemAboutToChange(P,M) @@ -108,7 +87,7 @@ static void updateMaxBlobsize(Mem *p){ #endif /* -** The next global variable is incremented each type the OP_Found opcode +** The next global variable is incremented each time the OP_Found opcode ** is executed. This is used to test whether or not the foreign key ** operation implemented using OP_FkIsZero is working. This variable ** has no function other than to help verify the correct operation of the @@ -152,7 +131,7 @@ int sqlite3_found_count = 0; && sqlite3VdbeMemMakeWriteable(P) ){ goto no_mem;} /* Return true if the cursor was opened using the OP_OpenSorter opcode. */ -# define isSorter(x) ((x)->pSorter!=0) +#define isSorter(x) ((x)->pSorter!=0) /* ** Argument pMem points at a register that will be passed to a @@ -458,20 +437,6 @@ static void registerTrace(int iReg, Mem *p){ #endif -/* -** The CHECK_FOR_INTERRUPT macro defined here looks to see if the -** sqlite3_interrupt() routine has been called. If it has been, then -** processing of the VDBE program is interrupted. -** -** This macro added to every instruction that does a jump in order to -** implement a loop. This test used to be on every single instruction, -** but that meant we more testing than we needed. By only testing the -** flag on jump instructions, we get a (small) speed improvement. -*/ -#define CHECK_FOR_INTERRUPT \ - if( db->u1.isInterrupted ) goto abort_due_to_interrupt; - - #ifndef NDEBUG /* ** This function is only called from within an assert() expression. It @@ -494,35 +459,8 @@ static int checkSavepointCount(sqlite3 *db){ /* -** Execute as much of a VDBE program as we can then return. -** -** sqlite3VdbeMakeReady() must be called before this routine in order to -** close the program with a final OP_Halt and to set up the callbacks -** and the error message pointer. -** -** Whenever a row or result data is available, this routine will either -** invoke the result callback (if there is one) or return with -** SQLITE_ROW. -** -** If an attempt is made to open a locked database, then this routine -** will either invoke the busy callback (if there is one) or it will -** return SQLITE_BUSY. -** -** If an error occurs, an error message is written to memory obtained -** from sqlite3_malloc() and p->zErrMsg is made to point to that memory. -** The error code is stored in p->rc and this routine returns SQLITE_ERROR. -** -** If the callback ever returns non-zero, then the program exits -** immediately. There will be no error message but the p->rc field is -** set to SQLITE_ABORT and this routine will return SQLITE_ERROR. -** -** A memory allocation error causes p->rc to be set to SQLITE_NOMEM and this -** routine to return SQLITE_ERROR. -** -** Other fatal errors return SQLITE_ERROR. -** -** After this routine has finished, sqlite3VdbeFinalize() should be -** used to clean up the mess that was left behind. +** Execute as much of a VDBE program as we can. +** This is the core of sqlite3_step(). */ int sqlite3VdbeExec( Vdbe *p /* The VDBE */ @@ -566,7 +504,7 @@ int sqlite3VdbeExec( assert( p->explain==0 ); p->pResultSet = 0; db->busyHandler.nBusy = 0; - CHECK_FOR_INTERRUPT; + if( db->u1.isInterrupted ) goto abort_due_to_interrupt; sqlite3VdbeIOTraceSql(p); #ifndef SQLITE_OMIT_PROGRESS_CALLBACK if( db->xProgress ){ @@ -742,7 +680,7 @@ case OP_Goto: { /* jump */ ** checks on every opcode. This helps sqlite3_step() to run about 1.5% ** faster according to "valgrind --tool=cachegrind" */ check_for_interrupt: - CHECK_FOR_INTERRUPT; + if( db->u1.isInterrupted ) goto abort_due_to_interrupt; #ifndef SQLITE_OMIT_PROGRESS_CALLBACK /* Call the progress callback if it is configured and the required number ** of VDBE ops have been executed (either since this invocation of @@ -764,6 +702,7 @@ check_for_interrupt: } /* Opcode: Gosub P1 P2 * * * +** Synopsis: r[P1]=pc; pc=P2 ** ** Write the current address onto register P1 ** and then jump to address P2. @@ -781,6 +720,7 @@ case OP_Gosub: { /* jump */ } /* Opcode: Return P1 * * * * +** Synopsis: pc=r[P1]+1 ** ** Jump to the next instruction after the address in register P1. */ @@ -792,6 +732,7 @@ case OP_Return: { /* in1 */ } /* Opcode: Yield P1 * * * * +** Synopsis: swap(pc,r[P1]) ** ** Swap the program counter with the value in register P1. */ @@ -808,7 +749,7 @@ case OP_Yield: { /* in1 */ } /* Opcode: HaltIfNull P1 P2 P3 P4 P5 -** Synopsis: if r[P3] null then halt +** Synopsis: if r[P3]=null halt ** ** Check the value in register P3. If it is NULL then Halt using ** parameter P1, P2, and P4 as if this were a Halt instruction. If the @@ -956,7 +897,9 @@ case OP_Real: { /* same as TK_FLOAT, out2-prerelease */ ** Synopsis: r[P2]='P4' ** ** P4 points to a nul terminated UTF-8 string. This opcode is transformed -** into an OP_String before it is executed for the first time. +** into an OP_String before it is executed for the first time. During +** this transformation, the length of string P4 is computed and stored +** as the P1 parameter. */ case OP_String8: { /* same as TK_STRING, out2-prerelease */ assert( pOp->p4.z!=0 ); @@ -1050,7 +993,7 @@ case OP_Blob: { /* out2-prerelease */ ** ** Transfer the values of bound parameter P1 into register P2 ** -** If the parameter is named, then its name appears in P4 and P3==1. +** If the parameter is named, then its name appears in P4. ** The P4 value is used by sqlite3_bind_parameter_name(). */ case OP_Variable: { /* out2-prerelease */ @@ -1169,8 +1112,8 @@ case OP_SCopy: { /* out2 */ ** The registers P1 through P1+P2-1 contain a single row of ** results. This opcode causes the sqlite3_step() call to terminate ** with an SQLITE_ROW return code and it sets up the sqlite3_stmt -** structure to provide access to the top P1 values as the result -** row. +** structure to provide access to the r[P1]..r[P1+P2-1] values as +** the result row. */ case OP_ResultRow: { Mem *pMem; @@ -1698,7 +1641,7 @@ case OP_RealAffinity: { /* in1 */ ** ** Force the value in register P1 to be text. ** If the value is numeric, convert it to a string using the -** equivalent of printf(). Blob values are unchanged and +** equivalent of sprintf(). Blob values are unchanged and ** are afterwards simply interpreted as text. ** ** A NULL value is not changed by this routine. It remains NULL. @@ -2153,7 +2096,9 @@ case OP_BitNot: { /* same as TK_BITNOT, in1, out2 */ /* Opcode: Once P1 P2 * * * ** ** Check if OP_Once flag P1 is set. If so, jump to instruction P2. Otherwise, -** set the flag and fall through to the next instruction. +** set the flag and fall through to the next instruction. In other words, +** this opcode causes all following up codes up through P2 (but not including +** P2) to run just once and skipped on subsequent times through the loop. */ case OP_Once: { /* jump */ assert( pOp->p1nOnceFlag ); @@ -3346,7 +3291,7 @@ case OP_OpenEphemeral: { break; } -/* Opcode: SorterOpen P1 * * P4 * +/* Opcode: SorterOpen P1 P2 * P4 * ** ** This opcode works like OP_OpenEphemeral except that it opens ** a transient index that is specifically designed to sort large @@ -4213,7 +4158,7 @@ case OP_SorterData: { ** ** Write into register P2 the complete row key for cursor P1. ** There is no interpretation of the data. -** The key is copied onto the P3 register exactly as +** The key is copied onto the P2 register exactly as ** it is found in the database file. ** ** If the P1 cursor must be pointing to a valid row (not a NULL row) @@ -4439,7 +4384,7 @@ case OP_Rewind: { /* jump */ break; } -/* Opcode: Next P1 P2 P3 * P5 +/* Opcode: Next P1 P2 P3 P4 P5 ** ** Advance cursor P1 so that it points to the next key/data pair in its ** table or index. If there are no more key/value pairs then fall through @@ -4462,12 +4407,12 @@ case OP_Rewind: { /* jump */ ** ** See also: Prev, NextIfOpen */ -/* Opcode: NextIfOpen P1 P2 P3 * P5 +/* Opcode: NextIfOpen P1 P2 P3 P4 P5 ** ** This opcode works just like OP_Next except that if cursor P1 is not ** open it behaves a no-op. */ -/* Opcode: Prev P1 P2 P3 * P5 +/* Opcode: Prev P1 P2 P3 P4 P5 ** ** Back up cursor P1 so that it points to the previous key/data pair in its ** table or index. If there is no previous key/value pairs then fall through @@ -4488,7 +4433,7 @@ case OP_Rewind: { /* jump */ ** If P5 is positive and the jump is taken, then event counter ** number P5-1 in the prepared statement is incremented. */ -/* Opcode: PrevIfOpen P1 P2 P3 * P5 +/* Opcode: PrevIfOpen P1 P2 P3 P4 P5 ** ** This opcode works just like OP_Prev except that if cursor P1 is not ** open it behaves a no-op. @@ -4547,6 +4492,14 @@ next_tail: ** P3 is a flag that provides a hint to the b-tree layer that this ** insert is likely to be an append. ** +** If P5 contains bet OPFLAG_NCHANGE, then the change counter is +** incremented by this instruction. If OPFLAG_NCHANGE is clear, then +** the change counter is unchanged. +** +** If P5 contains OPFLAG_USESEEKRESULT then the cursor must have just +** done a seek to the spot where the new entry is to be inserted. This +** flag avoids doing an extra seek. +** ** This instruction only works for indices. The equivalent instruction ** for tables is OP_Insert. */ @@ -5147,7 +5100,7 @@ case OP_RowSetTest: { /* jump, in1, in3 */ #ifndef SQLITE_OMIT_TRIGGER -/* Opcode: Program P1 P2 P3 P4 * +/* Opcode: Program P1 P2 P3 P4 P5 ** ** Execute the trigger program passed as P4 (type P4_SUBPROGRAM). ** @@ -5159,6 +5112,8 @@ case OP_RowSetTest: { /* jump, in1, in3 */ ** memory required by the sub-vdbe at runtime. ** ** P4 is a pointer to the VM containing the trigger program. +** +** If P5 is non-zero, then recursive program invocation is enabled. */ case OP_Program: { /* jump */ int nMem; /* Number of memory registers for sub-program */ @@ -5546,7 +5501,7 @@ case OP_Checkpoint: { #endif #ifndef SQLITE_OMIT_PRAGMA -/* Opcode: JournalMode P1 P2 P3 * P5 +/* Opcode: JournalMode P1 P2 P3 * * ** ** Change the journal mode of database P1 to P3. P3 must be one of the ** PAGER_JOURNALMODE_XXX values. If changing between the various rollback @@ -6032,7 +5987,7 @@ case OP_VRename: { #endif #ifndef SQLITE_OMIT_VIRTUALTABLE -/* Opcode: VUpdate P1 P2 P3 P4 * +/* Opcode: VUpdate P1 P2 P3 P4 P5 ** Synopsis: data=r[P3@P2] ** ** P4 is a pointer to a virtual table object, an sqlite3_vtab structure. @@ -6055,6 +6010,9 @@ case OP_VRename: { ** P1 is a boolean flag. If it is set to true and the xUpdate call ** is successful, then the value returned by sqlite3_last_insert_rowid() ** is set to the value of the rowid for the row just inserted. +** +** P5 is the error actions (OE_Replace, OE_Fail, OE_Ignore, etc) to +** apply in the case of a constraint failure on an insert or update. */ case OP_VUpdate: { sqlite3_vtab *pVtab; From 21a919f63022549c8f76e2892573aac9178d1528 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 7 Feb 2014 03:28:02 +0000 Subject: [PATCH 222/276] More comment updates. No changes to code. FossilOrigin-Name: be24fbc22106e508975e316abe0471edd3833291 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbe.c | 12 ++++++------ 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 5ce0f954c3..5537506c47 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\scomments\sin\svdbe.c.\s\sNo\schanges\sto\scode. -D 2014-02-07T02:29:45.685 +C More\scomment\supdates.\s\sNo\schanges\sto\scode. +D 2014-02-07T03:28:02.783 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -280,7 +280,7 @@ F src/update.c a7df6fffce6bfedc578fda6136dd33e34a63f8ee F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c 15ac2627f548f5481d0d7e6c4eb67be673027695 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c 962cb7aad1a89ecc2b0cb879d7021c591ddc9a31 +F src/vdbe.c 575189caf33bc3f2b9557f420e9b815afcd5ace8 F src/vdbe.h e6c4c610fcabad4fa80ebb1efc6822a9367e2b26 F src/vdbeInt.h 42db251e9f863401ff847b90d5fe1614c89a6a56 F src/vdbeapi.c ce4e68ea4842cc6081046f533d088dcf01d247ad @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 2f3376ebf13df44e6acf27cb1f07172cd8b34033 -R aa84db7692e8a0ce37f76fa70188d582 -U drh -Z 06749a17929b89f5bdf09dbcde9d47c5 +P 1122b410de68a3c79b4c719a3a4cc4dc6a5bb39d +R ba81bea358565b1489c187d643f4773f +U mistachkin +Z fafd555fb9fada47058f4a33fbcaaf41 diff --git a/manifest.uuid b/manifest.uuid index 214aabe77c..affff2d9c4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1122b410de68a3c79b4c719a3a4cc4dc6a5bb39d \ No newline at end of file +be24fbc22106e508975e316abe0471edd3833291 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index b97d6135ad..5816c4a797 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -4492,13 +4492,13 @@ next_tail: ** P3 is a flag that provides a hint to the b-tree layer that this ** insert is likely to be an append. ** -** If P5 contains bet OPFLAG_NCHANGE, then the change counter is -** incremented by this instruction. If OPFLAG_NCHANGE is clear, then -** the change counter is unchanged. +** If P5 has the OPFLAG_NCHANGE bit set, then the change counter is +** incremented by this instruction. If the OPFLAG_NCHANGE bit is clear, +** then the change counter is unchanged. ** -** If P5 contains OPFLAG_USESEEKRESULT then the cursor must have just -** done a seek to the spot where the new entry is to be inserted. This -** flag avoids doing an extra seek. +** If P5 has the OPFLAG_USESEEKRESULT bit set, then the cursor must have +** just done a seek to the spot where the new entry is to be inserted. +** This flag avoids doing an extra seek. ** ** This instruction only works for indices. The equivalent instruction ** for tables is OP_Insert. From a5750cfe01b8fb83cf7382fc04b288c0b649b023 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 7 Feb 2014 13:20:31 +0000 Subject: [PATCH 223/276] Add the OP_Undef and OP_IsUndef opcodes. With these, use the first register in the result register range as the flag to indicate EOF on an INSERT from a SELECT, rather than allocating a separate boolean register for that task. FossilOrigin-Name: 6fb7448550f28a3c93053e125faeaf11de1011d0 --- manifest | 22 +++++++++++----------- manifest.uuid | 2 +- src/insert.c | 45 ++++++++++++++++----------------------------- src/vdbe.c | 37 +++++++++++++++++++++++++++++++------ src/vdbeInt.h | 4 ++-- src/vdbeaux.c | 6 +++--- src/vdbemem.c | 2 +- 7 files changed, 65 insertions(+), 53 deletions(-) diff --git a/manifest b/manifest index 5537506c47..9feb2fda5b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C More\scomment\supdates.\s\sNo\schanges\sto\scode. -D 2014-02-07T03:28:02.783 +C Add\sthe\sOP_Undef\sand\sOP_IsUndef\sopcodes.\s\sWith\sthese,\suse\sthe\sfirst\sregister\nin\sthe\sresult\sregister\srange\sas\sthe\sflag\sto\sindicate\sEOF\son\san\sINSERT\sfrom\na\sSELECT,\srather\sthan\sallocating\sa\sseparate\sboolean\sregister\sfor\sthat\stask. +D 2014-02-07T13:20:31.855 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -183,7 +183,7 @@ F src/global.c 1d7bb7ea8254ae6a68ed9bfaf65fcb3d1690b486 F src/hash.c d139319967164f139c8d1bb8a11b14db9c4ba3cd F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c a4450f0c46a9f221622e6551ab0953b03c4f8ee8 +F src/insert.c fa98632fbf46e01c7b4d2130558c74b42947f50d F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b @@ -280,13 +280,13 @@ F src/update.c a7df6fffce6bfedc578fda6136dd33e34a63f8ee F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c 15ac2627f548f5481d0d7e6c4eb67be673027695 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c 575189caf33bc3f2b9557f420e9b815afcd5ace8 +F src/vdbe.c 8697f15ad86604c5a8d598b1566e1594a7956469 F src/vdbe.h e6c4c610fcabad4fa80ebb1efc6822a9367e2b26 -F src/vdbeInt.h 42db251e9f863401ff847b90d5fe1614c89a6a56 +F src/vdbeInt.h bd6d5e70fe7c80f6aa4c56c34589762b9e933929 F src/vdbeapi.c ce4e68ea4842cc6081046f533d088dcf01d247ad -F src/vdbeaux.c a3327afa8cfcc5bb3d38f2b2a599bac5fb63c6be +F src/vdbeaux.c 3fd95b226330e1d50aedb40d750effe726ebb3fb F src/vdbeblob.c 9542e116c1db5ed813977581d506c176e117c0ec -F src/vdbemem.c 23cdc14ed43e0aafa57bd72b9bf3d5b1641afa91 +F src/vdbemem.c c0bcc02d6816ab4218ac0f94b63c8ee78a0f739f F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147 F src/vdbetrace.c 6f52bc0c51e144b7efdcfb2a8f771167a8816767 F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 1122b410de68a3c79b4c719a3a4cc4dc6a5bb39d -R ba81bea358565b1489c187d643f4773f -U mistachkin -Z fafd555fb9fada47058f4a33fbcaaf41 +P be24fbc22106e508975e316abe0471edd3833291 +R 7163c03b39a8cc1205867ee33d31d20c +U drh +Z 84c60c97897782670b677e52594a24b3 diff --git a/manifest.uuid b/manifest.uuid index affff2d9c4..a1ffd679c6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -be24fbc22106e508975e316abe0471edd3833291 \ No newline at end of file +6fb7448550f28a3c93053e125faeaf11de1011d0 \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index a2366360c7..edf277876f 100644 --- a/src/insert.c +++ b/src/insert.c @@ -349,17 +349,13 @@ void sqlite3AutoincrementEnd(Parse *pParse){ ** co-routine. Run the co-routine to its next breakpoint ** by calling "OP_Yield $X" where $X is pDest->iSDParm. ** -** pDest->iSDParm+1 The register holding the "completed" flag for the -** co-routine. This register is 0 if the previous Yield -** generated a new result row, or 1 if the subquery -** has completed. If the Yield is called again -** after this register becomes 1, then the VDBE will -** halt with an SQLITE_INTERNAL error. -** ** pDest->iSdst First result register. ** ** pDest->nSdst Number of result registers. ** +** At EOF the first result register will be marked as "undefined" so that +** the caller can know when to stop reading results. +** ** This routine handles all of the register allocation and fills in the ** pDest structure appropriately. ** @@ -370,7 +366,6 @@ void sqlite3AutoincrementEnd(Parse *pParse){ ** reg[pDest->iSdst+pDest->nSdst-1]: ** ** X <- A -** EOF <- 0 ** goto B ** A: setup for the SELECT ** loop rows in the SELECT @@ -378,7 +373,7 @@ void sqlite3AutoincrementEnd(Parse *pParse){ ** yield X ** end loop ** cleanup after the SELECT -** EOF <- 1 +** R <- undefined (signals EOF) ** yield X ** halt-error ** B: @@ -387,7 +382,7 @@ void sqlite3AutoincrementEnd(Parse *pParse){ ** ** [ Co-routine generated by this subroutine, shown above ] ** S: yield X -** if EOF goto E +** if R==undefined goto E ** if skip this row, goto C ** if terminate loop, goto E ** deal with this row @@ -396,28 +391,24 @@ void sqlite3AutoincrementEnd(Parse *pParse){ */ int sqlite3CodeCoroutine(Parse *pParse, Select *pSelect, SelectDest *pDest){ int regYield; /* Register holding co-routine entry-point */ - int regEof; /* Register holding co-routine completion flag */ int addrTop; /* Top of the co-routine */ int j1; /* Jump instruction */ int rc; /* Result code */ Vdbe *v; /* VDBE under construction */ regYield = ++pParse->nMem; - regEof = ++pParse->nMem; v = sqlite3GetVdbe(pParse); addrTop = sqlite3VdbeCurrentAddr(v); - sqlite3VdbeAddOp2(v, OP_Integer, addrTop+2, regYield); /* X <- A */ + sqlite3VdbeAddOp2(v, OP_Integer, addrTop+1, regYield); /* X <- A */ VdbeComment((v, "Co-routine entry point")); - sqlite3VdbeAddOp2(v, OP_Integer, 0, regEof); /* EOF <- 0 */ - VdbeComment((v, "Co-routine completion flag")); sqlite3SelectDestInit(pDest, SRT_Coroutine, regYield); j1 = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0); rc = sqlite3Select(pParse, pSelect, pDest); assert( pParse->nErr==0 || rc ); if( pParse->db->mallocFailed && rc==SQLITE_OK ) rc = SQLITE_NOMEM; if( rc ) return rc; - sqlite3VdbeAddOp2(v, OP_Integer, 1, regEof); /* EOF <- 1 */ - sqlite3VdbeAddOp1(v, OP_Yield, regYield); /* yield X */ + sqlite3VdbeAddOp1(v, OP_Undef, pDest->iSdst); /* Signal EOF */ + sqlite3VdbeAddOp1(v, OP_Yield, regYield); /* yield X */ sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_INTERNAL, OE_Abort); VdbeComment((v, "End of coroutine")); sqlite3VdbeJumpHere(v, j1); /* label B: */ @@ -488,7 +479,6 @@ static int xferOptimization( ** and the SELECT clause does not read from
    at any time. ** The generated code follows this template: ** -** EOF <- 0 ** X <- A ** goto B ** A: setup for the SELECT @@ -497,12 +487,12 @@ static int xferOptimization( ** yield X ** end loop ** cleanup after the SELECT -** EOF <- 1 +** R <- undefined (signals EOF) ** yield X ** goto A ** B: open write cursor to
    and its indices ** C: yield X -** if EOF goto D +** if R=undefined goto D ** insert the select result into
    from R..R+n ** goto C ** D: cleanup @@ -513,7 +503,6 @@ static int xferOptimization( ** we have to use a intermediate table to store the results of ** the select. The template is like this: ** -** EOF <- 0 ** X <- A ** goto B ** A: setup for the SELECT @@ -522,12 +511,12 @@ static int xferOptimization( ** yield X ** end loop ** cleanup after the SELECT -** EOF <- 1 +** R <- undefined (signals EOF) ** yield X ** halt-error ** B: open temp table ** L: yield X -** if EOF goto M +** if R=undefined goto M ** insert row from R..R+n into temp table ** goto L ** M: open write cursor to
    and its indices @@ -576,7 +565,6 @@ void sqlite3Insert( int regIns; /* Block of regs holding rowid+data being inserted */ int regRowid; /* registers holding insert rowid */ int regData; /* register holding first column to insert */ - int regEof = 0; /* Register recording end of SELECT data */ int *aRegIdx = 0; /* One register allocated to each index */ #ifndef SQLITE_OMIT_TRIGGER @@ -689,7 +677,6 @@ void sqlite3Insert( int rc = sqlite3CodeCoroutine(pParse, pSelect, &dest); if( rc ) goto insert_cleanup; - regEof = dest.iSDParm + 1; regFromSelect = dest.iSdst; assert( pSelect->pEList ); nColumn = pSelect->pEList->nExpr; @@ -715,7 +702,7 @@ void sqlite3Insert( ** ** B: open temp table ** L: yield X - ** if EOF goto M + ** if R=undefined goto M ** insert row from R..R+n into temp table ** goto L ** M: ... @@ -730,7 +717,7 @@ void sqlite3Insert( regTempRowid = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp2(v, OP_OpenEphemeral, srcTab, nColumn); addrTop = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); - addrIf = sqlite3VdbeAddOp1(v, OP_If, regEof); + addrIf = sqlite3VdbeAddOp1(v, OP_IsUndef, regFromSelect); sqlite3VdbeAddOp3(v, OP_MakeRecord, regFromSelect, nColumn, regRec); sqlite3VdbeAddOp2(v, OP_NewRowid, srcTab, regTempRowid); sqlite3VdbeAddOp3(v, OP_Insert, srcTab, regRec, regTempRowid); @@ -860,13 +847,13 @@ void sqlite3Insert( ** following pseudocode (template 3): ** ** C: yield X - ** if EOF goto D + ** if R=undefined goto D ** insert the select result into
    from R..R+n ** goto C ** D: ... */ addrCont = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); - addrInsTop = sqlite3VdbeAddOp1(v, OP_If, regEof); + addrInsTop = sqlite3VdbeAddOp1(v, OP_IsUndef, dest.iSdst); } /* Allocate registers for holding the rowid of the new row, diff --git a/src/vdbe.c b/src/vdbe.c index 5816c4a797..ab025ac48d 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -393,7 +393,7 @@ void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf){ ** Print the value of a register for tracing purposes: */ static void memTracePrint(Mem *p){ - if( p->flags & MEM_Invalid ){ + if( p->flags & MEM_Undefined ){ printf(" undefined"); }else if( p->flags & MEM_Null ){ printf(" NULL"); @@ -702,7 +702,6 @@ check_for_interrupt: } /* Opcode: Gosub P1 P2 * * * -** Synopsis: r[P1]=pc; pc=P2 ** ** Write the current address onto register P1 ** and then jump to address P2. @@ -720,7 +719,6 @@ case OP_Gosub: { /* jump */ } /* Opcode: Return P1 * * * * -** Synopsis: pc=r[P1]+1 ** ** Jump to the next instruction after the address in register P1. */ @@ -732,7 +730,6 @@ case OP_Return: { /* in1 */ } /* Opcode: Yield P1 * * * * -** Synopsis: swap(pc,r[P1]) ** ** Swap the program counter with the value in register P1. */ @@ -974,7 +971,7 @@ case OP_Null: { /* out2-prerelease */ } -/* Opcode: Blob P1 P2 * P4 +/* Opcode: Blob P1 P2 * P4 * ** Synopsis: r[P2]=P4 (len=P1) ** ** P4 points to a blob of data P1 bytes long. Store this @@ -988,6 +985,21 @@ case OP_Blob: { /* out2-prerelease */ break; } +/* Opcode: Undef P1 * * * * +** Synopsis: r[P1]=undef +** +** Mark register P1 as undefined. +*/ +case OP_Undef: { + assert( pOp->p1>0 ); + assert( pOp->p1<=(p->nMem-p->nCursor) ); + pOut = &aMem[pOp->p1]; + memAboutToChange(p, pOut); + VdbeMemRelease(pOut); + pOut->flags = MEM_Undefined; + break; +} + /* Opcode: Variable P1 P2 * P4 * ** Synopsis: r[P2]=parameter(P1,P4) ** @@ -2142,6 +2154,19 @@ case OP_IfNot: { /* jump, in1 */ break; } +/* Opcode: IsUndef P1 P2 * * * +** Synopsis: if r[P1]==undefined goto P2 +** +** Jump to P2 if the value in register P1 is undefined +*/ +case OP_IsUndef: { /* jump */ + pIn1 = &aMem[pOp->p1]; + if( (pIn1->flags & MEM_Undefined)!=0 ){ + pc = pOp->p2 - 1; + } + break; +} + /* Opcode: IsNull P1 P2 * * * ** Synopsis: if r[P1]==NULL goto P2 ** @@ -5191,7 +5216,7 @@ case OP_Program: { /* jump */ pEnd = &VdbeFrameMem(pFrame)[pFrame->nChildMem]; for(pMem=VdbeFrameMem(pFrame); pMem!=pEnd; pMem++){ - pMem->flags = MEM_Invalid; + pMem->flags = MEM_Undefined; pMem->db = db; } }else{ diff --git a/src/vdbeInt.h b/src/vdbeInt.h index c4fa26cc05..4da24b2374 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -198,7 +198,7 @@ struct Mem { #define MEM_Blob 0x0010 /* Value is a BLOB */ #define MEM_RowSet 0x0020 /* Value is a RowSet object */ #define MEM_Frame 0x0040 /* Value is a VdbeFrame object */ -#define MEM_Invalid 0x0080 /* Value is undefined */ +#define MEM_Undefined 0x0080 /* Value is undefined */ #define MEM_Cleared 0x0100 /* NULL set by OP_Null, not from data */ #define MEM_TypeMask 0x01ff /* Mask of type bits */ @@ -230,7 +230,7 @@ struct Mem { ** is for use inside assert() statements only. */ #ifdef SQLITE_DEBUG -#define memIsValid(M) ((M)->flags & MEM_Invalid)==0 +#define memIsValid(M) ((M)->flags & MEM_Undefined)==0 #endif /* diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 69611622af..59b766a79c 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1234,7 +1234,7 @@ static void releaseMemArray(Mem *p, int N){ p->zMalloc = 0; } - p->flags = MEM_Invalid; + p->flags = MEM_Undefined; } db->mallocFailed = malloc_failed; } @@ -1702,7 +1702,7 @@ void sqlite3VdbeMakeReady( p->aMem--; /* aMem[] goes from 1..nMem */ p->nMem = nMem; /* not from 0..nMem-1 */ for(n=1; n<=nMem; n++){ - p->aMem[n].flags = MEM_Invalid; + p->aMem[n].flags = MEM_Undefined; p->aMem[n].db = db; } } @@ -1814,7 +1814,7 @@ static void Cleanup(Vdbe *p){ int i; if( p->apCsr ) for(i=0; inCursor; i++) assert( p->apCsr[i]==0 ); if( p->aMem ){ - for(i=1; i<=p->nMem; i++) assert( p->aMem[i].flags==MEM_Invalid ); + for(i=1; i<=p->nMem; i++) assert( p->aMem[i].flags==MEM_Undefined ); } #endif diff --git a/src/vdbemem.c b/src/vdbemem.c index 9a621d1f73..982a44537d 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -587,7 +587,7 @@ void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){ Mem *pX; for(i=1, pX=&pVdbe->aMem[1]; i<=pVdbe->nMem; i++, pX++){ if( pX->pScopyFrom==pMem ){ - pX->flags |= MEM_Invalid; + pX->flags |= MEM_Undefined; pX->pScopyFrom = 0; } } From 81cf13ec7b271740b6c6b7ccd00206e666c6cdc6 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 7 Feb 2014 18:27:53 +0000 Subject: [PATCH 224/276] Get rid of the OP_Undef and OP_IsUndef opcodes in favor of higher-level OP_InitCoroutine and OP_EndCoroutine. FossilOrigin-Name: 1ec0e9dd4b26d9f597adc8e062317d4866c5a6a6 --- manifest | 21 ++++++++------ manifest.uuid | 2 +- src/insert.c | 44 +++++++++-------------------- src/select.c | 70 +++++++++++++++------------------------------ src/vdbe.c | 78 ++++++++++++++++++++++++++++++--------------------- src/where.c | 5 ++-- 6 files changed, 97 insertions(+), 123 deletions(-) diff --git a/manifest b/manifest index 9feb2fda5b..87abf54582 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sOP_Undef\sand\sOP_IsUndef\sopcodes.\s\sWith\sthese,\suse\sthe\sfirst\sregister\nin\sthe\sresult\sregister\srange\sas\sthe\sflag\sto\sindicate\sEOF\son\san\sINSERT\sfrom\na\sSELECT,\srather\sthan\sallocating\sa\sseparate\sboolean\sregister\sfor\sthat\stask. -D 2014-02-07T13:20:31.855 +C Get\srid\sof\sthe\sOP_Undef\sand\sOP_IsUndef\sopcodes\sin\sfavor\sof\shigher-level\nOP_InitCoroutine\sand\sOP_EndCoroutine. +D 2014-02-07T18:27:53.008 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -183,7 +183,7 @@ F src/global.c 1d7bb7ea8254ae6a68ed9bfaf65fcb3d1690b486 F src/hash.c d139319967164f139c8d1bb8a11b14db9c4ba3cd F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c fa98632fbf46e01c7b4d2130558c74b42947f50d +F src/insert.c 5997c3fbd5957b323f851d84d2ede380519cf2f6 F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b @@ -219,7 +219,7 @@ F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c b78f5e62c283aca2e38657938bc1fec1051df728 +F src/select.c 01d0eca0938b588daabb36cd73e395309bdc6097 F src/shell.c 7dedf7367ee49050b0366bf8dbc8ec2bd15b42c7 F src/sqlite.h.in eed7f7d66a60daaa7b4a597dcd9bad87aad9611b F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e @@ -280,7 +280,7 @@ F src/update.c a7df6fffce6bfedc578fda6136dd33e34a63f8ee F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c 15ac2627f548f5481d0d7e6c4eb67be673027695 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c 8697f15ad86604c5a8d598b1566e1594a7956469 +F src/vdbe.c 10ddcf5fd28ff23655b6e953e345c45b42642472 F src/vdbe.h e6c4c610fcabad4fa80ebb1efc6822a9367e2b26 F src/vdbeInt.h bd6d5e70fe7c80f6aa4c56c34589762b9e933929 F src/vdbeapi.c ce4e68ea4842cc6081046f533d088dcf01d247ad @@ -293,7 +293,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45 -F src/where.c bacb79fb31e082c9c599e68e5e9f161e1d5430ca +F src/where.c 07179d15d72c1dfffaf7d175d7e26517de04971e F src/whereInt.h 921f935af8b684ffb49705610bda7284db1db138 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1152,7 +1152,10 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P be24fbc22106e508975e316abe0471edd3833291 -R 7163c03b39a8cc1205867ee33d31d20c +P 6fb7448550f28a3c93053e125faeaf11de1011d0 +R 0b346c83ba3e4f94eace870fa077c226 +T *branch * coroutine-refactor +T *sym-coroutine-refactor * +T -sym-trunk * U drh -Z 84c60c97897782670b677e52594a24b3 +Z 037b150ffb17771c8c249859dd8749bd diff --git a/manifest.uuid b/manifest.uuid index a1ffd679c6..dfcfb30fb0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6fb7448550f28a3c93053e125faeaf11de1011d0 \ No newline at end of file +1ec0e9dd4b26d9f597adc8e062317d4866c5a6a6 \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index edf277876f..c7e60a478e 100644 --- a/src/insert.c +++ b/src/insert.c @@ -373,16 +373,13 @@ void sqlite3AutoincrementEnd(Parse *pParse){ ** yield X ** end loop ** cleanup after the SELECT -** R <- undefined (signals EOF) -** yield X -** halt-error +** end co-routine R ** B: ** ** To use this subroutine, the caller generates code as follows: ** ** [ Co-routine generated by this subroutine, shown above ] -** S: yield X -** if R==undefined goto E +** S: yield X, at EOF goto E ** if skip this row, goto C ** if terminate loop, goto E ** deal with this row @@ -399,18 +396,14 @@ int sqlite3CodeCoroutine(Parse *pParse, Select *pSelect, SelectDest *pDest){ regYield = ++pParse->nMem; v = sqlite3GetVdbe(pParse); addrTop = sqlite3VdbeCurrentAddr(v); - sqlite3VdbeAddOp2(v, OP_Integer, addrTop+1, regYield); /* X <- A */ - VdbeComment((v, "Co-routine entry point")); + sqlite3VdbeAddOp2(v, OP_InitCoroutine, regYield, addrTop+2); sqlite3SelectDestInit(pDest, SRT_Coroutine, regYield); j1 = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0); rc = sqlite3Select(pParse, pSelect, pDest); assert( pParse->nErr==0 || rc ); if( pParse->db->mallocFailed && rc==SQLITE_OK ) rc = SQLITE_NOMEM; if( rc ) return rc; - sqlite3VdbeAddOp1(v, OP_Undef, pDest->iSdst); /* Signal EOF */ - sqlite3VdbeAddOp1(v, OP_Yield, regYield); /* yield X */ - sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_INTERNAL, OE_Abort); - VdbeComment((v, "End of coroutine")); + sqlite3VdbeAddOp1(v, OP_EndCoroutine, regYield); sqlite3VdbeJumpHere(v, j1); /* label B: */ return rc; } @@ -487,12 +480,9 @@ static int xferOptimization( ** yield X ** end loop ** cleanup after the SELECT -** R <- undefined (signals EOF) -** yield X -** goto A +** end-coroutine X ** B: open write cursor to
    and its indices -** C: yield X -** if R=undefined goto D +** C: yield X, at EOF goto D ** insert the select result into
    from R..R+n ** goto C ** D: cleanup @@ -511,12 +501,9 @@ static int xferOptimization( ** yield X ** end loop ** cleanup after the SELECT -** R <- undefined (signals EOF) -** yield X -** halt-error +** end co-routine R ** B: open temp table -** L: yield X -** if R=undefined goto M +** L: yield X, at EOF goto M ** insert row from R..R+n into temp table ** goto L ** M: open write cursor to
    and its indices @@ -701,8 +688,7 @@ void sqlite3Insert( ** here is from the 4th template: ** ** B: open temp table - ** L: yield X - ** if R=undefined goto M + ** L: yield X, goto M at EOF ** insert row from R..R+n into temp table ** goto L ** M: ... @@ -710,19 +696,17 @@ void sqlite3Insert( int regRec; /* Register to hold packed record */ int regTempRowid; /* Register to hold temp table ROWID */ int addrTop; /* Label "L" */ - int addrIf; /* Address of jump to M */ srcTab = pParse->nTab++; regRec = sqlite3GetTempReg(pParse); regTempRowid = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp2(v, OP_OpenEphemeral, srcTab, nColumn); addrTop = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); - addrIf = sqlite3VdbeAddOp1(v, OP_IsUndef, regFromSelect); sqlite3VdbeAddOp3(v, OP_MakeRecord, regFromSelect, nColumn, regRec); sqlite3VdbeAddOp2(v, OP_NewRowid, srcTab, regTempRowid); sqlite3VdbeAddOp3(v, OP_Insert, srcTab, regRec, regTempRowid); sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop); - sqlite3VdbeJumpHere(v, addrIf); + sqlite3VdbeJumpHere(v, addrTop); sqlite3ReleaseTempReg(pParse, regRec); sqlite3ReleaseTempReg(pParse, regTempRowid); } @@ -834,7 +818,7 @@ void sqlite3Insert( /* This block codes the top of loop only. The complete loop is the ** following pseudocode (template 4): ** - ** rewind temp table + ** rewind temp table, if empty goto D ** C: loop over rows of intermediate table ** transfer values form intermediate table into
    ** end loop @@ -846,14 +830,12 @@ void sqlite3Insert( /* This block codes the top of loop only. The complete loop is the ** following pseudocode (template 3): ** - ** C: yield X - ** if R=undefined goto D + ** C: yield X, at EOF goto D ** insert the select result into
    from R..R+n ** goto C ** D: ... */ - addrCont = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); - addrInsTop = sqlite3VdbeAddOp1(v, OP_IsUndef, dest.iSdst); + addrInsTop = addrCont = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); } /* Allocate registers for holding the rowid of the new row, diff --git a/src/select.c b/src/select.c index f923766c85..c82e3d30c5 100644 --- a/src/select.c +++ b/src/select.c @@ -765,12 +765,8 @@ static void selectInnerLoop( } #endif /* #ifndef SQLITE_OMIT_SUBQUERY */ - /* Send the data to the callback function or to a subroutine. In the - ** case of a subroutine, the subroutine itself is responsible for - ** popping the data from the stack. - */ - case SRT_Coroutine: - case SRT_Output: { + case SRT_Coroutine: /* Send data to a co-routine */ + case SRT_Output: { /* Return the results */ testcase( eDest==SRT_Coroutine ); testcase( eDest==SRT_Output ); if( pOrderBy ){ @@ -2572,9 +2568,7 @@ static int multiSelectOrderBy( SelectDest destA; /* Destination for coroutine A */ SelectDest destB; /* Destination for coroutine B */ int regAddrA; /* Address register for select-A coroutine */ - int regEofA; /* Flag to indicate when select-A is complete */ int regAddrB; /* Address register for select-B coroutine */ - int regEofB; /* Flag to indicate when select-B is complete */ int addrSelectA; /* Address of the select-A coroutine */ int addrSelectB; /* Address of the select-B coroutine */ int regOutA; /* Address register for the output-A subroutine */ @@ -2582,6 +2576,7 @@ static int multiSelectOrderBy( int addrOutA; /* Address of the output-A subroutine */ int addrOutB = 0; /* Address of the output-B subroutine */ int addrEofA; /* Address of the select-A-exhausted subroutine */ + int addrEofA_noB; /* Alternate addrEofA if B is uninitialized */ int addrEofB; /* Address of the select-B-exhausted subroutine */ int addrAltB; /* Address of the ApOffset = 0; regAddrA = ++pParse->nMem; - regEofA = ++pParse->nMem; regAddrB = ++pParse->nMem; - regEofB = ++pParse->nMem; regOutA = ++pParse->nMem; regOutB = ++pParse->nMem; sqlite3SelectDestInit(&destA, SRT_Coroutine, regAddrA); @@ -2730,25 +2723,23 @@ static int multiSelectOrderBy( ** merge loop */ j1 = sqlite3VdbeAddOp0(v, OP_Goto); - addrSelectA = sqlite3VdbeCurrentAddr(v); /* Generate a coroutine to evaluate the SELECT statement to the ** left of the compound operator - the "A" select. */ - VdbeNoopComment((v, "Begin coroutine for left SELECT")); + VdbeNoopComment((v, "coroutine for left SELECT")); + addrSelectA = sqlite3VdbeCurrentAddr(v); pPrior->iLimit = regLimitA; explainSetInteger(iSub1, pParse->iNextSelectId); sqlite3Select(pParse, pPrior, &destA); - sqlite3VdbeAddOp2(v, OP_Integer, 1, regEofA); - sqlite3VdbeAddOp1(v, OP_Yield, regAddrA); - VdbeNoopComment((v, "End coroutine for left SELECT")); + sqlite3VdbeAddOp1(v, OP_EndCoroutine, regAddrA); /* Generate a coroutine to evaluate the SELECT statement on ** the right - the "B" select */ + VdbeNoopComment((v, "coroutine for right SELECT")); addrSelectB = sqlite3VdbeCurrentAddr(v); - VdbeNoopComment((v, "Begin coroutine for right SELECT")); savedLimit = p->iLimit; savedOffset = p->iOffset; p->iLimit = regLimitB; @@ -2757,9 +2748,7 @@ static int multiSelectOrderBy( sqlite3Select(pParse, p, &destB); p->iLimit = savedLimit; p->iOffset = savedOffset; - sqlite3VdbeAddOp2(v, OP_Integer, 1, regEofB); - sqlite3VdbeAddOp1(v, OP_Yield, regAddrB); - VdbeNoopComment((v, "End coroutine for right SELECT")); + sqlite3VdbeAddOp1(v, OP_EndCoroutine, regAddrB); /* Generate a subroutine that outputs the current row of the A ** select as the next output row of the compound select. @@ -2783,13 +2772,12 @@ static int multiSelectOrderBy( /* Generate a subroutine to run when the results from select A ** are exhausted and only data in select B remains. */ - VdbeNoopComment((v, "eof-A subroutine")); if( op==TK_EXCEPT || op==TK_INTERSECT ){ - addrEofA = sqlite3VdbeAddOp2(v, OP_Goto, 0, labelEnd); + addrEofA_noB = addrEofA = labelEnd; }else{ - addrEofA = sqlite3VdbeAddOp2(v, OP_If, regEofB, labelEnd); - sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB); - sqlite3VdbeAddOp1(v, OP_Yield, regAddrB); + VdbeNoopComment((v, "eof-A subroutine")); + addrEofA = sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB); + addrEofA_noB = sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, labelEnd); sqlite3VdbeAddOp2(v, OP_Goto, 0, addrEofA); p->nSelectRow += pPrior->nSelectRow; } @@ -2802,9 +2790,8 @@ static int multiSelectOrderBy( if( p->nSelectRow > pPrior->nSelectRow ) p->nSelectRow = pPrior->nSelectRow; }else{ VdbeNoopComment((v, "eof-B subroutine")); - addrEofB = sqlite3VdbeAddOp2(v, OP_If, regEofA, labelEnd); - sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA); - sqlite3VdbeAddOp1(v, OP_Yield, regAddrA); + addrEofB = sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA); + sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, labelEnd); sqlite3VdbeAddOp2(v, OP_Goto, 0, addrEofB); } @@ -2812,8 +2799,7 @@ static int multiSelectOrderBy( */ VdbeNoopComment((v, "A-lt-B subroutine")); addrAltB = sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA); - sqlite3VdbeAddOp1(v, OP_Yield, regAddrA); - sqlite3VdbeAddOp2(v, OP_If, regEofA, addrEofA); + sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, addrEofA); sqlite3VdbeAddOp2(v, OP_Goto, 0, labelCmpr); /* Generate code to handle the case of A==B @@ -2826,8 +2812,7 @@ static int multiSelectOrderBy( }else{ VdbeNoopComment((v, "A-eq-B subroutine")); addrAeqB = - sqlite3VdbeAddOp1(v, OP_Yield, regAddrA); - sqlite3VdbeAddOp2(v, OP_If, regEofA, addrEofA); + sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, addrEofA); sqlite3VdbeAddOp2(v, OP_Goto, 0, labelCmpr); } @@ -2838,19 +2823,16 @@ static int multiSelectOrderBy( if( op==TK_ALL || op==TK_UNION ){ sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB); } - sqlite3VdbeAddOp1(v, OP_Yield, regAddrB); - sqlite3VdbeAddOp2(v, OP_If, regEofB, addrEofB); + sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, addrEofB); sqlite3VdbeAddOp2(v, OP_Goto, 0, labelCmpr); /* This code runs once to initialize everything. */ sqlite3VdbeJumpHere(v, j1); - sqlite3VdbeAddOp2(v, OP_Integer, 0, regEofA); - sqlite3VdbeAddOp2(v, OP_Integer, 0, regEofB); - sqlite3VdbeAddOp2(v, OP_Gosub, regAddrA, addrSelectA); - sqlite3VdbeAddOp2(v, OP_Gosub, regAddrB, addrSelectB); - sqlite3VdbeAddOp2(v, OP_If, regEofA, addrEofA); - sqlite3VdbeAddOp2(v, OP_If, regEofB, addrEofB); + sqlite3VdbeAddOp2(v, OP_InitCoroutine, regAddrA, addrSelectA); + sqlite3VdbeAddOp2(v, OP_InitCoroutine, regAddrB, addrSelectB); + sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, addrEofA_noB); + sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, addrEofB); /* Implement the main merge loop */ @@ -4559,9 +4541,7 @@ int sqlite3Select( ** set on each invocation. */ int addrTop; - int addrEof; pItem->regReturn = ++pParse->nMem; - addrEof = ++pParse->nMem; /* Before coding the OP_Goto to jump to the start of the main routine, ** ensure that the jump to the verify-schema routine has already ** been coded. Otherwise, the verify-schema would likely be coded as @@ -4574,10 +4554,8 @@ int sqlite3Select( sqlite3VdbeAddOp0(v, OP_Goto); addrTop = sqlite3VdbeAddOp1(v, OP_OpenPseudo, pItem->iCursor); sqlite3VdbeChangeP5(v, 1); - VdbeComment((v, "coroutine for %s", pItem->pTab->zName)); + VdbeComment((v, "coroutine %s", pItem->pTab->zName)); pItem->addrFillSub = addrTop; - sqlite3VdbeAddOp2(v, OP_Integer, 0, addrEof); - sqlite3VdbeChangeP5(v, 1); sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn); explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId); sqlite3Select(pParse, pSub, &dest); @@ -4585,9 +4563,7 @@ int sqlite3Select( pItem->viaCoroutine = 1; sqlite3VdbeChangeP2(v, addrTop, dest.iSdst); sqlite3VdbeChangeP3(v, addrTop, dest.nSdst); - sqlite3VdbeAddOp2(v, OP_Integer, 1, addrEof); - sqlite3VdbeAddOp1(v, OP_Yield, pItem->regReturn); - VdbeComment((v, "end %s", pItem->pTab->zName)); + sqlite3VdbeAddOp1(v, OP_EndCoroutine, pItem->regReturn); sqlite3VdbeJumpHere(v, addrTop-1); sqlite3ClearTempRegCache(pParse); }else{ diff --git a/src/vdbe.c b/src/vdbe.c index ab025ac48d..dd854d7c18 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -720,20 +720,62 @@ case OP_Gosub: { /* jump */ /* Opcode: Return P1 * * * * ** -** Jump to the next instruction after the address in register P1. +** Jump to the next instruction after the address in register P1. After +** the jump, register P1 becomes undefined. */ case OP_Return: { /* in1 */ pIn1 = &aMem[pOp->p1]; - assert( pIn1->flags & MEM_Int ); + assert( pIn1->flags==MEM_Int ); pc = (int)pIn1->u.i; + pIn1->flags = MEM_Undefined; break; } -/* Opcode: Yield P1 * * * * +/* Opcode: InitCoroutine P1 P2 * * * +** +** Identify the co-routine at address P2 using the register P1 +** as its return address. Run this opcode prior to the first +** OP_Yield to invoke the co-routine. +*/ +case OP_InitCoroutine: { /* jump */ + assert( pOp->p1>0 ); + assert( pOp->p1<=(p->nMem-p->nCursor) ); + pOut = &aMem[pOp->p1]; + memAboutToChange(p, pOut); + VdbeMemRelease(pOut); + pOut->u.i = pOp->p2 - 1; + pOut->flags = MEM_Int; + break; +} + +/* Opcode: EndCoroutine P1 * * * * +** +** The instruction at the address in register P1 is an OP_Yield. +** Jump to the P2 parameter of that OP_Yield. +** After the jump, register P1 becomes undefined. +*/ +case OP_EndCoroutine: { /* in1 */ + VdbeOp *pCaller; + pIn1 = &aMem[pOp->p1]; + assert( pIn1->flags==MEM_Int ); + assert( pIn1->u.i>=0 && pIn1->u.inOp ); + pCaller = &aOp[pIn1->u.i]; + assert( pCaller->opcode==OP_Yield ); + assert( pCaller->p2>=0 && pCaller->p2nOp ); + pc = pCaller->p2 - 1; + pIn1->flags = MEM_Undefined; + break; +} + +/* Opcode: Yield P1 P2 * * * ** ** Swap the program counter with the value in register P1. +** +** If the co-routine ends with OP_Yield or OP_Return then continue +** to the next instruction. But if the co-routine ends with +** OP_EndCoroutine, jump immediately to P2. */ -case OP_Yield: { /* in1 */ +case OP_Yield: { /* in1, jump */ int pcDest; pIn1 = &aMem[pOp->p1]; assert( (pIn1->flags & MEM_Dyn)==0 ); @@ -985,21 +1027,6 @@ case OP_Blob: { /* out2-prerelease */ break; } -/* Opcode: Undef P1 * * * * -** Synopsis: r[P1]=undef -** -** Mark register P1 as undefined. -*/ -case OP_Undef: { - assert( pOp->p1>0 ); - assert( pOp->p1<=(p->nMem-p->nCursor) ); - pOut = &aMem[pOp->p1]; - memAboutToChange(p, pOut); - VdbeMemRelease(pOut); - pOut->flags = MEM_Undefined; - break; -} - /* Opcode: Variable P1 P2 * P4 * ** Synopsis: r[P2]=parameter(P1,P4) ** @@ -2154,19 +2181,6 @@ case OP_IfNot: { /* jump, in1 */ break; } -/* Opcode: IsUndef P1 P2 * * * -** Synopsis: if r[P1]==undefined goto P2 -** -** Jump to P2 if the value in register P1 is undefined -*/ -case OP_IsUndef: { /* jump */ - pIn1 = &aMem[pOp->p1]; - if( (pIn1->flags & MEM_Undefined)!=0 ){ - pc = pOp->p2 - 1; - } - break; -} - /* Opcode: IsNull P1 P2 * * * ** Synopsis: if r[P1]==NULL goto P2 ** diff --git a/src/where.c b/src/where.c index a900dd0b84..5ae72e9152 100644 --- a/src/where.c +++ b/src/where.c @@ -2785,10 +2785,9 @@ static Bitmask codeOneLoopStart( /* Special case of a FROM clause subquery implemented as a co-routine */ if( pTabItem->viaCoroutine ){ int regYield = pTabItem->regReturn; - sqlite3VdbeAddOp2(v, OP_Integer, pTabItem->addrFillSub-1, regYield); - pLevel->p2 = sqlite3VdbeAddOp1(v, OP_Yield, regYield); + sqlite3VdbeAddOp2(v, OP_InitCoroutine, regYield, pTabItem->addrFillSub); + pLevel->p2 = sqlite3VdbeAddOp2(v, OP_Yield, regYield, addrBrk); VdbeComment((v, "next row of co-routine %s", pTabItem->pTab->zName)); - sqlite3VdbeAddOp2(v, OP_If, regYield+1, addrBrk); pLevel->op = OP_Goto; }else From ed71a839fdc5a1fc9ae7bf42fb223db7e0bf8d6d Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 7 Feb 2014 19:18:10 +0000 Subject: [PATCH 225/276] Change the OP_InitCoroutine instruction to jump over the co-routine implementation. FossilOrigin-Name: a522f364a6b8ca6f69c353b30609a2166f6e94cf --- manifest | 23 ++++++++++------------- manifest.uuid | 2 +- src/insert.c | 8 +++----- src/select.c | 19 +++++++------------ src/vdbe.c | 22 +++++++++++++--------- src/vdbeInt.h | 5 +++-- src/where.c | 2 +- 7 files changed, 38 insertions(+), 43 deletions(-) diff --git a/manifest b/manifest index 87abf54582..cea46f3009 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Get\srid\sof\sthe\sOP_Undef\sand\sOP_IsUndef\sopcodes\sin\sfavor\sof\shigher-level\nOP_InitCoroutine\sand\sOP_EndCoroutine. -D 2014-02-07T18:27:53.008 +C Change\sthe\sOP_InitCoroutine\sinstruction\sto\sjump\sover\sthe\sco-routine\nimplementation. +D 2014-02-07T19:18:10.928 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -183,7 +183,7 @@ F src/global.c 1d7bb7ea8254ae6a68ed9bfaf65fcb3d1690b486 F src/hash.c d139319967164f139c8d1bb8a11b14db9c4ba3cd F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c 5997c3fbd5957b323f851d84d2ede380519cf2f6 +F src/insert.c b50cb5a51edb0d6e1a99e04b232b8632a54e522a F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b @@ -219,7 +219,7 @@ F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c 01d0eca0938b588daabb36cd73e395309bdc6097 +F src/select.c 47d93e6f0b58000e2093e7b489bdca778884f82a F src/shell.c 7dedf7367ee49050b0366bf8dbc8ec2bd15b42c7 F src/sqlite.h.in eed7f7d66a60daaa7b4a597dcd9bad87aad9611b F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e @@ -280,9 +280,9 @@ F src/update.c a7df6fffce6bfedc578fda6136dd33e34a63f8ee F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c 15ac2627f548f5481d0d7e6c4eb67be673027695 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c 10ddcf5fd28ff23655b6e953e345c45b42642472 +F src/vdbe.c e7bb0587ad4866c0db5fe3b83104c4df8f93d19f F src/vdbe.h e6c4c610fcabad4fa80ebb1efc6822a9367e2b26 -F src/vdbeInt.h bd6d5e70fe7c80f6aa4c56c34589762b9e933929 +F src/vdbeInt.h b5d62957a408c4bea649484008e5f98335b09e97 F src/vdbeapi.c ce4e68ea4842cc6081046f533d088dcf01d247ad F src/vdbeaux.c 3fd95b226330e1d50aedb40d750effe726ebb3fb F src/vdbeblob.c 9542e116c1db5ed813977581d506c176e117c0ec @@ -293,7 +293,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45 -F src/where.c 07179d15d72c1dfffaf7d175d7e26517de04971e +F src/where.c 8c2aada8b44140382406cf07b84ff2f6127cb39e F src/whereInt.h 921f935af8b684ffb49705610bda7284db1db138 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1152,10 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 6fb7448550f28a3c93053e125faeaf11de1011d0 -R 0b346c83ba3e4f94eace870fa077c226 -T *branch * coroutine-refactor -T *sym-coroutine-refactor * -T -sym-trunk * +P 1ec0e9dd4b26d9f597adc8e062317d4866c5a6a6 +R dbad771d6a0c64046f81724e16a6d61c U drh -Z 037b150ffb17771c8c249859dd8749bd +Z bb5cd7d324cd2ad57b192424d498539f diff --git a/manifest.uuid b/manifest.uuid index dfcfb30fb0..9e9204f927 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1ec0e9dd4b26d9f597adc8e062317d4866c5a6a6 \ No newline at end of file +a522f364a6b8ca6f69c353b30609a2166f6e94cf \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index c7e60a478e..5dbdf9108a 100644 --- a/src/insert.c +++ b/src/insert.c @@ -389,22 +389,20 @@ void sqlite3AutoincrementEnd(Parse *pParse){ int sqlite3CodeCoroutine(Parse *pParse, Select *pSelect, SelectDest *pDest){ int regYield; /* Register holding co-routine entry-point */ int addrTop; /* Top of the co-routine */ - int j1; /* Jump instruction */ int rc; /* Result code */ Vdbe *v; /* VDBE under construction */ regYield = ++pParse->nMem; v = sqlite3GetVdbe(pParse); - addrTop = sqlite3VdbeCurrentAddr(v); - sqlite3VdbeAddOp2(v, OP_InitCoroutine, regYield, addrTop+2); + addrTop = sqlite3VdbeCurrentAddr(v) + 1; + sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop); sqlite3SelectDestInit(pDest, SRT_Coroutine, regYield); - j1 = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0); rc = sqlite3Select(pParse, pSelect, pDest); assert( pParse->nErr==0 || rc ); if( pParse->db->mallocFailed && rc==SQLITE_OK ) rc = SQLITE_NOMEM; if( rc ) return rc; sqlite3VdbeAddOp1(v, OP_EndCoroutine, regYield); - sqlite3VdbeJumpHere(v, j1); /* label B: */ + sqlite3VdbeJumpHere(v, addrTop - 1); /* label B: */ return rc; } diff --git a/src/select.c b/src/select.c index c82e3d30c5..c0728f8873 100644 --- a/src/select.c +++ b/src/select.c @@ -2719,27 +2719,24 @@ static int multiSelectOrderBy( sqlite3SelectDestInit(&destA, SRT_Coroutine, regAddrA); sqlite3SelectDestInit(&destB, SRT_Coroutine, regAddrB); - /* Jump past the various subroutines and coroutines to the main - ** merge loop - */ - j1 = sqlite3VdbeAddOp0(v, OP_Goto); - - /* Generate a coroutine to evaluate the SELECT statement to the ** left of the compound operator - the "A" select. */ - VdbeNoopComment((v, "coroutine for left SELECT")); - addrSelectA = sqlite3VdbeCurrentAddr(v); + addrSelectA = sqlite3VdbeCurrentAddr(v) + 1; + j1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrA, 0, addrSelectA); + VdbeComment((v, "left SELECT")); pPrior->iLimit = regLimitA; explainSetInteger(iSub1, pParse->iNextSelectId); sqlite3Select(pParse, pPrior, &destA); sqlite3VdbeAddOp1(v, OP_EndCoroutine, regAddrA); + sqlite3VdbeJumpHere(v, j1); /* Generate a coroutine to evaluate the SELECT statement on ** the right - the "B" select */ - VdbeNoopComment((v, "coroutine for right SELECT")); - addrSelectB = sqlite3VdbeCurrentAddr(v); + addrSelectB = sqlite3VdbeCurrentAddr(v) + 1; + j1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrB, 0, addrSelectB); + VdbeComment((v, "right SELECT")); savedLimit = p->iLimit; savedOffset = p->iOffset; p->iLimit = regLimitB; @@ -2829,8 +2826,6 @@ static int multiSelectOrderBy( /* This code runs once to initialize everything. */ sqlite3VdbeJumpHere(v, j1); - sqlite3VdbeAddOp2(v, OP_InitCoroutine, regAddrA, addrSelectA); - sqlite3VdbeAddOp2(v, OP_InitCoroutine, regAddrB, addrSelectB); sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, addrEofA_noB); sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, addrEofB); diff --git a/src/vdbe.c b/src/vdbe.c index dd854d7c18..8067f9a12b 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -731,20 +731,24 @@ case OP_Return: { /* in1 */ break; } -/* Opcode: InitCoroutine P1 P2 * * * +/* Opcode: InitCoroutine P1 P2 P3 * * ** -** Identify the co-routine at address P2 using the register P1 -** as its return address. Run this opcode prior to the first -** OP_Yield to invoke the co-routine. +** Set up register P1 so that it will OP_Yield to the co-routine +** located at address P3. +** +** If P2!=0 then the co-routine implementation immediately follows +** this opcode. So jump over the co-routine implementation to +** address P2. */ case OP_InitCoroutine: { /* jump */ - assert( pOp->p1>0 ); - assert( pOp->p1<=(p->nMem-p->nCursor) ); + assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) ); + assert( pOp->p2>=0 && pOp->p2nOp ); + assert( pOp->p3>=0 && pOp->p3nOp ); pOut = &aMem[pOp->p1]; - memAboutToChange(p, pOut); - VdbeMemRelease(pOut); - pOut->u.i = pOp->p2 - 1; + assert( !VdbeMemDynamic(pOut) ); + pOut->u.i = pOp->p3 - 1; pOut->flags = MEM_Int; + if( pOp->p2 ) pc = pOp->p2 - 1; break; } diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 4da24b2374..f1d136a8ef 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -425,9 +425,10 @@ int sqlite3VdbeMemNumerify(Mem*); int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,int,Mem*); void sqlite3VdbeMemRelease(Mem *p); void sqlite3VdbeMemReleaseExternal(Mem *p); +#define VdbeMemDynamic(X) \ + (((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame))!=0) #define VdbeMemRelease(X) \ - if((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame)) \ - sqlite3VdbeMemReleaseExternal(X); + if( VdbeMemDynamic(X) ) sqlite3VdbeMemReleaseExternal(X); int sqlite3VdbeMemFinalize(Mem*, FuncDef*); const char *sqlite3OpcodeName(int); int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve); diff --git a/src/where.c b/src/where.c index 5ae72e9152..9abe3ad1cb 100644 --- a/src/where.c +++ b/src/where.c @@ -2785,7 +2785,7 @@ static Bitmask codeOneLoopStart( /* Special case of a FROM clause subquery implemented as a co-routine */ if( pTabItem->viaCoroutine ){ int regYield = pTabItem->regReturn; - sqlite3VdbeAddOp2(v, OP_InitCoroutine, regYield, pTabItem->addrFillSub); + sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub); pLevel->p2 = sqlite3VdbeAddOp2(v, OP_Yield, regYield, addrBrk); VdbeComment((v, "next row of co-routine %s", pTabItem->pTab->zName)); pLevel->op = OP_Goto; From a198f2b55d716dd03b4a18b4b361c7e092797f3d Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 7 Feb 2014 19:26:13 +0000 Subject: [PATCH 226/276] In the TCL bindings, make sure Tcl_AppendResult() is always terminated by "(char*)0" and not just "0". FossilOrigin-Name: ea4d23d1c0df4fde2e532daa081888712f465884 --- manifest | 14 +++++----- manifest.uuid | 2 +- src/tclsqlite.c | 69 ++++++++++++++++++++++++++----------------------- 3 files changed, 45 insertions(+), 40 deletions(-) diff --git a/manifest b/manifest index 5537506c47..700f104ff6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C More\scomment\supdates.\s\sNo\schanges\sto\scode. -D 2014-02-07T03:28:02.783 +C In\sthe\sTCL\sbindings,\smake\ssure\sTcl_AppendResult()\sis\salways\sterminated\nby\s"(char*)0"\sand\snot\sjust\s"0". +D 2014-02-07T19:26:13.604 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -228,7 +228,7 @@ F src/sqliteInt.h fdab572b3567d587cf3096e3ca5dabcedda3fa66 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e -F src/tclsqlite.c 21ca0043d7c48cde5dabed5c1116eee1be692f62 +F src/tclsqlite.c 649d373f2a3cfbefe8e935a8dec83686616f9a85 F src/test1.c 2401eee14a4309a7cfe2aeb2f30ad517a1d9c299 F src/test2.c 7355101c085304b90024f2261e056cdff13c6c35 F src/test3.c 1c0e5d6f080b8e33c1ce8b3078e7013fdbcd560c @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 1122b410de68a3c79b4c719a3a4cc4dc6a5bb39d -R ba81bea358565b1489c187d643f4773f -U mistachkin -Z fafd555fb9fada47058f4a33fbcaaf41 +P be24fbc22106e508975e316abe0471edd3833291 +R 3b20a064262155765ddc1dcd7881cbe1 +U drh +Z 32dadfb086ccda5c6d983ac169fd7f6c diff --git a/manifest.uuid b/manifest.uuid index affff2d9c4..4ba30ed9a5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -be24fbc22106e508975e316abe0471edd3833291 \ No newline at end of file +ea4d23d1c0df4fde2e532daa081888712f465884 \ No newline at end of file diff --git a/src/tclsqlite.c b/src/tclsqlite.c index 969a83ad45..980032cfd6 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -1025,7 +1025,7 @@ static int DbTransPostCmd( ** this method's logic. Not clear how this would be best handled. */ if( rc!=TCL_ERROR ){ - Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), 0); + Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), (char*)0); rc = TCL_ERROR; } sqlite3_exec(pDb->db, "ROLLBACK", 0, 0, 0); @@ -1675,7 +1675,8 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ */ case DB_AUTHORIZER: { #ifdef SQLITE_OMIT_AUTHORIZATION - Tcl_AppendResult(interp, "authorization not available in this build", 0); + Tcl_AppendResult(interp, "authorization not available in this build", + (char*)0); return TCL_ERROR; #else if( objc>3 ){ @@ -1683,7 +1684,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ return TCL_ERROR; }else if( objc==2 ){ if( pDb->zAuth ){ - Tcl_AppendResult(interp, pDb->zAuth, 0); + Tcl_AppendResult(interp, pDb->zAuth, (char*)0); } }else{ char *zAuth; @@ -1769,7 +1770,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ return TCL_ERROR; }else if( objc==2 ){ if( pDb->zBusy ){ - Tcl_AppendResult(interp, pDb->zBusy, 0); + Tcl_AppendResult(interp, pDb->zBusy, (char*)0); } }else{ char *zBusy; @@ -1823,7 +1824,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ }else{ if( TCL_ERROR==Tcl_GetIntFromObj(interp, objv[3], &n) ){ Tcl_AppendResult( interp, "cannot convert \"", - Tcl_GetStringFromObj(objv[3],0), "\" to integer", 0); + Tcl_GetStringFromObj(objv[3],0), "\" to integer", (char*)0); return TCL_ERROR; }else{ if( n<0 ){ @@ -1837,7 +1838,8 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ } }else{ Tcl_AppendResult( interp, "bad option \"", - Tcl_GetStringFromObj(objv[2],0), "\": must be flush or size", 0); + Tcl_GetStringFromObj(objv[2],0), "\": must be flush or size", + (char*)0); return TCL_ERROR; } break; @@ -1934,7 +1936,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ return TCL_ERROR; }else if( objc==2 ){ if( pDb->zCommit ){ - Tcl_AppendResult(interp, pDb->zCommit, 0); + Tcl_AppendResult(interp, pDb->zCommit, (char*)0); } }else{ const char *zCommit; @@ -2039,7 +2041,8 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ nSep = strlen30(zSep); nNull = strlen30(zNull); if( nSep==0 ){ - Tcl_AppendResult(interp,"Error: non-null separator required for copy",0); + Tcl_AppendResult(interp,"Error: non-null separator required for copy", + (char*)0); return TCL_ERROR; } if(strcmp(zConflict, "rollback") != 0 && @@ -2049,19 +2052,19 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ strcmp(zConflict, "replace" ) != 0 ) { Tcl_AppendResult(interp, "Error: \"", zConflict, "\", conflict-algorithm must be one of: rollback, " - "abort, fail, ignore, or replace", 0); + "abort, fail, ignore, or replace", (char*)0); return TCL_ERROR; } zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable); if( zSql==0 ){ - Tcl_AppendResult(interp, "Error: no such table: ", zTable, 0); + Tcl_AppendResult(interp, "Error: no such table: ", zTable, (char*)0); return TCL_ERROR; } nByte = strlen30(zSql); rc = sqlite3_prepare(pDb->db, zSql, -1, &pStmt, 0); sqlite3_free(zSql); if( rc ){ - Tcl_AppendResult(interp, "Error: ", sqlite3_errmsg(pDb->db), 0); + Tcl_AppendResult(interp, "Error: ", sqlite3_errmsg(pDb->db), (char*)0); nCol = 0; }else{ nCol = sqlite3_column_count(pStmt); @@ -2072,7 +2075,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ } zSql = malloc( nByte + 50 + nCol*2 ); if( zSql==0 ) { - Tcl_AppendResult(interp, "Error: can't malloc()", 0); + Tcl_AppendResult(interp, "Error: can't malloc()", (char*)0); return TCL_ERROR; } sqlite3_snprintf(nByte+50, zSql, "INSERT OR %q INTO '%q' VALUES(?", @@ -2087,7 +2090,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ rc = sqlite3_prepare(pDb->db, zSql, -1, &pStmt, 0); free(zSql); if( rc ){ - Tcl_AppendResult(interp, "Error: ", sqlite3_errmsg(pDb->db), 0); + Tcl_AppendResult(interp, "Error: ", sqlite3_errmsg(pDb->db), (char*)0); sqlite3_finalize(pStmt); return TCL_ERROR; } @@ -2099,7 +2102,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ } azCol = malloc( sizeof(azCol[0])*(nCol+1) ); if( azCol==0 ) { - Tcl_AppendResult(interp, "Error: can't malloc()", 0); + Tcl_AppendResult(interp, "Error: can't malloc()", (char*)0); fclose(in); return TCL_ERROR; } @@ -2127,7 +2130,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ sqlite3_snprintf(nErr, zErr, "Error: %s line %d: expected %d columns of data but found %d", zFile, lineno, nCol, i+1); - Tcl_AppendResult(interp, zErr, 0); + Tcl_AppendResult(interp, zErr, (char*)0); free(zErr); } zCommit = "ROLLBACK"; @@ -2147,7 +2150,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ rc = sqlite3_reset(pStmt); free(zLine); if( rc!=SQLITE_OK ){ - Tcl_AppendResult(interp,"Error: ", sqlite3_errmsg(pDb->db), 0); + Tcl_AppendResult(interp,"Error: ", sqlite3_errmsg(pDb->db), (char*)0); zCommit = "ROLLBACK"; break; } @@ -2165,7 +2168,8 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ }else{ /* failure, append lineno where failed */ sqlite3_snprintf(sizeof(zLineNum), zLineNum,"%d",lineno); - Tcl_AppendResult(interp,", failed while processing line: ",zLineNum,0); + Tcl_AppendResult(interp,", failed while processing line: ",zLineNum, + (char*)0); rc = TCL_ERROR; } break; @@ -2191,7 +2195,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ break; #else Tcl_AppendResult(interp, "extension loading is turned off at compile-time", - 0); + (char*)0); return TCL_ERROR; #endif } @@ -2349,7 +2353,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ */ case DB_INCRBLOB: { #ifdef SQLITE_OMIT_INCRBLOB - Tcl_AppendResult(interp, "incrblob not available in this build", 0); + Tcl_AppendResult(interp, "incrblob not available in this build", (char*)0); return TCL_ERROR; #else int isReadonly = 0; @@ -2456,7 +2460,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ case DB_PROGRESS: { if( objc==2 ){ if( pDb->zProgress ){ - Tcl_AppendResult(interp, pDb->zProgress, 0); + Tcl_AppendResult(interp, pDb->zProgress, (char*)0); } }else if( objc==4 ){ char *zProgress; @@ -2502,7 +2506,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ return TCL_ERROR; }else if( objc==2 ){ if( pDb->zProfile ){ - Tcl_AppendResult(interp, pDb->zProfile, 0); + Tcl_AppendResult(interp, pDb->zProfile, (char*)0); } }else{ char *zProfile; @@ -2547,7 +2551,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ pKey = Tcl_GetByteArrayFromObj(objv[2], &nKey); rc = sqlite3_rekey(pDb->db, pKey, nKey); if( rc ){ - Tcl_AppendResult(interp, sqlite3_errstr(rc), 0); + Tcl_AppendResult(interp, sqlite3_errstr(rc), (char*)0); rc = TCL_ERROR; } #endif @@ -2688,7 +2692,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ return TCL_ERROR; }else if( objc==2 ){ if( pDb->zTrace ){ - Tcl_AppendResult(interp, pDb->zTrace, 0); + Tcl_AppendResult(interp, pDb->zTrace, (char*)0); } }else{ char *zTrace; @@ -2759,7 +2763,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ rc = sqlite3_exec(pDb->db, zBegin, 0, 0, 0); pDb->disableAuth--; if( rc!=SQLITE_OK ){ - Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), 0); + Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), (char*)0); return TCL_ERROR; } pDb->nTransaction++; @@ -2783,7 +2787,8 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ */ case DB_UNLOCK_NOTIFY: { #ifndef SQLITE_ENABLE_UNLOCK_NOTIFY - Tcl_AppendResult(interp, "unlock_notify not available in this build", 0); + Tcl_AppendResult(interp, "unlock_notify not available in this build", + (char*)0); rc = TCL_ERROR; #else if( objc!=2 && objc!=3 ){ @@ -2806,7 +2811,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ } if( sqlite3_unlock_notify(pDb->db, xNotify, pNotifyArg) ){ - Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), 0); + Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), (char*)0); rc = TCL_ERROR; } } @@ -2935,14 +2940,14 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ if( objc==2 ){ zArg = Tcl_GetStringFromObj(objv[1], 0); if( strcmp(zArg,"-version")==0 ){ - Tcl_AppendResult(interp,sqlite3_libversion(),0); + Tcl_AppendResult(interp,sqlite3_libversion(), (char*)0); return TCL_OK; } if( strcmp(zArg,"-has-codec")==0 ){ #ifdef SQLITE_HAS_CODEC - Tcl_AppendResult(interp,"1",0); + Tcl_AppendResult(interp,"1",(char*)0); #else - Tcl_AppendResult(interp,"0",0); + Tcl_AppendResult(interp,"0",(char*)0); #endif return TCL_OK; } @@ -3424,7 +3429,7 @@ static int md5_cmd(void*cd, Tcl_Interp *interp, int argc, const char **argv){ if( argc!=2 ){ Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0], - " TEXT\"", 0); + " TEXT\"", (char*)0); return TCL_ERROR; } MD5Init(&ctx); @@ -3449,13 +3454,13 @@ static int md5file_cmd(void*cd, Tcl_Interp*interp, int argc, const char **argv){ if( argc!=2 ){ Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0], - " FILENAME\"", 0); + " FILENAME\"", (char*)0); return TCL_ERROR; } in = fopen(argv[1],"rb"); if( in==0 ){ Tcl_AppendResult(interp,"unable to open file \"", argv[1], - "\" for reading", 0); + "\" for reading", (char*)0); return TCL_ERROR; } MD5Init(&ctx); From dddf6978d21314e1835630f0e02c65fc231dbec9 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 7 Feb 2014 19:33:31 +0000 Subject: [PATCH 227/276] Fix redundant definitions of _LARGE_FILE and _LARGEFILE_SOURCE. FossilOrigin-Name: 4043d879795bfad55af35e9cb48e0a42eb4087ae --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/os_unix.c | 26 -------------------------- src/sqliteInt.h | 5 +++++ 4 files changed, 13 insertions(+), 34 deletions(-) diff --git a/manifest b/manifest index 700f104ff6..18259af769 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\sTCL\sbindings,\smake\ssure\sTcl_AppendResult()\sis\salways\sterminated\nby\s"(char*)0"\sand\snot\sjust\s"0". -D 2014-02-07T19:26:13.604 +C Fix\sredundant\sdefinitions\sof\s_LARGE_FILE\sand\s_LARGEFILE_SOURCE. +D 2014-02-07T19:33:31.352 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -205,7 +205,7 @@ F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30 F src/os.c 1b147e4cf7cc39e618115c14a086aed44bc91ace F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 -F src/os_unix.c f3ed0e406cbf9c820565b2118232d0796346130f +F src/os_unix.c 18f7f95dc6bcb9cf4d4a238d8e2de96611bc2ae5 F src/os_win.c d4284f003445054a26689f1264b1b9bf7261bd1b F src/pager.c efa923693e958696eee69b205a20bfbc402c8480 F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428 @@ -224,7 +224,7 @@ F src/shell.c 7dedf7367ee49050b0366bf8dbc8ec2bd15b42c7 F src/sqlite.h.in eed7f7d66a60daaa7b4a597dcd9bad87aad9611b F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h fdab572b3567d587cf3096e3ca5dabcedda3fa66 +F src/sqliteInt.h d3dd8e370f0c4e72a612c71c9b4255fee44806c8 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P be24fbc22106e508975e316abe0471edd3833291 -R 3b20a064262155765ddc1dcd7881cbe1 +P ea4d23d1c0df4fde2e532daa081888712f465884 +R fe35814af819067492f7e22674ab8b60 U drh -Z 32dadfb086ccda5c6d983ac169fd7f6c +Z bbbf5c390e5238e969c1eb355ec42634 diff --git a/manifest.uuid b/manifest.uuid index 4ba30ed9a5..c78d46e5f2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ea4d23d1c0df4fde2e532daa081888712f465884 \ No newline at end of file +4043d879795bfad55af35e9cb48e0a42eb4087ae \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index b539550220..deb9e51d07 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -83,32 +83,6 @@ # endif #endif -/* -** These #defines should enable >2GB file support on Posix if the -** underlying operating system supports it. If the OS lacks -** large file support, these should be no-ops. -** -** Large file support can be disabled using the -DSQLITE_DISABLE_LFS switch -** on the compiler command line. This is necessary if you are compiling -** on a recent machine (ex: RedHat 7.2) but you want your code to work -** on an older machine (ex: RedHat 6.0). If you compile on RedHat 7.2 -** without this option, LFS is enable. But LFS does not exist in the kernel -** in RedHat 6.0, so the code won't work. Hence, for maximum binary -** portability you should omit LFS. -** -** The previous paragraph was written in 2005. (This paragraph is written -** on 2008-11-28.) These days, all Linux kernels support large files, so -** you should probably leave LFS enabled. But some embedded platforms might -** lack LFS in which case the SQLITE_DISABLE_LFS macro might still be useful. -*/ -#ifndef SQLITE_DISABLE_LFS -# define _LARGE_FILE 1 -# ifndef _FILE_OFFSET_BITS -# define _FILE_OFFSET_BITS 64 -# endif -# define _LARGEFILE_SOURCE 1 -#endif - /* ** standard include files. */ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 7c5e1e3ed9..45a3986d8c 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -33,6 +33,11 @@ ** in Red Hat 6.0, so the code won't work. Hence, for maximum binary ** portability you should omit LFS. ** +** The previous paragraph was written in 2005. (This paragraph is written +** on 2008-11-28.) These days, all Linux kernels support large files, so +** you should probably leave LFS enabled. But some embedded platforms might +** lack LFS in which case the SQLITE_DISABLE_LFS macro might still be useful. +** ** Similar is true for Mac OS X. LFS is only supported on Mac OS X 9 and later. */ #ifndef SQLITE_DISABLE_LFS From aceb31b1205c01e933619b05a5f11b0280e2faed Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 8 Feb 2014 01:40:27 +0000 Subject: [PATCH 228/276] Change the OP_Trace opcode to OP_Init and give it the ability to jump to the initialization code at the bottom of the program, thus avoiding the need for an extra OP_Goto. FossilOrigin-Name: 192dea97316144f15f6dd0eabff08a0bf9ef203e --- manifest | 27 ++++++++--------- manifest.uuid | 2 +- src/build.c | 81 +++++++++++++++---------------------------------- src/insert.c | 2 +- src/select.c | 15 +-------- src/sqliteInt.h | 5 ++- src/trigger.c | 10 +----- src/vdbe.c | 18 ++++++++--- src/vdbeaux.c | 15 ++------- src/where.c | 3 +- 10 files changed, 61 insertions(+), 117 deletions(-) diff --git a/manifest b/manifest index 07138b4ba8..9dc0f3326e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sopcodes\sOP_InitCoroutine\sand\sOP_EndCoroutine.\s\sUse\sthese\sto\sremove\sthe\nneed\sfor\sseparate\sboolean\sregisters\sto\srecord\swhen\sa\sco-routine\shas\sfinished. -D 2014-02-07T22:21:07.782 +C Change\sthe\sOP_Trace\sopcode\sto\sOP_Init\sand\sgive\sit\sthe\sability\sto\sjump\sto\sthe\ninitialization\scode\sat\sthe\sbottom\sof\sthe\sprogram,\sthus\savoiding\sthe\sneed\sfor\nan\sextra\sOP_Goto. +D 2014-02-08T01:40:27.230 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -169,7 +169,7 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btree.c 7b2c3cd16deedff7f4904f2e871e7b77328b9872 F src/btree.h a61ddebc78c66795a2b93181321a116746302cc9 F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0 -F src/build.c 40c38ec8f10835cf68879cb12e7c00e32b8edf78 +F src/build.c 1bc258476158bfe7707d21daa5221dd95c03d37c F src/callback.c 174e3c8656bc29f91d710ab61550d16eea34be98 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd @@ -183,7 +183,7 @@ F src/global.c 1d7bb7ea8254ae6a68ed9bfaf65fcb3d1690b486 F src/hash.c d139319967164f139c8d1bb8a11b14db9c4ba3cd F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c b50cb5a51edb0d6e1a99e04b232b8632a54e522a +F src/insert.c 89526b031cf8f0e2306f02099a73cee56110c580 F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b @@ -219,12 +219,12 @@ F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c 47d93e6f0b58000e2093e7b489bdca778884f82a +F src/select.c 0b6011a51496c916914f6fba11c3a6a0042a0439 F src/shell.c 7dedf7367ee49050b0366bf8dbc8ec2bd15b42c7 F src/sqlite.h.in eed7f7d66a60daaa7b4a597dcd9bad87aad9611b F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h d3dd8e370f0c4e72a612c71c9b4255fee44806c8 +F src/sqliteInt.h ab719053ec9fb58702dd8cdfc4fc9d4870af9979 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -275,16 +275,16 @@ F src/test_vfs.c e72f555ef7a59080f898fcf1a233deb9eb704ea9 F src/test_vfstrace.c 3a0ab304682fecbceb689e7d9b904211fde11d78 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/tokenize.c 6da2de6e12218ccb0aea5184b56727d011f4bee7 -F src/trigger.c 5c1c0b899ac0ce284763dcb8fdbaa38ecf15ef98 +F src/trigger.c a417d386e214f0abd2e0f756b834b4d9f4d3368a F src/update.c a7df6fffce6bfedc578fda6136dd33e34a63f8ee F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c 15ac2627f548f5481d0d7e6c4eb67be673027695 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c e7bb0587ad4866c0db5fe3b83104c4df8f93d19f +F src/vdbe.c 0944fe28f711ce12b631f00d18ecf9d82f2f04f8 F src/vdbe.h e6c4c610fcabad4fa80ebb1efc6822a9367e2b26 F src/vdbeInt.h b5d62957a408c4bea649484008e5f98335b09e97 F src/vdbeapi.c ce4e68ea4842cc6081046f533d088dcf01d247ad -F src/vdbeaux.c 3fd95b226330e1d50aedb40d750effe726ebb3fb +F src/vdbeaux.c 379343f1d98b60b0771366e5955f3cab34f1a3ca F src/vdbeblob.c 9542e116c1db5ed813977581d506c176e117c0ec F src/vdbemem.c c0bcc02d6816ab4218ac0f94b63c8ee78a0f739f F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147 @@ -293,7 +293,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45 -F src/where.c 8c2aada8b44140382406cf07b84ff2f6127cb39e +F src/where.c 924f24a04bb639eb391ad12618f941bfb641a472 F src/whereInt.h 921f935af8b684ffb49705610bda7284db1db138 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1152,8 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 4043d879795bfad55af35e9cb48e0a42eb4087ae a522f364a6b8ca6f69c353b30609a2166f6e94cf -R fcb91b77c89313a695cdcaff36627dad -T +closed a522f364a6b8ca6f69c353b30609a2166f6e94cf +P 5a88b6a7aef3a0d5380e19eee2ee38439cc9b08b +R a9b46d5717be39fdc7732934fcbad0a2 U drh -Z 935dc7a454a2a09335ff0c234e8fb57e +Z 07d97eaa48af367d9c2a599f3698a466 diff --git a/manifest.uuid b/manifest.uuid index 81d36a4a86..37444b7afd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5a88b6a7aef3a0d5380e19eee2ee38439cc9b08b \ No newline at end of file +192dea97316144f15f6dd0eabff08a0bf9ef203e \ No newline at end of file diff --git a/src/build.c b/src/build.c index afd68a8f63..1032893f38 100644 --- a/src/build.c +++ b/src/build.c @@ -149,10 +149,11 @@ void sqlite3FinishCoding(Parse *pParse){ ** transaction on each used database and to verify the schema cookie ** on each used database. */ - if( pParse->cookieGoto>0 ){ + if( db->mallocFailed==0 && pParse->cookieMask ){ yDbMask mask; - int iDb, i, addr; - sqlite3VdbeJumpHere(v, pParse->cookieGoto-1); + int iDb, i; + assert( sqlite3VdbeGetOp(v, 0)->opcode==OP_Init ); + sqlite3VdbeJumpHere(v, 0); for(iDb=0, mask=1; iDbnDb; mask<<=1, iDb++){ if( (mask & pParse->cookieMask)==0 ) continue; sqlite3VdbeUsesBtree(v, iDb); @@ -184,17 +185,16 @@ void sqlite3FinishCoding(Parse *pParse){ sqlite3AutoincrementBegin(pParse); /* Code constant expressions that where factored out of inner loops */ - addr = pParse->cookieGoto; if( pParse->pConstExpr ){ ExprList *pEL = pParse->pConstExpr; - pParse->cookieGoto = 0; + pParse->okConstFactor = 0; for(i=0; inExpr; i++){ sqlite3ExprCode(pParse, pEL->a[i].pExpr, pEL->a[i].u.iConstExprReg); } } /* Finally, jump back to the beginning of the executable code. */ - sqlite3VdbeAddOp2(v, OP_Goto, 0, addr); + sqlite3VdbeAddOp2(v, OP_Goto, 0, 1); } } @@ -217,7 +217,6 @@ void sqlite3FinishCoding(Parse *pParse){ pParse->nSet = 0; pParse->nVar = 0; pParse->cookieMask = 0; - pParse->cookieGoto = 0; } /* @@ -3826,59 +3825,29 @@ int sqlite3OpenTempDatabase(Parse *pParse){ } /* -** Generate VDBE code that will verify the schema cookie and start -** a read-transaction for all named database files. -** -** It is important that all schema cookies be verified and all -** read transactions be started before anything else happens in -** the VDBE program. But this routine can be called after much other -** code has been generated. So here is what we do: -** -** The first time this routine is called, we code an OP_Goto that -** will jump to a subroutine at the end of the program. Then we -** record every database that needs its schema verified in the -** pParse->cookieMask field. Later, after all other code has been -** generated, the subroutine that does the cookie verifications and -** starts the transactions will be coded and the OP_Goto P2 value -** will be made to point to that subroutine. The generation of the -** cookie verification subroutine code happens in sqlite3FinishCoding(). -** -** If iDb<0 then code the OP_Goto only - don't set flag to verify the -** schema on any databases. This can be used to position the OP_Goto -** early in the code, before we know if any database tables will be used. +** Record the fact that the schema cookie will need to be verified +** for database iDb. The code to actually verify the schema cookie +** will occur at the end of the top-level VDBE and will be generated +** later, by sqlite3FinishCoding(). */ void sqlite3CodeVerifySchema(Parse *pParse, int iDb){ Parse *pToplevel = sqlite3ParseToplevel(pParse); + sqlite3 *db = pToplevel->db; + yDbMask mask; -#ifndef SQLITE_OMIT_TRIGGER - if( pToplevel!=pParse ){ - /* This branch is taken if a trigger is currently being coded. In this - ** case, set cookieGoto to a non-zero value to show that this function - ** has been called. This is used by the sqlite3ExprCodeConstants() - ** function. */ - pParse->cookieGoto = -1; - } -#endif - if( pToplevel->cookieGoto==0 ){ - Vdbe *v = sqlite3GetVdbe(pToplevel); - if( v==0 ) return; /* This only happens if there was a prior error */ - pToplevel->cookieGoto = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0)+1; - } - if( iDb>=0 ){ - sqlite3 *db = pToplevel->db; - yDbMask mask; - - assert( iDbnDb ); - assert( db->aDb[iDb].pBt!=0 || iDb==1 ); - assert( iDbcookieMask & mask)==0 ){ - pToplevel->cookieMask |= mask; - pToplevel->cookieValue[iDb] = db->aDb[iDb].pSchema->schema_cookie; - if( !OMIT_TEMPDB && iDb==1 ){ - sqlite3OpenTempDatabase(pToplevel); - } + assert( iDb>=0 && iDbnDb ); + assert( db->aDb[iDb].pBt!=0 || iDb==1 ); + assert( iDbcookieMask & mask)==0 ){ + pToplevel->cookieMask |= mask; + pToplevel->cookieValue[iDb] = db->aDb[iDb].pSchema->schema_cookie; + if( !OMIT_TEMPDB && iDb==1 ){ + sqlite3OpenTempDatabase(pToplevel); + } + if( pToplevel==pParse && OptimizationEnabled(db,SQLITE_FactorOutConst) ){ + pParse->okConstFactor = 1; } } } diff --git a/src/insert.c b/src/insert.c index 5dbdf9108a..bd15832ac6 100644 --- a/src/insert.c +++ b/src/insert.c @@ -2038,7 +2038,7 @@ static int xferOptimization( sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0); sqlite3VdbeAddOp2(v, OP_Close, iDest, 0); } - sqlite3VdbeJumpHere(v, emptySrcTest); + if( emptySrcTest ) sqlite3VdbeJumpHere(v, emptySrcTest); sqlite3ReleaseTempReg(pParse, regRowid); sqlite3ReleaseTempReg(pParse, regData); if( emptyDestTest ){ diff --git a/src/select.c b/src/select.c index c0728f8873..8e5e4dd9d4 100644 --- a/src/select.c +++ b/src/select.c @@ -1615,11 +1615,7 @@ Vdbe *sqlite3GetVdbe(Parse *pParse){ Vdbe *v = pParse->pVdbe; if( v==0 ){ v = pParse->pVdbe = sqlite3VdbeCreate(pParse); -#ifndef SQLITE_OMIT_TRACE - if( v ){ - sqlite3VdbeAddOp0(v, OP_Trace); - } -#endif + if( v ) sqlite3VdbeAddOp0(v, OP_Init); } return v; } @@ -4537,15 +4533,6 @@ int sqlite3Select( */ int addrTop; pItem->regReturn = ++pParse->nMem; - /* Before coding the OP_Goto to jump to the start of the main routine, - ** ensure that the jump to the verify-schema routine has already - ** been coded. Otherwise, the verify-schema would likely be coded as - ** part of the co-routine. If the main routine then accessed the - ** database before invoking the co-routine for the first time (for - ** example to initialize a LIMIT register from a sub-select), it would - ** be doing so without having verified the schema version and obtained - ** the required db locks. See ticket d6b36be38. */ - sqlite3CodeVerifySchema(pParse, -1); sqlite3VdbeAddOp0(v, OP_Goto); addrTop = sqlite3VdbeAddOp1(v, OP_OpenPseudo, pItem->iCursor); sqlite3VdbeChangeP5(v, 1); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 45a3986d8c..42851ab342 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1088,8 +1088,7 @@ struct sqlite3 { ** Return true if it OK to factor constant expressions into the initialization ** code. The argument is a Parse object for the code generator. */ -#define ConstFactorOk(P) \ - ((P)->cookieGoto>0 && OptimizationEnabled((P)->db,SQLITE_FactorOutConst)) +#define ConstFactorOk(P) ((P)->okConstFactor) /* ** Possible values for the sqlite.magic field. @@ -2354,6 +2353,7 @@ struct Parse { u8 isMultiWrite; /* True if statement may modify/insert multiple rows */ u8 mayAbort; /* True if statement may throw an ABORT exception */ u8 hasCompound; /* Need to invoke convertCompoundSelectToSubquery() */ + u8 okConstFactor; /* OK to factor out constants */ int aTempReg[8]; /* Holding area for temporary registers */ int nRangeReg; /* Size of the temporary register block */ int iRangeReg; /* First register in temporary register block */ @@ -2382,7 +2382,6 @@ struct Parse { Token constraintName;/* Name of the constraint currently being parsed */ yDbMask writeMask; /* Start a write transaction on these databases */ yDbMask cookieMask; /* Bitmask of schema verified databases */ - int cookieGoto; /* Address of OP_Goto to cookie verifier subroutine */ int cookieValue[SQLITE_MAX_ATTACHED+2]; /* Values of cookies to verify */ int regRowid; /* Register holding rowid of CREATE TABLE entry */ int regRoot; /* Register holding root page number for new objects */ diff --git a/src/trigger.c b/src/trigger.c index fdc2a0388c..cbc87abf45 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -726,15 +726,7 @@ static int codeTriggerProgram( ** INSERT OR IGNORE INTO t1 ... ; -- insert into t2 uses IGNORE policy */ pParse->eOrconf = (orconf==OE_Default)?pStep->orconf:(u8)orconf; - - /* Clear the cookieGoto flag. When coding triggers, the cookieGoto - ** variable is used as a flag to indicate to sqlite3ExprCodeConstants() - ** that it is not safe to refactor constants (this happens after the - ** start of the first loop in the SQL statement is coded - at that - ** point code may be conditionally executed, so it is no longer safe to - ** initialize constant register values). */ - assert( pParse->cookieGoto==0 || pParse->cookieGoto==-1 ); - pParse->cookieGoto = 0; + assert( pParse->okConstFactor==0 ); switch( pStep->op ){ case TK_UPDATE: { diff --git a/src/vdbe.c b/src/vdbe.c index 8067f9a12b..657b9a78ce 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -6144,16 +6144,26 @@ case OP_MaxPgcnt: { /* out2-prerelease */ #endif -#ifndef SQLITE_OMIT_TRACE -/* Opcode: Trace * * * P4 * +/* Opcode: Init * P2 * P4 * +** Synopsis: Start at P2 +** +** Programs contain a single instance of this opcode as the very first +** opcode. ** ** If tracing is enabled (by the sqlite3_trace()) interface, then ** the UTF-8 string contained in P4 is emitted on the trace callback. +** Or if P4 is blank, use the string returned by sqlite3_sql(). +** +** If P2 is not zero, jump to instruction P2. */ -case OP_Trace: { +case OP_Init: { /* jump */ char *zTrace; char *z; + if( pOp->p2 ){ + pc = pOp->p2 - 1; + } +#ifndef SQLITE_OMIT_TRACE if( db->xTrace && !p->doingRerun && (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 @@ -6179,9 +6189,9 @@ case OP_Trace: { sqlite3DebugPrintf("SQL-trace: %s\n", zTrace); } #endif /* SQLITE_DEBUG */ +#endif /* SQLITE_OMIT_TRACE */ break; } -#endif /* Opcode: Noop * * * * * diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 59b766a79c..1904cf131d 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -863,14 +863,6 @@ void sqlite3VdbeNoopComment(Vdbe *p, const char *zFormat, ...){ ** this routine is a valid pointer. But because the dummy.opcode is 0, ** dummy will never be written to. This is verified by code inspection and ** by running with Valgrind. -** -** About the #ifdef SQLITE_OMIT_TRACE: Normally, this routine is never called -** unless p->nOp>0. This is because in the absense of SQLITE_OMIT_TRACE, -** an OP_Trace instruction is always inserted by sqlite3VdbeGet() as soon as -** a new VDBE is created. So we are free to set addr to p->nOp-1 without -** having to double-check to make sure that the result is non-negative. But -** if SQLITE_OMIT_TRACE is defined, the OP_Trace is omitted and we do need to -** check the value of p->nOp-1 before continuing. */ VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){ /* C89 specifies that the constant "dummy" will be initialized to all @@ -878,9 +870,6 @@ VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){ static VdbeOp dummy; /* Ignore the MSVC warning about no initializer */ assert( p->magic==VDBE_MAGIC_INIT ); if( addr<0 ){ -#ifdef SQLITE_OMIT_TRACE - if( p->nOp==0 ) return (VdbeOp*)&dummy; -#endif addr = p->nOp - 1; } assert( (addr>=0 && addrnOp) || p->db->mallocFailed ); @@ -1465,7 +1454,7 @@ void sqlite3VdbePrintSql(Vdbe *p){ z = p->zSql; }else if( p->nOp>=1 ){ const VdbeOp *pOp = &p->aOp[0]; - if( pOp->opcode==OP_Trace && pOp->p4.z!=0 ){ + if( pOp->opcode==OP_Init && pOp->p4.z!=0 ){ z = pOp->p4.z; while( sqlite3Isspace(*z) ) z++; } @@ -1484,7 +1473,7 @@ void sqlite3VdbeIOTraceSql(Vdbe *p){ if( sqlite3IoTrace==0 ) return; if( nOp<1 ) return; pOp = &p->aOp[0]; - if( pOp->opcode==OP_Trace && pOp->p4.z!=0 ){ + if( pOp->opcode==OP_Init && pOp->p4.z!=0 ){ int i, j; char z[1000]; sqlite3_snprintf(sizeof(z), z, "%s", pOp->p4.z); diff --git a/src/where.c b/src/where.c index 9abe3ad1cb..91ab6972fa 100644 --- a/src/where.c +++ b/src/where.c @@ -5436,7 +5436,6 @@ WhereInfo *sqlite3WhereBegin( initMaskSet(pMaskSet); whereClauseInit(&pWInfo->sWC, pWInfo); whereSplit(&pWInfo->sWC, pWhere, TK_AND); - sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */ /* Special case: a WHERE clause that is constant. Evaluate the ** expression and either jump over all of the code or fall thru. @@ -5725,7 +5724,7 @@ WhereInfo *sqlite3WhereBegin( sqlite3VdbeSetP4KeyInfo(pParse, pIx); VdbeComment((v, "%s", pIx->zName)); } - sqlite3CodeVerifySchema(pParse, iDb); + if( iDb>=0 ) sqlite3CodeVerifySchema(pParse, iDb); notReady &= ~getMask(&pWInfo->sMaskSet, pTabItem->iCursor); } pWInfo->iTop = sqlite3VdbeCurrentAddr(v); From e0e261a4733f741432755d3f0ee238cf31e49b5c Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 8 Feb 2014 04:24:37 +0000 Subject: [PATCH 229/276] Enable constant expression factoring even if no tables are read and no transaction is started. FossilOrigin-Name: a45b87713c0afca2be2ace9500513620a024c0a2 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/build.c | 5 +---- src/select.c | 6 ++++++ 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 9dc0f3326e..e73dfc19e1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\sOP_Trace\sopcode\sto\sOP_Init\sand\sgive\sit\sthe\sability\sto\sjump\sto\sthe\ninitialization\scode\sat\sthe\sbottom\sof\sthe\sprogram,\sthus\savoiding\sthe\sneed\sfor\nan\sextra\sOP_Goto. -D 2014-02-08T01:40:27.230 +C Enable\sconstant\sexpression\sfactoring\seven\sif\sno\stables\sare\sread\sand\sno\ntransaction\sis\sstarted. +D 2014-02-08T04:24:37.181 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -169,7 +169,7 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btree.c 7b2c3cd16deedff7f4904f2e871e7b77328b9872 F src/btree.h a61ddebc78c66795a2b93181321a116746302cc9 F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0 -F src/build.c 1bc258476158bfe7707d21daa5221dd95c03d37c +F src/build.c 13b9d82181d95af7b00ec8a8e1304bac096432d4 F src/callback.c 174e3c8656bc29f91d710ab61550d16eea34be98 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd @@ -219,7 +219,7 @@ F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c 0b6011a51496c916914f6fba11c3a6a0042a0439 +F src/select.c deb41db22f671b4f2a3e0e48a99b896e227aefdb F src/shell.c 7dedf7367ee49050b0366bf8dbc8ec2bd15b42c7 F src/sqlite.h.in eed7f7d66a60daaa7b4a597dcd9bad87aad9611b F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 5a88b6a7aef3a0d5380e19eee2ee38439cc9b08b -R a9b46d5717be39fdc7732934fcbad0a2 +P 192dea97316144f15f6dd0eabff08a0bf9ef203e +R e90c019788474c8101c0d70d2228b12b U drh -Z 07d97eaa48af367d9c2a599f3698a466 +Z 46adb7aa7b0c0d2f1d0d873b94d6c7bb diff --git a/manifest.uuid b/manifest.uuid index 37444b7afd..c2f346156d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -192dea97316144f15f6dd0eabff08a0bf9ef203e \ No newline at end of file +a45b87713c0afca2be2ace9500513620a024c0a2 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 1032893f38..99bba67dd2 100644 --- a/src/build.c +++ b/src/build.c @@ -149,7 +149,7 @@ void sqlite3FinishCoding(Parse *pParse){ ** transaction on each used database and to verify the schema cookie ** on each used database. */ - if( db->mallocFailed==0 && pParse->cookieMask ){ + if( db->mallocFailed==0 && (pParse->cookieMask || pParse->pConstExpr) ){ yDbMask mask; int iDb, i; assert( sqlite3VdbeGetOp(v, 0)->opcode==OP_Init ); @@ -3846,9 +3846,6 @@ void sqlite3CodeVerifySchema(Parse *pParse, int iDb){ if( !OMIT_TEMPDB && iDb==1 ){ sqlite3OpenTempDatabase(pToplevel); } - if( pToplevel==pParse && OptimizationEnabled(db,SQLITE_FactorOutConst) ){ - pParse->okConstFactor = 1; - } } } diff --git a/src/select.c b/src/select.c index 8e5e4dd9d4..8d6c432ac7 100644 --- a/src/select.c +++ b/src/select.c @@ -1616,6 +1616,12 @@ Vdbe *sqlite3GetVdbe(Parse *pParse){ if( v==0 ){ v = pParse->pVdbe = sqlite3VdbeCreate(pParse); if( v ) sqlite3VdbeAddOp0(v, OP_Init); + if( pParse->pToplevel==0 + && OptimizationEnabled(pParse->db,SQLITE_FactorOutConst) + ){ + pParse->okConstFactor = 1; + } + } return v; } From 725de29a2d771971c090a8a3af1aa366dec058f9 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 8 Feb 2014 13:12:19 +0000 Subject: [PATCH 230/276] Tweaks to the generated VDBE code to make it a little easier to follow. FossilOrigin-Name: 129217ee91782ec77ff82661753ae5bee8ca99d0 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/select.c | 12 +++++++----- src/where.c | 2 +- 4 files changed, 16 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index e73dfc19e1..b3265fa750 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enable\sconstant\sexpression\sfactoring\seven\sif\sno\stables\sare\sread\sand\sno\ntransaction\sis\sstarted. -D 2014-02-08T04:24:37.181 +C Tweaks\sto\sthe\sgenerated\sVDBE\scode\sto\smake\sit\sa\slittle\seasier\sto\sfollow. +D 2014-02-08T13:12:19.189 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -219,7 +219,7 @@ F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c deb41db22f671b4f2a3e0e48a99b896e227aefdb +F src/select.c b854d23224c44f10a2dbe233c885e208701a5a08 F src/shell.c 7dedf7367ee49050b0366bf8dbc8ec2bd15b42c7 F src/sqlite.h.in eed7f7d66a60daaa7b4a597dcd9bad87aad9611b F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e @@ -293,7 +293,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45 -F src/where.c 924f24a04bb639eb391ad12618f941bfb641a472 +F src/where.c 30fd77c349cb97bf737c5a880b88f265b7c66316 F src/whereInt.h 921f935af8b684ffb49705610bda7284db1db138 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 192dea97316144f15f6dd0eabff08a0bf9ef203e -R e90c019788474c8101c0d70d2228b12b +P a45b87713c0afca2be2ace9500513620a024c0a2 +R a1eedfcdaaa5c268df32788e5659e391 U drh -Z 46adb7aa7b0c0d2f1d0d873b94d6c7bb +Z ddd6a3acafdcef4fba36e852a5d855f1 diff --git a/manifest.uuid b/manifest.uuid index c2f346156d..8e8f092ffd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a45b87713c0afca2be2ace9500513620a024c0a2 \ No newline at end of file +129217ee91782ec77ff82661753ae5bee8ca99d0 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 8d6c432ac7..28bbcb2eb9 100644 --- a/src/select.c +++ b/src/select.c @@ -4537,12 +4537,12 @@ int sqlite3Select( /* Implement a co-routine that will return a single row of the result ** set on each invocation. */ - int addrTop; + int addrTop = sqlite3VdbeCurrentAddr(v)+1; pItem->regReturn = ++pParse->nMem; - sqlite3VdbeAddOp0(v, OP_Goto); - addrTop = sqlite3VdbeAddOp1(v, OP_OpenPseudo, pItem->iCursor); + sqlite3VdbeAddOp3(v, OP_InitCoroutine, pItem->regReturn, 0, addrTop); + VdbeComment((v, "%s", pItem->pTab->zName)); + sqlite3VdbeAddOp1(v, OP_OpenPseudo, pItem->iCursor); sqlite3VdbeChangeP5(v, 1); - VdbeComment((v, "coroutine %s", pItem->pTab->zName)); pItem->addrFillSub = addrTop; sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn); explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId); @@ -4567,12 +4567,14 @@ int sqlite3Select( pItem->regReturn = ++pParse->nMem; topAddr = sqlite3VdbeAddOp2(v, OP_Integer, 0, pItem->regReturn); pItem->addrFillSub = topAddr+1; - VdbeNoopComment((v, "materialize %s", pItem->pTab->zName)); if( pItem->isCorrelated==0 ){ /* If the subquery is not correlated and if we are not inside of ** a trigger, then we only need to compute the value of the subquery ** once. */ onceAddr = sqlite3CodeOnce(pParse); + VdbeComment((v, "materialize \"%s\"", pItem->pTab->zName)); + }else{ + VdbeNoopComment((v, "materialize \"%s\"", pItem->pTab->zName)); } sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor); explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId); diff --git a/src/where.c b/src/where.c index 91ab6972fa..0eeb8df7ab 100644 --- a/src/where.c +++ b/src/where.c @@ -2787,7 +2787,7 @@ static Bitmask codeOneLoopStart( int regYield = pTabItem->regReturn; sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub); pLevel->p2 = sqlite3VdbeAddOp2(v, OP_Yield, regYield, addrBrk); - VdbeComment((v, "next row of co-routine %s", pTabItem->pTab->zName)); + VdbeComment((v, "next row of \"%s\"", pTabItem->pTab->zName)); pLevel->op = OP_Goto; }else From 04d0bcd5331985f4f59612af29bf4e12821da732 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 8 Feb 2014 13:22:36 +0000 Subject: [PATCH 231/276] Fix a harmless compiler warning in VS2013. FossilOrigin-Name: 35f2793db5eb58484554477a23f8320843ebcd71 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/pager.c | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index e648887520..19223fd379 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Version\s3.8.3 -D 2014-02-03T13:52:03.248 +C Fix\sa\sharmless\scompiler\swarning\sin\sVS2013. +D 2014-02-08T13:22:36.857 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -207,7 +207,7 @@ F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_unix.c f3ed0e406cbf9c820565b2118232d0796346130f F src/os_win.c 1b21af72c5fa6f9e519a5fcab33e80d182b1aedb -F src/pager.c efa923693e958696eee69b205a20bfbc402c8480 +F src/pager.c 0ffa313a30ed6d061d9c6601b7b175cc50a1cab7 F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428 F src/parse.y bd51bc17cbfe7549adb4ca3747b1c3d384645065 F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 @@ -1152,10 +1152,10 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P af3c775e5d6a399bfc985a5dae27451908766546 -R d59f4c16611ef76ed43b5f579f765c07 -T +bgcolor * #d0c0ff -T +sym-release * -T +sym-version-3.8.3 * +P e816dd924619db5f766de6df74ea2194f3e3b538 +R 73e287cc1a6edbdb5e3e210fabc10684 +T *branch * branch-3.8.3 +T *sym-branch-3.8.3 * +T -sym-trunk * U drh -Z be66093eab6507921c2b573a40e5f8d7 +Z 85563bddc8fc07f7442defb50aa2e866 diff --git a/manifest.uuid b/manifest.uuid index 514369c84f..25396cbf6d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e816dd924619db5f766de6df74ea2194f3e3b538 \ No newline at end of file +35f2793db5eb58484554477a23f8320843ebcd71 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 954ba7f1e5..b6cd93b723 100644 --- a/src/pager.c +++ b/src/pager.c @@ -1683,7 +1683,7 @@ static int writeMasterJournal(Pager *pPager, const char *zMaster){ ** already in memory. */ static PgHdr *pager_lookup(Pager *pPager, Pgno pgno){ - PgHdr *p; /* Return value */ + PgHdr *p = 0; /* Return value */ /* It is not possible for a call to PcacheFetch() with createFlag==0 to ** fail, since no attempt to allocate dynamic memory will be made. From 826af37865cffde6e08d8e761cc9058d6a9d38b4 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 8 Feb 2014 19:12:21 +0000 Subject: [PATCH 232/276] Change the OP_Found opcode so that it expands zero-blobs prior to comparing them. Fix for ticket [fccbde530a6583b] FossilOrigin-Name: e2303d1b0c17b6e7494fb7db8264f4c2ac193723 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbe.c | 12 +++++------- test/distinct.test | 25 +++++++++++++++++++++++++ 4 files changed, 38 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index f4095f17ac..b0c7343970 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sharmless\scompiler\swarning\sin\sVS2013. -D 2014-02-08T13:24:04.793 +C Change\sthe\sOP_Found\sopcode\sso\sthat\sit\sexpands\szero-blobs\sprior\sto\scomparing\nthem.\s\sFix\sfor\sticket\s[fccbde530a6583b] +D 2014-02-08T19:12:21.547 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -280,7 +280,7 @@ F src/update.c a7df6fffce6bfedc578fda6136dd33e34a63f8ee F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c 15ac2627f548f5481d0d7e6c4eb67be673027695 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c 0944fe28f711ce12b631f00d18ecf9d82f2f04f8 +F src/vdbe.c a5556442eb6ada77eb432c98f22baa51b6abf3a9 F src/vdbe.h e6c4c610fcabad4fa80ebb1efc6822a9367e2b26 F src/vdbeInt.h b5d62957a408c4bea649484008e5f98335b09e97 F src/vdbeapi.c ce4e68ea4842cc6081046f533d088dcf01d247ad @@ -432,7 +432,7 @@ F test/descidx1.test 6d03b44c8538fe0eb4924e19fba10cdd8f3c9240 F test/descidx2.test 9f1a0c83fd57f8667c82310ca21b30a350888b5d F test/descidx3.test 09ddbe3f5295f482d2f8b687cf6db8bad7acd9a2 F test/diskfull.test 106391384780753ea6896b7b4f005d10e9866b6e -F test/distinct.test 44028aaf161a5e80a2f229622b3a174d3b352810 +F test/distinct.test c7b194ef95dbddb32d77acbbab2e023c6eed0cb2 F test/distinctagg.test 1a6ef9c87a58669438fc771450d7a72577417376 F test/e_createtable.test ee95d48664503d40f6cc9ef4a7d03216188e2ada F test/e_delete.test d5186e2f5478b659f16a2c8b66c09892823e542a @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 129217ee91782ec77ff82661753ae5bee8ca99d0 35f2793db5eb58484554477a23f8320843ebcd71 -R aef457d9a6de27675d731f11fafa24ac +P 83116ee3e0f2b9110c70a4f73a9badc9c2a56f28 +R a13d7a863184cc3e51d017457c46ee29 U drh -Z 07817b5f1db7ebfb28393b8fc72b06af +Z 47328ab39b0e370926e85f5f82006e15 diff --git a/manifest.uuid b/manifest.uuid index b20608ceb2..8d5ca2327f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -83116ee3e0f2b9110c70a4f73a9badc9c2a56f28 \ No newline at end of file +e2303d1b0c17b6e7494fb7db8264f4c2ac193723 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 657b9a78ce..334931d7c5 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3694,15 +3694,13 @@ case OP_Found: { /* jump, in3 */ r.pKeyInfo = pC->pKeyInfo; r.nField = (u16)pOp->p4.i; r.aMem = pIn3; + for(ii=0; iip3+i, &r.aMem[i]); - } - } + if( ii ) REGISTER_TRACE(pOp->p3+ii, &r.aMem[ii]); #endif + } r.flags = UNPACKED_PREFIX_MATCH; pIdxKey = &r; }else{ diff --git a/test/distinct.test b/test/distinct.test index 2b006d3e61..5198113920 100644 --- a/test/distinct.test +++ b/test/distinct.test @@ -197,4 +197,29 @@ do_test 3.1 { }] } {0} +#------------------------------------------------------------------------- +# Ticket [fccbde530a6583bf2748400919f1603d5425995c] (2014-01-08) +# The logic that computes DISTINCT sometimes thinks that a zeroblob() +# and a blob of all zeros are different when they should be the same. +# +do_execsql_test 4.1 { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t2; + CREATE TABLE t1(a INTEGER); + INSERT INTO t1 VALUES(3); + INSERT INTO t1 VALUES(2); + INSERT INTO t1 VALUES(1); + INSERT INTO t1 VALUES(2); + INSERT INTO t1 VALUES(3); + INSERT INTO t1 VALUES(1); + CREATE TABLE t2(x); + INSERT INTO t2 + SELECT DISTINCT + CASE a WHEN 1 THEN x'0000000000' + WHEN 2 THEN zeroblob(5) + ELSE 'xyzzy' END + FROM t1; + SELECT quote(x) FROM t2 ORDER BY 1; +} {'xyzzy' X'0000000000'} + finish_test From 5f61229504bc56387db38fd7194652860b53c772 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 8 Feb 2014 23:20:32 +0000 Subject: [PATCH 233/276] Do away with the "multi-register pseudo-table" abstration. Instead, just use an OP_SCopy to load results directory from the result registers of the co-routine. FossilOrigin-Name: 1e64dd782a126f48d78c43a664844a41d0e6334e --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/select.c | 5 +---- src/sqliteInt.h | 1 + src/vdbe.c | 16 +++++----------- src/vdbeInt.h | 1 - src/where.c | 29 ++++++++++++++++++++++++++--- 7 files changed, 44 insertions(+), 30 deletions(-) diff --git a/manifest b/manifest index b0c7343970..d5e1ef9945 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\sOP_Found\sopcode\sso\sthat\sit\sexpands\szero-blobs\sprior\sto\scomparing\nthem.\s\sFix\sfor\sticket\s[fccbde530a6583b] -D 2014-02-08T19:12:21.547 +C Do\saway\swith\sthe\s"multi-register\spseudo-table"\sabstration.\s\sInstead,\sjust\nuse\san\sOP_SCopy\sto\sload\sresults\sdirectory\sfrom\sthe\sresult\sregisters\sof\nthe\sco-routine. +D 2014-02-08T23:20:32.439 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -219,12 +219,12 @@ F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c b854d23224c44f10a2dbe233c885e208701a5a08 +F src/select.c de28cd6d49e0334a3c693fbcce7cd8dfe5fc3979 F src/shell.c 7dedf7367ee49050b0366bf8dbc8ec2bd15b42c7 F src/sqlite.h.in eed7f7d66a60daaa7b4a597dcd9bad87aad9611b F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h ab719053ec9fb58702dd8cdfc4fc9d4870af9979 +F src/sqliteInt.h edee30d57dd287aea523406f53123583ca7f0089 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -280,9 +280,9 @@ F src/update.c a7df6fffce6bfedc578fda6136dd33e34a63f8ee F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c 15ac2627f548f5481d0d7e6c4eb67be673027695 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c a5556442eb6ada77eb432c98f22baa51b6abf3a9 +F src/vdbe.c 78b41fd0a3b3ab4647e3bf99905fb65831a1a92a F src/vdbe.h e6c4c610fcabad4fa80ebb1efc6822a9367e2b26 -F src/vdbeInt.h b5d62957a408c4bea649484008e5f98335b09e97 +F src/vdbeInt.h 6714e9eb5c3a481976d32ca767f03ac0469fc9df F src/vdbeapi.c ce4e68ea4842cc6081046f533d088dcf01d247ad F src/vdbeaux.c 379343f1d98b60b0771366e5955f3cab34f1a3ca F src/vdbeblob.c 9542e116c1db5ed813977581d506c176e117c0ec @@ -293,7 +293,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45 -F src/where.c 30fd77c349cb97bf737c5a880b88f265b7c66316 +F src/where.c 90fef20dd178db262ecd522a214a4eee6f76a44b F src/whereInt.h 921f935af8b684ffb49705610bda7284db1db138 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 83116ee3e0f2b9110c70a4f73a9badc9c2a56f28 -R a13d7a863184cc3e51d017457c46ee29 +P e2303d1b0c17b6e7494fb7db8264f4c2ac193723 +R eb37dbfa0e5b1c125492efcb100d4ba8 U drh -Z 47328ab39b0e370926e85f5f82006e15 +Z 5d0b8c0ebed26b99f999abde70f4aea6 diff --git a/manifest.uuid b/manifest.uuid index 8d5ca2327f..43ad228af7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e2303d1b0c17b6e7494fb7db8264f4c2ac193723 \ No newline at end of file +1e64dd782a126f48d78c43a664844a41d0e6334e \ No newline at end of file diff --git a/src/select.c b/src/select.c index 28bbcb2eb9..4c426e76b2 100644 --- a/src/select.c +++ b/src/select.c @@ -4541,16 +4541,13 @@ int sqlite3Select( pItem->regReturn = ++pParse->nMem; sqlite3VdbeAddOp3(v, OP_InitCoroutine, pItem->regReturn, 0, addrTop); VdbeComment((v, "%s", pItem->pTab->zName)); - sqlite3VdbeAddOp1(v, OP_OpenPseudo, pItem->iCursor); - sqlite3VdbeChangeP5(v, 1); pItem->addrFillSub = addrTop; sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn); explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId); sqlite3Select(pParse, pSub, &dest); pItem->pTab->nRowEst = (unsigned)pSub->nSelectRow; pItem->viaCoroutine = 1; - sqlite3VdbeChangeP2(v, addrTop, dest.iSdst); - sqlite3VdbeChangeP3(v, addrTop, dest.nSdst); + pItem->regResult = dest.iSdst; sqlite3VdbeAddOp1(v, OP_EndCoroutine, pItem->regReturn); sqlite3VdbeJumpHere(v, addrTop-1); sqlite3ClearTempRegCache(pParse); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 42851ab342..4cfa9d39a5 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2019,6 +2019,7 @@ struct SrcList { Select *pSelect; /* A SELECT statement used in place of a table name */ int addrFillSub; /* Address of subroutine to manifest a subquery */ int regReturn; /* Register holding return address of addrFillSub */ + int regResult; /* Registers holding results of a co-routine */ u8 jointype; /* Type of join between this able and the previous */ unsigned notIndexed :1; /* True if there is a NOT INDEXED clause */ unsigned isCorrelated :1; /* True if sub-query is correlated */ diff --git a/src/vdbe.c b/src/vdbe.c index 334931d7c5..25090e3b31 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2281,11 +2281,6 @@ case OP_Column: { if( pCrsr==0 ){ assert( pC->pseudoTableReg>0 ); pReg = &aMem[pC->pseudoTableReg]; - if( pC->multiPseudo ){ - sqlite3VdbeMemShallowCopy(pDest, pReg+p2, MEM_Ephem); - Deephemeralize(pDest); - goto op_column_out; - } assert( pReg->flags & MEM_Blob ); assert( memIsValid(pReg) ); pC->payloadSize = pC->szRow = avail = pReg->n; @@ -3354,14 +3349,13 @@ case OP_SorterOpen: { break; } -/* Opcode: OpenPseudo P1 P2 P3 * P5 +/* Opcode: OpenPseudo P1 P2 P3 * * ** Synopsis: content in r[P2@P3] ** ** Open a new cursor that points to a fake table that contains a single -** row of data. The content of that one row in the content of memory -** register P2 when P5==0. In other words, cursor P1 becomes an alias for the -** MEM_Blob content contained in register P2. When P5==1, then the -** row is represented by P3 consecutive registers beginning with P2. +** row of data. The content of that one row is the content of memory +** register P2. In other words, cursor P1 becomes an alias for the +** MEM_Blob content contained in register P2. ** ** A pseudo-table created by this opcode is used to hold a single ** row output from the sorter so that the row can be decomposed into @@ -3381,7 +3375,7 @@ case OP_OpenPseudo: { pCx->nullRow = 1; pCx->pseudoTableReg = pOp->p2; pCx->isTable = 1; - pCx->multiPseudo = pOp->p5; + assert( pOp->p5==0 ); break; } diff --git a/src/vdbeInt.h b/src/vdbeInt.h index f1d136a8ef..508b61e95c 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -75,7 +75,6 @@ struct VdbeCursor { Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */ Bool isTable:1; /* True if a table requiring integer keys */ Bool isOrdered:1; /* True if the underlying table is BTREE_UNORDERED */ - Bool multiPseudo:1; /* Multi-register pseudo-cursor */ sqlite3_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */ i64 seqCount; /* Sequence counter */ i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */ diff --git a/src/where.c b/src/where.c index 0eeb8df7ab..91b9e0c537 100644 --- a/src/where.c +++ b/src/where.c @@ -5835,12 +5835,38 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ assert( pWInfo->nLevel<=pTabList->nSrc ); for(i=0, pLevel=pWInfo->a; inLevel; i++, pLevel++){ + int k, last; + VdbeOp *pOp; Index *pIdx = 0; struct SrcList_item *pTabItem = &pTabList->a[pLevel->iFrom]; Table *pTab = pTabItem->pTab; assert( pTab!=0 ); pLoop = pLevel->pWLoop; + /* For a co-routine, change all OP_Column references to the table of + ** the co-routine into OP_SCopy of result contained in a register. + ** OP_Rowid becomes OP_Null. + */ + if( pTabItem->viaCoroutine ){ + last = sqlite3VdbeCurrentAddr(v); + k = pLevel->addrBody; + pOp = sqlite3VdbeGetOp(v, k); + for(; kp1!=pLevel->iTabCur ) continue; + if( pOp->opcode==OP_Column ){ + pOp->opcode = OP_SCopy; + pOp->p1 = pOp->p2 + pTabItem->regResult; + pOp->p2 = pOp->p3; + pOp->p3 = 0; + }else if( pOp->opcode==OP_Rowid ){ + pOp->opcode = OP_Null; + pOp->p1 = 0; + pOp->p3 = 0; + } + } + continue; + } + /* Close all of the cursors that were opened by sqlite3WhereBegin. ** Except, do not close cursors that will be reused by the OR optimization ** (WHERE_OMIT_OPEN_CLOSE). And do not close the OP_OpenWrite cursors @@ -5879,9 +5905,6 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ pIdx = pLevel->u.pCovidx; } if( pIdx && !db->mallocFailed ){ - int k, last; - VdbeOp *pOp; - last = sqlite3VdbeCurrentAddr(v); k = pLevel->addrBody; pOp = sqlite3VdbeGetOp(v, k); From c47548057d8cca3821ae4bd6c2b322f595a69f0e Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 9 Feb 2014 00:18:21 +0000 Subject: [PATCH 234/276] Add a new "testset" to the speedtest1 program: The sudoku solver. FossilOrigin-Name: 4677ef2f8a726573c48ee2e532c00a68308dd7e1 --- manifest | 12 ++--- manifest.uuid | 2 +- test/speedtest1.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 121 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index d5e1ef9945..0b4f5767ef 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\saway\swith\sthe\s"multi-register\spseudo-table"\sabstration.\s\sInstead,\sjust\nuse\san\sOP_SCopy\sto\sload\sresults\sdirectory\sfrom\sthe\sresult\sregisters\sof\nthe\sco-routine. -D 2014-02-08T23:20:32.439 +C Add\sa\snew\s"testset"\sto\sthe\sspeedtest1\sprogram:\s\sThe\ssudoku\ssolver. +D 2014-02-09T00:18:21.530 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -824,7 +824,7 @@ F test/speed3.test d32043614c08c53eafdc80f33191d5bd9b920523 F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b -F test/speedtest1.c 7130d2cb6db45baa553a4ab2f715116c71c2d9f4 +F test/speedtest1.c ba90413e95df3b6e2ddc5b4568b2756f38ed8aa0 F test/spellfix.test 61309f5efbec53603b3f86457d34a504f80abafe F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298 F test/stat.test 76fd746b85459e812a0193410fb599f0531f22de @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P e2303d1b0c17b6e7494fb7db8264f4c2ac193723 -R eb37dbfa0e5b1c125492efcb100d4ba8 +P 1e64dd782a126f48d78c43a664844a41d0e6334e +R feb25dc752d56bb4a29200c4d7633cb5 U drh -Z 5d0b8c0ebed26b99f999abde70f4aea6 +Z 251505f9c01c1bcece10c5ebfc8b7c5b diff --git a/manifest.uuid b/manifest.uuid index 43ad228af7..483fbfb6cd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1e64dd782a126f48d78c43a664844a41d0e6334e \ No newline at end of file +4677ef2f8a726573c48ee2e532c00a68308dd7e1 \ No newline at end of file diff --git a/test/speedtest1.c b/test/speedtest1.c index 38f891e431..ec4e717149 100644 --- a/test/speedtest1.c +++ b/test/speedtest1.c @@ -737,6 +737,118 @@ void testset_main(void){ speedtest1_end_test(); } +/* +** A testset for common table expressions. This exercises code +** for views, subqueries, co-routines, etc. +*/ +void testset_cte(void){ + static const char *azPuzzle[] = { + /* Easy */ + "534...9.." + "67.195..." + ".98....6." + "8...6...3" + "4..8.3..1" + "....2...6" + ".6....28." + "...419..5" + "...28..79", + + /* Medium */ + "53....9.." + "6..195..." + ".98....6." + "8...6...3" + "4..8.3..1" + "....2...6" + ".6....28." + "...419..5" + "....8..79", + + /* Hard */ + "53......." + "6..195..." + ".98....6." + "8...6...3" + "4..8.3..1" + "....2...6" + ".6....28." + "...419..5" + "....8..79", + }; + const char *zPuz; + + if( g.szTest<25 ){ + zPuz = azPuzzle[0]; + }else if( g.szTest<70 ){ + zPuz = azPuzzle[1]; + }else{ + zPuz = azPuzzle[2]; + } + speedtest1_begin_test(100, "Sudoku with recursive 'digits'"); + speedtest1_prepare( + "WITH RECURSIVE\n" + " input(sud) AS (VALUES(?1)),\n" + " digits(z,lp) AS (\n" + " VALUES('1', 1)\n" + " UNION ALL\n" + " SELECT CAST(lp+1 AS TEXT), lp+1 FROM digits WHERE lp<9\n" + " ),\n" + " x(s, ind) AS (\n" + " SELECT sud, instr(sud, '.') FROM input\n" + " UNION ALL\n" + " SELECT\n" + " substr(s, 1, ind-1) || z || substr(s, ind+1),\n" + " instr( substr(s, 1, ind-1) || z || substr(s, ind+1), '.' )\n" + " FROM x, digits AS z\n" + " WHERE ind>0\n" + " AND NOT EXISTS (\n" + " SELECT 1\n" + " FROM digits AS lp\n" + " WHERE z.z = substr(s, ((ind-1)/9)*9 + lp, 1)\n" + " OR z.z = substr(s, ((ind-1)%%9) + (lp-1)*9 + 1, 1)\n" + " OR z.z = substr(s, (((ind-1)/3) %% 3) * 3\n" + " + ((ind-1)/27) * 27 + lp\n" + " + ((lp-1) / 3) * 6, 1)\n" + " )\n" + " )\n" + "SELECT s FROM x WHERE ind=0;" + ); + sqlite3_bind_text(g.pStmt, 1, zPuz, -1, SQLITE_STATIC); + speedtest1_run(); + speedtest1_end_test(); + + speedtest1_begin_test(200, "Sudoku with VALUES 'digits'"); + speedtest1_prepare( + "WITH RECURSIVE\n" + " input(sud) AS (VALUES(?1)),\n" + " digits(z,lp) AS (VALUES('1',1),('2',2),('3',3),('4',4),('5',5),\n" + " ('6',6),('7',7),('8',8),('9',9)),\n" + " x(s, ind) AS (\n" + " SELECT sud, instr(sud, '.') FROM input\n" + " UNION ALL\n" + " SELECT\n" + " substr(s, 1, ind-1) || z || substr(s, ind+1),\n" + " instr( substr(s, 1, ind-1) || z || substr(s, ind+1), '.' )\n" + " FROM x, digits AS z\n" + " WHERE ind>0\n" + " AND NOT EXISTS (\n" + " SELECT 1\n" + " FROM digits AS lp\n" + " WHERE z.z = substr(s, ((ind-1)/9)*9 + lp, 1)\n" + " OR z.z = substr(s, ((ind-1)%%9) + (lp-1)*9 + 1, 1)\n" + " OR z.z = substr(s, (((ind-1)/3) %% 3) * 3\n" + " + ((ind-1)/27) * 27 + lp\n" + " + ((lp-1) / 3) * 6, 1)\n" + " )\n" + " )\n" + "SELECT s FROM x WHERE ind=0;" + ); + sqlite3_bind_text(g.pStmt, 1, zPuz, -1, SQLITE_STATIC); + speedtest1_run(); + speedtest1_end_test(); +} + /* ** A testset used for debugging speedtest1 itself. */ @@ -945,6 +1057,8 @@ int main(int argc, char **argv){ testset_main(); }else if( strcmp(zTSet,"debug1")==0 ){ testset_debug1(); + }else if( strcmp(zTSet,"cte")==0 ){ + testset_cte(); }else{ fatal_error("unknown testset: \"%s\"\n", zTSet); } From fa46bfbbc557444b92cccc2158139f14c7e24681 Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 9 Feb 2014 00:52:53 +0000 Subject: [PATCH 235/276] Add the Mandelbrot Set testcase to the "cte" testset of speedtest1. FossilOrigin-Name: 56febbeb575a298ae8839b3a59711150ceb9999d --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/speedtest1.c | 28 ++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 0b4f5767ef..1f964073bd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\snew\s"testset"\sto\sthe\sspeedtest1\sprogram:\s\sThe\ssudoku\ssolver. -D 2014-02-09T00:18:21.530 +C Add\sthe\sMandelbrot\sSet\stestcase\sto\sthe\s"cte"\stestset\sof\sspeedtest1. +D 2014-02-09T00:52:53.682 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -824,7 +824,7 @@ F test/speed3.test d32043614c08c53eafdc80f33191d5bd9b920523 F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b -F test/speedtest1.c ba90413e95df3b6e2ddc5b4568b2756f38ed8aa0 +F test/speedtest1.c 8b3b85c82018cdbc492ab43b841157bcbf6b281c F test/spellfix.test 61309f5efbec53603b3f86457d34a504f80abafe F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298 F test/stat.test 76fd746b85459e812a0193410fb599f0531f22de @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 1e64dd782a126f48d78c43a664844a41d0e6334e -R feb25dc752d56bb4a29200c4d7633cb5 +P 4677ef2f8a726573c48ee2e532c00a68308dd7e1 +R 439cd23f35fb63451d5f47c7c9c57942 U drh -Z 251505f9c01c1bcece10c5ebfc8b7c5b +Z 01b4847ed4d0397261d6befa79512d70 diff --git a/manifest.uuid b/manifest.uuid index 483fbfb6cd..1cd0a889dd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4677ef2f8a726573c48ee2e532c00a68308dd7e1 \ No newline at end of file +56febbeb575a298ae8839b3a59711150ceb9999d \ No newline at end of file diff --git a/test/speedtest1.c b/test/speedtest1.c index ec4e717149..1de5177106 100644 --- a/test/speedtest1.c +++ b/test/speedtest1.c @@ -777,6 +777,7 @@ void testset_cte(void){ "....8..79", }; const char *zPuz; + double rSpacing; if( g.szTest<25 ){ zPuz = azPuzzle[0]; @@ -847,6 +848,33 @@ void testset_cte(void){ sqlite3_bind_text(g.pStmt, 1, zPuz, -1, SQLITE_STATIC); speedtest1_run(); speedtest1_end_test(); + + rSpacing = 5.0/g.szTest; + speedtest1_begin_test(300, "Mandelbrot Set with spacing=%f", rSpacing); + speedtest1_prepare( + "WITH RECURSIVE \n" + " xaxis(x) AS (VALUES(-2.0) UNION ALL SELECT x+?1 FROM xaxis WHERE x<1.2),\n" + " yaxis(y) AS (VALUES(-1.0) UNION ALL SELECT y+?2 FROM yaxis WHERE y<1.0),\n" + " m(iter, cx, cy, x, y) AS (\n" + " SELECT 0, x, y, 0.0, 0.0 FROM xaxis, yaxis\n" + " UNION ALL\n" + " SELECT iter+1, cx, cy, x*x-y*y + cx, 2.0*x*y + cy FROM m \n" + " WHERE (x*x + y*y) < 4.0 AND iter<28\n" + " ),\n" + " m2(iter, cx, cy) AS (\n" + " SELECT max(iter), cx, cy FROM m GROUP BY cx, cy\n" + " ),\n" + " a(t) AS (\n" + " SELECT group_concat( substr(' .+*#', 1+min(iter/7,4), 1), '') \n" + " FROM m2 GROUP BY cy\n" + " )\n" + "SELECT group_concat(rtrim(t),x'0a') FROM a;" + ); + sqlite3_bind_double(g.pStmt, 1, rSpacing*.05); + sqlite3_bind_double(g.pStmt, 2, rSpacing); + speedtest1_run(); + speedtest1_end_test(); + } /* From d227a291b257f0ea07c214cb2a4c0148e9946adf Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 9 Feb 2014 18:02:09 +0000 Subject: [PATCH 236/276] Use the WITH clause to help resolve names for SELECT statements on the left of a compound query. Proposed fix for ticket [31a19d11b97088296a]. FossilOrigin-Name: 67bfd59d9087a987f15f6148efa1ff104983e1fb --- manifest | 20 ++++++++-------- manifest.uuid | 2 +- src/expr.c | 1 - src/parse.y | 21 +++++++++++++---- src/select.c | 62 +++++++++++++++++++++---------------------------- src/sqliteInt.h | 2 +- test/with1.test | 13 ++++++++++- 7 files changed, 67 insertions(+), 54 deletions(-) diff --git a/manifest b/manifest index 1f964073bd..ea5c267291 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sMandelbrot\sSet\stestcase\sto\sthe\s"cte"\stestset\sof\sspeedtest1. -D 2014-02-09T00:52:53.682 +C Use\sthe\sWITH\sclause\sto\shelp\sresolve\snames\sfor\sSELECT\sstatements\son\sthe\sleft\nof\sa\scompound\squery.\s\sProposed\sfix\sfor\sticket\s[31a19d11b97088296a]. +D 2014-02-09T18:02:09.253 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -175,7 +175,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 F src/delete.c 6765a421f08adbedc5d52d21760ec6dbe5123fd3 -F src/expr.c fabda9e9320e3284c2a35cdc558313d9e80ce92a +F src/expr.c 9bea427f95665c1aa8fdc87b7678546eef50c296 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 2ab0f5384b70594468ef3ac5c7ed8ca24bfd17d5 F src/func.c f4499b39d66b71825514334ce67b32ff14bd19f5 @@ -209,7 +209,7 @@ F src/os_unix.c 18f7f95dc6bcb9cf4d4a238d8e2de96611bc2ae5 F src/os_win.c d4284f003445054a26689f1264b1b9bf7261bd1b F src/pager.c 0ffa313a30ed6d061d9c6601b7b175cc50a1cab7 F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428 -F src/parse.y bd51bc17cbfe7549adb4ca3747b1c3d384645065 +F src/parse.y cce844ccb80b5f969b04c25100c8d94338488efb F src/pcache.c d8eafac28290d4bb80332005435db44991d07fc2 F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222 F src/pcache1.c 102e6f5a2fbc646154463eb856d1fd716867b64c @@ -219,12 +219,12 @@ F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c de28cd6d49e0334a3c693fbcce7cd8dfe5fc3979 +F src/select.c c055a9fa25a4e7fc8c1652c44a31d6382dbb1e8a F src/shell.c 7dedf7367ee49050b0366bf8dbc8ec2bd15b42c7 F src/sqlite.h.in eed7f7d66a60daaa7b4a597dcd9bad87aad9611b F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h edee30d57dd287aea523406f53123583ca7f0089 +F src/sqliteInt.h 5b1f4e30c8332270e4c14254ef1fbcbd92a4a4c7 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -1092,7 +1092,7 @@ F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c F test/win32lock.test 7a6bd73a5dcdee39b5bb93e92395e1773a194361 F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d -F test/with1.test ce15d69d34a2576b0e47d78c244d1ba2a31679d1 +F test/with1.test 268081a6b14817a262ced4d0ee34d4d2a1dd2068 F test/with2.test 2fe78fcd8deef2a0f9cfc49bfc755911d0b3fd64 F test/withM.test e97f2a8c506ab3ea9eab94e6f6072f6cc924c991 F test/without_rowid1.test aaa26da19d543cd8d3d2d0e686dfa255556c15c8 @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 4677ef2f8a726573c48ee2e532c00a68308dd7e1 -R 439cd23f35fb63451d5f47c7c9c57942 +P 56febbeb575a298ae8839b3a59711150ceb9999d +R c206aab6ac6bc2f14c7db43625790fe8 U drh -Z 01b4847ed4d0397261d6befa79512d70 +Z c763a50ce107ca4b3399be4e022f486e diff --git a/manifest.uuid b/manifest.uuid index 1cd0a889dd..cc9edf8507 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -56febbeb575a298ae8839b3a59711150ceb9999d \ No newline at end of file +67bfd59d9087a987f15f6148efa1ff104983e1fb \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index e417d8aadd..0f07181019 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1060,7 +1060,6 @@ Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){ pNew->iLimit = 0; pNew->iOffset = 0; pNew->selFlags = p->selFlags & ~SF_UsesEphemeral; - pNew->pRightmost = 0; pNew->addrOpenEphm[0] = -1; pNew->addrOpenEphm[1] = -1; pNew->addrOpenEphm[2] = -1; diff --git a/src/parse.y b/src/parse.y index d0ec821d7a..373c126a25 100644 --- a/src/parse.y +++ b/src/parse.y @@ -412,13 +412,26 @@ cmd ::= select(X). { %type oneselect {Select*} %destructor oneselect {sqlite3SelectDelete(pParse->db, $$);} -select(A) ::= with(W) selectnowith(X). { - if( X ){ - X->pWith = W; +select(A) ::= with(W) selectnowith(X). { + Select *p = X, *pNext, *pLoop; + if( p ){ + int cnt = 0, mxSelect; + p->pWith = W; + if( p->pPrior ){ + pNext = 0; + for(pLoop=p; pLoop; pNext=pLoop, pLoop=pLoop->pPrior, cnt++){ + pLoop->pNext = pNext; + pLoop->selFlags |= SF_Compound; + } + mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT]; + if( mxSelect && cnt>mxSelect ){ + sqlite3ErrorMsg(pParse, "too many terms in compound SELECT"); + } + } }else{ sqlite3WithDelete(pParse->db, W); } - A = X; + A = p; } selectnowith(A) ::= oneselect(X). {A = X;} diff --git a/src/select.c b/src/select.c index 4c426e76b2..07cb571daa 100644 --- a/src/select.c +++ b/src/select.c @@ -109,6 +109,14 @@ void sqlite3SelectDelete(sqlite3 *db, Select *p){ } } +/* +** Return a pointer to the right-most SELECT statement in a compound. +*/ +static Select *findRightmost(Select *p){ + while( p->pNext ) p = p->pNext; + return p; +} + /* ** Given 1 to 3 identifiers preceding the JOIN keyword, determine the ** type of join. Return an integer constant that expresses that type @@ -1877,7 +1885,9 @@ static void generateWithRecursiveQuery( p->pOrderBy = 0; /* Store the results of the setup-query in Queue. */ + pSetup->pNext = 0; rc = sqlite3Select(pParse, pSetup, &destQueue); + pSetup->pNext = p; if( rc ) goto end_of_recursive_query; /* Find the next row in the Queue and output that row */ @@ -1982,8 +1992,6 @@ static int multiSelect( assert( (p->selFlags & SF_Recursive)==0 || p->op==TK_ALL || p->op==TK_UNION ); db = pParse->db; pPrior = p->pPrior; - assert( pPrior->pRightmost!=pPrior ); - assert( pPrior->pRightmost==p->pRightmost ); dest = *pDest; if( pPrior->pOrderBy ){ sqlite3ErrorMsg(pParse,"ORDER BY clause should come after %s not before", @@ -2091,12 +2099,10 @@ static int multiSelect( testcase( p->op==TK_EXCEPT ); testcase( p->op==TK_UNION ); priorOp = SRT_Union; - if( dest.eDest==priorOp && ALWAYS(!p->pLimit &&!p->pOffset) ){ + if( dest.eDest==priorOp ){ /* We can reuse a temporary table generated by a SELECT to our ** right. */ - assert( p->pRightmost!=p ); /* Can only happen for leftward elements - ** of a 3-way or more compound */ assert( p->pLimit==0 ); /* Not allowed on leftward elements */ assert( p->pOffset==0 ); /* Not allowed on leftward elements */ unionTab = dest.iSDParm; @@ -2109,7 +2115,7 @@ static int multiSelect( addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, unionTab, 0); assert( p->addrOpenEphm[0] == -1 ); p->addrOpenEphm[0] = addr; - p->pRightmost->selFlags |= SF_UsesEphemeral; + findRightmost(p)->selFlags |= SF_UsesEphemeral; assert( p->pEList ); } @@ -2198,7 +2204,7 @@ static int multiSelect( addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab1, 0); assert( p->addrOpenEphm[0] == -1 ); p->addrOpenEphm[0] = addr; - p->pRightmost->selFlags |= SF_UsesEphemeral; + findRightmost(p)->selFlags |= SF_UsesEphemeral; assert( p->pEList ); /* Code the SELECTs to our left into temporary table "tab1". @@ -2277,7 +2283,7 @@ static int multiSelect( CollSeq **apColl; /* For looping through pKeyInfo->aColl[] */ int nCol; /* Number of columns in result set */ - assert( p->pRightmost==p ); + assert( p->pNext==0 ); nCol = p->pEList->nExpr; pKeyInfo = sqlite3KeyInfoAlloc(db, nCol, 1); if( !pKeyInfo ){ @@ -2693,6 +2699,7 @@ static int multiSelectOrderBy( /* Separate the left and the right query from one another */ p->pPrior = 0; + pPrior->pNext = 0; sqlite3ResolveOrderGroupBy(pParse, p, p->pOrderBy, "ORDER"); if( pPrior->pPrior==0 ){ sqlite3ResolveOrderGroupBy(pParse, pPrior, pPrior->pOrderBy, "ORDER"); @@ -2858,6 +2865,7 @@ static int multiSelectOrderBy( sqlite3SelectDelete(db, p->pPrior); } p->pPrior = pPrior; + pPrior->pNext = p; /*** TBD: Insert subroutine calls to close cursors on incomplete **** subqueries ****/ @@ -3123,7 +3131,7 @@ static int flattenSubquery( ** and (14). */ if( pSub->pLimit && p->pLimit ) return 0; /* Restriction (13) */ if( pSub->pOffset ) return 0; /* Restriction (14) */ - if( p->pRightmost && pSub->pLimit ){ + if( (p->selFlags & SF_Compound)!=0 && pSub->pLimit ){ return 0; /* Restriction (15) */ } if( pSubSrc->nSrc==0 ) return 0; /* Restriction (7) */ @@ -3274,14 +3282,14 @@ static int flattenSubquery( p->pOrderBy = pOrderBy; p->pSrc = pSrc; p->op = TK_ALL; - p->pRightmost = 0; if( pNew==0 ){ - pNew = pPrior; + p->pPrior = pPrior; }else{ pNew->pPrior = pPrior; - pNew->pRightmost = 0; + if( pPrior ) pPrior->pNext = pNew; + pNew->pNext = p; + p->pPrior = pNew; } - p->pPrior = pNew; if( db->mallocFailed ) return 1; } @@ -3807,9 +3815,10 @@ static int withExpand( */ static void selectPopWith(Walker *pWalker, Select *p){ Parse *pParse = pWalker->pParse; - if( p->pWith ){ - assert( pParse->pWith==p->pWith ); - pParse->pWith = p->pWith->pOuter; + With *pWith = findRightmost(p)->pWith; + if( pWith!=0 ){ + assert( pParse->pWith==pWith ); + pParse->pWith = pWith->pOuter; } } #else @@ -3859,7 +3868,7 @@ static int selectExpander(Walker *pWalker, Select *p){ } pTabList = p->pSrc; pEList = p->pEList; - sqlite3WithPush(pParse, p->pWith, 0); + sqlite3WithPush(pParse, findRightmost(p)->pWith, 0); /* Make sure cursor numbers have been assigned to all entries in ** the FROM clause of the SELECT statement. @@ -4603,21 +4612,6 @@ int sqlite3Select( /* If there is are a sequence of queries, do the earlier ones first. */ if( p->pPrior ){ - if( p->pRightmost==0 ){ - Select *pLoop, *pRight = 0; - int cnt = 0; - int mxSelect; - for(pLoop=p; pLoop; pLoop=pLoop->pPrior, cnt++){ - pLoop->pRightmost = p; - pLoop->pNext = pRight; - pRight = pLoop; - } - mxSelect = db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT]; - if( mxSelect && cnt>mxSelect ){ - sqlite3ErrorMsg(pParse, "too many terms in compound SELECT"); - goto select_end; - } - } rc = multiSelect(pParse, p, pDest); explainSetInteger(pParse->iSelectId, iRestoreSelectId); return rc; @@ -5279,10 +5273,6 @@ void sqlite3ExplainSelect(Vdbe *pVdbe, Select *p){ sqlite3ExplainPrintf(pVdbe, "(null-select)"); return; } - while( p->pPrior ){ - p->pPrior->pNext = p; - p = p->pPrior; - } sqlite3ExplainPush(pVdbe); while( p ){ explainOneSelect(pVdbe, p); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 4cfa9d39a5..8b9337a2b0 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2148,7 +2148,6 @@ struct Select { ExprList *pOrderBy; /* The ORDER BY clause */ Select *pPrior; /* Prior select in a compound select statement */ Select *pNext; /* Next select to the left in a compound */ - Select *pRightmost; /* Right-most select in a compound select statement */ Expr *pLimit; /* LIMIT expression. NULL means not used. */ Expr *pOffset; /* OFFSET expression. NULL means not used. */ With *pWith; /* WITH clause attached to this select. Or NULL. */ @@ -2170,6 +2169,7 @@ struct Select { #define SF_NestedFrom 0x0200 /* Part of a parenthesized FROM clause */ #define SF_MaybeConvert 0x0400 /* Need convertCompoundSelectToSubquery() */ #define SF_Recursive 0x0800 /* The recursive part of a recursive CTE */ +#define SF_Compound 0x1000 /* Part of a compound query */ /* diff --git a/test/with1.test b/test/with1.test index 2fca12817f..42d2277aef 100644 --- a/test/with1.test +++ b/test/with1.test @@ -816,5 +816,16 @@ do_execsql_test 11.3 { .........Noland .........Olivia}} -finish_test +#-------------------------------------------------------------------------- +# Ticket [31a19d11b97088296ac104aaff113a9790394927] (2014-02-09) +# Name resolution issue with compound SELECTs and Common Table Expressions +# +do_execsql_test 12.1 { +WITH RECURSIVE + t1(x) AS (VALUES(2) UNION ALL SELECT x+2 FROM t1 WHERE x<20), + t2(y) AS (VALUES(3) UNION ALL SELECT y+3 FROM t2 WHERE y<20) +SELECT x FROM t1 EXCEPT SELECT y FROM t2 ORDER BY 1; +} {2 4 8 10 14 16 20} + +finish_test From 5574e3f456c353dc4ccdfa52c893ae937ce369ee Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 9 Feb 2014 23:59:28 +0000 Subject: [PATCH 237/276] Add a compound-query test to the speedtest1 test program. FossilOrigin-Name: 532995759114ab7a7cba18cc9d8820d78eb1a96e --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/speedtest1.c | 15 +++++++++++++++ 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index ea5c267291..a08edf5d8c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Use\sthe\sWITH\sclause\sto\shelp\sresolve\snames\sfor\sSELECT\sstatements\son\sthe\sleft\nof\sa\scompound\squery.\s\sProposed\sfix\sfor\sticket\s[31a19d11b97088296a]. -D 2014-02-09T18:02:09.253 +C Add\sa\scompound-query\stest\sto\sthe\sspeedtest1\stest\sprogram. +D 2014-02-09T23:59:28.966 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -824,7 +824,7 @@ F test/speed3.test d32043614c08c53eafdc80f33191d5bd9b920523 F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b -F test/speedtest1.c 8b3b85c82018cdbc492ab43b841157bcbf6b281c +F test/speedtest1.c 1603da7b4897716f9df15bd71b0310f56ec3181e F test/spellfix.test 61309f5efbec53603b3f86457d34a504f80abafe F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298 F test/stat.test 76fd746b85459e812a0193410fb599f0531f22de @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 56febbeb575a298ae8839b3a59711150ceb9999d -R c206aab6ac6bc2f14c7db43625790fe8 +P 67bfd59d9087a987f15f6148efa1ff104983e1fb +R 08e9f131a35b941b5219bd5647483bf9 U drh -Z c763a50ce107ca4b3399be4e022f486e +Z 03478c9c29bcc9ab89e223c27b70af04 diff --git a/manifest.uuid b/manifest.uuid index cc9edf8507..85633fa577 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -67bfd59d9087a987f15f6148efa1ff104983e1fb \ No newline at end of file +532995759114ab7a7cba18cc9d8820d78eb1a96e \ No newline at end of file diff --git a/test/speedtest1.c b/test/speedtest1.c index 1de5177106..05160e0eeb 100644 --- a/test/speedtest1.c +++ b/test/speedtest1.c @@ -778,6 +778,7 @@ void testset_cte(void){ }; const char *zPuz; double rSpacing; + int nElem; if( g.szTest<25 ){ zPuz = azPuzzle[0]; @@ -875,6 +876,20 @@ void testset_cte(void){ speedtest1_run(); speedtest1_end_test(); + nElem = 10000*g.szTest; + speedtest1_begin_test(400, "EXCEPT operator on %d-element tables", nElem); + speedtest1_prepare( + "WITH RECURSIVE \n" + " t1(x) AS (VALUES(2) UNION ALL SELECT x+2 FROM t1 WHERE x<%d),\n" + " t2(y) AS (VALUES(3) UNION ALL SELECT y+3 FROM t2 WHERE y<%d)\n" + "SELECT count(x), avg(x) FROM (\n" + " SELECT x FROM t1 EXCEPT SELECT y FROM t2 ORDER BY 1\n" + ");", + nElem, nElem + ); + speedtest1_run(); + speedtest1_end_test(); + } /* From 1b27b8c0a0cff6895ffcc2608b78449e648a6de9 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 10 Feb 2014 03:21:57 +0000 Subject: [PATCH 238/276] Faster and smaller implementation of sqlite3_value_type(). FossilOrigin-Name: 5708bc24b8cab623b833121183042b43e5a7021b --- manifest | 22 +++++++++++----------- manifest.uuid | 2 +- src/test5.c | 2 +- src/vdbe.c | 32 +++++--------------------------- src/vdbeInt.h | 5 +++-- src/vdbeapi.c | 38 ++++++++++++++++++++++++++++++++++++-- src/vdbeaux.c | 18 +++++++++--------- src/vdbemem.c | 20 ++++++++++---------- 8 files changed, 76 insertions(+), 63 deletions(-) diff --git a/manifest b/manifest index a08edf5d8c..5af97eeec4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\scompound-query\stest\sto\sthe\sspeedtest1\stest\sprogram. -D 2014-02-09T23:59:28.966 +C Faster\sand\ssmaller\simplementation\sof\ssqlite3_value_type(). +D 2014-02-10T03:21:57.367 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -233,7 +233,7 @@ F src/test1.c 2401eee14a4309a7cfe2aeb2f30ad517a1d9c299 F src/test2.c 7355101c085304b90024f2261e056cdff13c6c35 F src/test3.c 1c0e5d6f080b8e33c1ce8b3078e7013fdbcd560c F src/test4.c 9b32d22f5f150abe23c1830e2057c4037c45b3df -F src/test5.c a6d1ac55ac054d0b2b8f37b5e655b6c92645a013 +F src/test5.c 41e6e732f14a54c7b47f753e364700760f6521b0 F src/test6.c 41cacf3b0dd180823919bf9e1fbab287c9266723 F src/test7.c 72b732baa5642f795655ba1126ea032af46ecfd2 F src/test8.c 54ccd7b1df5062f0ecbf50a8f7b618f8b1f13b20 @@ -280,13 +280,13 @@ F src/update.c a7df6fffce6bfedc578fda6136dd33e34a63f8ee F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c 15ac2627f548f5481d0d7e6c4eb67be673027695 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c 78b41fd0a3b3ab4647e3bf99905fb65831a1a92a +F src/vdbe.c 66c3e5c49ff61aaa3e3182fb9962ceddb847b05f F src/vdbe.h e6c4c610fcabad4fa80ebb1efc6822a9367e2b26 -F src/vdbeInt.h 6714e9eb5c3a481976d32ca767f03ac0469fc9df -F src/vdbeapi.c ce4e68ea4842cc6081046f533d088dcf01d247ad -F src/vdbeaux.c 379343f1d98b60b0771366e5955f3cab34f1a3ca +F src/vdbeInt.h 5286af9067cabdb8ba57b87c0c988a931be6c6c8 +F src/vdbeapi.c 5bc41aaea448a7fc250902c418f1795859be3820 +F src/vdbeaux.c dac6e571262a322b2f889752a8dd36549bdacd2b F src/vdbeblob.c 9542e116c1db5ed813977581d506c176e117c0ec -F src/vdbemem.c c0bcc02d6816ab4218ac0f94b63c8ee78a0f739f +F src/vdbemem.c 06603e8e9d2f3247b68c6bbe4bd37fb6721b5bda F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147 F src/vdbetrace.c 6f52bc0c51e144b7efdcfb2a8f771167a8816767 F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 67bfd59d9087a987f15f6148efa1ff104983e1fb -R 08e9f131a35b941b5219bd5647483bf9 +P 532995759114ab7a7cba18cc9d8820d78eb1a96e +R 1d6572df35f58f7e82be516ccbec8b1d U drh -Z 03478c9c29bcc9ab89e223c27b70af04 +Z d879d19c9c74c4f3aa3952d43b5ccba0 diff --git a/manifest.uuid b/manifest.uuid index 85633fa577..da59cef8ea 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -532995759114ab7a7cba18cc9d8820d78eb1a96e \ No newline at end of file +5708bc24b8cab623b833121183042b43e5a7021b \ No newline at end of file diff --git a/src/test5.c b/src/test5.c index 303d1205b2..bf574e3c3c 100644 --- a/src/test5.c +++ b/src/test5.c @@ -76,7 +76,7 @@ static int test_value_overhead( val.flags = MEM_Str|MEM_Term|MEM_Static; val.z = "hello world"; - val.type = SQLITE_TEXT; + val.memType = MEM_Str; val.enc = SQLITE_UTF8; for(i=0; ipSorter!=0) -/* -** Argument pMem points at a register that will be passed to a -** user-defined function or returned to the user as the result of a query. -** This routine sets the pMem->type variable used by the sqlite3_value_*() -** routines. -*/ -void sqlite3VdbeMemStoreType(Mem *pMem){ - int flags = pMem->flags; - if( flags & MEM_Null ){ - pMem->type = SQLITE_NULL; - } - else if( flags & MEM_Int ){ - pMem->type = SQLITE_INTEGER; - } - else if( flags & MEM_Real ){ - pMem->type = SQLITE_FLOAT; - } - else if( flags & MEM_Str ){ - pMem->type = SQLITE_TEXT; - }else{ - pMem->type = SQLITE_BLOB; - } -} - /* ** Allocate VdbeCursor number iCur. Return a pointer to it. Return NULL ** if we run out of memory. @@ -285,12 +261,14 @@ static void applyAffinity( ** loss of information and return the revised type of the argument. */ int sqlite3_value_numeric_type(sqlite3_value *pVal){ - Mem *pMem = (Mem*)pVal; - if( pMem->type==SQLITE_TEXT ){ + int eType = sqlite3_value_type(pVal); + if( eType==SQLITE_TEXT ){ + Mem *pMem = (Mem*)pVal; applyNumericAffinity(pMem); sqlite3VdbeMemStoreType(pMem); + eType = sqlite3_value_type(pVal); } - return pMem->type; + return eType; } /* diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 508b61e95c..88c072adec 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -168,7 +168,7 @@ struct Mem { } u; int n; /* Number of characters in string value, excluding '\0' */ u16 flags; /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */ - u8 type; /* One of SQLITE_NULL, SQLITE_TEXT, SQLITE_INTEGER, etc */ + u8 memType; /* Lower 5 bits of flags */ u8 enc; /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */ #ifdef SQLITE_DEBUG Mem *pScopyFrom; /* This Mem is a shallow copy of pScopyFrom */ @@ -434,7 +434,8 @@ int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve); int sqlite3VdbeCloseStatement(Vdbe *, int); void sqlite3VdbeFrameDelete(VdbeFrame*); int sqlite3VdbeFrameRestore(VdbeFrame *); -void sqlite3VdbeMemStoreType(Mem *pMem); +#define sqlite3VdbeMemStoreType(X) (X)->memType = (u8)((X)->flags&0x1f) +/* void sqlite3VdbeMemStoreType(Mem *pMem); */ int sqlite3VdbeTransferError(Vdbe *p); int sqlite3VdbeSorterInit(sqlite3 *, VdbeCursor *); diff --git a/src/vdbeapi.c b/src/vdbeapi.c index ea383dffda..c1edbe48e2 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -172,7 +172,41 @@ const void *sqlite3_value_text16le(sqlite3_value *pVal){ } #endif /* SQLITE_OMIT_UTF16 */ int sqlite3_value_type(sqlite3_value* pVal){ - return pVal->type; + static const u8 aType[] = { + SQLITE_BLOB, /* 0x00 */ + SQLITE_NULL, /* 0x01 */ + SQLITE_TEXT, /* 0x02 */ + SQLITE_NULL, /* 0x03 */ + SQLITE_INTEGER, /* 0x04 */ + SQLITE_NULL, /* 0x05 */ + SQLITE_INTEGER, /* 0x06 */ + SQLITE_NULL, /* 0x07 */ + SQLITE_FLOAT, /* 0x08 */ + SQLITE_NULL, /* 0x09 */ + SQLITE_FLOAT, /* 0x0a */ + SQLITE_NULL, /* 0x0b */ + SQLITE_INTEGER, /* 0x0c */ + SQLITE_NULL, /* 0x0d */ + SQLITE_INTEGER, /* 0x0e */ + SQLITE_NULL, /* 0x0f */ + SQLITE_BLOB, /* 0x10 */ + SQLITE_NULL, /* 0x11 */ + SQLITE_TEXT, /* 0x12 */ + SQLITE_NULL, /* 0x13 */ + SQLITE_INTEGER, /* 0x14 */ + SQLITE_NULL, /* 0x15 */ + SQLITE_INTEGER, /* 0x16 */ + SQLITE_NULL, /* 0x17 */ + SQLITE_FLOAT, /* 0x18 */ + SQLITE_NULL, /* 0x19 */ + SQLITE_FLOAT, /* 0x1a */ + SQLITE_NULL, /* 0x1b */ + SQLITE_INTEGER, /* 0x1c */ + SQLITE_NULL, /* 0x1d */ + SQLITE_INTEGER, /* 0x1e */ + SQLITE_NULL, /* 0x1f */ + }; + return aType[pVal->memType&0x1f]; } /**************************** sqlite3_result_ ******************************* @@ -1131,7 +1165,7 @@ int sqlite3_bind_text16( #endif /* SQLITE_OMIT_UTF16 */ int sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_value *pValue){ int rc; - switch( pValue->type ){ + switch( sqlite3_value_type((sqlite3_value*)pValue) ){ case SQLITE_INTEGER: { rc = sqlite3_bind_int64(pStmt, i, pValue->u.i); break; diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 1904cf131d..95c05f7e5c 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1345,7 +1345,7 @@ int sqlite3VdbeList( } if( p->explain==1 ){ pMem->flags = MEM_Int; - pMem->type = SQLITE_INTEGER; + pMem->memType = MEM_Int; pMem->u.i = i; /* Program counter */ pMem++; @@ -1353,7 +1353,7 @@ int sqlite3VdbeList( pMem->z = (char*)sqlite3OpcodeName(pOp->opcode); /* Opcode */ assert( pMem->z!=0 ); pMem->n = sqlite3Strlen30(pMem->z); - pMem->type = SQLITE_TEXT; + pMem->memType = MEM_Str; pMem->enc = SQLITE_UTF8; pMem++; @@ -1379,17 +1379,17 @@ int sqlite3VdbeList( pMem->flags = MEM_Int; pMem->u.i = pOp->p1; /* P1 */ - pMem->type = SQLITE_INTEGER; + pMem->memType = MEM_Int; pMem++; pMem->flags = MEM_Int; pMem->u.i = pOp->p2; /* P2 */ - pMem->type = SQLITE_INTEGER; + pMem->memType = MEM_Int; pMem++; pMem->flags = MEM_Int; pMem->u.i = pOp->p3; /* P3 */ - pMem->type = SQLITE_INTEGER; + pMem->memType = MEM_Int; pMem++; if( sqlite3VdbeMemGrow(pMem, 32, 0) ){ /* P4 */ @@ -1405,7 +1405,7 @@ int sqlite3VdbeList( pMem->n = sqlite3Strlen30(pMem->z); pMem->enc = SQLITE_UTF8; } - pMem->type = SQLITE_TEXT; + pMem->memType = MEM_Str; pMem++; if( p->explain==1 ){ @@ -1416,7 +1416,7 @@ int sqlite3VdbeList( pMem->flags = MEM_Dyn|MEM_Str|MEM_Term; pMem->n = 2; sqlite3_snprintf(3, pMem->z, "%.2x", pOp->p5); /* P5 */ - pMem->type = SQLITE_TEXT; + pMem->memType = MEM_Str; pMem->enc = SQLITE_UTF8; pMem++; @@ -1427,11 +1427,11 @@ int sqlite3VdbeList( } pMem->flags = MEM_Dyn|MEM_Str|MEM_Term; pMem->n = displayComment(pOp, zP4, pMem->z, 500); - pMem->type = SQLITE_TEXT; + pMem->memType = MEM_Str; pMem->enc = SQLITE_UTF8; #else pMem->flags = MEM_Null; /* Comment */ - pMem->type = SQLITE_NULL; + pMem->memType = MEM_Null; #endif } diff --git a/src/vdbemem.c b/src/vdbemem.c index 982a44537d..bcf9586b3f 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -289,7 +289,7 @@ void sqlite3VdbeMemReleaseExternal(Mem *p){ /* ** Release any memory held by the Mem. This may leave the Mem in an ** inconsistent state, for example with (Mem.z==0) and -** (Mem.type==SQLITE_TEXT). +** (Mem.memType==MEM_Str). */ void sqlite3VdbeMemRelease(Mem *p){ VdbeMemRelease(p); @@ -480,7 +480,7 @@ void sqlite3VdbeMemSetNull(Mem *pMem){ sqlite3RowSetClear(pMem->u.pRowSet); } MemSetTypeFlag(pMem, MEM_Null); - pMem->type = SQLITE_NULL; + pMem->memType = MEM_Null; } void sqlite3ValueSetNull(sqlite3_value *p){ sqlite3VdbeMemSetNull((Mem*)p); @@ -493,7 +493,7 @@ void sqlite3ValueSetNull(sqlite3_value *p){ void sqlite3VdbeMemSetZeroBlob(Mem *pMem, int n){ sqlite3VdbeMemRelease(pMem); pMem->flags = MEM_Blob|MEM_Zero; - pMem->type = SQLITE_BLOB; + pMem->memType = MEM_Blob; pMem->n = 0; if( n<0 ) n = 0; pMem->u.nZero = n; @@ -516,7 +516,7 @@ void sqlite3VdbeMemSetInt64(Mem *pMem, i64 val){ sqlite3VdbeMemRelease(pMem); pMem->u.i = val; pMem->flags = MEM_Int; - pMem->type = SQLITE_INTEGER; + pMem->memType = MEM_Int; } #ifndef SQLITE_OMIT_FLOATING_POINT @@ -531,7 +531,7 @@ void sqlite3VdbeMemSetDouble(Mem *pMem, double val){ sqlite3VdbeMemRelease(pMem); pMem->r = val; pMem->flags = MEM_Real; - pMem->type = SQLITE_FLOAT; + pMem->memType = MEM_Real; } } #endif @@ -739,7 +739,7 @@ int sqlite3VdbeMemSetStr( pMem->n = nByte; pMem->flags = flags; pMem->enc = (enc==0 ? SQLITE_UTF8 : enc); - pMem->type = (enc==0 ? SQLITE_BLOB : SQLITE_TEXT); + pMem->memType = flags&0x1f; #ifndef SQLITE_OMIT_UTF16 if( pMem->enc!=SQLITE_UTF8 && sqlite3VdbeMemHandleBom(pMem) ){ @@ -910,7 +910,7 @@ int sqlite3VdbeMemFromBtree( }else if( SQLITE_OK==(rc = sqlite3VdbeMemGrow(pMem, amt+2, 0)) ){ pMem->flags = MEM_Blob|MEM_Dyn|MEM_Term; pMem->enc = 0; - pMem->type = SQLITE_BLOB; + pMem->memType = MEM_Blob; if( key ){ rc = sqlite3BtreeKey(pCur, offset, amt, pMem->z); }else{ @@ -980,7 +980,7 @@ sqlite3_value *sqlite3ValueNew(sqlite3 *db){ Mem *p = sqlite3DbMallocZero(db, sizeof(*p)); if( p ){ p->flags = MEM_Null; - p->type = SQLITE_NULL; + p->memType = MEM_Null; p->db = db; } return p; @@ -1030,7 +1030,7 @@ static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){ pRec->aMem = (Mem *)((u8*)pRec + ROUND8(sizeof(UnpackedRecord))); for(i=0; iaMem[i].flags = MEM_Null; - pRec->aMem[i].type = SQLITE_NULL; + pRec->aMem[i].memType = MEM_Null; pRec->aMem[i].db = db; } }else{ @@ -1103,7 +1103,7 @@ static int valueFromExpr( zVal = sqlite3MPrintf(db, "%s%s", zNeg, pExpr->u.zToken); if( zVal==0 ) goto no_mem; sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, SQLITE_DYNAMIC); - if( op==TK_FLOAT ) pVal->type = SQLITE_FLOAT; + if( op==TK_FLOAT ) pVal->memType = MEM_Real; } if( (op==TK_INTEGER || op==TK_FLOAT ) && affinity==SQLITE_AFF_NONE ){ sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, SQLITE_UTF8); From 53a6eb3f3ca4890211b1e989e59a7f4ba0824298 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 10 Feb 2014 12:59:15 +0000 Subject: [PATCH 239/276] Faster implementation for sqlite3MulInt64(). FossilOrigin-Name: 010c48f671e909cb406f3716102a0032bc72a592 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/util.c | 18 +++++++++++++----- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 5af97eeec4..f2bf30fbc7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Faster\sand\ssmaller\simplementation\sof\ssqlite3_value_type(). -D 2014-02-10T03:21:57.367 +C Faster\simplementation\sfor\ssqlite3MulInt64(). +D 2014-02-10T12:59:15.771 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -278,7 +278,7 @@ F src/tokenize.c 6da2de6e12218ccb0aea5184b56727d011f4bee7 F src/trigger.c a417d386e214f0abd2e0f756b834b4d9f4d3368a F src/update.c a7df6fffce6bfedc578fda6136dd33e34a63f8ee F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 -F src/util.c 15ac2627f548f5481d0d7e6c4eb67be673027695 +F src/util.c c46c90459ef9bdc0c6c73803cf4c55425b4771cf F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 F src/vdbe.c 66c3e5c49ff61aaa3e3182fb9962ceddb847b05f F src/vdbe.h e6c4c610fcabad4fa80ebb1efc6822a9367e2b26 @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 532995759114ab7a7cba18cc9d8820d78eb1a96e -R 1d6572df35f58f7e82be516ccbec8b1d +P 5708bc24b8cab623b833121183042b43e5a7021b +R 96b6443498b3eb7df60c900f013f8cef U drh -Z d879d19c9c74c4f3aa3952d43b5ccba0 +Z d856cf5d0cd482b54ac364a01a0fe1f8 diff --git a/manifest.uuid b/manifest.uuid index da59cef8ea..f2a051d0be 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5708bc24b8cab623b833121183042b43e5a7021b \ No newline at end of file +010c48f671e909cb406f3716102a0032bc72a592 \ No newline at end of file diff --git a/src/util.c b/src/util.c index 3f3a9649e0..d88c17b759 100644 --- a/src/util.c +++ b/src/util.c @@ -1123,13 +1123,12 @@ int sqlite3AddInt64(i64 *pA, i64 iB){ testcase( iA>0 && LARGEST_INT64 - iA == iB ); testcase( iA>0 && LARGEST_INT64 - iA == iB - 1 ); if( iA>0 && LARGEST_INT64 - iA < iB ) return 1; - *pA += iB; }else{ testcase( iA<0 && -(iA + LARGEST_INT64) == iB + 1 ); testcase( iA<0 && -(iA + LARGEST_INT64) == iB + 2 ); if( iA<0 && -(iA + LARGEST_INT64) > iB + 1 ) return 1; - *pA += iB; } + *pA += iB; return 0; } int sqlite3SubInt64(i64 *pA, i64 iB){ @@ -1153,9 +1152,18 @@ int sqlite3MulInt64(i64 *pA, i64 iB){ iA0 = iA % TWOPOWER32; iB1 = iB/TWOPOWER32; iB0 = iB % TWOPOWER32; - if( iA1*iB1 != 0 ) return 1; - assert( iA1*iB0==0 || iA0*iB1==0 ); - r = iA1*iB0 + iA0*iB1; + if( iA1==0 ){ + if( iB1==0 ){ + *pA *= iB; + return 0; + } + r = iA0*iB1; + }else if( iB1==0 ){ + r = iA1*iB0; + }else{ + /* If both iA1 and iB1 are non-zero, overflow will result */ + return 1; + } testcase( r==(-TWOPOWER31)-1 ); testcase( r==(-TWOPOWER31) ); testcase( r==TWOPOWER31 ); From 60830e3c535f080a4c63ed73b7ba2c5108265d49 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 10 Feb 2014 15:56:34 +0000 Subject: [PATCH 240/276] Improvements to a "Synopsis:" comment in the VDBE engine. FossilOrigin-Name: 0dfa7ee9157ea6b1c745732d6c3fcd066cf4f849 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index f2bf30fbc7..9310c89691 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Faster\simplementation\sfor\ssqlite3MulInt64(). -D 2014-02-10T12:59:15.771 +C Improvements\sto\sa\s"Synopsis:"\scomment\sin\sthe\sVDBE\sengine. +D 2014-02-10T15:56:34.917 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -280,7 +280,7 @@ F src/update.c a7df6fffce6bfedc578fda6136dd33e34a63f8ee F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c c46c90459ef9bdc0c6c73803cf4c55425b4771cf F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c 66c3e5c49ff61aaa3e3182fb9962ceddb847b05f +F src/vdbe.c e5c87476d717aebef5dafceab11417ebf2730554 F src/vdbe.h e6c4c610fcabad4fa80ebb1efc6822a9367e2b26 F src/vdbeInt.h 5286af9067cabdb8ba57b87c0c988a931be6c6c8 F src/vdbeapi.c 5bc41aaea448a7fc250902c418f1795859be3820 @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 5708bc24b8cab623b833121183042b43e5a7021b -R 96b6443498b3eb7df60c900f013f8cef +P 010c48f671e909cb406f3716102a0032bc72a592 +R 578e19c460bd25472755ddb73b8e954a U drh -Z d856cf5d0cd482b54ac364a01a0fe1f8 +Z b51a63f783c162fa8d14eeaf754f2b2d diff --git a/manifest.uuid b/manifest.uuid index f2a051d0be..2d5b959f98 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -010c48f671e909cb406f3716102a0032bc72a592 \ No newline at end of file +0dfa7ee9157ea6b1c745732d6c3fcd066cf4f849 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 0fcc4a9202..aa34ad091a 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3328,7 +3328,7 @@ case OP_SorterOpen: { } /* Opcode: OpenPseudo P1 P2 P3 * * -** Synopsis: content in r[P2@P3] +** Synopsis: P3 columns in r[P2] ** ** Open a new cursor that points to a fake table that contains a single ** row of data. The content of that one row is the content of memory From b373591c5e7e976e6e6779c027662f99ce02df22 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 10 Feb 2014 16:13:42 +0000 Subject: [PATCH 241/276] Modify the command-line shell to print a warning when using an in-memory database. FossilOrigin-Name: 90e9deae4a2bf63308a212226314aa7838c161d9 --- manifest | 15 +++++++++------ manifest.uuid | 2 +- src/shell.c | 9 +++++++++ 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 9310c89691..afa8cdb9ea 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvements\sto\sa\s"Synopsis:"\scomment\sin\sthe\sVDBE\sengine. -D 2014-02-10T15:56:34.917 +C Modify\sthe\scommand-line\sshell\sto\sprint\sa\swarning\swhen\susing\san\sin-memory\ndatabase. +D 2014-02-10T16:13:42.339 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -220,7 +220,7 @@ F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c c055a9fa25a4e7fc8c1652c44a31d6382dbb1e8a -F src/shell.c 7dedf7367ee49050b0366bf8dbc8ec2bd15b42c7 +F src/shell.c df7d96e50415a0aaf63a6cc96c15643229a603ac F src/sqlite.h.in eed7f7d66a60daaa7b4a597dcd9bad87aad9611b F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc @@ -1152,7 +1152,10 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 010c48f671e909cb406f3716102a0032bc72a592 -R 578e19c460bd25472755ddb73b8e954a +P 0dfa7ee9157ea6b1c745732d6c3fcd066cf4f849 +R 795791e045aa26fa5bb54a48e6e7e719 +T *branch * memdb-warning +T *sym-memdb-warning * +T -sym-trunk * U drh -Z b51a63f783c162fa8d14eeaf754f2b2d +Z fcf385e884073e6fe85607df422ee196 diff --git a/manifest.uuid b/manifest.uuid index 2d5b959f98..349369484a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0dfa7ee9157ea6b1c745732d6c3fcd066cf4f849 \ No newline at end of file +90e9deae4a2bf63308a212226314aa7838c161d9 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 8fa32105d9..395cf30b29 100644 --- a/src/shell.c +++ b/src/shell.c @@ -3520,6 +3520,7 @@ int main(int argc, char **argv){ char *zFirstCmd = 0; int i; int rc = 0; + int warnInmemoryDb = 0; if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){ fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n", @@ -3614,6 +3615,7 @@ int main(int argc, char **argv){ if( data.zDbFilename==0 ){ #ifndef SQLITE_OMIT_MEMORYDB data.zDbFilename = ":memory:"; + warnInmemoryDb = 1; #else fprintf(stderr,"%s: Error: no database filename specified\n", Argv0); return 1; @@ -3754,6 +3756,13 @@ int main(int argc, char **argv){ "Enter SQL statements terminated with a \";\"\n", sqlite3_libversion(), sqlite3_sourceid() ); + if( warnInmemoryDb ){ + printf( + "Warning: connected to an in-memory database. " + "Use \".open FILENAME\" to change\nto a persistent " + "on-disk database.\n" + ); + } zHome = find_home_dir(); if( zHome ){ nHistory = strlen30(zHome) + 20; From 8af9ad951da6621872eefdc2f5c896adaabf89cb Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 10 Feb 2014 18:56:05 +0000 Subject: [PATCH 242/276] Fix the compound-select-to-subquery converter so that it works with the new compound-select object linkage introduced as part of the fix for ticket [31a19d11b97088296]. FossilOrigin-Name: 572d4be4db03ce4afe9ae70f148703c74e0d8de0 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/select.c | 3 +++ 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 9310c89691..0fd54c6585 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvements\sto\sa\s"Synopsis:"\scomment\sin\sthe\sVDBE\sengine. -D 2014-02-10T15:56:34.917 +C Fix\sthe\scompound-select-to-subquery\sconverter\sso\sthat\sit\sworks\swith\sthe\nnew\scompound-select\sobject\slinkage\sintroduced\sas\spart\sof\sthe\sfix\nfor\sticket\s[31a19d11b97088296]. +D 2014-02-10T18:56:05.414 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -219,7 +219,7 @@ F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c c055a9fa25a4e7fc8c1652c44a31d6382dbb1e8a +F src/select.c 6afe4c3f3944b229d01c37bb399a9c3761e71698 F src/shell.c 7dedf7367ee49050b0366bf8dbc8ec2bd15b42c7 F src/sqlite.h.in eed7f7d66a60daaa7b4a597dcd9bad87aad9611b F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 010c48f671e909cb406f3716102a0032bc72a592 -R 578e19c460bd25472755ddb73b8e954a +P 0dfa7ee9157ea6b1c745732d6c3fcd066cf4f849 +R 0a0a7ffb9514767b9649cf14141c47c8 U drh -Z b51a63f783c162fa8d14eeaf754f2b2d +Z f074d58f6f28d25d0d7533e32b528413 diff --git a/manifest.uuid b/manifest.uuid index 2d5b959f98..154f91e861 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0dfa7ee9157ea6b1c745732d6c3fcd066cf4f849 \ No newline at end of file +572d4be4db03ce4afe9ae70f148703c74e0d8de0 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 07cb571daa..75e495f108 100644 --- a/src/select.c +++ b/src/select.c @@ -3628,6 +3628,9 @@ static int convertCompoundSelectToSubquery(Walker *pWalker, Select *p){ pNew->pHaving = 0; pNew->pOrderBy = 0; p->pPrior = 0; + p->pNext = 0; + p->selFlags &= ~SF_Compound; + if( pNew->pPrior ) pNew->pPrior->pNext = pNew; pNew->pLimit = 0; pNew->pOffset = 0; return WRC_Continue; From 1247aa4e4ae3ceaa92817a38c834f5c67fff950c Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 10 Feb 2014 19:27:05 +0000 Subject: [PATCH 243/276] In the command-line shell, on the banner, warn about the use of a transient in-memory database in bold red text. FossilOrigin-Name: 0fbc0fcec1b3a67065fa0ebb49375bf675789edc --- manifest | 15 ++++++--------- manifest.uuid | 2 +- src/shell.c | 39 +++++++++++++++++++++++++++++++-------- 3 files changed, 38 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index afa8cdb9ea..4419fb4d11 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Modify\sthe\scommand-line\sshell\sto\sprint\sa\swarning\swhen\susing\san\sin-memory\ndatabase. -D 2014-02-10T16:13:42.339 +C In\sthe\scommand-line\sshell,\son\sthe\sbanner,\swarn\sabout\sthe\suse\sof\sa\ntransient\sin-memory\sdatabase\sin\sbold\sred\stext. +D 2014-02-10T19:27:05.611 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -220,7 +220,7 @@ F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c c055a9fa25a4e7fc8c1652c44a31d6382dbb1e8a -F src/shell.c df7d96e50415a0aaf63a6cc96c15643229a603ac +F src/shell.c 7e4d5dcb21c860137748899d5025594cd993458e F src/sqlite.h.in eed7f7d66a60daaa7b4a597dcd9bad87aad9611b F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc @@ -1152,10 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 0dfa7ee9157ea6b1c745732d6c3fcd066cf4f849 -R 795791e045aa26fa5bb54a48e6e7e719 -T *branch * memdb-warning -T *sym-memdb-warning * -T -sym-trunk * +P 90e9deae4a2bf63308a212226314aa7838c161d9 +R f1273e6958b105060eecb1997e0942c3 U drh -Z fcf385e884073e6fe85607df422ee196 +Z 7cce0cacf21f263fd79f8eafb0090d99 diff --git a/manifest.uuid b/manifest.uuid index 349369484a..5af2c88934 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -90e9deae4a2bf63308a212226314aa7838c161d9 \ No newline at end of file +0fbc0fcec1b3a67065fa0ebb49375bf675789edc \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 395cf30b29..82b1fdf96a 100644 --- a/src/shell.c +++ b/src/shell.c @@ -3500,6 +3500,29 @@ static void main_init(struct callback_data *data) { sqlite3_config(SQLITE_CONFIG_SINGLETHREAD); } +/* +** Arrange for subsequent text console output to be RED or normal. Use +** the SetConsoleTextAttribute() function on windows. On all other +** platforms, assume VT100 escape sequences are recognized. +*/ +#ifdef _WIN32 +static void outputRed(void){ + SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), + FOREGROUND_RED|FOREGROUND_INTENSITY); +} +static void outputNormal(void){ + SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), + FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE); +} +#else +static void outputRed(void){ + printf("\033[1;31m"); +} +static void outputNormal(void){ + printf("\033[0m"); +} +#endif + /* ** Get the argument to an --option. Throw an error and die if no argument ** is available. @@ -3615,7 +3638,7 @@ int main(int argc, char **argv){ if( data.zDbFilename==0 ){ #ifndef SQLITE_OMIT_MEMORYDB data.zDbFilename = ":memory:"; - warnInmemoryDb = 1; + warnInmemoryDb = argc==1; #else fprintf(stderr,"%s: Error: no database filename specified\n", Argv0); return 1; @@ -3752,16 +3775,16 @@ int main(int argc, char **argv){ int nHistory; printf( "SQLite version %s %.19s\n" /*extra-version-info*/ - "Enter \".help\" for instructions\n" - "Enter SQL statements terminated with a \";\"\n", + "Enter \".help\" for usage hints.\n", sqlite3_libversion(), sqlite3_sourceid() ); if( warnInmemoryDb ){ - printf( - "Warning: connected to an in-memory database. " - "Use \".open FILENAME\" to change\nto a persistent " - "on-disk database.\n" - ); + printf("Connected to a "); + outputRed(); + printf("transient in-memory database"); + outputNormal(); + printf(".\nUse \".open FILENAME\" to reopen on a " + "persistent database.\n"); } zHome = find_home_dir(); if( zHome ){ From ba47ba76a51e4be67f93213c22ac5015005f6f18 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 10 Feb 2014 19:36:06 +0000 Subject: [PATCH 244/276] On unix, make the "transient in-memory database" text bold, but not red. Leave the text read on windows. FossilOrigin-Name: c9eba2f7be468ae7fc843ffd5b09bd062ee311c3 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 4419fb4d11..f555c4c7ec 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\scommand-line\sshell,\son\sthe\sbanner,\swarn\sabout\sthe\suse\sof\sa\ntransient\sin-memory\sdatabase\sin\sbold\sred\stext. -D 2014-02-10T19:27:05.611 +C On\sunix,\smake\sthe\s"transient\sin-memory\sdatabase"\stext\sbold,\sbut\snot\sred.\nLeave\sthe\stext\sread\son\swindows. +D 2014-02-10T19:36:06.410 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -220,7 +220,7 @@ F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c c055a9fa25a4e7fc8c1652c44a31d6382dbb1e8a -F src/shell.c 7e4d5dcb21c860137748899d5025594cd993458e +F src/shell.c 8b549f83209f8b1df9490c9f50116a0c8ac4cae5 F src/sqlite.h.in eed7f7d66a60daaa7b4a597dcd9bad87aad9611b F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 90e9deae4a2bf63308a212226314aa7838c161d9 -R f1273e6958b105060eecb1997e0942c3 +P 0fbc0fcec1b3a67065fa0ebb49375bf675789edc +R 1d621b0234ebbbe4535aa1198b61b626 U drh -Z 7cce0cacf21f263fd79f8eafb0090d99 +Z 2f66f19a9b47ffbd33cb1946222fcf2d diff --git a/manifest.uuid b/manifest.uuid index 5af2c88934..8f0ec83094 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0fbc0fcec1b3a67065fa0ebb49375bf675789edc \ No newline at end of file +c9eba2f7be468ae7fc843ffd5b09bd062ee311c3 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 82b1fdf96a..9f1d2a9a41 100644 --- a/src/shell.c +++ b/src/shell.c @@ -3516,7 +3516,7 @@ static void outputNormal(void){ } #else static void outputRed(void){ - printf("\033[1;31m"); + printf("\033[1m"); } static void outputNormal(void){ printf("\033[0m"); From 5c7976fe869bed377871c443378145674c701882 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 10 Feb 2014 19:59:27 +0000 Subject: [PATCH 245/276] Add the ".save" command as an alias for ".backup". Improvements to the way font changes are implemented on the in-memory database warning. FossilOrigin-Name: fe284afe739c497e153ac2bc0275f7c9e862c824 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c | 38 ++++++++++++++++++-------------------- 3 files changed, 25 insertions(+), 27 deletions(-) diff --git a/manifest b/manifest index f555c4c7ec..cf02950ed8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C On\sunix,\smake\sthe\s"transient\sin-memory\sdatabase"\stext\sbold,\sbut\snot\sred.\nLeave\sthe\stext\sread\son\swindows. -D 2014-02-10T19:36:06.410 +C Add\sthe\s".save"\scommand\sas\san\salias\sfor\s".backup".\s\sImprovements\sto\sthe\nway\sfont\schanges\sare\simplemented\son\sthe\sin-memory\sdatabase\swarning. +D 2014-02-10T19:59:27.437 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -220,7 +220,7 @@ F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c c055a9fa25a4e7fc8c1652c44a31d6382dbb1e8a -F src/shell.c 8b549f83209f8b1df9490c9f50116a0c8ac4cae5 +F src/shell.c cb8d19594483d23d6e35244bb043cf0cd1816a52 F src/sqlite.h.in eed7f7d66a60daaa7b4a597dcd9bad87aad9611b F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 0fbc0fcec1b3a67065fa0ebb49375bf675789edc -R 1d621b0234ebbbe4535aa1198b61b626 +P c9eba2f7be468ae7fc843ffd5b09bd062ee311c3 +R 5e3b4e27dbbde8802d4b99c9e620e482 U drh -Z 2f66f19a9b47ffbd33cb1946222fcf2d +Z be8b5d9bf50fdc639aa9aecf25f98639 diff --git a/manifest.uuid b/manifest.uuid index 8f0ec83094..ae460c3067 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c9eba2f7be468ae7fc843ffd5b09bd062ee311c3 \ No newline at end of file +fe284afe739c497e153ac2bc0275f7c9e862c824 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 9f1d2a9a41..1606e9d3e2 100644 --- a/src/shell.c +++ b/src/shell.c @@ -1583,6 +1583,7 @@ static char zHelp[] = ".quit Exit this program\n" ".read FILENAME Execute SQL in FILENAME\n" ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n" + ".save FILE Write in-memory database into FILE\n" ".schema ?TABLE? Show the CREATE statements\n" " If TABLE specified, only show tables matching\n" " LIKE pattern TABLE.\n" @@ -2152,7 +2153,9 @@ static int do_meta_command(char *zLine, struct callback_data *p){ if( nArg==0 ) return 0; /* no tokens, no error */ n = strlen30(azArg[0]); c = azArg[0][0]; - if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 ){ + if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0) + || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0) + ){ const char *zDestFile = 0; const char *zDb = 0; sqlite3 *pDest; @@ -3501,25 +3504,22 @@ static void main_init(struct callback_data *data) { } /* -** Arrange for subsequent text console output to be RED or normal. Use -** the SetConsoleTextAttribute() function on windows. On all other -** platforms, assume VT100 escape sequences are recognized. +** Output text to the console in a font that attracts extra attention. */ #ifdef _WIN32 -static void outputRed(void){ - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), - FOREGROUND_RED|FOREGROUND_INTENSITY); -} -static void outputNormal(void){ - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), - FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE); +static void printBold(const char *zText){ + HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE); + CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo; + GetConsoleScreenBufferInfo(out, &defaultScreenInfo); + SetConsoleTextAttribute(out, + FOREGROUND_RED|FOREGROUND_INTENSITY + ); + printf("%s", zText); + SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes); } #else -static void outputRed(void){ - printf("\033[1m"); -} -static void outputNormal(void){ - printf("\033[0m"); +static void printBold(const char *zText){ + printf("\033[1m%s\033[0m", zText); } #endif @@ -3780,10 +3780,8 @@ int main(int argc, char **argv){ ); if( warnInmemoryDb ){ printf("Connected to a "); - outputRed(); - printf("transient in-memory database"); - outputNormal(); - printf(".\nUse \".open FILENAME\" to reopen on a " + printBold("transient in-memory database."); + printf("\nUse \".open FILENAME\" to reopen on a " "persistent database.\n"); } zHome = find_home_dir(); From a6e3a8c9d50f149d586f86b19f7edd20a589aa69 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 10 Feb 2014 21:07:51 +0000 Subject: [PATCH 246/276] Fix a pointless conditional. Add a test case. FossilOrigin-Name: 9367632dd7e4fec9197227e35b0627c2e81ebffc --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/select.c | 3 ++- test/selectA.test | 17 +++++++++++++++++ 4 files changed, 27 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 0fd54c6585..02a30132dc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\scompound-select-to-subquery\sconverter\sso\sthat\sit\sworks\swith\sthe\nnew\scompound-select\sobject\slinkage\sintroduced\sas\spart\sof\sthe\sfix\nfor\sticket\s[31a19d11b97088296]. -D 2014-02-10T18:56:05.414 +C Fix\sa\spointless\sconditional.\s\sAdd\sa\stest\scase. +D 2014-02-10T21:07:51.589 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -219,7 +219,7 @@ F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c 6afe4c3f3944b229d01c37bb399a9c3761e71698 +F src/select.c 50961f0d0ab8f2d45ff29ec5f91d8db221330ca7 F src/shell.c 7dedf7367ee49050b0366bf8dbc8ec2bd15b42c7 F src/sqlite.h.in eed7f7d66a60daaa7b4a597dcd9bad87aad9611b F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e @@ -786,7 +786,7 @@ F test/select6.test e76bd10a56988f15726c097a5d5a7966fe82d3b2 F test/select7.test 7fd2ef598cfabb6b9ff6ac13973b91d0527df49d F test/select8.test 391de11bdd52339c30580dabbbbe97e3e9a3c79d F test/select9.test aebc2bb0c3bc44606125033cbcaac2c8d1f33a95 -F test/selectA.test 99cf21df033b93033ea4f34aba14a500f48f04fe +F test/selectA.test 77adaffe9704cb80e301ebaeff4b107b58d435c5 F test/selectB.test 954e4e49cf1f896d61794e440669e03a27ceea25 F test/selectC.test 871fb55d884d3de5943c4057ebd22c2459e71977 F test/selectD.test b0f02a04ef7737decb24e08be2c39b9664b43394 @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 0dfa7ee9157ea6b1c745732d6c3fcd066cf4f849 -R 0a0a7ffb9514767b9649cf14141c47c8 +P 572d4be4db03ce4afe9ae70f148703c74e0d8de0 +R b7d0a27ba761fd3ba9cef17cacd1ce16 U drh -Z f074d58f6f28d25d0d7533e32b528413 +Z 5a7d977408b7fd9f1bc56f50ea9feaff diff --git a/manifest.uuid b/manifest.uuid index 154f91e861..7c2363e7ef 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -572d4be4db03ce4afe9ae70f148703c74e0d8de0 \ No newline at end of file +9367632dd7e4fec9197227e35b0627c2e81ebffc \ No newline at end of file diff --git a/src/select.c b/src/select.c index 75e495f108..dd445deed3 100644 --- a/src/select.c +++ b/src/select.c @@ -3630,7 +3630,8 @@ static int convertCompoundSelectToSubquery(Walker *pWalker, Select *p){ p->pPrior = 0; p->pNext = 0; p->selFlags &= ~SF_Compound; - if( pNew->pPrior ) pNew->pPrior->pNext = pNew; + assert( pNew->pPrior!=0 ); + pNew->pPrior->pNext = pNew; pNew->pLimit = 0; pNew->pOffset = 0; return WRC_Continue; diff --git a/test/selectA.test b/test/selectA.test index 5fd2288dbf..ca2ec38da4 100644 --- a/test/selectA.test +++ b/test/selectA.test @@ -1292,5 +1292,22 @@ do_test selectA-3.97 { ORDER BY y COLLATE NOCASE DESC,x,z))) } } {MAD} +do_execsql_test selectA-3.98 { + WITH RECURSIVE + xyz(n) AS ( + SELECT upper((SELECT x FROM ( + SELECT x,y,z FROM t2 + INTERSECT SELECT a,b,c FROM t3 + EXCEPT SELECT c,b,a FROM t1 + UNION SELECT a,b,c FROM t3 + INTERSECT SELECT a,b,c FROM t3 + EXCEPT SELECT c,b,a FROM t1 + UNION SELECT a,b,c FROM t3 + ORDER BY y COLLATE NOCASE DESC,x,z))) + UNION ALL + SELECT n || '+' FROM xyz WHERE length(n)<5 + ) + SELECT n FROM xyz ORDER BY +n; +} {MAD MAD+ MAD++} finish_test From 7c3280649a11b1ea0cce16fdd91a602aa3ec6c9b Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 11 Feb 2014 01:50:29 +0000 Subject: [PATCH 247/276] Make sure that virtual WHERE-clause terms do not get transformed into real terms when processing set of OR-connected terms. Fix for ticket [4c86b126f22ad]. FossilOrigin-Name: c950d6c4117d076f871518e738cdf9e8c46a19fc --- manifest | 15 ++++++------ manifest.uuid | 2 +- src/where.c | 4 +++- test/tkt-4c86b126f2.test | 49 ++++++++++++++++++++++++++++++++++++++++ test/where8.test | 4 ++-- 5 files changed, 63 insertions(+), 11 deletions(-) create mode 100644 test/tkt-4c86b126f2.test diff --git a/manifest b/manifest index 02a30132dc..a40ed0160c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\spointless\sconditional.\s\sAdd\sa\stest\scase. -D 2014-02-10T21:07:51.589 +C Make\ssure\sthat\svirtual\sWHERE-clause\sterms\sdo\snot\sget\stransformed\sinto\sreal\nterms\swhen\sprocessing\sset\sof\sOR-connected\sterms.\nFix\sfor\sticket\s[4c86b126f22ad]. +D 2014-02-11T01:50:29.864 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -293,7 +293,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45 -F src/where.c 90fef20dd178db262ecd522a214a4eee6f76a44b +F src/where.c b0436385f40e86f0f4cc60355cd018bde2c89d4b F src/whereInt.h 921f935af8b684ffb49705610bda7284db1db138 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -869,6 +869,7 @@ F test/tkt-3998683a16.test 6d1d04d551ed1704eb3396ca87bb9ccc8c5c1eb7 F test/tkt-3a77c9714e.test b08bca26de1140bdf004a37716582a43d7bd8be8 F test/tkt-3fe897352e.test 27e26eb0f1811aeba4d65aba43a4c52e99da5e70 F test/tkt-4a03edc4c8.test 91c0e135888cdc3d4eea82406a44b05c8c1648d0 +F test/tkt-4c86b126f2.test cbcc611becd0396890169ab23102dd70048bbc9a F test/tkt-4dd95f6943.test 3d0ce415d2ee15d3d564121960016b9c7be79407 F test/tkt-54844eea3f.test a12b851128f46a695e4e378cca67409b9b8f5894 F test/tkt-5d863f876e.test c9f36ca503fa154a3655f92a69d2c30da1747bfa @@ -1077,7 +1078,7 @@ F test/where4.test e9b9e2f2f98f00379e6031db6a6fca29bae782a2 F test/where5.test fdf66f96d29a064b63eb543e28da4dfdccd81ad2 F test/where6.test 5da5a98cec820d488e82708301b96cb8c18a258b F test/where7.test 5a4b0abc207d71da4deecd734ad8579e8dd40aa8 -F test/where8.test d2b4fd6d7b7c5d44f590182a05033d78a14c00a1 +F test/where8.test 84033c4da466d90fe7ef0152661ff67fd218105f F test/where8m.test da346596e19d54f0aba35ebade032a7c47d79739 F test/where9.test 4f3eab951353a3ae164befc521c777dfa903e46c F test/whereA.test 4d253178d135ec46d1671e440cd8f2b916aa6e6b @@ -1152,7 +1153,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 572d4be4db03ce4afe9ae70f148703c74e0d8de0 -R b7d0a27ba761fd3ba9cef17cacd1ce16 +P 9367632dd7e4fec9197227e35b0627c2e81ebffc +R c0a7ad49332334bf360852ac9acfe6b0 U drh -Z 5a7d977408b7fd9f1bc56f50ea9feaff +Z c0afcb3ac05ab221eadb28aadee413b3 diff --git a/manifest.uuid b/manifest.uuid index 7c2363e7ef..256068af9a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9367632dd7e4fec9197227e35b0627c2e81ebffc \ No newline at end of file +c950d6c4117d076f871518e738cdf9e8c46a19fc \ No newline at end of file diff --git a/src/where.c b/src/where.c index 91b9e0c537..d0d95c081d 100644 --- a/src/where.c +++ b/src/where.c @@ -3315,7 +3315,9 @@ static Bitmask codeOneLoopStart( Expr *pExpr = pWC->a[iTerm].pExpr; if( &pWC->a[iTerm] == pTerm ) continue; if( ExprHasProperty(pExpr, EP_FromJoin) ) continue; - if( pWC->a[iTerm].wtFlags & (TERM_ORINFO) ) continue; + testcase( pWC->a[iTerm].wtFlags & TERM_ORINFO ); + testcase( pWC->a[iTerm].wtFlags & TERM_VIRTUAL ); + if( pWC->a[iTerm].wtFlags & (TERM_ORINFO|TERM_VIRTUAL) ) continue; if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue; pExpr = sqlite3ExprDup(db, pExpr, 0); pAndExpr = sqlite3ExprAnd(db, pAndExpr, pExpr); diff --git a/test/tkt-4c86b126f2.test b/test/tkt-4c86b126f2.test new file mode 100644 index 0000000000..3c5177ed31 --- /dev/null +++ b/test/tkt-4c86b126f2.test @@ -0,0 +1,49 @@ +# 2014-02-11 +# +# 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. Specifically, +# it tests that ticket [4c86b126f22ad548fee0125337bdc9366912d9ac]. +# +# When SQLite is compiled using SQLITE_ENABLE_STAT3 or SQLITE_ENABLE_STAT4, +# it gets the wrong answer... +# +# The problem was introduced in SQLite 3.8.1. + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +do_execsql_test tkt-4c86b126f2-1.1 { + CREATE TABLE nodes( + local_relpath TEXT PRIMARY KEY, + moved_to TEXT + ); + INSERT INTO nodes VALUES('A',NULL); + INSERT INTO nodes VALUES('A/B',NULL); + INSERT INTO nodes VALUES('',NULL); + INSERT INTO nodes VALUES('A/B/C-move',NULL); + INSERT INTO nodes VALUES('A/B/C','A/B/C-move'); + INSERT INTO nodes VALUES('A/B-move',NULL); + INSERT INTO nodes VALUES('A/B-move/C-move',NULL); + INSERT INTO nodes VALUES('A/B-move/C','x'); + SELECT local_relpath, moved_to + FROM nodes + WHERE (local_relpath = 'A/B' OR + ((local_relpath > 'A/B/') AND (local_relpath < 'A/B0'))) + AND moved_to IS NOT NULL; +} {A/B/C A/B/C-move} + +do_execsql_test tkt-4c86b126f2-2.1 { + CREATE TABLE t1(x TEXT UNIQUE, y TEXT UNIQUE, z); + INSERT INTO t1 VALUES('ghi','jkl','y'); + SELECT * FROM t1 WHERE (x='ghi' OR y='jkl') AND z IS NOT NULL; +} {ghi jkl y} + + +finish_test diff --git a/test/where8.test b/test/where8.test index a1ef1d796c..287e4004c8 100644 --- a/test/where8.test +++ b/test/where8.test @@ -210,7 +210,7 @@ do_test where8-3.4 { do_test where8-3.5 { execsql_status { - SELECT a, d FROM t1, t2 WHERE (a = 2 OR a = 3) AND (d = a OR e = 'sixteen') + SELECT a, d FROM t1, t2 WHERE (a = 2 OR a = 3) AND (d = +a OR e = 'sixteen') ORDER BY +a, +d; } } {2 2 2 4 3 3 3 4 0 1} @@ -222,7 +222,7 @@ do_test where8-3.6 { execsql_status { SELECT a, d FROM t1, t2 - WHERE (a = 2 OR a = 3) AND (d = a OR e = 'sixteen') + WHERE (a = 2 OR a = 3) AND (d = +a OR e = 'sixteen') ORDER BY t1.rowid } } {2 2 2 4 3 3 3 4 0 1} From aaa21b41e8ce0587d81ac6a2eff0d5f27acb7d44 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 11 Feb 2014 14:37:51 +0000 Subject: [PATCH 248/276] Fixes to the "editline" support in the command-line shell. FossilOrigin-Name: 7989ce5f105657060a39be295255da8eff9ed56e --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c | 17 ++++++++++------- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index a40ed0160c..fc78ad919e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\sthat\svirtual\sWHERE-clause\sterms\sdo\snot\sget\stransformed\sinto\sreal\nterms\swhen\sprocessing\sset\sof\sOR-connected\sterms.\nFix\sfor\sticket\s[4c86b126f22ad]. -D 2014-02-11T01:50:29.864 +C Fixes\sto\sthe\s"editline"\ssupport\sin\sthe\scommand-line\sshell. +D 2014-02-11T14:37:51.706 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -220,7 +220,7 @@ F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c 50961f0d0ab8f2d45ff29ec5f91d8db221330ca7 -F src/shell.c 7dedf7367ee49050b0366bf8dbc8ec2bd15b42c7 +F src/shell.c b1f75cfcd05b7921d74361f1cb9c01b9ca0b13df F src/sqlite.h.in eed7f7d66a60daaa7b4a597dcd9bad87aad9611b F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc @@ -1153,7 +1153,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 9367632dd7e4fec9197227e35b0627c2e81ebffc -R c0a7ad49332334bf360852ac9acfe6b0 +P c950d6c4117d076f871518e738cdf9e8c46a19fc +R c9ba63de227fe5f3c297f7ef3cdd12e1 U drh -Z c0afcb3ac05ab221eadb28aadee413b3 +Z ef37a62508215b02b96d545bd9d80c32 diff --git a/manifest.uuid b/manifest.uuid index 256068af9a..364e642e70 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c950d6c4117d076f871518e738cdf9e8c46a19fc \ No newline at end of file +7989ce5f105657060a39be295255da8eff9ed56e \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 8fa32105d9..b6733b7ce7 100644 --- a/src/shell.c +++ b/src/shell.c @@ -45,14 +45,17 @@ # include #endif -#ifdef HAVE_EDITLINE -# include -#endif -#if defined(HAVE_READLINE) && HAVE_READLINE==1 +#if defined(HAVE_READLINE) && HAVE_READLINE!=0 # include # include +#else +# undef HAVE_READLINE #endif -#if !defined(HAVE_EDITLINE) && (!defined(HAVE_READLINE) || HAVE_READLINE!=1) +#if defined(HAVE_EDITLINE) && !defined(HAVE_READLINE) +# define HAVE_READLINE 1 +# include +#endif +#if !defined(HAVE_READLINE) # define add_history(X) # define read_history(X) # define write_history(X) @@ -413,7 +416,7 @@ static char *one_input_line(FILE *in, char *zPrior, int isContinuation){ zResult = local_getline(zPrior, in); }else{ zPrompt = isContinuation ? continuePrompt : mainPrompt; -#if defined(HAVE_READLINE) && HAVE_READLINE==1 +#if defined(HAVE_READLINE) free(zPrior); zResult = readline(zPrompt); if( zResult && *zResult ) add_history(zResult); @@ -3761,7 +3764,7 @@ int main(int argc, char **argv){ sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome); } } -#if defined(HAVE_READLINE) && HAVE_READLINE==1 +#if defined(HAVE_READLINE) if( zHistory ) read_history(zHistory); #endif rc = process_input(&data, 0); From c5185cd845664005898f8a00b4b5ecfc3b106f2c Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 11 Feb 2014 16:24:34 +0000 Subject: [PATCH 249/276] Increase the version number to 3.8.4 FossilOrigin-Name: 0a8bcbbd4e11a60923736b2be9b1ce83ea2263fb --- VERSION | 2 +- configure | 18 +++++++++--------- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/VERSION b/VERSION index 269aa9c86d..ff313b8c21 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.8.3 +3.8.4 diff --git a/configure b/configure index 2403018bb8..c182a4a92d 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.62 for sqlite 3.8.3. +# Generated by GNU Autoconf 2.62 for sqlite 3.8.4. # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. @@ -743,8 +743,8 @@ SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='sqlite' PACKAGE_TARNAME='sqlite' -PACKAGE_VERSION='3.8.3' -PACKAGE_STRING='sqlite 3.8.3' +PACKAGE_VERSION='3.8.4' +PACKAGE_STRING='sqlite 3.8.4' PACKAGE_BUGREPORT='' # Factoring default headers for most tests. @@ -1483,7 +1483,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures sqlite 3.8.3 to adapt to many kinds of systems. +\`configure' configures sqlite 3.8.4 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1548,7 +1548,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of sqlite 3.8.3:";; + short | recursive ) echo "Configuration of sqlite 3.8.4:";; esac cat <<\_ACEOF @@ -1664,7 +1664,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -sqlite configure 3.8.3 +sqlite configure 3.8.4 generated by GNU Autoconf 2.62 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -1678,7 +1678,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by sqlite $as_me 3.8.3, which was +It was created by sqlite $as_me 3.8.4, which was generated by GNU Autoconf 2.62. Invocation command line was $ $0 $@ @@ -14021,7 +14021,7 @@ exec 6>&1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by sqlite $as_me 3.8.3, which was +This file was extended by sqlite $as_me 3.8.4, which was generated by GNU Autoconf 2.62. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -14074,7 +14074,7 @@ Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_version="\\ -sqlite config.status 3.8.3 +sqlite config.status 3.8.4 configured by $0, generated by GNU Autoconf 2.62, with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" diff --git a/manifest b/manifest index 72514dd434..19a6fafab1 100644 --- a/manifest +++ b/manifest @@ -1,12 +1,12 @@ -C Updates\sto\sthe\scommand-line\sshell.\s\sSimplify\sthe\sbanner\smessage.\s\sAdd\sthe\n".save"\scommand\sas\san\salias\sfor\s".backup".\s\sWhen\sstarting\swith\sno\sarguments,\ninclude\sa\sbanner\smessage\swarning\sthat\sthe\sdatabase\sis\stransient\sand\sin-memory\nand\smention\sthe\s".open"\scommand. -D 2014-02-11T16:22:18.453 +C Increase\sthe\sversion\snumber\sto\s3.8.4 +D 2014-02-11T16:24:34.448 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.msc 6ff3ff2eef45c7dd309a8626ff7947b20bd387e7 F Makefile.vxworks db21ed42a01d5740e656b16f92cb5d8d5e5dd315 F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6 -F VERSION 8ed548d87d0a27fd7d7620476f9e25f9fa742d73 +F VERSION 0dc30ad5cf90736d5fd9e540c9f05c542658abe7 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 F addopcodes.awk 9eb448a552d5c0185cf62c463f9c173cedae3811 F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 @@ -38,7 +38,7 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63 F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977 F config.h.in 0921066a13130082764ab4ab6456f7b5bebe56de F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55 -F configure 1673bc402f8fc95015f72c279adc5a9a668ee237 x +F configure e12e1a4f031354f9af735bcb377941a72dc2cca5 x F configure.ac 4cf9f60785143fa141b10962ccc885d973792e9a F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/lemon.html 334dbf6621b8fb8790297ec1abf3cfa4621709d1 @@ -1153,7 +1153,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 7989ce5f105657060a39be295255da8eff9ed56e fe284afe739c497e153ac2bc0275f7c9e862c824 -R 6488d4d20aaa0785dbe5d9952b0b36b8 +P f5ad1e1bf2828c5da70c1ff944d8212036142e6f +R 07c665af95e97929880dcb47f3f495f9 U drh -Z d484b7c22506286af852445c160c123b +Z 585a1fb26982d5587e4e3f114773e866 diff --git a/manifest.uuid b/manifest.uuid index eacd85a75d..a4c42c8f7f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f5ad1e1bf2828c5da70c1ff944d8212036142e6f \ No newline at end of file +0a8bcbbd4e11a60923736b2be9b1ce83ea2263fb \ No newline at end of file From 784156f84c7a64d0546ec600a0e7ce0612b48565 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 12 Feb 2014 14:43:52 +0000 Subject: [PATCH 250/276] Make sure "rowid" columns are correctly resolved in joins between normal tables and WITHOUT ROWID tables. Fix for ticket [c34d0557f740c45070]. FossilOrigin-Name: 5d01426ddfb2d47c57f93f71378594e637424be0 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/resolve.c | 4 ++-- test/without_rowid1.test | 16 +++++++++++++++- 4 files changed, 25 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 19a6fafab1..e5839e439d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Increase\sthe\sversion\snumber\sto\s3.8.4 -D 2014-02-11T16:24:34.448 +C Make\ssure\s"rowid"\scolumns\sare\scorrectly\sresolved\sin\sjoins\sbetween\snormal\ntables\sand\sWITHOUT\sROWID\stables.\s\sFix\sfor\sticket\s[c34d0557f740c45070]. +D 2014-02-12T14:43:52.953 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -217,7 +217,7 @@ F src/pragma.c ed409ce4104cf4d9de6ead40ace70974f124853b F src/prepare.c 677521ab7132615a8a26107a1d1c3132f44ae337 F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece -F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 +F src/resolve.c ca8b99d894164435f5c55cb304c1b8121705c51e F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c 50961f0d0ab8f2d45ff29ec5f91d8db221330ca7 F src/shell.c 3dd86bf73ccd079f0e32ef5069600586085e8239 @@ -1096,7 +1096,7 @@ F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d F test/with1.test 268081a6b14817a262ced4d0ee34d4d2a1dd2068 F test/with2.test 2fe78fcd8deef2a0f9cfc49bfc755911d0b3fd64 F test/withM.test e97f2a8c506ab3ea9eab94e6f6072f6cc924c991 -F test/without_rowid1.test aaa26da19d543cd8d3d2d0e686dfa255556c15c8 +F test/without_rowid1.test e00a0a9dc9f0be651f011d61e8a32b7add5afb30 F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99 F test/without_rowid3.test eac3d5c8a1924725b58503a368f2cbd24fd6c8a0 F test/without_rowid4.test 4e08bcbaee0399f35d58b5581881e7a6243d458a @@ -1153,7 +1153,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P f5ad1e1bf2828c5da70c1ff944d8212036142e6f -R 07c665af95e97929880dcb47f3f495f9 +P 0a8bcbbd4e11a60923736b2be9b1ce83ea2263fb +R ece7306a4645e7a68a79bfe14ec94970 U drh -Z 585a1fb26982d5587e4e3f114773e866 +Z 89db972fa80a38407f6b56a44d53bf78 diff --git a/manifest.uuid b/manifest.uuid index a4c42c8f7f..564e92ae29 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0a8bcbbd4e11a60923736b2be9b1ce83ea2263fb \ No newline at end of file +5d01426ddfb2d47c57f93f71378594e637424be0 \ No newline at end of file diff --git a/src/resolve.c b/src/resolve.c index b0adb86295..07e0e919a5 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -380,8 +380,8 @@ static int lookupName( /* ** Perhaps the name is a reference to the ROWID */ - assert( pTab!=0 || cntTab==0 ); - if( cnt==0 && cntTab==1 && sqlite3IsRowid(zCol) && HasRowid(pTab) ){ + if( cnt==0 && cntTab==1 && pMatch && sqlite3IsRowid(zCol) + && HasRowid(pMatch->pTab) ){ cnt = 1; pExpr->iColumn = -1; /* IMP: R-44911-55124 */ pExpr->affinity = SQLITE_AFF_INTEGER; diff --git a/test/without_rowid1.test b/test/without_rowid1.test index 1a53d26e66..bdd03c57bb 100644 --- a/test/without_rowid1.test +++ b/test/without_rowid1.test @@ -198,6 +198,20 @@ do_execsql_test 3.1.5 { INSERT INTO t3 SELECT * FROM t4; SELECT * FROM t3; } {i ii iii} + +############################################################################ +# Ticket [c34d0557f740c450709d6e33df72d4f3f651a3cc] +# Name resolution issue with WITHOUT ROWID +# +do_execsql_test 4.1 { + CREATE TABLE t41(a PRIMARY KEY) WITHOUT ROWID; + INSERT INTO t41 VALUES('abc'); + CREATE TABLE t42(x); + INSERT INTO t42 VALUES('xyz'); + SELECT t42.rowid FROM t41, t42; +} {1} +do_execsql_test 4.2 { + SELECT t42.rowid FROM t42, t41; +} {1} finish_test - From e0670b6220ce4c0819c30faefc100e9228456fc9 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 12 Feb 2014 21:31:12 +0000 Subject: [PATCH 251/276] Remove the "rowid cache" that sought to remember the largest rowid for a table and thereby speed up OP_NewRowid. That cache was ineffective. Removing it results in a performance increase of 0.4%, less memory usage, and a slightly smaller library size. FossilOrigin-Name: 56bc5ce8958c8e6250531b4052b905d7ac993db3 --- manifest | 18 +++++------ manifest.uuid | 2 +- src/btree.c | 45 ++++++-------------------- src/btree.h | 2 -- src/btreeInt.h | 1 - src/vdbe.c | 85 +++++++++++++++++++++++--------------------------- 6 files changed, 59 insertions(+), 94 deletions(-) diff --git a/manifest b/manifest index e5839e439d..fd4cbee264 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\s"rowid"\scolumns\sare\scorrectly\sresolved\sin\sjoins\sbetween\snormal\ntables\sand\sWITHOUT\sROWID\stables.\s\sFix\sfor\sticket\s[c34d0557f740c45070]. -D 2014-02-12T14:43:52.953 +C Remove\sthe\s"rowid\scache"\sthat\ssought\sto\sremember\sthe\slargest\srowid\sfor\sa\ntable\sand\sthereby\sspeed\sup\sOP_NewRowid.\s\sThat\scache\swas\sineffective.\nRemoving\sit\sresults\sin\sa\sperformance\sincrease\sof\s0.4%,\sless\smemory\susage,\nand\sa\sslightly\ssmaller\slibrary\ssize. +D 2014-02-12T21:31:12.616 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,9 +166,9 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c a729e63cf5cd1829507cb7b8e89f99b95141bb53 F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c 7b2c3cd16deedff7f4904f2e871e7b77328b9872 -F src/btree.h a61ddebc78c66795a2b93181321a116746302cc9 -F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0 +F src/btree.c 97020a77cb53fb9d8e7f172d489b8f92af1d1b82 +F src/btree.h 9e0f97c01b972f779eb7655cfb4f8727fd6dc26f +F src/btreeInt.h 0be66063468a520e4d66b80c7a1dc26d04ee6ea4 F src/build.c 13b9d82181d95af7b00ec8a8e1304bac096432d4 F src/callback.c 174e3c8656bc29f91d710ab61550d16eea34be98 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac @@ -280,7 +280,7 @@ F src/update.c a7df6fffce6bfedc578fda6136dd33e34a63f8ee F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c c46c90459ef9bdc0c6c73803cf4c55425b4771cf F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c e5c87476d717aebef5dafceab11417ebf2730554 +F src/vdbe.c 3f0872b12ec3fc24ee540f8bb09de181ddad6d8d F src/vdbe.h e6c4c610fcabad4fa80ebb1efc6822a9367e2b26 F src/vdbeInt.h 5286af9067cabdb8ba57b87c0c988a931be6c6c8 F src/vdbeapi.c 5bc41aaea448a7fc250902c418f1795859be3820 @@ -1153,7 +1153,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 0a8bcbbd4e11a60923736b2be9b1ce83ea2263fb -R ece7306a4645e7a68a79bfe14ec94970 +P 5d01426ddfb2d47c57f93f71378594e637424be0 +R 0f58210f2a6ea71dc58155d3b9fc47e4 U drh -Z 89db972fa80a38407f6b56a44d53bf78 +Z 0cd8ad70eddd970bc8638e6270cc29ff diff --git a/manifest.uuid b/manifest.uuid index 564e92ae29..b2a9658b53 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5d01426ddfb2d47c57f93f71378594e637424be0 \ No newline at end of file +56bc5ce8958c8e6250531b4052b905d7ac993db3 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index cf135b1e14..2aac72d55c 100644 --- a/src/btree.c +++ b/src/btree.c @@ -3632,7 +3632,6 @@ static int btreeCursor( } pBt->pCursor = pCur; pCur->eState = CURSOR_INVALID; - pCur->cachedRowid = 0; return SQLITE_OK; } int sqlite3BtreeCursor( @@ -3673,36 +3672,6 @@ void sqlite3BtreeCursorZero(BtCursor *p){ memset(p, 0, offsetof(BtCursor, iPage)); } -/* -** Set the cached rowid value of every cursor in the same database file -** as pCur and having the same root page number as pCur. The value is -** set to iRowid. -** -** Only positive rowid values are considered valid for this cache. -** The cache is initialized to zero, indicating an invalid cache. -** A btree will work fine with zero or negative rowids. We just cannot -** cache zero or negative rowids, which means tables that use zero or -** negative rowids might run a little slower. But in practice, zero -** or negative rowids are very uncommon so this should not be a problem. -*/ -void sqlite3BtreeSetCachedRowid(BtCursor *pCur, sqlite3_int64 iRowid){ - BtCursor *p; - for(p=pCur->pBt->pCursor; p; p=p->pNext){ - if( p->pgnoRoot==pCur->pgnoRoot ) p->cachedRowid = iRowid; - } - assert( pCur->cachedRowid==iRowid ); -} - -/* -** Return the cached rowid for the given cursor. A negative or zero -** return value indicates that the rowid cache is invalid and should be -** ignored. If the rowid cache has never before been set, then a -** zero is returned. -*/ -sqlite3_int64 sqlite3BtreeGetCachedRowid(BtCursor *pCur){ - return pCur->cachedRowid; -} - /* ** Close a cursor. The read lock on the database file is released ** when the last cursor is closed. @@ -6986,11 +6955,17 @@ int sqlite3BtreeInsert( rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur); if( rc ) return rc; - /* If this is an insert into a table b-tree, invalidate any incrblob - ** cursors open on the row being replaced (assuming this is a replace - ** operation - if it is not, the following is a no-op). */ if( pCur->pKeyInfo==0 ){ + /* If this is an insert into a table b-tree, invalidate any incrblob + ** cursors open on the row being replaced */ invalidateIncrblobCursors(p, nKey, 0); + + /* If the cursor is currently on the last row and we are appending a + ** new row onto the end, set the "loc" to avoid an unnecessary btreeMoveto() + ** call */ + if( pCur->validNKey && nKey>0 && pCur->info.nKey==nKey-1 ){ + loc = -1; + } } if( !loc ){ @@ -7060,8 +7035,8 @@ int sqlite3BtreeInsert( ** row without seeking the cursor. This can be a big performance boost. */ pCur->info.nSize = 0; - pCur->validNKey = 0; if( rc==SQLITE_OK && pPage->nOverflow ){ + pCur->validNKey = 0; rc = balance(pCur); /* Must make sure nOverflow is reset to zero even if the balance() diff --git a/src/btree.h b/src/btree.h index 3eb5906955..eda7bef70a 100644 --- a/src/btree.h +++ b/src/btree.h @@ -182,8 +182,6 @@ const void *sqlite3BtreeKeyFetch(BtCursor*, u32 *pAmt); const void *sqlite3BtreeDataFetch(BtCursor*, u32 *pAmt); int sqlite3BtreeDataSize(BtCursor*, u32 *pSize); int sqlite3BtreeData(BtCursor*, u32 offset, u32 amt, void*); -void sqlite3BtreeSetCachedRowid(BtCursor*, sqlite3_int64); -sqlite3_int64 sqlite3BtreeGetCachedRowid(BtCursor*); char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot, int, int*); struct Pager *sqlite3BtreePager(Btree*); diff --git a/src/btreeInt.h b/src/btreeInt.h index 3ebdeb663e..87b4181f82 100644 --- a/src/btreeInt.h +++ b/src/btreeInt.h @@ -500,7 +500,6 @@ struct BtCursor { Pgno *aOverflow; /* Cache of overflow page locations */ #endif Pgno pgnoRoot; /* The root page of this tree */ - sqlite3_int64 cachedRowid; /* Next rowid cache. 0 means not valid */ CellInfo info; /* A parse of the cell we are pointing at */ i64 nKey; /* Size of pKey, or last integer key */ void *pKey; /* Saved key that was cursor's last known position */ diff --git a/src/vdbe.c b/src/vdbe.c index aa34ad091a..00cff1e21e 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3834,59 +3834,54 @@ case OP_NewRowid: { /* out2-prerelease */ #endif if( !pC->useRandomRowid ){ - v = sqlite3BtreeGetCachedRowid(pC->pCursor); - if( v==0 ){ - rc = sqlite3BtreeLast(pC->pCursor, &res); - if( rc!=SQLITE_OK ){ - goto abort_due_to_error; - } - if( res ){ - v = 1; /* IMP: R-61914-48074 */ + rc = sqlite3BtreeLast(pC->pCursor, &res); + if( rc!=SQLITE_OK ){ + goto abort_due_to_error; + } + if( res ){ + v = 1; /* IMP: R-61914-48074 */ + }else{ + assert( sqlite3BtreeCursorIsValid(pC->pCursor) ); + rc = sqlite3BtreeKeySize(pC->pCursor, &v); + assert( rc==SQLITE_OK ); /* Cannot fail following BtreeLast() */ + if( v>=MAX_ROWID ){ + pC->useRandomRowid = 1; }else{ - assert( sqlite3BtreeCursorIsValid(pC->pCursor) ); - rc = sqlite3BtreeKeySize(pC->pCursor, &v); - assert( rc==SQLITE_OK ); /* Cannot fail following BtreeLast() */ - if( v>=MAX_ROWID ){ - pC->useRandomRowid = 1; - }else{ - v++; /* IMP: R-29538-34987 */ - } + v++; /* IMP: R-29538-34987 */ } } + } #ifndef SQLITE_OMIT_AUTOINCREMENT - if( pOp->p3 ){ + if( pOp->p3 ){ + /* Assert that P3 is a valid memory cell. */ + assert( pOp->p3>0 ); + if( p->pFrame ){ + for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent); /* Assert that P3 is a valid memory cell. */ - assert( pOp->p3>0 ); - if( p->pFrame ){ - for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent); - /* Assert that P3 is a valid memory cell. */ - assert( pOp->p3<=pFrame->nMem ); - pMem = &pFrame->aMem[pOp->p3]; - }else{ - /* Assert that P3 is a valid memory cell. */ - assert( pOp->p3<=(p->nMem-p->nCursor) ); - pMem = &aMem[pOp->p3]; - memAboutToChange(p, pMem); - } - assert( memIsValid(pMem) ); - - REGISTER_TRACE(pOp->p3, pMem); - sqlite3VdbeMemIntegerify(pMem); - assert( (pMem->flags & MEM_Int)!=0 ); /* mem(P3) holds an integer */ - if( pMem->u.i==MAX_ROWID || pC->useRandomRowid ){ - rc = SQLITE_FULL; /* IMP: R-12275-61338 */ - goto abort_due_to_error; - } - if( vu.i+1 ){ - v = pMem->u.i + 1; - } - pMem->u.i = v; + assert( pOp->p3<=pFrame->nMem ); + pMem = &pFrame->aMem[pOp->p3]; + }else{ + /* Assert that P3 is a valid memory cell. */ + assert( pOp->p3<=(p->nMem-p->nCursor) ); + pMem = &aMem[pOp->p3]; + memAboutToChange(p, pMem); } -#endif + assert( memIsValid(pMem) ); - sqlite3BtreeSetCachedRowid(pC->pCursor, vp3, pMem); + sqlite3VdbeMemIntegerify(pMem); + assert( (pMem->flags & MEM_Int)!=0 ); /* mem(P3) holds an integer */ + if( pMem->u.i==MAX_ROWID || pC->useRandomRowid ){ + rc = SQLITE_FULL; /* IMP: R-12275-61338 */ + goto abort_due_to_error; + } + if( vu.i+1 ){ + v = pMem->u.i + 1; + } + pMem->u.i = v; } +#endif if( pC->useRandomRowid ){ /* IMPLEMENTATION-OF: R-07677-41881 If the largest ROWID is equal to the ** largest possible integer (9223372036854775807) then the database @@ -4020,7 +4015,6 @@ case OP_InsertInt: { }else{ nZero = 0; } - sqlite3BtreeSetCachedRowid(pC->pCursor, 0); rc = sqlite3BtreeInsert(pC->pCursor, 0, iKey, pData->z, pData->n, nZero, (pOp->p5 & OPFLAG_APPEND)!=0, seekResult @@ -4082,7 +4076,6 @@ case OP_Delete: { rc = sqlite3VdbeCursorMoveto(pC); if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error; - sqlite3BtreeSetCachedRowid(pC->pCursor, 0); rc = sqlite3BtreeDelete(pC->pCursor); pC->cacheStatus = CACHE_STALE; From fe48599294e5e09b036f8c06fddb14e6d8c55fb6 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 12 Feb 2014 23:52:16 +0000 Subject: [PATCH 252/276] Minor simplifications to the "zeroPage()" routine in btree.c. FossilOrigin-Name: cc8f10bcb206c9def69b06f26decf025b8d9119d --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 3 +-- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index fd4cbee264..e344356edb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sthe\s"rowid\scache"\sthat\ssought\sto\sremember\sthe\slargest\srowid\sfor\sa\ntable\sand\sthereby\sspeed\sup\sOP_NewRowid.\s\sThat\scache\swas\sineffective.\nRemoving\sit\sresults\sin\sa\sperformance\sincrease\sof\s0.4%,\sless\smemory\susage,\nand\sa\sslightly\ssmaller\slibrary\ssize. -D 2014-02-12T21:31:12.616 +C Minor\ssimplifications\sto\sthe\s"zeroPage()"\sroutine\sin\sbtree.c. +D 2014-02-12T23:52:16.136 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,7 +166,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c a729e63cf5cd1829507cb7b8e89f99b95141bb53 F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c 97020a77cb53fb9d8e7f172d489b8f92af1d1b82 +F src/btree.c b945df4f0114b4cc71006acc2fbb1333fb33a200 F src/btree.h 9e0f97c01b972f779eb7655cfb4f8727fd6dc26f F src/btreeInt.h 0be66063468a520e4d66b80c7a1dc26d04ee6ea4 F src/build.c 13b9d82181d95af7b00ec8a8e1304bac096432d4 @@ -1153,7 +1153,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 5d01426ddfb2d47c57f93f71378594e637424be0 -R 0f58210f2a6ea71dc58155d3b9fc47e4 +P 56bc5ce8958c8e6250531b4052b905d7ac993db3 +R 08bd4c102c2d08f0774c76e162878c69 U drh -Z 0cd8ad70eddd970bc8638e6270cc29ff +Z ed630d5c913dd5b0515f56c704c7877e diff --git a/manifest.uuid b/manifest.uuid index b2a9658b53..2af58e32b8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -56bc5ce8958c8e6250531b4052b905d7ac993db3 \ No newline at end of file +cc8f10bcb206c9def69b06f26decf025b8d9119d \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 2aac72d55c..4fd8e27bf4 100644 --- a/src/btree.c +++ b/src/btree.c @@ -1542,13 +1542,12 @@ static void zeroPage(MemPage *pPage, int flags){ memset(&data[hdr], 0, pBt->usableSize - hdr); } data[hdr] = (char)flags; - first = hdr + 8 + 4*((flags&PTF_LEAF)==0 ?1:0); + first = hdr + ((flags&PTF_LEAF)==0 ? 12 : 8); memset(&data[hdr+1], 0, 4); data[hdr+7] = 0; put2byte(&data[hdr+5], pBt->usableSize); pPage->nFree = (u16)(pBt->usableSize - first); decodeFlags(pPage, flags); - pPage->hdrOffset = hdr; pPage->cellOffset = first; pPage->aDataEnd = &data[pBt->usableSize]; pPage->aCellIdx = &data[first]; From 962f9669b6cb5f476deced48107b5b3a7525508d Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 13 Feb 2014 13:42:43 +0000 Subject: [PATCH 253/276] Update the tclconfig files to the latest from http://core.tcl.tk/tclconfig. FossilOrigin-Name: b81ba7a4bc7e840fce25fc6801957a64f877ff60 --- autoconf/tea/tclconfig/install-sh | 569 +++++++++++++++++++++++++----- autoconf/tea/tclconfig/tcl.m4 | 458 ++++++++++++++++-------- manifest | 14 +- manifest.uuid | 2 +- 4 files changed, 810 insertions(+), 233 deletions(-) diff --git a/autoconf/tea/tclconfig/install-sh b/autoconf/tea/tclconfig/install-sh index 0ff4b6a08e..7c34c3f926 100644 --- a/autoconf/tea/tclconfig/install-sh +++ b/autoconf/tea/tclconfig/install-sh @@ -1,119 +1,528 @@ #!/bin/sh - -# # install - install a program, script, or datafile -# This comes from X11R5; it is not part of GNU. + +scriptversion=2011-04-20.01; # UTC + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. # -# $XConsortium: install.sh,v 1.2 89/12/18 14:47:22 jim Exp $ +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. -# +nl=' +' +IFS=" "" $nl" # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. -doit="${DOITPROG-}" +doit=${DOITPROG-} +if test -z "$doit"; then + doit_exec=exec +else + doit_exec=$doit +fi +# Put in absolute file names if you don't have them in your path; +# or use environment vars. -# put in absolute paths if you don't have them in your path; or use env. vars. +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} -mvprog="${MVPROG-mv}" -cpprog="${CPPROG-cp}" -chmodprog="${CHMODPROG-chmod}" -chownprog="${CHOWNPROG-chown}" -chgrpprog="${CHGRPPROG-chgrp}" -stripprog="${STRIPPROG-strip}" -rmprog="${RMPROG-rm}" +posix_glob='?' +initialize_posix_glob=' + test "$posix_glob" != "?" || { + if (set -f) 2>/dev/null; then + posix_glob= + else + posix_glob=: + fi + } +' -instcmd="$mvprog" -chmodcmd="" -chowncmd="" -chgrpcmd="" -stripcmd="" +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog rmcmd="$rmprog -f" -mvcmd="$mvprog" -src="" -dst="" +stripcmd= -while [ x"$1" != x ]; do - case $1 in - -c) instcmd="$cpprog" - shift - continue;; +src= +dst= +dir_arg= +dst_arg= - -m) chmodcmd="$chmodprog $2" - shift - shift - continue;; +copy_on_change=false +no_target_directory= - -o) chowncmd="$chownprog $2" - shift - shift - continue;; +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... - -g) chgrpcmd="$chgrpprog $2" - shift - shift - continue;; +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. - -s) stripcmd="$stripprog" - shift - continue;; +Options: + --help display this help and exit. + --version display version info and exit. - *) if [ x"$src" = x ] - then - src=$1 - else - dst=$1 - fi - shift - continue;; - esac + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -S $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *' '* | *' +'* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -S) stripcmd="$stripprog $2" + shift;; + + -t) dst_arg=$2 + shift;; + + -T) no_target_directory=true;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift done -if [ x"$src" = x ] -then - echo "install: no input file specified" +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + do_exit='(exit $ret); exit $ret' + trap "ret=129; $do_exit" 1 + trap "ret=130; $do_exit" 2 + trap "ret=141; $do_exit" 13 + trap "ret=143; $do_exit" 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names starting with `-'. + case $src in + -*) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + + dst=$dst_arg + # Protect names starting with `-'. + case $dst in + -*) dst=./$dst;; + esac + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dst_arg: Is a directory" >&2 exit 1 -fi + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + # Prefer dirname, but fall back on a substitute if dirname fails. + dstdir=` + (dirname "$dst") 2>/dev/null || + expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$dst" : 'X\(//\)[^/]' \| \ + X"$dst" : 'X\(//\)$' \| \ + X"$dst" : 'X\(/\)' \| . 2>/dev/null || + echo X"$dst" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q' + ` -if [ x"$dst" = x ] -then - echo "install: no destination specified" - exit 1 -fi + test -d "$dstdir" + dstdir_status=$? + fi + fi + obsolete_mkdir_used=false -# If destination is a directory, append the input filename; if your system -# does not like double slashes in filenames, you may need to add some logic + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; -if [ -d $dst ] -then - dst="$dst"/`basename $src` -fi + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac -# Make a temp file name in the proper directory. + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi -dstdir=`dirname $dst` -dsttmp=$dstdir/#inst.$$# + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 -# Move or copy the file name to the temp name + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writeable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac -$doit $instcmd $src $dsttmp + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else -# and set any options; do chmod last to preserve setuid bits + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. -if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; fi -if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; fi -if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; fi -if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; fi + case $dstdir in + /*) prefix='/';; + -*) prefix='./';; + *) prefix='';; + esac -# Now rename the file to the real destination. + eval "$initialize_posix_glob" -$doit $rmcmd $dst -$doit $mvcmd $dsttmp $dst + oIFS=$IFS + IFS=/ + $posix_glob set -f + set fnord $dstdir + shift + $posix_glob set +f + IFS=$oIFS + prefixes= -exit 0 + for d + do + test -z "$d" && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + + eval "$initialize_posix_glob" && + $posix_glob set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + $posix_glob set +f && + + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/autoconf/tea/tclconfig/tcl.m4 b/autoconf/tea/tclconfig/tcl.m4 index f910bc2a1f..66214e78a2 100644 --- a/autoconf/tea/tclconfig/tcl.m4 +++ b/autoconf/tea/tclconfig/tcl.m4 @@ -8,8 +8,6 @@ # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. -# -# RCS: @(#) $Id: tcl.m4,v 1.145 2010/08/17 00:33:40 hobbs Exp $ AC_PREREQ(2.57) @@ -140,6 +138,8 @@ AC_DEFUN([TEA_PATH_TCLCONFIG], [ `ls -d /usr/contrib/lib 2>/dev/null` \ `ls -d /usr/lib 2>/dev/null` \ `ls -d /usr/lib64 2>/dev/null` \ + `ls -d /usr/lib/tcl8.6 2>/dev/null` \ + `ls -d /usr/lib/tcl8.5 2>/dev/null` \ ; do if test -f "$i/tclConfig.sh" ; then ac_cv_c_tclconfig="`(cd $i; pwd)`" @@ -170,7 +170,7 @@ AC_DEFUN([TEA_PATH_TCLCONFIG], [ if test x"${ac_cv_c_tclconfig}" = x ; then TCL_BIN_DIR="# no Tcl configs found" - AC_MSG_ERROR([Can't find Tcl configuration definitions]) + AC_MSG_ERROR([Can't find Tcl configuration definitions. Use --with-tcl to specify a directory containing tclConfig.sh]) else no_tcl= TCL_BIN_DIR="${ac_cv_c_tclconfig}" @@ -323,7 +323,7 @@ AC_DEFUN([TEA_PATH_TKCONFIG], [ if test x"${ac_cv_c_tkconfig}" = x ; then TK_BIN_DIR="# no Tk configs found" - AC_MSG_ERROR([Can't find Tk configuration definitions]) + AC_MSG_ERROR([Can't find Tk configuration definitions. Use --with-tk to specify a directory containing tkConfig.sh]) else no_tk= TK_BIN_DIR="${ac_cv_c_tkconfig}" @@ -344,11 +344,10 @@ AC_DEFUN([TEA_PATH_TKCONFIG], [ # # Results: # -# Subst the following vars: +# Substitutes the following vars: # TCL_BIN_DIR # TCL_SRC_DIR # TCL_LIB_FILE -# #------------------------------------------------------------------------ AC_DEFUN([TEA_LOAD_TCLCONFIG], [ @@ -417,32 +416,26 @@ AC_DEFUN([TEA_LOAD_TCLCONFIG], [ AC_SUBST(TCL_STUB_LIB_FLAG) AC_SUBST(TCL_STUB_LIB_SPEC) - case "`uname -s`" in - *CYGWIN_*) - AC_MSG_CHECKING([for cygwin variant]) - case ${TCL_EXTRA_CFLAGS} in - *-mwin32*|*-mno-cygwin*) - TEA_PLATFORM="windows" - CFLAGS="$CFLAGS -mwin32" - AC_MSG_RESULT([win32]) - ;; - *) - TEA_PLATFORM="unix" - AC_MSG_RESULT([unix]) - ;; - esac - EXEEXT=".exe" - ;; - *) - ;; - esac + AC_MSG_CHECKING([platform]) + hold_cc=$CC; CC="$TCL_CC" + AC_TRY_COMPILE(,[ + #ifdef _WIN32 + #error win32 + #endif + ], TEA_PLATFORM="unix", + TEA_PLATFORM="windows" + ) + CC=$hold_cc + AC_MSG_RESULT($TEA_PLATFORM) + # The BUILD_$pkg is to define the correct extern storage class + # handling when making this package + AC_DEFINE_UNQUOTED(BUILD_${PACKAGE_NAME}, [], + [Building extension source?]) # Do this here as we have fully defined TEA_PLATFORM now if test "${TEA_PLATFORM}" = "windows" ; then - # The BUILD_$pkg is to define the correct extern storage class - # handling when making this package - AC_DEFINE_UNQUOTED(BUILD_${PACKAGE_NAME}) - CLEANFILES="$CLEANFILES *.lib *.dll *.pdb" + EXEEXT=".exe" + CLEANFILES="$CLEANFILES *.lib *.dll *.pdb *.exp" fi # TEA specific: @@ -566,11 +559,11 @@ AC_DEFUN([TEA_LOAD_TKCONFIG], [ # only for running extension test cases. It should never be # or generation of files (like pkgIndex.tcl) at build time. # -# Arguments +# Arguments: # none # -# Results -# Subst's the following values: +# Results: +# Substitutes the following vars: # TCLSH_PROG #------------------------------------------------------------------------ @@ -616,11 +609,11 @@ AC_DEFUN([TEA_PROG_TCLSH], [ # only for running extension test cases. It should never be # or generation of files (like pkgIndex.tcl) at build time. # -# Arguments +# Arguments: # none # -# Results -# Subst's the following values: +# Results: +# Substitutes the following vars: # WISH_PROG #------------------------------------------------------------------------ @@ -731,7 +724,6 @@ AC_DEFUN([TEA_ENABLE_SHARED], [ # TCL_THREADS # _REENTRANT # _THREAD_SAFE -# #------------------------------------------------------------------------ AC_DEFUN([TEA_ENABLE_THREADS], [ @@ -855,12 +847,11 @@ AC_DEFUN([TEA_ENABLE_THREADS], [ # # Defines the following vars: # CFLAGS_DEFAULT Sets to $(CFLAGS_DEBUG) if true -# Sets to $(CFLAGS_OPTIMIZE) if false +# Sets to "$(CFLAGS_OPTIMIZE) -DNDEBUG" if false # LDFLAGS_DEFAULT Sets to $(LDFLAGS_DEBUG) if true # Sets to $(LDFLAGS_OPTIMIZE) if false # DBGX Formerly used as debug library extension; # always blank now. -# #------------------------------------------------------------------------ AC_DEFUN([TEA_ENABLE_SYMBOLS], [ @@ -873,7 +864,7 @@ AC_DEFUN([TEA_ENABLE_SYMBOLS], [ [tcl_ok=$enableval], [tcl_ok=no]) DBGX="" if test "$tcl_ok" = "no"; then - CFLAGS_DEFAULT="${CFLAGS_OPTIMIZE}" + CFLAGS_DEFAULT="${CFLAGS_OPTIMIZE} -DNDEBUG" LDFLAGS_DEFAULT="${LDFLAGS_OPTIMIZE}" AC_MSG_RESULT([no]) else @@ -920,7 +911,6 @@ AC_DEFUN([TEA_ENABLE_SYMBOLS], [ # # Defines the following vars: # HAVE_LANGINFO Triggers use of nl_langinfo if defined. -# #------------------------------------------------------------------------ AC_DEFUN([TEA_ENABLE_LANGINFO], [ @@ -961,7 +951,6 @@ AC_DEFUN([TEA_ENABLE_LANGINFO], [ # Defines the following var: # # system - System/platform/version identification code. -# #-------------------------------------------------------------------- AC_DEFUN([TEA_CONFIG_SYSTEM], [ @@ -1030,21 +1019,20 @@ AC_DEFUN([TEA_CONFIG_SYSTEM], [ # extensions. An empty string means we don't know how # to use shared libraries on this platform. # LIB_SUFFIX - Specifies everything that comes after the "libfoo" -# in a static or shared library name, using the $VERSION variable +# in a static or shared library name, using the $PACKAGE_VERSION variable # to put the version in the right place. This is used # by platforms that need non-standard library names. -# Examples: ${VERSION}.so.1.1 on NetBSD, since it needs -# to have a version after the .so, and ${VERSION}.a +# Examples: ${PACKAGE_VERSION}.so.1.1 on NetBSD, since it needs +# to have a version after the .so, and ${PACKAGE_VERSION}.a # on AIX, since a shared library needs to have # a .a extension whereas shared objects for loadable # extensions have a .so extension. Defaults to -# ${VERSION}${SHLIB_SUFFIX}. +# ${PACKAGE_VERSION}${SHLIB_SUFFIX}. # CFLAGS_DEBUG - # Flags used when running the compiler in debug mode # CFLAGS_OPTIMIZE - # Flags used when running the compiler in optimize mode # CFLAGS - Additional CFLAGS added as necessary (usually 64-bit) -# #-------------------------------------------------------------------- AC_DEFUN([TEA_CONFIG_CFLAGS], [ @@ -1086,6 +1074,7 @@ AC_DEFUN([TEA_CONFIG_CFLAGS], [ AC_DEFINE(MODULE_SCOPE, [extern __attribute__((__visibility__("hidden")))], [Compiler support for module scope symbols]) + AC_DEFINE(HAVE_HIDDEN, [1], [Compiler support for module scope symbols]) ]) # Step 0.d: Disable -rpath support? @@ -1134,15 +1123,14 @@ AC_DEFUN([TEA_CONFIG_CFLAGS], [ ECHO_VERSION='`echo ${PACKAGE_VERSION}`' TCL_LIB_VERSIONS_OK=ok CFLAGS_DEBUG=-g - CFLAGS_OPTIMIZE=-O AS_IF([test "$GCC" = yes], [ - # TEA specific: CFLAGS_OPTIMIZE=-O2 CFLAGS_WARNING="-Wall" - ], [CFLAGS_WARNING=""]) -dnl FIXME: Replace AC_CHECK_PROG with AC_CHECK_TOOL once cross compiling is fixed. -dnl AC_CHECK_TOOL(AR, ar) - AC_CHECK_PROG(AR, ar, ar) + ], [ + CFLAGS_OPTIMIZE=-O + CFLAGS_WARNING="" + ]) + AC_CHECK_TOOL(AR, ar) STLIB_LD='${AR} cr' LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH" AS_IF([test "x$SHLIB_VERSION" = x],[SHLIB_VERSION="1.0"]) @@ -1171,7 +1159,7 @@ dnl AC_CHECK_TOOL(AR, ar) PATH64="${MSSDK}/Bin/Win64" ;; esac - if test ! -d "${PATH64}" ; then + if test "$GCC" != "yes" -a ! -d "${PATH64}" ; then AC_MSG_WARN([Could not find 64-bit $MACHINE SDK to enable 64bit mode]) AC_MSG_WARN([Ensure latest Platform SDK is installed]) do64bit="no" @@ -1288,7 +1276,7 @@ dnl AC_CHECK_TOOL(AR, ar) else RC="rc" lflags="-nologo" - LINKBIN="link" + LINKBIN="link" CFLAGS_DEBUG="-nologo -Z7 -Od -W3 -WX ${runtime}d" CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}" fi @@ -1296,13 +1284,43 @@ dnl AC_CHECK_TOOL(AR, ar) if test "$GCC" = "yes"; then # mingw gcc mode - RC="windres" + AC_CHECK_TOOL(RC, windres) CFLAGS_DEBUG="-g" CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer" - SHLIB_LD="$CC -shared" + SHLIB_LD='${CC} -shared' UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' LDFLAGS_CONSOLE="-wl,--subsystem,console ${lflags}" LDFLAGS_WINDOW="-wl,--subsystem,windows ${lflags}" + + AC_CACHE_CHECK(for cross-compile version of gcc, + ac_cv_cross, + AC_TRY_COMPILE([ + #ifdef _WIN32 + #error cross-compiler + #endif + ], [], + ac_cv_cross=yes, + ac_cv_cross=no) + ) + if test "$ac_cv_cross" = "yes"; then + case "$do64bit" in + amd64|x64|yes) + CC="x86_64-w64-mingw32-gcc" + LD="x86_64-w64-mingw32-ld" + AR="x86_64-w64-mingw32-ar" + RANLIB="x86_64-w64-mingw32-ranlib" + RC="x86_64-w64-mingw32-windres" + ;; + *) + CC="i686-w64-mingw32-gcc" + LD="i686-w64-mingw32-ld" + AR="i686-w64-mingw32-ar" + RANLIB="i686-w64-mingw32-ranlib" + RC="i686-w64-mingw32-windres" + ;; + esac + fi + else SHLIB_LD="${LINKBIN} -dll ${lflags}" # link -lib only works when -lib is the first arg @@ -1409,7 +1427,8 @@ dnl AC_CHECK_TOOL(AR, ar) SHLIB_CFLAGS="" SHLIB_LD='${CC} -shared' SHLIB_SUFFIX=".dll" - EXE_SUFFIX=".exe" + EXEEXT=".exe" + do64bit_ok=yes CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; @@ -1438,7 +1457,7 @@ dnl AC_CHECK_TOOL(AR, ar) ]) AC_CHECK_LIB(dld, shl_load, tcl_ok=yes, tcl_ok=no) AS_IF([test "$tcl_ok" = yes], [ - LDFLAGS="$LDFLAGS -E" + LDFLAGS="$LDFLAGS -Wl,-E" CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.' LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.' LD_LIBRARY_PATH_VAR="SHLIB_PATH" @@ -1520,7 +1539,7 @@ dnl AC_CHECK_TOOL(AR, ar) ]) ]) ;; - Linux*) + Linux*|GNU*|NetBSD-Debian) SHLIB_CFLAGS="-fPIC" SHLIB_SUFFIX=".so" @@ -1553,17 +1572,6 @@ dnl AC_CHECK_TOOL(AR, ar) # files in compat/*.c is being linked in. AS_IF([test x"${USE_COMPAT}" != x],[CFLAGS="$CFLAGS -fno-inline"]) - - ;; - GNU*) - SHLIB_CFLAGS="-fPIC" - SHLIB_SUFFIX=".so" - - SHLIB_LD='${CC} -shared' - LDFLAGS="$LDFLAGS -Wl,--export-dynamic" - CC_SEARCH_FLAGS="" - LD_SEARCH_FLAGS="" - AS_IF([test "`uname -m`" = "alpha"], [CFLAGS="$CFLAGS -mieee"]) ;; Lynx*) SHLIB_CFLAGS="-fPIC" @@ -1576,35 +1584,44 @@ dnl AC_CHECK_TOOL(AR, ar) LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}']) ;; OpenBSD-*) - SHLIB_CFLAGS="-fPIC" - SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}' - SHLIB_SUFFIX=".so" - AS_IF([test $doRpath = yes], [ - CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}']) - LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} - SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}' - AC_CACHE_CHECK([for ELF], tcl_cv_ld_elf, [ - AC_EGREP_CPP(yes, [ -#ifdef __ELF__ - yes -#endif - ], tcl_cv_ld_elf=yes, tcl_cv_ld_elf=no)]) - AS_IF([test $tcl_cv_ld_elf = yes], [ - LDFLAGS=-Wl,-export-dynamic - ], [LDFLAGS=""]) + arch=`arch -s` + case "$arch" in + vax) + SHLIB_SUFFIX="" + SHARED_LIB_SUFFIX="" + LDFLAGS="" + ;; + *) + SHLIB_CFLAGS="-fPIC" + SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}' + SHLIB_SUFFIX=".so" + AS_IF([test $doRpath = yes], [ + CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}']) + LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} + SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}' + LDFLAGS="-Wl,-export-dynamic" + ;; + esac + case "$arch" in + vax) + CFLAGS_OPTIMIZE="-O1" + ;; + *) + CFLAGS_OPTIMIZE="-O2" + ;; + esac AS_IF([test "${TCL_THREADS}" = "1"], [ - # OpenBSD builds and links with -pthread, never -lpthread. + # On OpenBSD: Compile with -pthread + # Don't link with -lpthread LIBS=`echo $LIBS | sed s/-lpthread//` CFLAGS="$CFLAGS -pthread" - SHLIB_CFLAGS="$SHLIB_CFLAGS -pthread" ]) # OpenBSD doesn't do version numbers with dots. UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' TCL_LIB_VERSIONS_OK=nodots ;; - NetBSD-*|FreeBSD-[[3-4]].*) - # FreeBSD 3.* and greater have ELF. - # NetBSD 2.* has ELF and can use 'cc -shared' to build shared libs + NetBSD-*) + # NetBSD has ELF and can use 'cc -shared' to build shared libs SHLIB_CFLAGS="-fPIC" SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}' SHLIB_SUFFIX=".so" @@ -1618,32 +1635,24 @@ dnl AC_CHECK_TOOL(AR, ar) CFLAGS="$CFLAGS -pthread" LDFLAGS="$LDFLAGS -pthread" ]) - case $system in - FreeBSD-3.*) - # FreeBSD-3 doesn't handle version numbers with dots. - UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' - SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so' - TCL_LIB_VERSIONS_OK=nodots - ;; - esac ;; FreeBSD-*) # This configuration from FreeBSD Ports. SHLIB_CFLAGS="-fPIC" SHLIB_LD="${CC} -shared" - TCL_SHLIB_LD_EXTRAS="-soname \$[@]" + TCL_SHLIB_LD_EXTRAS="-Wl,-soname=\$[@]" SHLIB_SUFFIX=".so" LDFLAGS="" AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' - LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}']) + LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}']) AS_IF([test "${TCL_THREADS}" = "1"], [ # The -pthread needs to go in the LDFLAGS, not LIBS LIBS=`echo $LIBS | sed s/-pthread//` CFLAGS="$CFLAGS $PTHREAD_CFLAGS" LDFLAGS="$LDFLAGS $PTHREAD_LIBS"]) # Version numbers are dot-stripped by system policy. - TCL_TRIM_DOTS=`echo ${VERSION} | tr -d .` + TCL_TRIM_DOTS=`echo ${PACKAGE_VERSION} | tr -d .` UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}\$\{DBGX\}.so.1' TCL_LIB_VERSIONS_OK=nodots @@ -1705,7 +1714,7 @@ dnl AC_CHECK_TOOL(AR, ar) AS_IF([test $tcl_cv_ld_single_module = yes], [ SHLIB_LD="${SHLIB_LD} -Wl,-single_module" ]) - # TEA specific: link shlib with current and compatiblity version flags + # TEA specific: link shlib with current and compatibility version flags vers=`echo ${PACKAGE_VERSION} | sed -e 's/^\([[0-9]]\{1,5\}\)\(\(\.[[0-9]]\{1,3\}\)\{0,2\}\).*$/\1\2/p' -e d` SHLIB_LD="${SHLIB_LD} -current_version ${vers:-0} -compatibility_version ${vers:-0}" SHLIB_SUFFIX=".dylib" @@ -1941,6 +1950,24 @@ dnl AC_CHECK_TOOL(AR, ar) LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}' ]) ;; + UNIX_SV* | UnixWare-5*) + SHLIB_CFLAGS="-KPIC" + SHLIB_LD='${CC} -G' + SHLIB_LD_LIBS="" + SHLIB_SUFFIX=".so" + # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers + # that don't grok the -Bexport option. Test that it does. + AC_CACHE_CHECK([for ld accepts -Bexport flag], tcl_cv_ld_Bexport, [ + hold_ldflags=$LDFLAGS + LDFLAGS="$LDFLAGS -Wl,-Bexport" + AC_TRY_LINK(, [int i;], tcl_cv_ld_Bexport=yes, tcl_cv_ld_Bexport=no) + LDFLAGS=$hold_ldflags]) + AS_IF([test $tcl_cv_ld_Bexport = yes], [ + LDFLAGS="$LDFLAGS -Wl,-Bexport" + ]) + CC_SEARCH_FLAGS="" + LD_SEARCH_FLAGS="" + ;; esac AS_IF([test "$do64bit" = yes -a "$do64bit_ok" = no], [ @@ -1965,7 +1992,7 @@ dnl # preprocessing tests use only CPPFLAGS. case $system in AIX-*) ;; BSD/OS*) ;; - CYGWIN_*) ;; + CYGWIN_*|MINGW32_*) ;; IRIX*) ;; NetBSD-*|FreeBSD-*|OpenBSD-*) ;; Darwin-*) ;; @@ -1977,15 +2004,109 @@ dnl # preprocessing tests use only CPPFLAGS. AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [ AC_DEFINE(MODULE_SCOPE, [extern], [No Compiler support for module scope symbols]) - AC_DEFINE(NO_VIZ) ]) AS_IF([test "$SHARED_LIB_SUFFIX" = ""], [ - # TEA specific: use PACKAGE_VERSION instead of VERSION - SHARED_LIB_SUFFIX='${PACKAGE_VERSION}${SHLIB_SUFFIX}']) + # TEA specific: use PACKAGE_VERSION instead of VERSION + SHARED_LIB_SUFFIX='${PACKAGE_VERSION}${SHLIB_SUFFIX}']) AS_IF([test "$UNSHARED_LIB_SUFFIX" = ""], [ - # TEA specific: use PACKAGE_VERSION instead of VERSION - UNSHARED_LIB_SUFFIX='${PACKAGE_VERSION}.a']) + # TEA specific: use PACKAGE_VERSION instead of VERSION + UNSHARED_LIB_SUFFIX='${PACKAGE_VERSION}.a']) + + if test "${GCC}" = "yes" -a ${SHLIB_SUFFIX} = ".dll"; then + AC_CACHE_CHECK(for SEH support in compiler, + tcl_cv_seh, + AC_TRY_RUN([ +#define WIN32_LEAN_AND_MEAN +#include +#undef WIN32_LEAN_AND_MEAN + + int main(int argc, char** argv) { + int a, b = 0; + __try { + a = 666 / b; + } + __except (EXCEPTION_EXECUTE_HANDLER) { + return 0; + } + return 1; + } + ], + tcl_cv_seh=yes, + tcl_cv_seh=no, + tcl_cv_seh=no) + ) + if test "$tcl_cv_seh" = "no" ; then + AC_DEFINE(HAVE_NO_SEH, 1, + [Defined when mingw does not support SEH]) + fi + + # + # Check to see if the excpt.h include file provided contains the + # definition for EXCEPTION_DISPOSITION; if not, which is the case + # with Cygwin's version as of 2002-04-10, define it to be int, + # sufficient for getting the current code to work. + # + AC_CACHE_CHECK(for EXCEPTION_DISPOSITION support in include files, + tcl_cv_eh_disposition, + AC_TRY_COMPILE([ +# define WIN32_LEAN_AND_MEAN +# include +# undef WIN32_LEAN_AND_MEAN + ],[ + EXCEPTION_DISPOSITION x; + ], + tcl_cv_eh_disposition=yes, + tcl_cv_eh_disposition=no) + ) + if test "$tcl_cv_eh_disposition" = "no" ; then + AC_DEFINE(EXCEPTION_DISPOSITION, int, + [Defined when cygwin/mingw does not support EXCEPTION DISPOSITION]) + fi + + # Check to see if winnt.h defines CHAR, SHORT, and LONG + # even if VOID has already been #defined. The win32api + # used by mingw and cygwin is known to do this. + + AC_CACHE_CHECK(for winnt.h that ignores VOID define, + tcl_cv_winnt_ignore_void, + AC_TRY_COMPILE([ +#define VOID void +#define WIN32_LEAN_AND_MEAN +#include +#undef WIN32_LEAN_AND_MEAN + ], [ + CHAR c; + SHORT s; + LONG l; + ], + tcl_cv_winnt_ignore_void=yes, + tcl_cv_winnt_ignore_void=no) + ) + if test "$tcl_cv_winnt_ignore_void" = "yes" ; then + AC_DEFINE(HAVE_WINNT_IGNORE_VOID, 1, + [Defined when cygwin/mingw ignores VOID define in winnt.h]) + fi + fi + + # See if the compiler supports casting to a union type. + # This is used to stop gcc from printing a compiler + # warning when initializing a union member. + + AC_CACHE_CHECK(for cast to union support, + tcl_cv_cast_to_union, + AC_TRY_COMPILE([], + [ + union foo { int i; double d; }; + union foo f = (union foo) (int) 0; + ], + tcl_cv_cast_to_union=yes, + tcl_cv_cast_to_union=no) + ) + if test "$tcl_cv_cast_to_union" = "yes"; then + AC_DEFINE(HAVE_CAST_TO_UNION, 1, + [Defined when compiler supports casting to union type.]) + fi AC_SUBST(CFLAGS_DEBUG) AC_SUBST(CFLAGS_OPTIMIZE) @@ -2024,7 +2145,6 @@ dnl # preprocessing tests use only CPPFLAGS. # USE_TERMIOS # USE_TERMIO # USE_SGTTY -# #-------------------------------------------------------------------- AC_DEFUN([TEA_SERIAL_PORT], [ @@ -2236,7 +2356,6 @@ closedir(d); # XINCLUDES # XLIBSW # PKG_LIBS (appends to) -# #-------------------------------------------------------------------- AC_DEFUN([TEA_PATH_X], [ @@ -2250,9 +2369,9 @@ AC_DEFUN([TEA_PATH_UNIX_X], [ not_really_there="" if test "$no_x" = ""; then if test "$x_includes" = ""; then - AC_TRY_CPP([#include ], , not_really_there="yes") + AC_TRY_CPP([#include ], , not_really_there="yes") else - if test ! -r $x_includes/X11/Intrinsic.h; then + if test ! -r $x_includes/X11/Xlib.h; then not_really_there="yes" fi fi @@ -2260,11 +2379,11 @@ AC_DEFUN([TEA_PATH_UNIX_X], [ if test "$no_x" = "yes" -o "$not_really_there" = "yes"; then AC_MSG_CHECKING([for X11 header files]) found_xincludes="no" - AC_TRY_CPP([#include ], found_xincludes="yes", found_xincludes="no") + AC_TRY_CPP([#include ], found_xincludes="yes", found_xincludes="no") if test "$found_xincludes" = "no"; then dirs="/usr/unsupported/include /usr/local/include /usr/X386/include /usr/X11R6/include /usr/X11R5/include /usr/include/X11R5 /usr/include/X11R4 /usr/openwin/include /usr/X11/include /usr/sww/include" for i in $dirs ; do - if test -r $i/X11/Intrinsic.h; then + if test -r $i/X11/Xlib.h; then AC_MSG_RESULT([$i]) XINCLUDES=" -I$i" found_xincludes="yes" @@ -2332,7 +2451,6 @@ AC_DEFUN([TEA_PATH_UNIX_X], [ # HAVE_SYS_FILIO_H # USE_FIONBIO # O_NONBLOCK -# #-------------------------------------------------------------------- AC_DEFUN([TEA_BLOCKING_STYLE], [ @@ -2367,7 +2485,6 @@ AC_DEFUN([TEA_BLOCKING_STYLE], [ # HAVE_TM_GMTOFF # HAVE_TM_TZADJ # HAVE_TIMEZONE_VAR -# #-------------------------------------------------------------------- AC_DEFUN([TEA_TIME_HANDLER], [ @@ -2436,7 +2553,6 @@ AC_DEFUN([TEA_TIME_HANDLER], [ # # Might defines some of the following vars: # strtod (=fixstrtod) -# #-------------------------------------------------------------------- AC_DEFUN([TEA_BUGGY_STRTOD], [ @@ -2487,7 +2603,7 @@ AC_DEFUN([TEA_BUGGY_STRTOD], [ # # Results: # -# Subst's the following var: +# Substitutes the following vars: # TCL_LIBS # MATH_LIBS # @@ -2496,7 +2612,6 @@ AC_DEFUN([TEA_BUGGY_STRTOD], [ # # Might define the following vars: # HAVE_NET_ERRNO_H -# #-------------------------------------------------------------------- AC_DEFUN([TEA_TCL_LINK_LIBS], [ @@ -2574,7 +2689,6 @@ AC_DEFUN([TEA_TCL_LINK_LIBS], [ # _ISOC99_SOURCE # _LARGEFILE64_SOURCE # _LARGEFILE_SOURCE64 -# #-------------------------------------------------------------------- AC_DEFUN([TEA_TCL_EARLY_FLAG],[ @@ -2622,7 +2736,6 @@ AC_DEFUN([TEA_TCL_EARLY_FLAGS],[ # HAVE_STRUCT_DIRENT64 # HAVE_STRUCT_STAT64 # HAVE_TYPE_OFF64_T -# #-------------------------------------------------------------------- AC_DEFUN([TEA_TCL_64BIT_FLAGS], [ @@ -2654,7 +2767,7 @@ AC_DEFUN([TEA_TCL_64BIT_FLAGS], [ # Now check for auxiliary declarations AC_CACHE_CHECK([for struct dirent64], tcl_cv_struct_dirent64,[ AC_TRY_COMPILE([#include -#include ],[struct dirent64 p;], +#include ],[struct dirent64 p;], tcl_cv_struct_dirent64=yes,tcl_cv_struct_dirent64=no)]) if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then AC_DEFINE(HAVE_STRUCT_DIRENT64, 1, [Is 'struct dirent64' in ?]) @@ -2739,6 +2852,13 @@ TEA version not specified.]) else AC_MSG_RESULT([ok (TEA ${TEA_VERSION})]) fi + + # If the user did not set CFLAGS, set it now to keep macros + # like AC_PROG_CC and AC_TRY_COMPILE from adding "-g -O2". + if test "${CFLAGS+set}" != "set" ; then + CFLAGS="" + fi + case "`uname -s`" in *win32*|*WIN32*|*MINGW32_*) AC_CHECK_PROG(CYGPATH, cygpath, cygpath -w, echo) @@ -2752,8 +2872,17 @@ TEA version not specified.]) ;; *) CYGPATH=echo - EXEEXT="" - TEA_PLATFORM="unix" + # Maybe we are cross-compiling.... + case ${host_alias} in + *mingw32*) + EXEEXT=".exe" + TEA_PLATFORM="windows" + ;; + *) + EXEEXT="" + TEA_PLATFORM="unix" + ;; + esac ;; esac @@ -2766,6 +2895,8 @@ TEA version not specified.]) exec_prefix=$prefix fi + AC_MSG_NOTICE([configuring ${PACKAGE_NAME} ${PACKAGE_VERSION}]) + AC_SUBST(EXEEXT) AC_SUBST(CYGPATH) @@ -3001,6 +3132,22 @@ AC_DEFUN([TEA_ADD_CFLAGS], [ AC_SUBST(PKG_CFLAGS) ]) +#------------------------------------------------------------------------ +# TEA_ADD_CLEANFILES -- +# +# Specify one or more CLEANFILES. +# +# Arguments: +# one or more file names to clean target +# +# Results: +# +# Appends to CLEANFILES, already defined for subst in LOAD_TCLCONFIG +#------------------------------------------------------------------------ +AC_DEFUN([TEA_ADD_CLEANFILES], [ + CLEANFILES="$CLEANFILES $@" +]) + #------------------------------------------------------------------------ # TEA_PREFIX -- # @@ -3055,16 +3202,17 @@ AC_DEFUN([TEA_SETUP_COMPILER_CC], [ # Don't put any macros that use the compiler (e.g. AC_TRY_COMPILE) # in this macro, they need to go into TEA_SETUP_COMPILER instead. - # If the user did not set CFLAGS, set it now to keep - # the AC_PROG_CC macro from adding "-g -O2". - if test "${CFLAGS+set}" != "set" ; then - CFLAGS="" - fi - AC_PROG_CC AC_PROG_CPP - AC_PROG_INSTALL + INSTALL="\$(SHELL) \$(srcdir)/tclconfig/install-sh -c" + AC_SUBST(INSTALL) + INSTALL_DATA="\${INSTALL} -m 644" + AC_SUBST(INSTALL_DATA) + INSTALL_PROGRAM="\${INSTALL}" + AC_SUBST(INSTALL_PROGRAM) + INSTALL_SCRIPT="\${INSTALL}" + AC_SUBST(INSTALL_SCRIPT) #-------------------------------------------------------------------- # Checks to see if the make program sets the $MAKE variable. @@ -3076,7 +3224,7 @@ AC_DEFUN([TEA_SETUP_COMPILER_CC], [ # Find ranlib #-------------------------------------------------------------------- - AC_PROG_RANLIB + AC_CHECK_TOOL(RANLIB, ranlib) #-------------------------------------------------------------------- # Determines the correct binary file extension (.o, .obj, .exe etc.) @@ -3155,13 +3303,26 @@ AC_DEFUN([TEA_SETUP_COMPILER], [ # MAKE_SHARED_LIB Makefile rule for building a shared library # MAKE_STATIC_LIB Makefile rule for building a static library # MAKE_STUB_LIB Makefile rule for building a stub library +# VC_MANIFEST_EMBED_DLL Makefile rule for embedded VC manifest in DLL +# VC_MANIFEST_EMBED_EXE Makefile rule for embedded VC manifest in EXE #------------------------------------------------------------------------ AC_DEFUN([TEA_MAKE_LIB], [ if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes"; then MAKE_STATIC_LIB="\${STLIB_LD} -out:\[$]@ \$(PKG_OBJECTS)" MAKE_SHARED_LIB="\${SHLIB_LD} \${SHLIB_LD_LIBS} \${LDFLAGS_DEFAULT} -out:\[$]@ \$(PKG_OBJECTS)" - MAKE_STUB_LIB="\${STLIB_LD} -out:\[$]@ \$(PKG_STUB_OBJECTS)" + AC_EGREP_CPP([manifest needed], [ +#if defined(_MSC_VER) && _MSC_VER >= 1400 +print("manifest needed") +#endif + ], [ + # Could do a CHECK_PROG for mt, but should always be with MSVC8+ + VC_MANIFEST_EMBED_DLL="if test -f \[$]@.manifest ; then mt.exe -nologo -manifest \[$]@.manifest -outputresource:\[$]@\;2 ; fi" + VC_MANIFEST_EMBED_EXE="if test -f \[$]@.manifest ; then mt.exe -nologo -manifest \[$]@.manifest -outputresource:\[$]@\;1 ; fi" + MAKE_SHARED_LIB="${MAKE_SHARED_LIB} ; ${VC_MANIFEST_EMBED_DLL}" + TEA_ADD_CLEANFILES([*.manifest]) + ]) + MAKE_STUB_LIB="\${STLIB_LD} -nodefaultlib -out:\[$]@ \$(PKG_STUB_OBJECTS)" else MAKE_STATIC_LIB="\${STLIB_LD} \[$]@ \$(PKG_OBJECTS)" MAKE_SHARED_LIB="\${SHLIB_LD} -o \[$]@ \$(PKG_OBJECTS) \${SHLIB_LD_LIBS}" @@ -3184,13 +3345,19 @@ AC_DEFUN([TEA_MAKE_LIB], [ if test "${SHARED_BUILD}" = "1" ; then # We force the unresolved linking of symbols that are really in # the private libraries of Tcl and Tk. - SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}`\"" if test x"${TK_BIN_DIR}" != x ; then SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TK_BIN_DIR}/${TK_STUB_LIB_FILE}`\"" fi + SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}`\"" + if test "$GCC" = "yes"; then + SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -static-libgcc" + fi eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${SHARED_LIB_SUFFIX}" else eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}" + if test "$GCC" = "yes"; then + PKG_LIB_FILE=lib${PKG_LIB_FILE} + fi fi # Some packages build their own stubs libraries eval eval "PKG_STUB_LIB_FILE=${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}" @@ -3228,6 +3395,8 @@ AC_DEFUN([TEA_MAKE_LIB], [ AC_SUBST(MAKE_STATIC_LIB) AC_SUBST(MAKE_STUB_LIB) AC_SUBST(RANLIB_STUB) + AC_SUBST(VC_MANIFEST_EMBED_DLL) + AC_SUBST(VC_MANIFEST_EMBED_EXE) ]) #------------------------------------------------------------------------ @@ -3316,7 +3485,7 @@ AC_DEFUN([TEA_LIB_SPEC], [ # # Results: # -# Substs the following vars: +# Substitutes the following vars: # TCL_TOP_DIR_NATIVE # TCL_INCLUDES #------------------------------------------------------------------------ @@ -3394,7 +3563,7 @@ AC_DEFUN([TEA_PRIVATE_TCL_HEADERS], [ # Adds a --with-tclinclude switch to configure. # Result is cached. # -# Substs the following vars: +# Substitutes the following vars: # TCL_INCLUDES #------------------------------------------------------------------------ @@ -3484,7 +3653,7 @@ AC_DEFUN([TEA_PUBLIC_TCL_HEADERS], [ # # Results: # -# Substs the following vars: +# Substitutes the following vars: # TK_INCLUDES #------------------------------------------------------------------------ @@ -3573,7 +3742,7 @@ AC_DEFUN([TEA_PRIVATE_TK_HEADERS], [ # Adds a --with-tkinclude switch to configure. # Result is cached. # -# Substs the following vars: +# Substitutes the following vars: # TK_INCLUDES #------------------------------------------------------------------------ @@ -3791,11 +3960,10 @@ AC_DEFUN([TEA_PATH_CONFIG], [ # # Results: # -# Subst the following vars: +# Substitutes the following vars: # $1_SRC_DIR # $1_LIB_FILE # $1_LIB_SPEC -# #------------------------------------------------------------------------ AC_DEFUN([TEA_LOAD_CONFIG], [ @@ -3822,6 +3990,8 @@ AC_DEFUN([TEA_LOAD_CONFIG], [ $1_LIB_SPEC=${$1_BUILD_LIB_SPEC} $1_STUB_LIB_SPEC=${$1_BUILD_STUB_LIB_SPEC} $1_STUB_LIB_PATH=${$1_BUILD_STUB_LIB_PATH} + $1_INCLUDE_SPEC=${$1_BUILD_INCLUDE_SPEC} + $1_LIBRARY_PATH=${$1_LIBRARY_PATH} fi AC_SUBST($1_VERSION) @@ -3854,7 +4024,6 @@ AC_DEFUN([TEA_LOAD_CONFIG], [ # # Results: # Adds to LIBS the appropriate extension library -# #------------------------------------------------------------------------ AC_DEFUN([TEA_LOAD_CONFIG_LIB], [ AC_MSG_CHECKING([For $1 library for LIBS]) @@ -3886,11 +4055,10 @@ AC_DEFUN([TEA_LOAD_CONFIG_LIB], [ # $1 # # Results: -# Subst the following vars: -# +# Substitutes the following vars: #------------------------------------------------------------------------ -AC_DEFUN(TEA_EXPORT_CONFIG, [ +AC_DEFUN([TEA_EXPORT_CONFIG], [ #-------------------------------------------------------------------- # These are for $1Config.sh #-------------------------------------------------------------------- diff --git a/manifest b/manifest index e344356edb..821fec76d7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\ssimplifications\sto\sthe\s"zeroPage()"\sroutine\sin\sbtree.c. -D 2014-02-12T23:52:16.136 +C Update\sthe\stclconfig\sfiles\sto\sthe\slatest\sfrom\shttp://core.tcl.tk/tclconfig. +D 2014-02-13T13:42:43.442 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -30,8 +30,8 @@ F autoconf/tea/configure.in e0466b881b53f31f5a4a69e7a91ad130902fb359 F autoconf/tea/doc/sqlite3.n e1fe45d4f5286ee3d0ccc877aca2a0def488e9bb F autoconf/tea/license.terms 13bd403c9610fd2b76ece0ab50c4c5eda933d523 F autoconf/tea/pkgIndex.tcl.in 3ef61715cf1c7bdcff56947ffadb26bc991ca39d -F autoconf/tea/tclconfig/install-sh b087e5c4b92820c60bffb74acc1d9c2d40d80b8f -F autoconf/tea/tclconfig/tcl.m4 a68179d7cc45524fa59db428a36610e20bdba808 +F autoconf/tea/tclconfig/install-sh bdd5e293591621ae60d9824d86a4b1c5f22c3d00 +F autoconf/tea/tclconfig/tcl.m4 f035b86539a5ab30689e997a11ae9e7fd2e65570 F autoconf/tea/win/makefile.vc f89d0184d0eee5f7e356ea407964dcd139939928 F autoconf/tea/win/nmakehlp.c 2070e086f39866b353a482d3a14dedaf26196506 F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63 @@ -1153,7 +1153,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 56bc5ce8958c8e6250531b4052b905d7ac993db3 -R 08bd4c102c2d08f0774c76e162878c69 +P cc8f10bcb206c9def69b06f26decf025b8d9119d +R 5827f3fddcd143de0504e7bdcdecb65f U drh -Z ed630d5c913dd5b0515f56c704c7877e +Z 978280b213079b27efd56c6d39f0432f diff --git a/manifest.uuid b/manifest.uuid index 2af58e32b8..12ee7ec0ac 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cc8f10bcb206c9def69b06f26decf025b8d9119d \ No newline at end of file +b81ba7a4bc7e840fce25fc6801957a64f877ff60 \ No newline at end of file From e5b6ea797ea935d0ae245d8ac29613e9ab7972ea Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 13 Feb 2014 18:46:59 +0000 Subject: [PATCH 254/276] Avoid passing a flags argument with the internal WAL_SYNC_TRANSACTIONS bit set when calling sqlite3OsSync(). FossilOrigin-Name: e3b79e920c298a39613631d689d1a2f182d00496 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/wal.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 821fec76d7..574e8a65cb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sthe\stclconfig\sfiles\sto\sthe\slatest\sfrom\shttp://core.tcl.tk/tclconfig. -D 2014-02-13T13:42:43.442 +C Avoid\spassing\sa\sflags\sargument\swith\sthe\sinternal\sWAL_SYNC_TRANSACTIONS\sbit\sset\swhen\scalling\ssqlite3OsSync(). +D 2014-02-13T18:46:59.101 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -290,7 +290,7 @@ F src/vdbemem.c 06603e8e9d2f3247b68c6bbe4bd37fb6721b5bda F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147 F src/vdbetrace.c 6f52bc0c51e144b7efdcfb2a8f771167a8816767 F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd -F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 +F src/wal.c d89e386ead8ecfc823b6162b09e1ada0623df37a F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45 F src/where.c b0436385f40e86f0f4cc60355cd018bde2c89d4b @@ -1153,7 +1153,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P cc8f10bcb206c9def69b06f26decf025b8d9119d -R 5827f3fddcd143de0504e7bdcdecb65f -U drh -Z 978280b213079b27efd56c6d39f0432f +P b81ba7a4bc7e840fce25fc6801957a64f877ff60 +R a59cd87bb88fdc66ea1a7d77759b0c27 +U dan +Z 4fedb8574b1ff1640e605452066ee2b1 diff --git a/manifest.uuid b/manifest.uuid index 12ee7ec0ac..8a95093ecf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b81ba7a4bc7e840fce25fc6801957a64f877ff60 \ No newline at end of file +e3b79e920c298a39613631d689d1a2f182d00496 \ No newline at end of file diff --git a/src/wal.c b/src/wal.c index f413920648..c2c3d369c1 100644 --- a/src/wal.c +++ b/src/wal.c @@ -2677,7 +2677,7 @@ static int walWriteToLog( iAmt -= iFirstAmt; pContent = (void*)(iFirstAmt + (char*)pContent); assert( p->syncFlags & (SQLITE_SYNC_NORMAL|SQLITE_SYNC_FULL) ); - rc = sqlite3OsSync(p->pFd, p->syncFlags); + rc = sqlite3OsSync(p->pFd, p->syncFlags & SQLITE_SYNC_MASK); if( iAmt==0 || rc ) return rc; } rc = sqlite3OsWrite(p->pFd, pContent, iAmt, iOffset); From 56e3767eb4776be108d0441c010c84787c38026a Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 13 Feb 2014 19:10:24 +0000 Subject: [PATCH 255/276] Change README to README.md and expand it. Remove unrelated and obsolete files. FossilOrigin-Name: 18d4e258c45c32984b23d97b896a761eeef2dbdf --- README | 39 ---------- README.md | 192 ++++++++++++++++++++++++++++++++++++++++++++++++++ manifest | 17 ++--- manifest.uuid | 2 +- mkdll.sh | 49 ------------- mkextu.sh | 13 ---- mkextw.sh | 22 ------ 7 files changed, 200 insertions(+), 134 deletions(-) delete mode 100644 README create mode 100644 README.md delete mode 100644 mkdll.sh delete mode 100644 mkextu.sh delete mode 100644 mkextw.sh diff --git a/README b/README deleted file mode 100644 index 0d65e518f9..0000000000 --- a/README +++ /dev/null @@ -1,39 +0,0 @@ -This directory contains source code to - - SQLite: An Embeddable SQL Database Engine - -To compile the project, first create a directory in which to place -the build products. It is recommended, but not required, that the -build directory be separate from the source directory. Cd into the -build directory and then from the build directory run the configure -script found at the root of the source tree. Then run "make". - -For example: - - tar xzf sqlite.tar.gz ;# Unpack the source tree into "sqlite" - mkdir bld ;# Build will occur in a sibling directory - cd bld ;# Change to the build directory - ../sqlite/configure ;# Run the configure script - make ;# Run the makefile. - make install ;# (Optional) Install the build products - -The configure script uses autoconf 2.61 and libtool. If the configure -script does not work out for you, there is a generic makefile named -"Makefile.linux-gcc" in the top directory of the source tree that you -can copy and edit to suit your needs. Comments on the generic makefile -show what changes are needed. - -The linux binaries on the website are created using the generic makefile, -not the configure script. The windows binaries on the website are created -using MinGW32 configured as a cross-compiler running under Linux. For -details, see the ./publish.sh script at the top-level of the source tree. -The developers do not use teh configure script. - -SQLite does not require TCL to run, but a TCL installation is required -by the makefiles. SQLite contains a lot of generated code and TCL is -used to do much of that code generation. The makefile also requires -AWK. - -Contacts: - - http://www.sqlite.org/ diff --git a/README.md b/README.md new file mode 100644 index 0000000000..d8042cee45 --- /dev/null +++ b/README.md @@ -0,0 +1,192 @@ +

    SQLite Source Repository

    + +This repository contains the complete source code for the SQLite database +engine. Some test scripts are also include. However, many other test scripts +and most of the documentation are managed separately. + +## Compiling + +First create a directory in which to place +the build products. It is recommended, but not required, that the +build directory be separate from the source directory. Cd into the +build directory and then from the build directory run the configure +script found at the root of the source tree. Then run "make". + +For example: + + tar xzf sqlite.tar.gz ;# Unpack the source tree into "sqlite" + mkdir bld ;# Build will occur in a sibling directory + cd bld ;# Change to the build directory + ../sqlite/configure ;# Run the configure script + make ;# Run the makefile. + make sqlite3.c ;# Build the "amalgamation" source file + make test ;# Run some tests (requires TCL) + +See the makefile for additional targets. + +The configure script uses autoconf 2.61 and libtool. If the configure +script does not work out for you, there is a generic makefile named +"Makefile.linux-gcc" in the top directory of the source tree that you +can copy and edit to suit your needs. Comments on the generic makefile +show what changes are needed. + +SQLite does not require TCL to run, but a TCL installation is required +by the makefiles. SQLite contains a lot of generated code and TCL is +used to do much of that code generation. The makefile also requires +AWK. + +## Source Code Tour + +Most of the core source files are in the **src/** subdirectory. But +src/ also contains files used to build the "testfixture" test harness; +those file all begin with "test". And src/ contains the "shell.c" file +which is the main program for the "sqlite3.exe" command-line shell and +the "tclsqlite.c" file which implements the bindings to SQLite from the +TCL programming language. (Historical note: SQLite began as a TCL +extension and only later escaped to the wild as an independent library.) + +Test scripts and programs are found in the **test/** subdirectory. +There are other test suites for SQLite (see +[How SQLite Is Tested](http://www.sqlite.org/testing.html)) +but those other test suites are +in separate source repositories. + +The **ext/** subdirectory contains code for extensions. The +Full-text search engine is in **ext/fts3**. The R-Tree engine is in +**ext/rtree**. The **ext/misc** subdirectory contains a number of +smaller, single-file extensions, such as a REGEXP operator. + +The **tool/** subdirectory contains various scripts and programs used +for building generated source code files or for testing or for generating +accessory programs such as "sqlite3_analyzer(.exe)". + +### Generated Source Code Files + +Several of the C-language source files used by SQLite are generated from +other sources rather than being typed in manually by a programmer. This +section will summarize those automatically-generated files. To create all +of the automatically-generated files, simply run "make target_source". +The "target_source" make target will create a subdirectory "tsrc/" and +fill it with all the source files needed to build SQLite, both +manually-edited files and automatically-generated files. + +The SQLite interface is defined by the **sqlite3.h** header file, which is +generated from src/sqlite.h.in, ./manifest.uuid, and ./VERSION. The +TCL script at tool/mksqlite3h.tcl does the conversion. The manifest.uuid +file contains the SHA1 hash of the particular check-in and is used to generate +the SQLITE_SOURCE_ID macro. The VERSION file contains the current SQLite +version number. The sqlite3.h header is really just a copy of src/sqlite.h.in +with the source-id and version number inserted at just the right spots. +Note that comment text in the sqlite3.h file is used to generate much of +the SQLite API documentation. The TCL scripts used to generate that +documentation are in a separate source repository. + +The SQL language parser is **parse.c** which is generate from a grammar in +the src/parse.y file. The conversion of "parse.y" into "parse.c" is done +by the [lemon](./doc/lemon.html) LALR(1) parser generator. The source code +for lemon is at tool/lemon.c. Lemon uses a +template for generating its parser. A generic template is in tool/lempar.c, +but SQLite uses a slightly modified template found in src/lempar.c. + +Lemon also generates the **parse.h** header file, at the same time it +generates parse.c. But the parse.h header file is +modified further (to add additional symbols) using the ./addopcodes.awk +AWK script. + +The **opcodes.h** header file contains macros that define the numbers +corresponding to opcodes in the "VDBE" virtual machine. The opcodes.h +file is generated by the scanning the src/vdbe.c source file. The +AWK script at ./mkopcodeh.awk does this scan and generates opcodes.h. +A second AWK script, ./mkopcodec.awk, then scans opcodes.h to generate +the **opcodes.c** source file, which contains a reverse mapping from +opcode-number to opcode-name that is used for EXPLAIN output. + +The **keywordhash.h** header file contains the definition of a hash table +that maps SQL language keywords (ex: "CREATE", "SELECT", "INDEX", etc.) into +the numeric codes used by the parse.c parser. The keywordhash.h file is +generated by a C-language program at tool mkkeywordhash.c. + +### The Amalgamation + +All of the individual C source code and header files (both manually-edited +and automatically-generated) can be combined into a single big source file +**sqlite3.c** called "the amalgamation". The amalgamation is the recommended +way of using SQLite in a larger application. Combining all individual +source code files into a single big source code file allows the C compiler +to perform more cross-procedure analysis and generate better code. SQLite +runs about 5% faster when compiled from the amalgamation versus when compiled +from individual source files. + +The amalgamation is generated from the tool/mksqlite3c.tcl TCL script. +First, all of the individual source files must be gathered into the tsrc/ +subdirectory (using the equivalent of "make target_source") then the +tool/mksqlite3c.tcl script is run to copy them all together in just the +right order while resolving internal "#include" references. + +The amalgamation source file is more than 100K lines long. Some symbolic +debuggers (most notably MSVC) are unable to deal with files longer than 64K +lines. To work around this, a separate TCL script, tool/split-sqlite3c.tcl, +can be run on the amalgamation to break it up into a single small C file +called **sqlite3-all.c** that does #include on about five other files +named **sqlite3-1.c**, **sqlite3-2.c**, ..., **sqlite3-5.c**. In this way, +all of the source code is contained within a single translation unit so +that the compiler can do extra cross-procedure optimization, but no +individual source file exceeds 32K lines in length. + +## How It All Fits Together + +SQLite is modular in design. +See the [architectural description](http://www.sqlite.org/arch.html) +for details. Other documents that are useful in +(helping to understand how SQLite works include the +[file format](http://www.sqlite.org/fileformat2.html) description, +the [virtual machine](http://www.sqlite.org/vdbe.html) that runs +prepared statements, the description of +[how transactions work](http://www.sqlite.org/atomiccommit.html), and +the [overview of the query planner](http://www.sqlite.org/optoverview.html). + +Unfortunately, years of effort have gone into optimizating SQLite, both +for small size and high performance. And optimizations tend to result in +complex code. So there is a lot of complexity in the SQLite implementation. + +Key files: + + * **sqlite3.h** - This file defines the public interface to the SQLite + library. Readers will need to be familiar with this interface before + trying to understand how the library works internally. + + * **sqliteInt.h** - this header file defines many of the data objects + used internally by SQLite. + + * **parse.y** - This file describes the LALR(1) grammer that SQLite uses + to parse SQL statements, and the actions that are taken at each stop + in the parsing process. + + * **vdbe.c** - This file implements the virtual machine that runs + prepared statements. There are various helper files whose names + begin with "vdbe". The VDBE has access to the vdbeInt.h header file + which defines internal data objects. The rest of SQLite interacts + with the VDBE through an interface defined by vdbe.h. + + * **where.c** - This file analyzes the WHERE clause and generates + virtual machine code to run queries efficiently. This file is + sometimes called the "query optimizer". It has its own private + header file, whereInt.h, that defines data objects used internally. + + * **btree.c** - This file contains the implementation of the B-Tree + storage engine used by SQLite. + + * **pager.c** - This file contains the "pager" implementation, the + module that implements transactions. + + * **os_unix.c** and **os_win.c** - These two files implement the interface + between SQLite and the underlying operating system using the run-time + pluggable VFS interface. + + +## Contacts + +The main SQLite webpage is [http://www.sqlite.org/](http://www.sqlite.org/) +with geographically distributed backup servers at +[http://www2.sqlite.org/](http://www2.sqlite.org) and +[http://www3.sqlite.org/](http://www3.sqlite.org). diff --git a/manifest b/manifest index 574e8a65cb..be8118db4b 100644 --- a/manifest +++ b/manifest @@ -1,11 +1,11 @@ -C Avoid\spassing\sa\sflags\sargument\swith\sthe\sinternal\sWAL_SYNC_TRANSACTIONS\sbit\sset\swhen\scalling\ssqlite3OsSync(). -D 2014-02-13T18:46:59.101 +C Change\sREADME\sto\sREADME.md\sand\sexpand\sit.\s\sRemove\sunrelated\sand\sobsolete\sfiles. +D 2014-02-13T19:10:24.061 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.msc 6ff3ff2eef45c7dd309a8626ff7947b20bd387e7 F Makefile.vxworks db21ed42a01d5740e656b16f92cb5d8d5e5dd315 -F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6 +F README.md 8ff4548af6f7cdf4b02e585d4dd552b233998a9b w README F VERSION 0dc30ad5cf90736d5fd9e540c9f05c542658abe7 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 F addopcodes.awk 9eb448a552d5c0185cf62c463f9c173cedae3811 @@ -143,9 +143,6 @@ F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt f439556c5ce01ced70987e5ee86549a45165d9ff F main.mk 3ae543fa446525c1dec55f58de67f41b78651812 -F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a -F mkextu.sh 416f9b7089d80e5590a29692c9d9280a10dbad9f -F mkextw.sh d2a981497b404d6498f5ff3e3b1f3816bdfcb338 F mkopcodec.awk c2ff431854d702cdd2d779c9c0d1f58fa16fa4ea F mkopcodeh.awk c6b3fa301db6ef7ac916b14c60868aeaec1337b5 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 @@ -1153,7 +1150,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P b81ba7a4bc7e840fce25fc6801957a64f877ff60 -R a59cd87bb88fdc66ea1a7d77759b0c27 -U dan -Z 4fedb8574b1ff1640e605452066ee2b1 +P e3b79e920c298a39613631d689d1a2f182d00496 +R 32cef02970d5145eabe1c7cffe4376d1 +U drh +Z 910a038630fdb9ee9dcf69294f2c5c44 diff --git a/manifest.uuid b/manifest.uuid index 8a95093ecf..540465f61a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e3b79e920c298a39613631d689d1a2f182d00496 \ No newline at end of file +18d4e258c45c32984b23d97b896a761eeef2dbdf \ No newline at end of file diff --git a/mkdll.sh b/mkdll.sh deleted file mode 100644 index 9e368d1d23..0000000000 --- a/mkdll.sh +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/sh -# -# This script is used to compile SQLite into a DLL. -# -# Two separate DLLs are generated. "sqlite3.dll" is the core -# library. "tclsqlite3.dll" contains the TCL bindings and is the -# library that is loaded into TCL in order to run SQLite. -# -make sqlite3.c -PATH=$PATH:/opt/mingw/bin -TCLDIR=/home/drh/tcltk/846/win/846win -TCLSTUBLIB=$TCLDIR/libtcl84stub.a -OPTS='-DUSE_TCL_STUBS=1 -DBUILD_sqlite=1 -DSQLITE_OS_WIN=1' -OPTS="$OPTS -DSQLITE_THREADSAFE=1" -OPTS="$OPTS -DSQLITE_ENABLE_FTS3=1" -OPTS="$OPTS -DSQLITE_ENABLE_RTREE=1" -OPTS="$OPTS -DSQLITE_ENABLE_COLUMN_METADATA=1" -CC="i386-mingw32msvc-gcc -Os $OPTS -Itsrc -I$TCLDIR" -NM="i386-mingw32msvc-nm" -CMD="$CC -c sqlite3.c" -echo $CMD -$CMD -CMD="$CC -c tclsqlite3.c" -echo $CMD -$CMD -echo 'EXPORTS' >tclsqlite3.def -$NM tclsqlite3.o | grep ' T ' >temp1 -grep '_Init$' temp1 >temp2 -grep '_SafeInit$' temp1 >>temp2 -grep ' T _sqlite3_' temp1 >>temp2 -echo 'EXPORTS' >tclsqlite3.def -sed 's/^.* T _//' temp2 | sort | uniq >>tclsqlite3.def -i386-mingw32msvc-dllwrap \ - --def tclsqlite3.def -v --export-all \ - --driver-name i386-mingw32msvc-gcc \ - --dlltool-name i386-mingw32msvc-dlltool \ - --as i386-mingw32msvc-as \ - --target i386-mingw32 \ - -dllname tclsqlite3.dll -lmsvcrt tclsqlite3.o $TCLSTUBLIB -$NM sqlite3.o | grep ' T ' >temp1 -echo 'EXPORTS' >sqlite3.def -grep ' _sqlite3_' temp1 | sed 's/^.* _//' >>sqlite3.def -i386-mingw32msvc-dllwrap \ - --def sqlite3.def -v --export-all \ - --driver-name i386-mingw32msvc-gcc \ - --dlltool-name i386-mingw32msvc-dlltool \ - --as i386-mingw32msvc-as \ - --target i386-mingw32 \ - -dllname sqlite3.dll -lmsvcrt sqlite3.o diff --git a/mkextu.sh b/mkextu.sh deleted file mode 100644 index 1d96897769..0000000000 --- a/mkextu.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh -# -# This script is used to compile SQLite into a shared library on Linux. -# -# Two separate shared libraries are generated. "sqlite3.so" is the core -# library. "tclsqlite3.so" contains the TCL bindings and is the -# library that is loaded into TCL in order to run SQLite. -# -CFLAGS=-O2 -Wall -make fts2amal.c -echo gcc $CFLAGS -shared fts2amal.c -o fts2.so -gcc $CFLAGS -shared fts2amal.c -o fts2.so -strip fts2.so diff --git a/mkextw.sh b/mkextw.sh deleted file mode 100644 index 909a126c38..0000000000 --- a/mkextw.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/sh -# -# This script is used to compile SQLite extensions into DLLs. -# -make fts2amal.c -PATH=$PATH:/opt/mingw/bin -OPTS='-DTHREADSAFE=1 -DBUILD_sqlite=1 -DSQLITE_OS_WIN=1' -CC="i386-mingw32msvc-gcc -O2 $OPTS -Itsrc" -NM="i386-mingw32msvc-nm" -CMD="$CC -c fts2amal.c" -echo $CMD -$CMD -echo 'EXPORTS' >fts2.def -echo 'sqlite3_fts2_init' >>fts2.def -i386-mingw32msvc-dllwrap \ - --def fts2.def -v --export-all \ - --driver-name i386-mingw32msvc-gcc \ - --dlltool-name i386-mingw32msvc-dlltool \ - --as i386-mingw32msvc-as \ - --target i386-mingw32 \ - -dllname fts2.dll -lmsvcrt fts2amal.o -zip fts2dll.zip fts2.dll fts2.def From dd973548f129b56f45cdf0eb9580a755f369a160 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 13 Feb 2014 19:27:08 +0000 Subject: [PATCH 256/276] Ensure that if the "psow=0" URI option or FCNTL_POWERSAFE_OVERWRITE file-control is used to clear the power-safe overwrite flag, extra padding frames are added to the WAL file. FossilOrigin-Name: 48c821fd97a8f03757c90560c37a46bd0843570e --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/wal.c | 2 +- test/unixexcl.test | 4 ++-- test/zerodamage.test | 2 +- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index be8118db4b..e5a8a9f156 100644 --- a/manifest +++ b/manifest @@ -1,11 +1,11 @@ -C Change\sREADME\sto\sREADME.md\sand\sexpand\sit.\s\sRemove\sunrelated\sand\sobsolete\sfiles. -D 2014-02-13T19:10:24.061 +C Ensure\sthat\sif\sthe\s"psow=0"\sURI\soption\sor\sFCNTL_POWERSAFE_OVERWRITE\sfile-control\sis\sused\sto\sclear\sthe\spower-safe\soverwrite\sflag,\sextra\spadding\sframes\sare\sadded\sto\sthe\sWAL\sfile. +D 2014-02-13T19:27:08.812 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.msc 6ff3ff2eef45c7dd309a8626ff7947b20bd387e7 F Makefile.vxworks db21ed42a01d5740e656b16f92cb5d8d5e5dd315 -F README.md 8ff4548af6f7cdf4b02e585d4dd552b233998a9b w README +F README.md 8ff4548af6f7cdf4b02e585d4dd552b233998a9b F VERSION 0dc30ad5cf90736d5fd9e540c9f05c542658abe7 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 F addopcodes.awk 9eb448a552d5c0185cf62c463f9c173cedae3811 @@ -287,7 +287,7 @@ F src/vdbemem.c 06603e8e9d2f3247b68c6bbe4bd37fb6721b5bda F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147 F src/vdbetrace.c 6f52bc0c51e144b7efdcfb2a8f771167a8816767 F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd -F src/wal.c d89e386ead8ecfc823b6162b09e1ada0623df37a +F src/wal.c 76e7fc6de229bea8b30bb2539110f03a494dc3a8 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45 F src/where.c b0436385f40e86f0f4cc60355cd018bde2c89d4b @@ -1013,7 +1013,7 @@ F test/types.test bf816ce73c7dfcfe26b700c19f97ef4050d194ff F test/types2.test 3555aacf8ed8dc883356e59efc314707e6247a84 F test/types3.test 99e009491a54f4dc02c06bdbc0c5eea56ae3e25a F test/unique.test 93f8b2ef5ea51b9495f8d6493429b1fd0f465264 -F test/unixexcl.test a9870e46cc6f8390a494513d4f2bf55b5a8b3e46 +F test/unixexcl.test cd6c765f75e50e8e2c2ba763149e5d340ea19825 F test/unordered.test ef85ac8f2f3c93ed2b9e811b684de73175fc464c F test/update.test 1b6c488a8f993d090b7ee9ad0e234faa161b3aeb F test/uri.test 63e03df051620a18f794b4f4adcdefb3c23b6751 @@ -1100,7 +1100,7 @@ F test/without_rowid4.test 4e08bcbaee0399f35d58b5581881e7a6243d458a F test/without_rowid5.test b4a639a367f04d382d20e8f44fc1be4f2d57d107 F test/wordcount.c 9915e06cb33d8ca8109b8700791afe80d305afda F test/zeroblob.test caaecfb4f908f7bc086ed238668049f96774d688 -F test/zerodamage.test 209d7ed441f44cc5299e4ebffbef06fd5aabfefd +F test/zerodamage.test cf6748bad89553cc1632be51a6f54e487e4039ac F tool/build-all-msvc.bat e0917e787df675b020d250d60a00de8abaa4e30a x F tool/build-shell.sh 950f47c6174f1eea171319438b93ba67ff5bf367 F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2 @@ -1150,7 +1150,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P e3b79e920c298a39613631d689d1a2f182d00496 -R 32cef02970d5145eabe1c7cffe4376d1 -U drh -Z 910a038630fdb9ee9dcf69294f2c5c44 +P 18d4e258c45c32984b23d97b896a761eeef2dbdf +R 8c9ce91bde08452c57ff8bd83f7e4683 +U dan +Z a2f4dabb4be0cf1b9a50023d91f3c52c diff --git a/manifest.uuid b/manifest.uuid index 540465f61a..678e82d8ec 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -18d4e258c45c32984b23d97b896a761eeef2dbdf \ No newline at end of file +48c821fd97a8f03757c90560c37a46bd0843570e \ No newline at end of file diff --git a/src/wal.c b/src/wal.c index c2c3d369c1..ad76065f50 100644 --- a/src/wal.c +++ b/src/wal.c @@ -1306,7 +1306,7 @@ int sqlite3WalOpen( sqlite3OsClose(pRet->pWalFd); sqlite3_free(pRet); }else{ - int iDC = sqlite3OsDeviceCharacteristics(pRet->pWalFd); + int iDC = sqlite3OsDeviceCharacteristics(pDbFd); if( iDC & SQLITE_IOCAP_SEQUENTIAL ){ pRet->syncHeader = 0; } if( iDC & SQLITE_IOCAP_POWERSAFE_OVERWRITE ){ pRet->padToSectorBoundary = 0; diff --git a/test/unixexcl.test b/test/unixexcl.test index 0147e6bbb4..d6762178dd 100644 --- a/test/unixexcl.test +++ b/test/unixexcl.test @@ -109,7 +109,7 @@ do_multiclient_test tn { } {1 2} do_test unixexcl-3.$tn.3 { sql1 { PRAGMA wal_checkpoint; INSERT INTO t1 VALUES(3, 4); } - } {0 3 3} + } {0 5 5} do_test unixexcl-3.$tn.4 { sql2 { SELECT * FROM t1; } } {1 2} @@ -121,7 +121,7 @@ do_multiclient_test tn { } {1 2 3 4} do_test unixexcl-3.$tn.7 { sql1 { PRAGMA wal_checkpoint; } - } {0 4 4} + } {0 7 7} } } diff --git a/test/zerodamage.test b/test/zerodamage.test index de5088b5a2..dccaba816e 100644 --- a/test/zerodamage.test +++ b/test/zerodamage.test @@ -115,7 +115,7 @@ ifcapable wal { UPDATE t1 SET y=randomblob(50) WHERE x=124; } file size test.db-wal - } {8416} + } {16800} } finish_test From 3f40d40ad90d5198c1f97f947892c6ff3059b7c0 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Thu, 13 Feb 2014 21:57:48 +0000 Subject: [PATCH 257/276] Improvements to the makefile and README for MSVC. FossilOrigin-Name: b22b61406899c2694dae984995d2484fdb8122f1 --- Makefile.msc | 4 ++-- README.md | 57 ++++++++++++++++++++++++++++++++++++--------------- manifest | 16 +++++++-------- manifest.uuid | 2 +- 4 files changed, 51 insertions(+), 28 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index 8dce52b5bc..61e5102607 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -214,7 +214,7 @@ NLTLIBPATHS = "/LIBPATH:$(NCRTLIBPATH)" "/LIBPATH:$(NSDKLIBPATH)" # will run on the target platform. (BCC and TCC are usually the # same unless your are cross-compiling.) # -TCC = $(CC) -W3 -DSQLITE_OS_WIN=1 -I$(TOP) -I$(TOP)\src -fp:precise +TCC = $(CC) -W3 -DSQLITE_OS_WIN=1 -I. -I$(TOP) -I$(TOP)\src -fp:precise RCC = $(RC) -DSQLITE_OS_WIN=1 -I$(TOP) -I$(TOP)\src # Check if assembly code listings should be generated for the source @@ -1219,7 +1219,7 @@ parse.c: $(TOP)\src\parse.y lemon.exe $(TOP)\addopcodes.awk $(NAWK) -f $(TOP)\addopcodes.awk parse.h.temp > parse.h sqlite3.h: $(TOP)\src\sqlite.h.in $(TOP)\manifest.uuid $(TOP)\VERSION - $(TCLSH_CMD) $(TOP)\tool\mksqlite3h.tcl $(TOP) > sqlite3.h + $(TCLSH_CMD) $(TOP)\tool\mksqlite3h.tcl $(TOP:\=/) > sqlite3.h mkkeywordhash.exe: $(TOP)\tool\mkkeywordhash.c $(BCC) -Fe$@ $(OPT_FEATURE_FLAGS) $(OPTS) $(TOP)\tool\mkkeywordhash.c /link $(NLTLIBPATHS) diff --git a/README.md b/README.md index d8042cee45..5e52dea507 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ For example: ../sqlite/configure ;# Run the configure script make ;# Run the makefile. make sqlite3.c ;# Build the "amalgamation" source file - make test ;# Run some tests (requires TCL) + make test ;# Run some tests (requires Tcl) See the makefile for additional targets. @@ -30,10 +30,33 @@ script does not work out for you, there is a generic makefile named can copy and edit to suit your needs. Comments on the generic makefile show what changes are needed. -SQLite does not require TCL to run, but a TCL installation is required -by the makefiles. SQLite contains a lot of generated code and TCL is -used to do much of that code generation. The makefile also requires -AWK. +## Using MSVC + +On Windows, all applicable build products can be compiled with MSVC. +First open the command prompt window associated with the desired compiler +version (e.g. "Developer Command Prompt for VS2013"). Next, use NMAKE +with the provided "Makefile.msc" to build one of the supported targets. + +For example: + + mkdir bld + cd bld + nmake /f Makefile.msc TOP=..\sqlite + nmake /f Makefile.msc sqlite3.c TOP=..\sqlite + nmake /f Makefile.msc sqlite3.dll TOP=..\sqlite + nmake /f Makefile.msc sqlite3.exe TOP=..\sqlite + nmake /f Makefile.msc test TOP=..\sqlite + +There are several build options that can be set via the NMAKE command +line. For example, to build for WinRT, simply add "FOR_WINRT=1" argument +to the "sqlite3.dll" command line above. When debugging into the SQLite +code, adding the "DEBUG=1" argument to one of the above command lines is +recommended. + +SQLite does not require Tcl to run, but a Tcl installation is required +by the makefiles (including those for MSVC). SQLite contains a lot of +generated code and Tcl is used to do much of that code generation. The +makefiles also require AWK. ## Source Code Tour @@ -42,11 +65,11 @@ src/ also contains files used to build the "testfixture" test harness; those file all begin with "test". And src/ contains the "shell.c" file which is the main program for the "sqlite3.exe" command-line shell and the "tclsqlite.c" file which implements the bindings to SQLite from the -TCL programming language. (Historical note: SQLite began as a TCL +Tcl programming language. (Historical note: SQLite began as a Tcl extension and only later escaped to the wild as an independent library.) Test scripts and programs are found in the **test/** subdirectory. -There are other test suites for SQLite (see +There are other test suites for SQLite (see [How SQLite Is Tested](http://www.sqlite.org/testing.html)) but those other test suites are in separate source repositories. @@ -67,23 +90,23 @@ other sources rather than being typed in manually by a programmer. This section will summarize those automatically-generated files. To create all of the automatically-generated files, simply run "make target_source". The "target_source" make target will create a subdirectory "tsrc/" and -fill it with all the source files needed to build SQLite, both +fill it with all the source files needed to build SQLite, both manually-edited files and automatically-generated files. The SQLite interface is defined by the **sqlite3.h** header file, which is generated from src/sqlite.h.in, ./manifest.uuid, and ./VERSION. The -TCL script at tool/mksqlite3h.tcl does the conversion. The manifest.uuid +Tcl script at tool/mksqlite3h.tcl does the conversion. The manifest.uuid file contains the SHA1 hash of the particular check-in and is used to generate the SQLITE_SOURCE_ID macro. The VERSION file contains the current SQLite version number. The sqlite3.h header is really just a copy of src/sqlite.h.in with the source-id and version number inserted at just the right spots. Note that comment text in the sqlite3.h file is used to generate much of -the SQLite API documentation. The TCL scripts used to generate that +the SQLite API documentation. The Tcl scripts used to generate that documentation are in a separate source repository. The SQL language parser is **parse.c** which is generate from a grammar in the src/parse.y file. The conversion of "parse.y" into "parse.c" is done -by the [lemon](./doc/lemon.html) LALR(1) parser generator. The source code +by the [lemon](./doc/lemon.html) LALR(1) parser generator. The source code for lemon is at tool/lemon.c. Lemon uses a template for generating its parser. A generic template is in tool/lempar.c, but SQLite uses a slightly modified template found in src/lempar.c. @@ -117,7 +140,7 @@ to perform more cross-procedure analysis and generate better code. SQLite runs about 5% faster when compiled from the amalgamation versus when compiled from individual source files. -The amalgamation is generated from the tool/mksqlite3c.tcl TCL script. +The amalgamation is generated from the tool/mksqlite3c.tcl Tcl script. First, all of the individual source files must be gathered into the tsrc/ subdirectory (using the equivalent of "make target_source") then the tool/mksqlite3c.tcl script is run to copy them all together in just the @@ -125,23 +148,23 @@ right order while resolving internal "#include" references. The amalgamation source file is more than 100K lines long. Some symbolic debuggers (most notably MSVC) are unable to deal with files longer than 64K -lines. To work around this, a separate TCL script, tool/split-sqlite3c.tcl, +lines. To work around this, a separate Tcl script, tool/split-sqlite3c.tcl, can be run on the amalgamation to break it up into a single small C file called **sqlite3-all.c** that does #include on about five other files named **sqlite3-1.c**, **sqlite3-2.c**, ..., **sqlite3-5.c**. In this way, all of the source code is contained within a single translation unit so -that the compiler can do extra cross-procedure optimization, but no +that the compiler can do extra cross-procedure optimization, but no individual source file exceeds 32K lines in length. ## How It All Fits Together SQLite is modular in design. -See the [architectural description](http://www.sqlite.org/arch.html) +See the [architectural description](http://www.sqlite.org/arch.html) for details. Other documents that are useful in (helping to understand how SQLite works include the [file format](http://www.sqlite.org/fileformat2.html) description, the [virtual machine](http://www.sqlite.org/vdbe.html) that runs -prepared statements, the description of +prepared statements, the description of [how transactions work](http://www.sqlite.org/atomiccommit.html), and the [overview of the query planner](http://www.sqlite.org/optoverview.html). @@ -182,7 +205,7 @@ Key files: * **os_unix.c** and **os_win.c** - These two files implement the interface between SQLite and the underlying operating system using the run-time pluggable VFS interface. - + ## Contacts diff --git a/manifest b/manifest index e5a8a9f156..a0e6034070 100644 --- a/manifest +++ b/manifest @@ -1,11 +1,11 @@ -C Ensure\sthat\sif\sthe\s"psow=0"\sURI\soption\sor\sFCNTL_POWERSAFE_OVERWRITE\sfile-control\sis\sused\sto\sclear\sthe\spower-safe\soverwrite\sflag,\sextra\spadding\sframes\sare\sadded\sto\sthe\sWAL\sfile. -D 2014-02-13T19:27:08.812 +C Improvements\sto\sthe\smakefile\sand\sREADME\sfor\sMSVC. +D 2014-02-13T21:57:48.016 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 -F Makefile.msc 6ff3ff2eef45c7dd309a8626ff7947b20bd387e7 +F Makefile.msc 371a17ef9cd011b103cfa1964119a8528f5427c9 F Makefile.vxworks db21ed42a01d5740e656b16f92cb5d8d5e5dd315 -F README.md 8ff4548af6f7cdf4b02e585d4dd552b233998a9b +F README.md 64f270c43c38c46de749e419c22f0ae2f4499fe8 F VERSION 0dc30ad5cf90736d5fd9e540c9f05c542658abe7 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 F addopcodes.awk 9eb448a552d5c0185cf62c463f9c173cedae3811 @@ -1150,7 +1150,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 18d4e258c45c32984b23d97b896a761eeef2dbdf -R 8c9ce91bde08452c57ff8bd83f7e4683 -U dan -Z a2f4dabb4be0cf1b9a50023d91f3c52c +P 48c821fd97a8f03757c90560c37a46bd0843570e +R e8c48a1ab293ac2d556c755a2d22ba69 +U mistachkin +Z fd16507dbadca8019665c7ea56e69ef4 diff --git a/manifest.uuid b/manifest.uuid index 678e82d8ec..267d4e00eb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -48c821fd97a8f03757c90560c37a46bd0843570e \ No newline at end of file +b22b61406899c2694dae984995d2484fdb8122f1 \ No newline at end of file From 2953ba9e20f02dad6c41eab2fbaaab4b5aae77e1 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 14 Feb 2014 00:25:03 +0000 Subject: [PATCH 258/276] Revise how the Tcl system encoding is handled by the test suite. FossilOrigin-Name: 9e573198e107f1b85ee37c52a10343d38968bda1 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/tclsqlite.c | 1 + test/capi3e.test | 6 +++++- 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index a0e6034070..823607add4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvements\sto\sthe\smakefile\sand\sREADME\sfor\sMSVC. -D 2014-02-13T21:57:48.016 +C Revise\show\sthe\sTcl\ssystem\sencoding\sis\shandled\sby\sthe\stest\ssuite. +D 2014-02-14T00:25:03.606 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -225,7 +225,7 @@ F src/sqliteInt.h 5b1f4e30c8332270e4c14254ef1fbcbd92a4a4c7 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e -F src/tclsqlite.c 649d373f2a3cfbefe8e935a8dec83686616f9a85 +F src/tclsqlite.c e87c99e28a145943666b51b212dacae35fcea0bd F src/test1.c 2401eee14a4309a7cfe2aeb2f30ad517a1d9c299 F src/test2.c 7355101c085304b90024f2261e056cdff13c6c35 F src/test3.c 1c0e5d6f080b8e33c1ce8b3078e7013fdbcd560c @@ -365,7 +365,7 @@ F test/capi3.test 6cdd49656bd62a296924f4d2fcfd05cd2a298369 F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4 F test/capi3c.test a21869e4d50d5dbb7e566e328fc0bc7c2efa6a32 F test/capi3d.test 6d0fc0a86d73f42dd19a7d8b7761ab9bc02277d0 -F test/capi3e.test ad90088b18b0367125ff2d4b5400153fd2f99aab +F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3 F test/check.test 5831ddb6f2c687782eaf2e1a07b6e17f24c4f763 F test/close.test 340bd24cc58b16c6bc01967402755027c37eb815 @@ -1150,7 +1150,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 48c821fd97a8f03757c90560c37a46bd0843570e -R e8c48a1ab293ac2d556c755a2d22ba69 +P b22b61406899c2694dae984995d2484fdb8122f1 +R e61eea6addc7b24a1393827be3ebc05a U mistachkin -Z fd16507dbadca8019665c7ea56e69ef4 +Z f753108c2da8e4ac5af912585f7a37ad diff --git a/manifest.uuid b/manifest.uuid index 267d4e00eb..70012cb83b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b22b61406899c2694dae984995d2484fdb8122f1 \ No newline at end of file +9e573198e107f1b85ee37c52a10343d38968bda1 \ No newline at end of file diff --git a/src/tclsqlite.c b/src/tclsqlite.c index 980032cfd6..9b977e54ae 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -3778,6 +3778,7 @@ int TCLSH_MAIN(int argc, char **argv){ sqlite3_shutdown(); Tcl_FindExecutable(argv[0]); + Tcl_SetSystemEncoding(NULL, "utf-8"); interp = Tcl_CreateInterp(); #if TCLSH==2 diff --git a/test/capi3e.test b/test/capi3e.test index d7ab8d0bd4..3e478e7904 100644 --- a/test/capi3e.test +++ b/test/capi3e.test @@ -20,7 +20,11 @@ source $testdir/tester.tcl # Make sure the system encoding is utf-8. Otherwise, if the system encoding # is other than utf-8, [file isfile $x] may not refer to the same file # as [sqlite3 db $x]. -encoding system utf-8 +# +# This is no longer needed here because it should be done within the test +# fixture executable itself, via Tcl_SetSystemEncoding. +# +# encoding system utf-8 # Do not use a codec for tests in this file, as the database file is # manipulated directly using tcl scripts (using the [hexio_write] command). From 4a1d365903ef55c06c7731fbd5fbb7811f9805ee Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 14 Feb 2014 15:13:36 +0000 Subject: [PATCH 259/276] Add OP_IdxGT and OP_IdxLE as distinct opcodes. Formerly these operations where done using OP_IdxGE and OP_IdxLT with the P5 flag set. But VDBE code is easier to read with distinct opcode names. Also change OP_SeekGe to OP_SeekGE, and so forth, so that the capitalization is consistent. The whole point of this change is to improve the readability of VDBE listings. FossilOrigin-Name: b6bea903ac8e1717ed50b221d73bd0be061c7663 --- manifest | 16 ++++---- manifest.uuid | 2 +- src/vdbe.c | 102 ++++++++++++++++++++++++++++++-------------------- src/where.c | 45 +++++++++++----------- 4 files changed, 94 insertions(+), 71 deletions(-) diff --git a/manifest b/manifest index 823607add4..b85a23bdd5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Revise\show\sthe\sTcl\ssystem\sencoding\sis\shandled\sby\sthe\stest\ssuite. -D 2014-02-14T00:25:03.606 +C Add\sOP_IdxGT\sand\sOP_IdxLE\sas\sdistinct\sopcodes.\s\sFormerly\sthese\soperations\swhere\ndone\susing\sOP_IdxGE\sand\sOP_IdxLT\swith\sthe\sP5\sflag\sset.\s\sBut\sVDBE\scode\sis\seasier\nto\sread\swith\sdistinct\sopcode\snames.\s\sAlso\schange\sOP_SeekGe\sto\sOP_SeekGE,\sand\nso\sforth,\sso\sthat\sthe\scapitalization\sis\sconsistent.\s\sThe\swhole\spoint\sof\sthis\nchange\sis\sto\simprove\sthe\sreadability\sof\sVDBE\slistings. +D 2014-02-14T15:13:36.850 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -277,7 +277,7 @@ F src/update.c a7df6fffce6bfedc578fda6136dd33e34a63f8ee F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c c46c90459ef9bdc0c6c73803cf4c55425b4771cf F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c 3f0872b12ec3fc24ee540f8bb09de181ddad6d8d +F src/vdbe.c 543ed4ed0c41b34affad239374d4c07e6e5b2401 F src/vdbe.h e6c4c610fcabad4fa80ebb1efc6822a9367e2b26 F src/vdbeInt.h 5286af9067cabdb8ba57b87c0c988a931be6c6c8 F src/vdbeapi.c 5bc41aaea448a7fc250902c418f1795859be3820 @@ -290,7 +290,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 76e7fc6de229bea8b30bb2539110f03a494dc3a8 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45 -F src/where.c b0436385f40e86f0f4cc60355cd018bde2c89d4b +F src/where.c 43eb827f10d90972578eb0759d01bf0094fcb8c7 F src/whereInt.h 921f935af8b684ffb49705610bda7284db1db138 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1150,7 +1150,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P b22b61406899c2694dae984995d2484fdb8122f1 -R e61eea6addc7b24a1393827be3ebc05a -U mistachkin -Z f753108c2da8e4ac5af912585f7a37ad +P 9e573198e107f1b85ee37c52a10343d38968bda1 +R 761a583803ea417c3e82fa617fd0a139 +U drh +Z 39171055bea51b7fba314c7bdb8e0ff5 diff --git a/manifest.uuid b/manifest.uuid index 70012cb83b..7c4fe4fd3a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9e573198e107f1b85ee37c52a10343d38968bda1 \ No newline at end of file +b6bea903ac8e1717ed50b221d73bd0be061c7663 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 00cff1e21e..610376dd20 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3425,10 +3425,10 @@ case OP_Close: { ** ** See also: Found, NotFound, Distinct, SeekGt, SeekGe, SeekLt */ -case OP_SeekLt: /* jump, in3 */ -case OP_SeekLe: /* jump, in3 */ -case OP_SeekGe: /* jump, in3 */ -case OP_SeekGt: { /* jump, in3 */ +case OP_SeekLT: /* jump, in3 */ +case OP_SeekLE: /* jump, in3 */ +case OP_SeekGE: /* jump, in3 */ +case OP_SeekGT: { /* jump, in3 */ int res; int oc; VdbeCursor *pC; @@ -3441,9 +3441,9 @@ case OP_SeekGt: { /* jump, in3 */ pC = p->apCsr[pOp->p1]; assert( pC!=0 ); assert( pC->pseudoTableReg==0 ); - assert( OP_SeekLe == OP_SeekLt+1 ); - assert( OP_SeekGe == OP_SeekLt+2 ); - assert( OP_SeekGt == OP_SeekLt+3 ); + assert( OP_SeekLE == OP_SeekLT+1 ); + assert( OP_SeekGE == OP_SeekLT+2 ); + assert( OP_SeekGT == OP_SeekLT+3 ); assert( pC->isOrdered ); assert( pC->pCursor!=0 ); oc = pOp->opcode; @@ -3475,19 +3475,19 @@ case OP_SeekGt: { /* jump, in3 */ ** (x <= 4.9) -> (x < 5) */ if( pIn3->r<(double)iKey ){ - assert( OP_SeekGe==(OP_SeekGt-1) ); - assert( OP_SeekLt==(OP_SeekLe-1) ); - assert( (OP_SeekLe & 0x0001)==(OP_SeekGt & 0x0001) ); - if( (oc & 0x0001)==(OP_SeekGt & 0x0001) ) oc--; + assert( OP_SeekGE==(OP_SeekGT-1) ); + assert( OP_SeekLT==(OP_SeekLE-1) ); + assert( (OP_SeekLE & 0x0001)==(OP_SeekGT & 0x0001) ); + if( (oc & 0x0001)==(OP_SeekGT & 0x0001) ) oc--; } /* If the approximation iKey is smaller than the actual real search ** term, substitute <= for < and > for >=. */ else if( pIn3->r>(double)iKey ){ - assert( OP_SeekLe==(OP_SeekLt+1) ); - assert( OP_SeekGt==(OP_SeekGe+1) ); - assert( (OP_SeekLt & 0x0001)==(OP_SeekGe & 0x0001) ); - if( (oc & 0x0001)==(OP_SeekLt & 0x0001) ) oc++; + assert( OP_SeekLE==(OP_SeekLT+1) ); + assert( OP_SeekGT==(OP_SeekGE+1) ); + assert( (OP_SeekLT & 0x0001)==(OP_SeekGE & 0x0001) ); + if( (oc & 0x0001)==(OP_SeekLT & 0x0001) ) oc++; } } rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)iKey, 0, &res); @@ -3506,17 +3506,17 @@ case OP_SeekGt: { /* jump, in3 */ r.nField = (u16)nField; /* The next line of code computes as follows, only faster: - ** if( oc==OP_SeekGt || oc==OP_SeekLe ){ + ** if( oc==OP_SeekGT || oc==OP_SeekLE ){ ** r.flags = UNPACKED_INCRKEY; ** }else{ ** r.flags = 0; ** } */ - r.flags = (u8)(UNPACKED_INCRKEY * (1 & (oc - OP_SeekLt))); - assert( oc!=OP_SeekGt || r.flags==UNPACKED_INCRKEY ); - assert( oc!=OP_SeekLe || r.flags==UNPACKED_INCRKEY ); - assert( oc!=OP_SeekGe || r.flags==0 ); - assert( oc!=OP_SeekLt || r.flags==0 ); + r.flags = (u8)(UNPACKED_INCRKEY * (1 & (oc - OP_SeekLT))); + assert( oc!=OP_SeekGT || r.flags==UNPACKED_INCRKEY ); + assert( oc!=OP_SeekLE || r.flags==UNPACKED_INCRKEY ); + assert( oc!=OP_SeekGE || r.flags==0 ); + assert( oc!=OP_SeekLT || r.flags==0 ); r.aMem = &aMem[pOp->p3]; #ifdef SQLITE_DEBUG @@ -3534,8 +3534,8 @@ case OP_SeekGt: { /* jump, in3 */ #ifdef SQLITE_TEST sqlite3_search_count++; #endif - if( oc>=OP_SeekGe ){ assert( oc==OP_SeekGe || oc==OP_SeekGt ); - if( res<0 || (res==0 && oc==OP_SeekGt) ){ + if( oc>=OP_SeekGE ){ assert( oc==OP_SeekGE || oc==OP_SeekGT ); + if( res<0 || (res==0 && oc==OP_SeekGT) ){ res = 0; rc = sqlite3BtreeNext(pC->pCursor, &res); if( rc!=SQLITE_OK ) goto abort_due_to_error; @@ -3544,8 +3544,8 @@ case OP_SeekGt: { /* jump, in3 */ res = 0; } }else{ - assert( oc==OP_SeekLt || oc==OP_SeekLe ); - if( res>0 || (res==0 && oc==OP_SeekLt) ){ + assert( oc==OP_SeekLT || oc==OP_SeekLE ); + if( res>0 || (res==0 && oc==OP_SeekLT) ){ res = 0; rc = sqlite3BtreePrevious(pC->pCursor, &res); if( rc!=SQLITE_OK ) goto abort_due_to_error; @@ -4620,32 +4620,50 @@ case OP_IdxRowid: { /* out2-prerelease */ ** Synopsis: key=r[P3@P4] ** ** The P4 register values beginning with P3 form an unpacked index -** key that omits the ROWID. Compare this key value against the index -** that P1 is currently pointing to, ignoring the ROWID on the P1 index. +** key that omits the PRIMARY KEY. Compare this key value against the index +** that P1 is currently pointing to, ignoring the PRIMARY KEY or ROWID +** fields at the end. ** ** If the P1 index entry is greater than or equal to the key value ** then jump to P2. Otherwise fall through to the next instruction. +*/ +/* Opcode: IdxGT P1 P2 P3 P4 P5 +** Synopsis: key=r[P3@P4] ** -** If P5 is non-zero then the key value is increased by an epsilon -** prior to the comparison. This make the opcode work like IdxGT except -** that if the key from register P3 is a prefix of the key in the cursor, -** the result is false whereas it would be true with IdxGT. +** The P4 register values beginning with P3 form an unpacked index +** key that omits the PRIMARY KEY. Compare this key value against the index +** that P1 is currently pointing to, ignoring the PRIMARY KEY or ROWID +** fields at the end. +** +** If the P1 index entry is greater than the key value +** then jump to P2. Otherwise fall through to the next instruction. */ /* Opcode: IdxLT P1 P2 P3 P4 P5 ** Synopsis: key=r[P3@P4] ** ** The P4 register values beginning with P3 form an unpacked index -** key that omits the ROWID. Compare this key value against the index -** that P1 is currently pointing to, ignoring the ROWID on the P1 index. +** key that omits the PRIMARY KEY or ROWID. Compare this key value against +** the index that P1 is currently pointing to, ignoring the PRIMARY KEY or +** ROWID on the P1 index. ** ** If the P1 index entry is less than the key value then jump to P2. ** Otherwise fall through to the next instruction. -** -** If P5 is non-zero then the key value is increased by an epsilon prior -** to the comparison. This makes the opcode work like IdxLE. */ +/* Opcode: IdxLE P1 P2 P3 P4 P5 +** Synopsis: key=r[P3@P4] +** +** The P4 register values beginning with P3 form an unpacked index +** key that omits the PRIMARY KEY or ROWID. Compare this key value against +** the index that P1 is currently pointing to, ignoring the PRIMARY KEY or +** ROWID on the P1 index. +** +** If the P1 index entry is less than or equal to the key value then jump +** to P2. Otherwise fall through to the next instruction. +*/ +case OP_IdxLE: /* jump */ +case OP_IdxGT: /* jump */ case OP_IdxLT: /* jump */ -case OP_IdxGE: { /* jump */ +case OP_IdxGE: { /* jump */ VdbeCursor *pC; int res; UnpackedRecord r; @@ -4660,9 +4678,11 @@ case OP_IdxGE: { /* jump */ assert( pOp->p4type==P4_INT32 ); r.pKeyInfo = pC->pKeyInfo; r.nField = (u16)pOp->p4.i; - if( pOp->p5 ){ + if( pOp->opcodeopcode==OP_IdxLE || pOp->opcode==OP_IdxGT ); r.flags = UNPACKED_INCRKEY | UNPACKED_PREFIX_MATCH; }else{ + assert( pOp->opcode==OP_IdxGE || pOp->opcode==OP_IdxLT ); r.flags = UNPACKED_PREFIX_MATCH; } r.aMem = &aMem[pOp->p3]; @@ -4671,10 +4691,12 @@ case OP_IdxGE: { /* jump */ #endif res = 0; /* Not needed. Only used to silence a warning. */ rc = sqlite3VdbeIdxKeyCompare(pC, &r, &res); - if( pOp->opcode==OP_IdxLT ){ + assert( (OP_IdxLE&1)==(OP_IdxLT&1) && (OP_IdxGE&1)==(OP_IdxGT&1) ); + if( (pOp->opcode&1)==(OP_IdxLT&1) ){ + assert( pOp->opcode==OP_IdxLE || pOp->opcode==OP_IdxLT ); res = -res; }else{ - assert( pOp->opcode==OP_IdxGE ); + assert( pOp->opcode==OP_IdxGE || pOp->opcode==OP_IdxGT ); res++; } if( res>0 ){ diff --git a/src/where.c b/src/where.c index d0d95c081d..94e939e27f 100644 --- a/src/where.c +++ b/src/where.c @@ -2505,7 +2505,7 @@ static int codeAllEqualityTerms( sqlite3VdbeAddOp1(v, (bRev?OP_Last:OP_Rewind), iIdxCur); VdbeComment((v, "begin skip-scan on %s", pIdx->zName)); j = sqlite3VdbeAddOp0(v, OP_Goto); - pLevel->addrSkip = sqlite3VdbeAddOp4Int(v, (bRev?OP_SeekLt:OP_SeekGt), + pLevel->addrSkip = sqlite3VdbeAddOp4Int(v, (bRev?OP_SeekLT:OP_SeekGT), iIdxCur, 0, regBase, nSkip); sqlite3VdbeJumpHere(v, j); for(j=0; ju.btree.nEq; /* Number of == or IN terms */ int isMinQuery = 0; /* If this is an optimized SELECT min(x).. */ @@ -3093,10 +3094,10 @@ static Bitmask codeOneLoopStart( assert( op!=0 ); testcase( op==OP_Rewind ); testcase( op==OP_Last ); - testcase( op==OP_SeekGt ); - testcase( op==OP_SeekGe ); - testcase( op==OP_SeekLe ); - testcase( op==OP_SeekLt ); + testcase( op==OP_SeekGT ); + testcase( op==OP_SeekGE ); + testcase( op==OP_SeekLE ); + testcase( op==OP_SeekLT ); sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint); /* Load the value for the inequality constraint at the end of the @@ -3124,13 +3125,13 @@ static Bitmask codeOneLoopStart( pLevel->p2 = sqlite3VdbeCurrentAddr(v); /* Check if the index cursor is past the end of the range. */ - op = aEndOp[(pRangeEnd || nEq) * (1 + bRev)]; - testcase( op==OP_Noop ); - testcase( op==OP_IdxGE ); - testcase( op==OP_IdxLT ); - if( op!=OP_Noop ){ + if( pRangeEnd || nEq ){ + op = aEndOp[bRev*2 + endEq]; + testcase( op==OP_IdxGT ); + testcase( op==OP_IdxGE ); + testcase( op==OP_IdxLT ); + testcase( op==OP_IdxLE ); sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint); - sqlite3VdbeChangeP5(v, endEq!=bRev ?1:0); } /* If there are inequality constraints, check that the value From f78da0e6afdadd579247630c21a80dda3c906ebd Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 14 Feb 2014 20:59:53 +0000 Subject: [PATCH 260/276] Reduce the number of cases where it is necessary to check for NULL after the loop terminating condition. FossilOrigin-Name: 3c1ae447dec8fc2af1c5105134061717594ac0e0 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/where.c | 12 +++++------- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index b85a23bdd5..d8dd849567 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sOP_IdxGT\sand\sOP_IdxLE\sas\sdistinct\sopcodes.\s\sFormerly\sthese\soperations\swhere\ndone\susing\sOP_IdxGE\sand\sOP_IdxLT\swith\sthe\sP5\sflag\sset.\s\sBut\sVDBE\scode\sis\seasier\nto\sread\swith\sdistinct\sopcode\snames.\s\sAlso\schange\sOP_SeekGe\sto\sOP_SeekGE,\sand\nso\sforth,\sso\sthat\sthe\scapitalization\sis\sconsistent.\s\sThe\swhole\spoint\sof\sthis\nchange\sis\sto\simprove\sthe\sreadability\sof\sVDBE\slistings. -D 2014-02-14T15:13:36.850 +C Reduce\sthe\snumber\sof\scases\swhere\sit\sis\snecessary\sto\scheck\sfor\sNULL\safter\nthe\sloop\sterminating\scondition. +D 2014-02-14T20:59:53.587 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -290,7 +290,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 76e7fc6de229bea8b30bb2539110f03a494dc3a8 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45 -F src/where.c 43eb827f10d90972578eb0759d01bf0094fcb8c7 +F src/where.c bf849f08ee09f15e507b5d5f4bc5b608761d5fe2 F src/whereInt.h 921f935af8b684ffb49705610bda7284db1db138 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1150,7 +1150,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 9e573198e107f1b85ee37c52a10343d38968bda1 -R 761a583803ea417c3e82fa617fd0a139 +P b6bea903ac8e1717ed50b221d73bd0be061c7663 +R f976ccc3e6f99e20be380cc680402b19 U drh -Z 39171055bea51b7fba314c7bdb8e0ff5 +Z d8a7427791a9ddd9c5e417477ea3c5a6 diff --git a/manifest.uuid b/manifest.uuid index 7c4fe4fd3a..3ff1fc2f3d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b6bea903ac8e1717ed50b221d73bd0be061c7663 \ No newline at end of file +3c1ae447dec8fc2af1c5105134061717594ac0e0 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 94e939e27f..96ee0e931e 100644 --- a/src/where.c +++ b/src/where.c @@ -3134,17 +3134,15 @@ static Bitmask codeOneLoopStart( sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint); } - /* If there are inequality constraints, check that the value - ** of the table column that the inequality contrains is not NULL. - ** If it is, jump to the next iteration of the loop. + /* If there are inequality constraint upper bound but not a lower + ** bound, then check that the value of the table column that the + ** inequality contrains is not NULL since there is alway an implied + ** lower bound of "column>NULL". */ r1 = sqlite3GetTempReg(pParse); - testcase( pLoop->wsFlags & WHERE_BTM_LIMIT ); - testcase( pLoop->wsFlags & WHERE_TOP_LIMIT ); - if( (pLoop->wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0 + if( (pLoop->wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==WHERE_TOP_LIMIT && (j = pIdx->aiColumn[nEq])>=0 && pIdx->pTable->aCol[j].notNull==0 - && (nEq || (pLoop->wsFlags & WHERE_BTM_LIMIT)==0) ){ sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, nEq, r1); VdbeComment((v, "%s", pIdx->pTable->aCol[j].zName)); From cfc6ca41797342ea1d572c982a416024528b7ccd Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 14 Feb 2014 23:49:13 +0000 Subject: [PATCH 261/276] Seek past NULLs in a top-constrained search. Avoid checking for NULLs in the body of the search. FossilOrigin-Name: e07a32f30862acf3b322d4d8deb015846d6f8f5f --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/where.c | 40 ++++++++++++++++++---------------------- test/where.test | 4 ++-- test/where4.test | 4 ++-- test/where8.test | 4 ++-- 6 files changed, 34 insertions(+), 38 deletions(-) diff --git a/manifest b/manifest index d8dd849567..8aef1ebcfc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Reduce\sthe\snumber\sof\scases\swhere\sit\sis\snecessary\sto\scheck\sfor\sNULL\safter\nthe\sloop\sterminating\scondition. -D 2014-02-14T20:59:53.587 +C Seek\spast\sNULLs\sin\sa\stop-constrained\ssearch.\s\sAvoid\schecking\sfor\sNULLs\sin\nthe\sbody\sof\sthe\ssearch. +D 2014-02-14T23:49:13.552 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -290,7 +290,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 76e7fc6de229bea8b30bb2539110f03a494dc3a8 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45 -F src/where.c bf849f08ee09f15e507b5d5f4bc5b608761d5fe2 +F src/where.c 7d9c988741c7d0e4a57774ae4b56e59675c4014a F src/whereInt.h 921f935af8b684ffb49705610bda7284db1db138 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1068,14 +1068,14 @@ F test/walro.test 6cc247a0cc9b36aeea2057dd28a922a1cdfbd630 F test/walshared.test 0befc811dcf0b287efae21612304d15576e35417 F test/walslow.test e7be6d9888f83aa5d3d3c7c08aa9b5c28b93609a F test/walthread.test de8dbaf6d9e41481c460ba31ca61e163d7348f8e -F test/where.test 701a633ed16c661cd597b9d504b485197a0f49d7 +F test/where.test 28b64e93428961b07b0d486778d63fd672948f6b F test/where2.test ed6baa9420a109d8be683dbef5d153d186f3690b F test/where3.test d28c51f257e60be30f74308fa385ceeddfb54a6e -F test/where4.test e9b9e2f2f98f00379e6031db6a6fca29bae782a2 +F test/where4.test d8420ceeb8323a41ceff1f1841fc528e824e1ecf F test/where5.test fdf66f96d29a064b63eb543e28da4dfdccd81ad2 F test/where6.test 5da5a98cec820d488e82708301b96cb8c18a258b F test/where7.test 5a4b0abc207d71da4deecd734ad8579e8dd40aa8 -F test/where8.test 84033c4da466d90fe7ef0152661ff67fd218105f +F test/where8.test 806f1dcec4088be2b826b33f757fe6e17c3236a1 F test/where8m.test da346596e19d54f0aba35ebade032a7c47d79739 F test/where9.test 4f3eab951353a3ae164befc521c777dfa903e46c F test/whereA.test 4d253178d135ec46d1671e440cd8f2b916aa6e6b @@ -1150,7 +1150,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P b6bea903ac8e1717ed50b221d73bd0be061c7663 -R f976ccc3e6f99e20be380cc680402b19 +P 3c1ae447dec8fc2af1c5105134061717594ac0e0 +R 20e62eafcdc3ac9a7a16fa36432e6177 U drh -Z d8a7427791a9ddd9c5e417477ea3c5a6 +Z f35a13e794e2689c6821aa3d892fcd6f diff --git a/manifest.uuid b/manifest.uuid index 3ff1fc2f3d..ed5e06552e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3c1ae447dec8fc2af1c5105134061717594ac0e0 \ No newline at end of file +e07a32f30862acf3b322d4d8deb015846d6f8f5f \ No newline at end of file diff --git a/src/where.c b/src/where.c index 96ee0e931e..c5bbeea0e1 100644 --- a/src/where.c +++ b/src/where.c @@ -2985,9 +2985,7 @@ static Bitmask codeOneLoopStart( OP_IdxLT, /* 3: (end_constraints && bRev && endEq) */ }; u16 nEq = pLoop->u.btree.nEq; /* Number of == or IN terms */ - int isMinQuery = 0; /* If this is an optimized SELECT min(x).. */ int regBase; /* Base register holding constraint values */ - int r1; /* Temp register */ WhereTerm *pRangeStart = 0; /* Inequality constraint at range start */ WhereTerm *pRangeEnd = 0; /* Inequality constraint at range end */ int startEq; /* True if range start uses ==, >= or <= */ @@ -3000,6 +2998,8 @@ static Bitmask codeOneLoopStart( int op; /* Instruction opcode */ char *zStartAff; /* Affinity for start of range constraint */ char cEndAff = 0; /* Affinity for end of range constraint */ + u8 bSeekPastNull = 0; /* True to seek past initial nulls */ + u8 bStopAtNull = 0; /* Add condition to terminate at NULLs */ pIdx = pLoop->u.btree.pIndex; iIdxCur = pLevel->iIdxCur; @@ -3018,7 +3018,7 @@ static Bitmask codeOneLoopStart( && (pIdx->nKeyCol>nEq) ){ assert( pLoop->u.btree.nSkip==0 ); - isMinQuery = 1; + bSeekPastNull = 1; nExtraReg = 1; } @@ -3033,6 +3033,13 @@ static Bitmask codeOneLoopStart( if( pLoop->wsFlags & WHERE_TOP_LIMIT ){ pRangeEnd = pLoop->aLTerm[j++]; nExtraReg = 1; + if( pRangeStart==0 + && (pRangeEnd->wtFlags & TERM_VNULL)==0 + && (j = pIdx->aiColumn[nEq])>=0 + && pIdx->pTable->aCol[j].notNull==0 + ){ + bSeekPastNull = 1; + } } /* Generate code to evaluate all constraint terms using == or IN @@ -3052,6 +3059,7 @@ static Bitmask codeOneLoopStart( || (bRev && pIdx->nKeyCol==nEq) ){ SWAP(WhereTerm *, pRangeEnd, pRangeStart); + SWAP(u8, bSeekPastNull, bStopAtNull); } testcase( pRangeStart && (pRangeStart->eOperator & WO_LE)!=0 ); @@ -3083,13 +3091,13 @@ static Bitmask codeOneLoopStart( } nConstraint++; testcase( pRangeStart->wtFlags & TERM_VIRTUAL ); - }else if( isMinQuery ){ + }else if( bSeekPastNull ){ sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq); nConstraint++; startEq = 0; start_constraints = 1; } - codeApplyAffinity(pParse, regBase, nConstraint, zStartAff); + codeApplyAffinity(pParse, regBase, nConstraint - bSeekPastNull, zStartAff); op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev]; assert( op!=0 ); testcase( op==OP_Rewind ); @@ -3118,6 +3126,10 @@ static Bitmask codeOneLoopStart( } nConstraint++; testcase( pRangeEnd->wtFlags & TERM_VIRTUAL ); + }else if( bStopAtNull ){ + sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq); + endEq = 0; + nConstraint++; } sqlite3DbFree(db, zStartAff); @@ -3125,7 +3137,7 @@ static Bitmask codeOneLoopStart( pLevel->p2 = sqlite3VdbeCurrentAddr(v); /* Check if the index cursor is past the end of the range. */ - if( pRangeEnd || nEq ){ + if( nConstraint ){ op = aEndOp[bRev*2 + endEq]; testcase( op==OP_IdxGT ); testcase( op==OP_IdxGE ); @@ -3134,22 +3146,6 @@ static Bitmask codeOneLoopStart( sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint); } - /* If there are inequality constraint upper bound but not a lower - ** bound, then check that the value of the table column that the - ** inequality contrains is not NULL since there is alway an implied - ** lower bound of "column>NULL". - */ - r1 = sqlite3GetTempReg(pParse); - if( (pLoop->wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==WHERE_TOP_LIMIT - && (j = pIdx->aiColumn[nEq])>=0 - && pIdx->pTable->aCol[j].notNull==0 - ){ - sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, nEq, r1); - VdbeComment((v, "%s", pIdx->pTable->aCol[j].zName)); - sqlite3VdbeAddOp2(v, OP_IsNull, r1, addrCont); - } - sqlite3ReleaseTempReg(pParse, r1); - /* Seek the table cursor, if required */ disableTerm(pLevel, pRangeStart); disableTerm(pLevel, pRangeEnd); diff --git a/test/where.test b/test/where.test index a50fe7ebcf..f560708cca 100644 --- a/test/where.test +++ b/test/where.test @@ -237,10 +237,10 @@ do_test where-1.34 { } {97 99} do_test where-1.35 { count {SELECT w FROM t1 WHERE w<3} -} {1 2 2} +} {1 2 3} do_test where-1.36 { count {SELECT w FROM t1 WHERE w<=3} -} {1 2 3 3} +} {1 2 3 4} do_test where-1.37 { count {SELECT w FROM t1 WHERE w+1<=4 ORDER BY w} } {1 2 3 99} diff --git a/test/where4.test b/test/where4.test index 280eb5ff7f..a26e9ad355 100644 --- a/test/where4.test +++ b/test/where4.test @@ -71,7 +71,7 @@ do_test where4-1.5 { } {1 2} do_test where4-1.6 { count {SELECT rowid FROM t1 WHERE w=1 AND x<9} -} {1 3} +} {1 2} do_test where4-1.7 { count {SELECT rowid FROM t1 WHERE w=1 AND x IS NULL AND y=3} } {2 2} @@ -98,7 +98,7 @@ do_test where4-1.14 { } {7 2} do_test where4-1.15 { count {SELECT rowid FROM t1 WHERE w IS NULL AND x IS NULL AND y<0} -} {2} +} {1} do_test where4-1.16 { count {SELECT rowid FROM t1 WHERE w IS NULL AND x IS NULL AND y>=0} } {1} diff --git a/test/where8.test b/test/where8.test index 287e4004c8..139251aa07 100644 --- a/test/where8.test +++ b/test/where8.test @@ -87,13 +87,13 @@ do_test where8-1.8 { do_test where8-1.9 { execsql_status2 { SELECT c FROM t1 WHERE a >= 9 OR b <= 'eight' } -} {IX X VIII 0 0 6} +} {IX X VIII 0 0 7} do_test where8-1.10 { execsql_status2 { SELECT c FROM t1 WHERE (a >= 9 AND c != 'X') OR b <= 'eight' } -} {IX VIII 0 0 6} +} {IX VIII 0 0 7} do_test where8-1.11 { execsql_status2 { From 05a86c5c0f0467098c4f6a333bf6daa1fbe443c1 Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 16 Feb 2014 01:55:49 +0000 Subject: [PATCH 262/276] Enhance the code generator for INSERT INTO ... SELECT so that the SELECT generates output directly in the registers that INSERT INTO will be using, in many cases, and OP_SCopy operations can thus be avoided. FossilOrigin-Name: aa2d8b0e8154dd2f5e2c837dc11ab362b083495b --- manifest | 27 +++--- manifest.uuid | 2 +- src/expr.c | 42 +++++---- src/insert.c | 232 +++++++++++++++++----------------------------- src/select.c | 12 ++- src/sqliteInt.h | 6 +- src/vdbe.c | 39 +++++--- test/insert.test | 2 +- test/insert4.test | 2 +- 9 files changed, 165 insertions(+), 199 deletions(-) diff --git a/manifest b/manifest index 8aef1ebcfc..392084a893 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Seek\spast\sNULLs\sin\sa\stop-constrained\ssearch.\s\sAvoid\schecking\sfor\sNULLs\sin\nthe\sbody\sof\sthe\ssearch. -D 2014-02-14T23:49:13.552 +C Enhance\sthe\scode\sgenerator\sfor\sINSERT\sINTO\s...\sSELECT\sso\sthat\sthe\sSELECT\ngenerates\soutput\sdirectly\sin\sthe\sregisters\sthat\sINSERT\sINTO\swill\sbe\susing,\nin\smany\scases,\sand\sOP_SCopy\soperations\scan\sthus\sbe\savoided. +D 2014-02-16T01:55:49.753 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -172,7 +172,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 F src/delete.c 6765a421f08adbedc5d52d21760ec6dbe5123fd3 -F src/expr.c 9bea427f95665c1aa8fdc87b7678546eef50c296 +F src/expr.c 90bba0ca6ec97d6857458f08a8ad2820130e13cf F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 2ab0f5384b70594468ef3ac5c7ed8ca24bfd17d5 F src/func.c f4499b39d66b71825514334ce67b32ff14bd19f5 @@ -180,7 +180,7 @@ F src/global.c 1d7bb7ea8254ae6a68ed9bfaf65fcb3d1690b486 F src/hash.c d139319967164f139c8d1bb8a11b14db9c4ba3cd F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c 89526b031cf8f0e2306f02099a73cee56110c580 +F src/insert.c 36e61dd2201c34a11886487e7afb86f3451ffc52 F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b @@ -216,12 +216,12 @@ F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c ca8b99d894164435f5c55cb304c1b8121705c51e F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c 50961f0d0ab8f2d45ff29ec5f91d8db221330ca7 +F src/select.c ebec4d3fad7fd5aa33cd69e2f50e9c109285dc73 F src/shell.c 3dd86bf73ccd079f0e32ef5069600586085e8239 F src/sqlite.h.in eed7f7d66a60daaa7b4a597dcd9bad87aad9611b F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h 5b1f4e30c8332270e4c14254ef1fbcbd92a4a4c7 +F src/sqliteInt.h 82aa6a9b068b5a827e85af0b7fa12661f5874459 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -277,7 +277,7 @@ F src/update.c a7df6fffce6bfedc578fda6136dd33e34a63f8ee F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c c46c90459ef9bdc0c6c73803cf4c55425b4771cf F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c 543ed4ed0c41b34affad239374d4c07e6e5b2401 +F src/vdbe.c 7b74ce685d05c1123b0360ce6bc377df114b8533 F src/vdbe.h e6c4c610fcabad4fa80ebb1efc6822a9367e2b26 F src/vdbeInt.h 5286af9067cabdb8ba57b87c0c988a931be6c6c8 F src/vdbeapi.c 5bc41aaea448a7fc250902c418f1795859be3820 @@ -613,10 +613,10 @@ F test/index7.test a3baf9a625bda7fd49471e99aeae04095fbfeecf F test/indexedby.test b2f22f3e693a53813aa3f50b812eb609ba6df1ec F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7 -F test/insert.test 489aa12a027c83d291f5034a83c8c32e6be1dca2 +F test/insert.test c120294273b18cf9c8b1a3158131f7a825bdba41 F test/insert2.test 4f3a04d168c728ed5ec2c88842e772606c7ce435 F test/insert3.test 1b7db95a03ad9c5013fdf7d6722b6cd66ee55e30 -F test/insert4.test b00ddf82d6d4f0a6f3999f42bb6a3c813ea70707 +F test/insert4.test 4791662c50518bdd37d394cae9a7a8014e845bb3 F test/insert5.test 394f96728d1258f406fe5f5aeb0aaf29487c39a6 F test/instr.test 737bbf80685232033f3abedc6ae92f75860b5dd2 F test/intarray.test 066b7d7ac38d25bf96f87f1b017bfc687551cdd4 @@ -1150,7 +1150,10 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 3c1ae447dec8fc2af1c5105134061717594ac0e0 -R 20e62eafcdc3ac9a7a16fa36432e6177 +P e07a32f30862acf3b322d4d8deb015846d6f8f5f +R 4c464651f87f73c0925f058052453922 +T *branch * insert-optimization +T *sym-insert-optimization * +T -sym-trunk * U drh -Z f35a13e794e2689c6821aa3d892fcd6f +Z fb4eb5dbe58efaaeaac33be3bebd9bdd diff --git a/manifest.uuid b/manifest.uuid index ed5e06552e..bab4067e49 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e07a32f30862acf3b322d4d8deb015846d6f8f5f \ No newline at end of file +aa2d8b0e8154dd2f5e2c837dc11ab362b083495b \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 0f07181019..79b50fbb33 100644 --- a/src/expr.c +++ b/src/expr.c @@ -3112,7 +3112,7 @@ int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){ ** results in register target. The results are guaranteed to appear ** in register target. */ -int sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){ +void sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){ int inReg; assert( target>0 && target<=pParse->nMem ); @@ -3125,7 +3125,20 @@ int sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){ sqlite3VdbeAddOp2(pParse->pVdbe, OP_SCopy, inReg, target); } } - return target; +} + +/* +** Generate code that will evaluate expression pExpr and store the +** results in register target. The results are guaranteed to appear +** in register target. If the expression is constant, then this routine +** might choose to code the expression at initialization time. +*/ +void sqlite3ExprCodeFactorable(Parse *pParse, Expr *pExpr, int target){ + if( pParse->okConstFactor && sqlite3ExprIsConstant(pExpr) ){ + sqlite3ExprCodeAtInit(pParse, pExpr, target, 0); + }else{ + sqlite3ExprCode(pParse, pExpr, target); + } } /* @@ -3140,25 +3153,16 @@ int sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){ ** times. They are evaluated once and the results of the expression ** are reused. */ -int sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr, int target){ +void sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr, int target){ Vdbe *v = pParse->pVdbe; - int inReg; - inReg = sqlite3ExprCode(pParse, pExpr, target); + int iMem; + assert( target>0 ); - /* The only place, other than this routine, where expressions can be - ** converted to TK_REGISTER is internal subexpressions in BETWEEN and - ** CASE operators. Neither ever calls this routine. And this routine - ** is never called twice on the same expression. Hence it is impossible - ** for the input to this routine to already be a register. Nevertheless, - ** it seems prudent to keep the ALWAYS() in case the conditions above - ** change with future modifications or enhancements. */ - if( ALWAYS(pExpr->op!=TK_REGISTER) ){ - int iMem; - iMem = ++pParse->nMem; - sqlite3VdbeAddOp2(v, OP_Copy, inReg, iMem); - exprToRegister(pExpr, iMem); - } - return inReg; + assert( pExpr->op!=TK_REGISTER ); + sqlite3ExprCode(pParse, pExpr, target); + iMem = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Copy, target, iMem); + exprToRegister(pExpr, iMem); } #if defined(SQLITE_ENABLE_TREE_EXPLAIN) diff --git a/src/insert.c b/src/insert.c index bd15832ac6..a9e6bd2866 100644 --- a/src/insert.c +++ b/src/insert.c @@ -148,7 +148,7 @@ void sqlite3TableAffinityStr(Vdbe *v, Table *pTab){ ** a statement of the form "INSERT INTO SELECT ..." can ** run without using temporary table for the results of the SELECT. */ -static int readsTable(Parse *p, int iStartAddr, int iDb, Table *pTab){ +static int readsTable(Parse *p, int iDb, Table *pTab){ Vdbe *v = sqlite3GetVdbe(p); int i; int iEnd = sqlite3VdbeCurrentAddr(v); @@ -156,7 +156,7 @@ static int readsTable(Parse *p, int iStartAddr, int iDb, Table *pTab){ VTable *pVTab = IsVirtual(pTab) ? sqlite3GetVTable(p->db, pTab) : 0; #endif - for(i=iStartAddr; iopcode==OP_OpenRead && pOp->p3==iDb ){ @@ -335,79 +335,6 @@ void sqlite3AutoincrementEnd(Parse *pParse){ #endif /* SQLITE_OMIT_AUTOINCREMENT */ -/* -** Generate code for a co-routine that will evaluate a subquery one -** row at a time. -** -** The pSelect parameter is the subquery that the co-routine will evaluation. -** Information about the location of co-routine and the registers it will use -** is returned by filling in the pDest object. -** -** Registers are allocated as follows: -** -** pDest->iSDParm The register holding the next entry-point of the -** co-routine. Run the co-routine to its next breakpoint -** by calling "OP_Yield $X" where $X is pDest->iSDParm. -** -** pDest->iSdst First result register. -** -** pDest->nSdst Number of result registers. -** -** At EOF the first result register will be marked as "undefined" so that -** the caller can know when to stop reading results. -** -** This routine handles all of the register allocation and fills in the -** pDest structure appropriately. -** -** Here is a schematic of the generated code assuming that X is the -** co-routine entry-point register reg[pDest->iSDParm], that EOF is the -** completed flag reg[pDest->iSDParm+1], and R and S are the range of -** registers that hold the result set, reg[pDest->iSdst] through -** reg[pDest->iSdst+pDest->nSdst-1]: -** -** X <- A -** goto B -** A: setup for the SELECT -** loop rows in the SELECT -** load results into registers R..S -** yield X -** end loop -** cleanup after the SELECT -** end co-routine R -** B: -** -** To use this subroutine, the caller generates code as follows: -** -** [ Co-routine generated by this subroutine, shown above ] -** S: yield X, at EOF goto E -** if skip this row, goto C -** if terminate loop, goto E -** deal with this row -** C: goto S -** E: -*/ -int sqlite3CodeCoroutine(Parse *pParse, Select *pSelect, SelectDest *pDest){ - int regYield; /* Register holding co-routine entry-point */ - int addrTop; /* Top of the co-routine */ - int rc; /* Result code */ - Vdbe *v; /* VDBE under construction */ - - regYield = ++pParse->nMem; - v = sqlite3GetVdbe(pParse); - addrTop = sqlite3VdbeCurrentAddr(v) + 1; - sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop); - sqlite3SelectDestInit(pDest, SRT_Coroutine, regYield); - rc = sqlite3Select(pParse, pSelect, pDest); - assert( pParse->nErr==0 || rc ); - if( pParse->db->mallocFailed && rc==SQLITE_OK ) rc = SQLITE_NOMEM; - if( rc ) return rc; - sqlite3VdbeAddOp1(v, OP_EndCoroutine, regYield); - sqlite3VdbeJumpHere(v, addrTop - 1); /* label B: */ - return rc; -} - - - /* Forward declaration */ static int xferOptimization( Parse *pParse, /* Parser context */ @@ -531,16 +458,16 @@ void sqlite3Insert( int iIdxCur = 0; /* First index cursor */ int ipkColumn = -1; /* Column that is the INTEGER PRIMARY KEY */ int endOfLoop; /* Label for the end of the insertion loop */ - int useTempTable = 0; /* Store SELECT results in intermediate table */ int srcTab = 0; /* Data comes from this temporary cursor if >=0 */ int addrInsTop = 0; /* Jump to label "D" */ int addrCont = 0; /* Top of insert loop. Label "C" in templates 3 and 4 */ - int addrSelect = 0; /* Address of coroutine that implements the SELECT */ SelectDest dest; /* Destination for SELECT on rhs of INSERT */ int iDb; /* Index of database holding TABLE */ Db *pDb; /* The database containing table being inserted into */ - int appendFlag = 0; /* True if the insert is likely to be an append */ - int withoutRowid; /* 0 for normal table. 1 for WITHOUT ROWID table */ + u8 useTempTable = 0; /* Store SELECT results in intermediate table */ + u8 appendFlag = 0; /* True if the insert is likely to be an append */ + u8 withoutRowid; /* 0 for normal table. 1 for WITHOUT ROWID table */ + u8 bIdListInOrder = 1; /* True if IDLIST is in table order */ ExprList *pList = 0; /* List of VALUES() to be inserted */ /* Register allocations */ @@ -652,6 +579,56 @@ void sqlite3Insert( */ regAutoinc = autoIncBegin(pParse, iDb, pTab); + /* Allocate registers for holding the rowid of the new row, + ** the content of the new row, and the assemblied row record. + */ + regRowid = regIns = pParse->nMem+1; + pParse->nMem += pTab->nCol + 1; + if( IsVirtual(pTab) ){ + regRowid++; + pParse->nMem++; + } + regData = regRowid+1; + + /* If the INSERT statement included an IDLIST term, then make sure + ** all elements of the IDLIST really are columns of the table and + ** remember the column indices. + ** + ** If the table has an INTEGER PRIMARY KEY column and that column + ** is named in the IDLIST, then record in the ipkColumn variable + ** the index into IDLIST of the primary key column. ipkColumn is + ** the index of the primary key as it appears in IDLIST, not as + ** is appears in the original table. (The index of the INTEGER + ** PRIMARY KEY in the original table is pTab->iPKey.) + */ + if( pColumn ){ + for(i=0; inId; i++){ + pColumn->a[i].idx = -1; + } + for(i=0; inId; i++){ + for(j=0; jnCol; j++){ + if( sqlite3StrICmp(pColumn->a[i].zName, pTab->aCol[j].zName)==0 ){ + pColumn->a[i].idx = j; + if( i!=j ) bIdListInOrder = 0; + if( j==pTab->iPKey ){ + ipkColumn = i; assert( !withoutRowid ); + } + break; + } + } + if( j>=pTab->nCol ){ + if( sqlite3IsRowid(pColumn->a[i].zName) && !withoutRowid ){ + ipkColumn = i; + }else{ + sqlite3ErrorMsg(pParse, "table %S has no column named %s", + pTabList, 0, pColumn->a[i].zName); + pParse->checkSchema = 1; + goto insert_cleanup; + } + } + } + } + /* Figure out how many columns of data are supplied. If the data ** is coming from a SELECT statement, then generate a co-routine that ** produces a single row of the SELECT on each invocation. The @@ -659,13 +636,24 @@ void sqlite3Insert( */ if( pSelect ){ /* Data is coming from a SELECT. Generate a co-routine to run the SELECT */ - int rc = sqlite3CodeCoroutine(pParse, pSelect, &dest); - if( rc ) goto insert_cleanup; + int regYield; /* Register holding co-routine entry-point */ + int addrTop; /* Top of the co-routine */ + int rc; /* Result code */ + regYield = ++pParse->nMem; + addrTop = sqlite3VdbeCurrentAddr(v) + 1; + sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop); + sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield); + dest.iSdst = bIdListInOrder ? regData : 0; + dest.nSdst = pTab->nCol; + rc = sqlite3Select(pParse, pSelect, &dest); regFromSelect = dest.iSdst; + assert( pParse->nErr==0 || rc ); + if( rc || db->mallocFailed ) goto insert_cleanup; + sqlite3VdbeAddOp1(v, OP_EndCoroutine, regYield); + sqlite3VdbeJumpHere(v, addrTop - 1); /* label B: */ assert( pSelect->pEList ); nColumn = pSelect->pEList->nExpr; - assert( dest.nSdst==nColumn ); /* Set useTempTable to TRUE if the result of the SELECT statement ** should be written into a temporary table (template 4). Set to @@ -676,7 +664,7 @@ void sqlite3Insert( ** of the tables being read by the SELECT statement. Also use a ** temp table in the case of row triggers. */ - if( pTrigger || readsTable(pParse, addrSelect, iDb, pTab) ){ + if( pTrigger || readsTable(pParse, iDb, pTab) ){ useTempTable = 1; } @@ -725,6 +713,14 @@ void sqlite3Insert( } } + /* If there is no IDLIST term but the table has an integer primary + ** key, the set the ipkColumn variable to the integer primary key + ** column index in the original table definition. + */ + if( pColumn==0 && nColumn>0 ){ + ipkColumn = pTab->iPKey; + } + /* Make sure the number of columns in the source data matches the number ** of columns to be inserted into the table. */ @@ -743,52 +739,6 @@ void sqlite3Insert( sqlite3ErrorMsg(pParse, "%d values for %d columns", nColumn, pColumn->nId); goto insert_cleanup; } - - /* If the INSERT statement included an IDLIST term, then make sure - ** all elements of the IDLIST really are columns of the table and - ** remember the column indices. - ** - ** If the table has an INTEGER PRIMARY KEY column and that column - ** is named in the IDLIST, then record in the ipkColumn variable - ** the index into IDLIST of the primary key column. ipkColumn is - ** the index of the primary key as it appears in IDLIST, not as - ** is appears in the original table. (The index of the INTEGER - ** PRIMARY KEY in the original table is pTab->iPKey.) - */ - if( pColumn ){ - for(i=0; inId; i++){ - pColumn->a[i].idx = -1; - } - for(i=0; inId; i++){ - for(j=0; jnCol; j++){ - if( sqlite3StrICmp(pColumn->a[i].zName, pTab->aCol[j].zName)==0 ){ - pColumn->a[i].idx = j; - if( j==pTab->iPKey ){ - ipkColumn = i; assert( !withoutRowid ); - } - break; - } - } - if( j>=pTab->nCol ){ - if( sqlite3IsRowid(pColumn->a[i].zName) && !withoutRowid ){ - ipkColumn = i; - }else{ - sqlite3ErrorMsg(pParse, "table %S has no column named %s", - pTabList, 0, pColumn->a[i].zName); - pParse->checkSchema = 1; - goto insert_cleanup; - } - } - } - } - - /* If there is no IDLIST term but the table has an integer primary - ** key, the set the ipkColumn variable to the integer primary key - ** column index in the original table definition. - */ - if( pColumn==0 && nColumn>0 ){ - ipkColumn = pTab->iPKey; - } /* Initialize the count of rows to be inserted */ @@ -836,17 +786,6 @@ void sqlite3Insert( addrInsTop = addrCont = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); } - /* Allocate registers for holding the rowid of the new row, - ** the content of the new row, and the assemblied row record. - */ - regRowid = regIns = pParse->nMem+1; - pParse->nMem += pTab->nCol + 1; - if( IsVirtual(pTab) ){ - regRowid++; - pParse->nMem++; - } - regData = regRowid+1; - /* Run the BEFORE and INSTEAD OF triggers, if there are any */ endOfLoop = sqlite3VdbeMakeLabel(v); @@ -930,7 +869,7 @@ void sqlite3Insert( if( useTempTable ){ sqlite3VdbeAddOp3(v, OP_Column, srcTab, ipkColumn, regRowid); }else if( pSelect ){ - sqlite3VdbeAddOp2(v, OP_SCopy, regFromSelect+ipkColumn, regRowid); + sqlite3VdbeAddOp2(v, OP_Copy, regFromSelect+ipkColumn, regRowid); }else{ VdbeOp *pOp; sqlite3ExprCode(pParse, pList->a[ipkColumn].pExpr, regRowid); @@ -976,8 +915,9 @@ void sqlite3Insert( /* The value of the INTEGER PRIMARY KEY column is always a NULL. ** Whenever this column is read, the rowid will be substituted ** in its place. Hence, fill this column with a NULL to avoid - ** taking up data space with information that will never be used. */ - sqlite3VdbeAddOp2(v, OP_Null, 0, iRegStore); + ** taking up data space with information that will never be used. + ** As there may be shallow copies of this value, make it a soft-NULL */ + sqlite3VdbeAddOp1(v, OP_SoftNull, iRegStore); continue; } if( pColumn==0 ){ @@ -994,11 +934,13 @@ void sqlite3Insert( } } if( j<0 || nColumn==0 || (pColumn && j>=pColumn->nId) ){ - sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, iRegStore); + sqlite3ExprCodeFactorable(pParse, pTab->aCol[i].pDflt, iRegStore); }else if( useTempTable ){ sqlite3VdbeAddOp3(v, OP_Column, srcTab, j, iRegStore); }else if( pSelect ){ - sqlite3VdbeAddOp2(v, OP_SCopy, regFromSelect+j, iRegStore); + if( regFromSelect!=regData ){ + sqlite3VdbeAddOp2(v, OP_SCopy, regFromSelect+j, iRegStore); + } }else{ sqlite3ExprCode(pParse, pList->a[j].pExpr, iRegStore); } diff --git a/src/select.c b/src/select.c index dd445deed3..a41f4a8254 100644 --- a/src/select.c +++ b/src/select.c @@ -585,13 +585,19 @@ static void selectInnerLoop( /* Pull the requested columns. */ nResultCol = pEList->nExpr; + if( pDest->iSdst==0 ){ pDest->iSdst = pParse->nMem+1; - pDest->nSdst = nResultCol; pParse->nMem += nResultCol; - }else{ - assert( pDest->nSdst==nResultCol ); + }else if( pDest->iSdst+nResultCol > pParse->nMem ){ + /* This is an error condition that can result, for example, when a SELECT + ** on the right-hand side of an INSERT contains more result columns than + ** there are columns in the table on the left. The error will be caught + ** and reported later. But we need to make sure enough memory is allocated + ** to avoid other spurious errors in the meantime. */ + pParse->nMem += nResultCol; } + pDest->nSdst = nResultCol; regResult = pDest->iSdst; if( srcTab>=0 ){ for(i=0; ip1>0 && pOp->p1<=(p->nMem-p->nCursor) ); + pOut = &aMem[pOp->p1]; + pOut->flags = (pOut->flags|MEM_Null)&~MEM_Undefined; + break; +} /* Opcode: Blob P1 P2 * P4 * ** Synopsis: r[P2]=P4 (len=P1) @@ -2909,23 +2923,17 @@ case OP_AutoCommit: { /* Opcode: Transaction P1 P2 P3 P4 P5 ** -** Begin a transaction. The transaction ends when a Commit or Rollback -** opcode is encountered. Depending on the ON CONFLICT setting, the -** transaction might also be rolled back if an error is encountered. +** Begin a transaction on database P1 if a transaction is not already +** active. +** If P2 is non-zero, then a write-transaction is started, or if a +** read-transaction is already active, it is upgraded to a write-transaction. +** If P2 is zero, then a read-transaction is started. ** ** P1 is the index of the database file on which the transaction is ** started. Index 0 is the main database file and index 1 is the ** file used for temporary tables. Indices of 2 or more are used for ** attached databases. ** -** If P2 is non-zero, then a write-transaction is started. A RESERVED lock is -** obtained on the database file when a write-transaction is started. No -** other process can start another write transaction while this transaction is -** underway. Starting a write transaction also creates a rollback journal. A -** write transaction must be started before any changes can be made to the -** database. If P2 is greater than or equal to 2 then an EXCLUSIVE lock is -** also obtained on the file. -** ** If a write-transaction is started and the Vdbe.usesStmtJournal flag is ** true (this flag is set if the Vdbe may modify more than one row and may ** throw an ABORT exception), a statement transaction may also be opened. @@ -2936,13 +2944,16 @@ case OP_AutoCommit: { ** entire transaction. If no error is encountered, the statement transaction ** will automatically commit when the VDBE halts. ** -** If P2 is zero, then a read-lock is obtained on the database file. -** ** If P5!=0 then this opcode also checks the schema cookie against P3 ** and the schema generation counter against P4. ** The cookie changes its value whenever the database schema changes. ** This operation is used to detect when that the cookie has changed -** and that the current process needs to reread the schema. +** and that the current process needs to reread the schema. If the schema +** cookie in P3 differs from the schema cookie in the database header or +** if the schema generation counter in P4 differs from the current +** generation counter, then an SQLITE_SCHEMA error is raised and execution +** halts. The sqlite3_step() wrapper function might then reprepare the +** statement and rerun it from the beginning. */ case OP_Transaction: { Btree *pBt; diff --git a/test/insert.test b/test/insert.test index e00b9a8028..83168122ab 100644 --- a/test/insert.test +++ b/test/insert.test @@ -398,7 +398,7 @@ ifcapable compound { } {1 2 3 4 5 6 7 8 9} do_test insert-10.2 { catchsql { - INSERT INTO t10 VALUES(11,12,13), (14,15); + INSERT INTO t10 VALUES(11,12,13), (14,15), (16,17,28); } } {1 {all VALUES must have the same number of terms}} } diff --git a/test/insert4.test b/test/insert4.test index 343a08af81..889d5e7807 100644 --- a/test/insert4.test +++ b/test/insert4.test @@ -253,7 +253,7 @@ ifcapable vacuum { # do_test insert4-5.1 { # Table does not exist. - catchsql { INSERT INTO t2 SELECT * FROM nosuchtable } + catchsql { INSERT INTO t2 SELECT a, b FROM nosuchtable } } {1 {no such table: nosuchtable}} do_test insert4-5.2 { # Number of columns does not match. From 2926f9694f7f9ed6669183832a224cc1a7c115c2 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 17 Feb 2014 01:13:28 +0000 Subject: [PATCH 263/276] Fix the VDBE_PROFILE logic. Add a script to process the output file. FossilOrigin-Name: 7adb3da235c8c162c84f05ef4ccf1cc463805d5f --- manifest | 13 +++---- manifest.uuid | 2 +- src/vdbeaux.c | 12 ++++++- tool/vdbe_profile.tcl | 82 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 101 insertions(+), 8 deletions(-) create mode 100644 tool/vdbe_profile.tcl diff --git a/manifest b/manifest index 8aef1ebcfc..567cd67cd1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Seek\spast\sNULLs\sin\sa\stop-constrained\ssearch.\s\sAvoid\schecking\sfor\sNULLs\sin\nthe\sbody\sof\sthe\ssearch. -D 2014-02-14T23:49:13.552 +C Fix\sthe\sVDBE_PROFILE\slogic.\s\sAdd\sa\sscript\sto\sprocess\sthe\soutput\sfile. +D 2014-02-17T01:13:28.650 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -281,7 +281,7 @@ F src/vdbe.c 543ed4ed0c41b34affad239374d4c07e6e5b2401 F src/vdbe.h e6c4c610fcabad4fa80ebb1efc6822a9367e2b26 F src/vdbeInt.h 5286af9067cabdb8ba57b87c0c988a931be6c6c8 F src/vdbeapi.c 5bc41aaea448a7fc250902c418f1795859be3820 -F src/vdbeaux.c dac6e571262a322b2f889752a8dd36549bdacd2b +F src/vdbeaux.c 9098973ff22c6fdfd68d061e11c2e64f65eea2d1 F src/vdbeblob.c 9542e116c1db5ed813977581d506c176e117c0ec F src/vdbemem.c 06603e8e9d2f3247b68c6bbe4bd37fb6721b5bda F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147 @@ -1147,10 +1147,11 @@ F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d F tool/symbols.sh fec58532668296d7c7dc48be9c87f75ccdb5814f F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 +F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 3c1ae447dec8fc2af1c5105134061717594ac0e0 -R 20e62eafcdc3ac9a7a16fa36432e6177 +P e07a32f30862acf3b322d4d8deb015846d6f8f5f +R a089b7b7dc577bc47ffd22f19eb9e985 U drh -Z f35a13e794e2689c6821aa3d892fcd6f +Z f101c06fe6a48199aebfe3f4c9baeea7 diff --git a/manifest.uuid b/manifest.uuid index ed5e06552e..79ba90c802 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e07a32f30862acf3b322d4d8deb015846d6f8f5f \ No newline at end of file +7adb3da235c8c162c84f05ef4ccf1cc463805d5f \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 95c05f7e5c..f7f1d5c288 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1174,7 +1174,7 @@ void sqlite3VdbePrintOp(FILE *pOut, int pc, Op *pOp){ #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS displayComment(pOp, zP4, zCom, sizeof(zCom)); #else - zCom[0] = 0 + zCom[0] = 0; #endif /* NB: The sqlite3OpcodeName() function is implemented by code created ** by the mkopcodeh.awk and mkopcodec.awk scripts which extract the @@ -2552,6 +2552,16 @@ int sqlite3VdbeReset(Vdbe *p){ fprintf(out, "%02x", p->aOp[i].opcode); } fprintf(out, "\n"); + if( p->zSql ){ + char c, pc = 0; + fprintf(out, "-- "); + for(i=0; (c = p->zSql[i])!=0; i++){ + if( pc=='\n' ) fprintf(out, "-- "); + putc(c, out); + pc = c; + } + if( pc!='\n' ) fprintf(out, "\n"); + } for(i=0; inOp; i++){ fprintf(out, "%6d %10lld %8lld ", p->aOp[i].cnt, diff --git a/tool/vdbe_profile.tcl b/tool/vdbe_profile.tcl new file mode 100644 index 0000000000..fb1f955391 --- /dev/null +++ b/tool/vdbe_profile.tcl @@ -0,0 +1,82 @@ +#!/bin/tclsh +# +# Run this script in the same directory as the "vdbe_profile.out" file. +# This script summarizes the results contained in that file. +# +if {![file readable vdbe_profile.out]} { + error "run this script in the same directory as the vdbe_profile.out file" +} +set in [open vdbe_profile.out r] +set stmt {} +set allstmt {} +while {![eof $in]} { + set line [gets $in] + if {$line==""} continue + if {[regexp {^---- } $line]} { + set stmt [lindex $line 1] + if {[info exists cnt($stmt)]} { + incr cnt($stmt) + set firsttime 0 + } else { + set cnt($stmt) 1 + set sql($stmt) {} + set firsttime 1 + lappend allstmt $stmt + } + continue; + } + if {[regexp {^-- } $line]} { + if {$firsttime} { + append sql($stmt) [string range $line 3 end]\n + } + continue + } + if {![regexp {^ *\d+ *\d+ *\d+ *\d+ ([A-Z].*)} $line all detail]} continue + set c [lindex $line 0] + set t [lindex $line 1] + set addr [lindex $line 3] + set op [lindex $line 4] + if {[info exists opcnt($op)]} { + incr opcnt($op) $c + incr opcycle($op) $t + } else { + set opcnt($op) $c + set opcycle($op) $t + } + if {[info exists stat($stmt,$addr)]} { + foreach {cx tx detail} $stat($stmt,$addr) break + incr cx $c + incr tx $t + set stat($stmt,$addr) [list $cx $tx $detail] + } else { + set stat($stmt,$addr) [list $c $t $detail] + } +} +close $in + +foreach stmt $allstmt { + puts "********************************************************************" + puts [string trim $sql($stmt)] + puts "Execution count: $cnt($stmt)" + for {set i 0} {[info exists stat($stmt,$i)]} {incr i} { + foreach {cx tx detail} $stat($stmt,$i) break + if {$cx==0} { + set ax 0 + } else { + set ax [expr {$tx/$cx}] + } + puts [format {%8d %12d %12d %4d %s} $cx $tx $ax $i $detail] + } +} +puts "********************************************************************" +puts "OPCODES:" +foreach op [lsort [array names opcnt]] { + set cx $opcnt($op) + set tx $opcycle($op) + if {$cx==0} { + set ax 0 + } else { + set ax [expr {$tx/$cx}] + } + puts [format {%8d %12d %12d %s} $cx $tx $ax $op] +} From 57bf4a8eeb6f0c0c70e16b1682846f57a4cb6595 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 17 Feb 2014 14:59:22 +0000 Subject: [PATCH 264/276] Avoid unnecessary calls to applyAffinity() during INSERT and UPDATE operations, especially for table that have indices and tables for which all columns have affinity "NONE". FossilOrigin-Name: 35b4d6e938164fabaf30b504c54cfd9a69060cee --- manifest | 29 +++++++++++-------------- manifest.uuid | 2 +- src/analyze.c | 2 +- src/delete.c | 2 +- src/fkey.c | 4 ++-- src/insert.c | 58 +++++++++++++++++++++++++++++-------------------- src/pragma.c | 5 ++--- src/sqliteInt.h | 2 +- src/update.c | 5 ++--- src/vdbe.c | 6 ++--- 10 files changed, 60 insertions(+), 55 deletions(-) diff --git a/manifest b/manifest index 392084a893..4d28d8ab47 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\scode\sgenerator\sfor\sINSERT\sINTO\s...\sSELECT\sso\sthat\sthe\sSELECT\ngenerates\soutput\sdirectly\sin\sthe\sregisters\sthat\sINSERT\sINTO\swill\sbe\susing,\nin\smany\scases,\sand\sOP_SCopy\soperations\scan\sthus\sbe\savoided. -D 2014-02-16T01:55:49.753 +C Avoid\sunnecessary\scalls\sto\sapplyAffinity()\sduring\sINSERT\sand\sUPDATE\noperations,\sespecially\sfor\stable\sthat\shave\sindices\sand\stables\sfor\swhich\nall\scolumns\shave\saffinity\s"NONE". +D 2014-02-17T14:59:22.345 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -157,7 +157,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 3d8b83c91651f53472ca17599dae3457b8b89494 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c d5348d0f86a5fc8fb3987727402f023953c021cf -F src/analyze.c 581d5c18ce89c6f45d4dca65914d0de5b4dad41f +F src/analyze.c 3ec444402a5d9ac1018ac8c549f8e82ac23d4122 F src/attach.c 3801129015ef59d76bf23c95ef9b0069d18a0c52 F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c a729e63cf5cd1829507cb7b8e89f99b95141bb53 @@ -171,16 +171,16 @@ F src/callback.c 174e3c8656bc29f91d710ab61550d16eea34be98 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 -F src/delete.c 6765a421f08adbedc5d52d21760ec6dbe5123fd3 +F src/delete.c 57a09d3d576dd15cd54d945b7b0b478bac71f379 F src/expr.c 90bba0ca6ec97d6857458f08a8ad2820130e13cf F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb -F src/fkey.c 2ab0f5384b70594468ef3ac5c7ed8ca24bfd17d5 +F src/fkey.c b3da26dfcd53a68e1b7162a84e0bf70e54092647 F src/func.c f4499b39d66b71825514334ce67b32ff14bd19f5 F src/global.c 1d7bb7ea8254ae6a68ed9bfaf65fcb3d1690b486 F src/hash.c d139319967164f139c8d1bb8a11b14db9c4ba3cd F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c 36e61dd2201c34a11886487e7afb86f3451ffc52 +F src/insert.c ddc56dc855069ddf530127a346ddc2e67f0396e6 F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b @@ -210,7 +210,7 @@ F src/parse.y cce844ccb80b5f969b04c25100c8d94338488efb F src/pcache.c d8eafac28290d4bb80332005435db44991d07fc2 F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222 F src/pcache1.c 102e6f5a2fbc646154463eb856d1fd716867b64c -F src/pragma.c ed409ce4104cf4d9de6ead40ace70974f124853b +F src/pragma.c 769d08f10b7848dbd1950d0723bfcb12fb22b7f3 F src/prepare.c 677521ab7132615a8a26107a1d1c3132f44ae337 F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece @@ -221,7 +221,7 @@ F src/shell.c 3dd86bf73ccd079f0e32ef5069600586085e8239 F src/sqlite.h.in eed7f7d66a60daaa7b4a597dcd9bad87aad9611b F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h 82aa6a9b068b5a827e85af0b7fa12661f5874459 +F src/sqliteInt.h c5ba0868bddac9fdb0df4686ab43150fefb27da5 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -273,11 +273,11 @@ F src/test_vfstrace.c 3a0ab304682fecbceb689e7d9b904211fde11d78 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/tokenize.c 6da2de6e12218ccb0aea5184b56727d011f4bee7 F src/trigger.c a417d386e214f0abd2e0f756b834b4d9f4d3368a -F src/update.c a7df6fffce6bfedc578fda6136dd33e34a63f8ee +F src/update.c b126167ee39470b6148fa3f89182e7c855dc15d0 F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c c46c90459ef9bdc0c6c73803cf4c55425b4771cf F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c 7b74ce685d05c1123b0360ce6bc377df114b8533 +F src/vdbe.c e3ba6ad0111dbd4234fef5e119dbe30d0abb3cf1 F src/vdbe.h e6c4c610fcabad4fa80ebb1efc6822a9367e2b26 F src/vdbeInt.h 5286af9067cabdb8ba57b87c0c988a931be6c6c8 F src/vdbeapi.c 5bc41aaea448a7fc250902c418f1795859be3820 @@ -1150,10 +1150,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P e07a32f30862acf3b322d4d8deb015846d6f8f5f -R 4c464651f87f73c0925f058052453922 -T *branch * insert-optimization -T *sym-insert-optimization * -T -sym-trunk * +P aa2d8b0e8154dd2f5e2c837dc11ab362b083495b +R 76ffa4a9c63f5b066cf1aa1863fa3f56 U drh -Z fb4eb5dbe58efaaeaac33be3bebd9bdd +Z c57e89c4432511b9873eed17e1f87e02 diff --git a/manifest.uuid b/manifest.uuid index bab4067e49..f218979de8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -aa2d8b0e8154dd2f5e2c837dc11ab362b083495b \ No newline at end of file +35b4d6e938164fabaf30b504c54cfd9a69060cee \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index 3d5c4f6bec..8e230f7571 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -1185,7 +1185,7 @@ static void analyzeOneTable( } sqlite3VdbeAddOp3(v, OP_MakeRecord, regCol, nCol+1, regSample); #endif - sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 6, regTemp, "bbbbbb", 0); + sqlite3VdbeAddOp3(v, OP_MakeRecord, regTabname, 6, regTemp); sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regNewRowid); sqlite3VdbeAddOp3(v, OP_Insert, iStatCur+1, regTemp, regNewRowid); sqlite3VdbeAddOp2(v, OP_Goto, 0, addrNext); diff --git a/src/delete.c b/src/delete.c index 936517c4a7..4ebda1b183 100644 --- a/src/delete.c +++ b/src/delete.c @@ -443,7 +443,7 @@ void sqlite3DeleteFrom( iKey = ++pParse->nMem; nKey = 0; /* Zero tells OP_Found to use a composite key */ sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, iKey, - sqlite3IndexAffinityStr(v, pPk), P4_TRANSIENT); + sqlite3IndexAffinityStr(v, pPk), nPk); sqlite3VdbeAddOp2(v, OP_IdxInsert, iEphCur, iKey); }else{ /* Get the rowid of the row to be deleted and remember it in the RowSet */ diff --git a/src/fkey.c b/src/fkey.c index 46c90a0989..c094783a85 100644 --- a/src/fkey.c +++ b/src/fkey.c @@ -412,8 +412,8 @@ static void fkLookupParent( sqlite3VdbeAddOp2(v, OP_Goto, 0, iOk); } - sqlite3VdbeAddOp3(v, OP_MakeRecord, regTemp, nCol, regRec); - sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v,pIdx), P4_TRANSIENT); + sqlite3VdbeAddOp4(v, OP_MakeRecord, regTemp, nCol, regRec, + sqlite3IndexAffinityStr(v,pIdx), nCol); sqlite3VdbeAddOp4Int(v, OP_Found, iCur, iOk, regRec, 0); sqlite3ReleaseTempReg(pParse, regRec); diff --git a/src/insert.c b/src/insert.c index a9e6bd2866..a9c0641474 100644 --- a/src/insert.c +++ b/src/insert.c @@ -98,10 +98,16 @@ const char *sqlite3IndexAffinityStr(Vdbe *v, Index *pIdx){ } /* -** Set P4 of the most recently inserted opcode to a column affinity -** string for table pTab. A column affinity string has one character -** for each column indexed by the index, according to the affinity of the -** column: +** Compute the affinity string for table pTab, if it has not already been +** computed. As an optimization, omit trailing SQLITE_AFF_NONE affinities. +** +** If the affinity exists (if it is no entirely SQLITE_AFF_NONE values and +** if iReg>0 then code an OP_Affinity opcode that will set the affinities +** for register iReg and following. Or if affinities exists and iReg==0, +** then just set the P4 operand of the previous opcode (which should be +** an OP_MakeRecord) to the affinity string. +** +** A column affinity string has one character column: ** ** Character Column affinity ** ------------------------------ @@ -111,19 +117,11 @@ const char *sqlite3IndexAffinityStr(Vdbe *v, Index *pIdx){ ** 'd' INTEGER ** 'e' REAL */ -void sqlite3TableAffinityStr(Vdbe *v, Table *pTab){ - /* The first time a column affinity string for a particular table - ** is required, it is allocated and populated here. It is then - ** stored as a member of the Table structure for subsequent use. - ** - ** The column affinity string will eventually be deleted by - ** sqlite3DeleteTable() when the Table structure itself is cleaned up. - */ - if( !pTab->zColAff ){ - char *zColAff; - int i; +void sqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){ + int i; + char *zColAff = pTab->zColAff; + if( zColAff==0 ){ sqlite3 *db = sqlite3VdbeDb(v); - zColAff = (char *)sqlite3DbMallocRaw(0, pTab->nCol+1); if( !zColAff ){ db->mallocFailed = 1; @@ -133,12 +131,19 @@ void sqlite3TableAffinityStr(Vdbe *v, Table *pTab){ for(i=0; inCol; i++){ zColAff[i] = pTab->aCol[i].affinity; } - zColAff[pTab->nCol] = '\0'; - + do{ + zColAff[i--] = 0; + }while( i>=0 && zColAff[i]==SQLITE_AFF_NONE ); pTab->zColAff = zColAff; } - - sqlite3VdbeChangeP4(v, -1, pTab->zColAff, P4_TRANSIENT); + i = sqlite3Strlen30(zColAff); + if( i ){ + if( iReg ){ + sqlite3VdbeAddOp4(v, OP_Affinity, iReg, i, 0, zColAff, i); + }else{ + sqlite3VdbeChangeP4(v, -1, zColAff, i); + } + } } /* @@ -846,8 +851,7 @@ void sqlite3Insert( ** table column affinities. */ if( !isView ){ - sqlite3VdbeAddOp2(v, OP_Affinity, regCols+1, pTab->nCol); - sqlite3TableAffinityStr(v, pTab); + sqlite3TableAffinity(v, pTab, regCols+1); } /* Fire BEFORE or INSTEAD OF triggers */ @@ -1153,6 +1157,7 @@ void sqlite3GenerateConstraintChecks( int ipkTop = 0; /* Top of the rowid change constraint check */ int ipkBottom = 0; /* Bottom of the rowid change constraint check */ u8 isUpdate; /* True if this is an UPDATE operation */ + u8 bAffinityDone = 0; /* True if the OP_Affinity operation has been run */ int regRowid = -1; /* Register holding ROWID value */ isUpdate = regOldData!=0; @@ -1364,6 +1369,10 @@ void sqlite3GenerateConstraintChecks( int addrUniqueOk; /* Jump here if the UNIQUE constraint is satisfied */ if( aRegIdx[ix]==0 ) continue; /* Skip indices that do not change */ + if( bAffinityDone==0 ){ + sqlite3TableAffinity(v, pTab, regNewData+1); + bAffinityDone = 1; + } iThisCur = iIdxCur+ix; addrUniqueOk = sqlite3VdbeMakeLabel(v); @@ -1394,7 +1403,6 @@ void sqlite3GenerateConstraintChecks( VdbeComment((v, "%s", iField<0 ? "rowid" : pTab->aCol[iField].zName)); } sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn, aRegIdx[ix]); - sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v, pIdx), P4_TRANSIENT); VdbeComment((v, "for %s", pIdx->zName)); sqlite3ExprCacheAffinityChange(pParse, regIdx, pIdx->nColumn); @@ -1539,12 +1547,14 @@ void sqlite3CompleteInsertion( int regData; /* Content registers (after the rowid) */ int regRec; /* Register holding assemblied record for the table */ int i; /* Loop counter */ + u8 bAffinityDone = 0; /* True if OP_Affinity has been run already */ v = sqlite3GetVdbe(pParse); assert( v!=0 ); assert( pTab->pSelect==0 ); /* This table is not a VIEW */ for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ if( aRegIdx[i]==0 ) continue; + bAffinityDone = 1; if( pIdx->pPartIdxWhere ){ sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2); } @@ -1561,7 +1571,7 @@ void sqlite3CompleteInsertion( regData = regNewData + 1; regRec = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp3(v, OP_MakeRecord, regData, pTab->nCol, regRec); - sqlite3TableAffinityStr(v, pTab); + if( !bAffinityDone ) sqlite3TableAffinity(v, pTab, 0); sqlite3ExprCacheAffinityChange(pParse, regData, pTab->nCol); if( pParse->nested ){ pik_flags = 0; diff --git a/src/pragma.c b/src/pragma.c index 7383bce96f..969dce8664 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1727,9 +1727,8 @@ void sqlite3Pragma( sqlite3VdbeAddOp2(v, OP_IsNull, regRow+j, addrOk); } if( pParent ){ - sqlite3VdbeAddOp3(v, OP_MakeRecord, regRow, pFK->nCol, regKey); - sqlite3VdbeChangeP4(v, -1, - sqlite3IndexAffinityStr(v,pIdx), P4_TRANSIENT); + sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, pFK->nCol, regKey, + sqlite3IndexAffinityStr(v,pIdx), pFK->nCol); sqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regKey, 0); } } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index a82b2e737e..392517c8d7 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3224,7 +3224,7 @@ int sqlite3VarintLen(u64 v); const char *sqlite3IndexAffinityStr(Vdbe *, Index *); -void sqlite3TableAffinityStr(Vdbe *, Table *); +void sqlite3TableAffinity(Vdbe*, Table*, int); char sqlite3CompareAffinity(Expr *pExpr, char aff2); int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity); char sqlite3ExprAffinity(Expr *pExpr); diff --git a/src/update.c b/src/update.c index a7da4ce71f..41ce7f0c77 100644 --- a/src/update.c +++ b/src/update.c @@ -390,7 +390,7 @@ void sqlite3Update( regKey = iPk; }else{ sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, regKey, - sqlite3IndexAffinityStr(v, pPk), P4_TRANSIENT); + sqlite3IndexAffinityStr(v, pPk), nPk); sqlite3VdbeAddOp2(v, OP_IdxInsert, iEph, regKey); } sqlite3WhereEnd(pWInfo); @@ -524,8 +524,7 @@ void sqlite3Update( ** verified. One could argue that this is wrong. */ if( tmask&TRIGGER_BEFORE ){ - sqlite3VdbeAddOp2(v, OP_Affinity, regNew, pTab->nCol); - sqlite3TableAffinityStr(v, pTab); + sqlite3TableAffinity(v, pTab, regNew); sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges, TRIGGER_BEFORE, pTab, regOldRowid, onError, labelContinue); diff --git a/src/vdbe.c b/src/vdbe.c index 41ad66215d..5f046a63e2 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2498,7 +2498,6 @@ case OP_Affinity: { while( (cAff = *(zAffinity++))!=0 ){ assert( pIn1 <= &p->aMem[(p->nMem-p->nCursor)] ); assert( memIsValid(pIn1) ); - ExpandBlob(pIn1); applyAffinity(pIn1, cAff, encoding); pIn1++; } @@ -2576,8 +2575,9 @@ case OP_MakeRecord: { if( zAffinity ){ pRec = pData0; do{ - applyAffinity(pRec, *(zAffinity++), encoding); - }while( (++pRec)<=pLast ); + applyAffinity(pRec++, *(zAffinity++), encoding); + assert( zAffinity[0]==0 || pRec<=pLast ); + }while( zAffinity[0] ); } /* Loop through the elements that will make up the record to figure From 8be09304b79dd5a2d5f53ca00b01ba9fcf81f21d Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 17 Feb 2014 15:40:19 +0000 Subject: [PATCH 265/276] Add a test case for OP_SoftNull. FossilOrigin-Name: f29d194e03d6bcc78bf883b77e591dbccada02f0 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/insert.test | 10 ++++++++++ 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 3a3470f9c7..41fc121645 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\sVDBE_PROFILE\sfixes\sfrom\strunk. -D 2014-02-17T15:36:39.392 +C Add\sa\stest\scase\sfor\sOP_SoftNull. +D 2014-02-17T15:40:19.609 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -613,7 +613,7 @@ F test/index7.test a3baf9a625bda7fd49471e99aeae04095fbfeecf F test/indexedby.test b2f22f3e693a53813aa3f50b812eb609ba6df1ec F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7 -F test/insert.test c120294273b18cf9c8b1a3158131f7a825bdba41 +F test/insert.test acf909b067b838eb55338d619e800e148c17f1f5 F test/insert2.test 4f3a04d168c728ed5ec2c88842e772606c7ce435 F test/insert3.test 1b7db95a03ad9c5013fdf7d6722b6cd66ee55e30 F test/insert4.test 4791662c50518bdd37d394cae9a7a8014e845bb3 @@ -1151,7 +1151,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 35b4d6e938164fabaf30b504c54cfd9a69060cee 7adb3da235c8c162c84f05ef4ccf1cc463805d5f -R 2b995c2f8f9fb3c739cf787130cc4e23 +P 2914e4191121004a3f564b1fbf1c235dcc595503 +R b009af851099e49da0fb1800028a0b8c U drh -Z a75f767ce30ab2f817d9dd9884981718 +Z ba859408f13b87421335d53499aa861e diff --git a/manifest.uuid b/manifest.uuid index 5178dd9e5a..6e6a7e7211 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2914e4191121004a3f564b1fbf1c235dcc595503 \ No newline at end of file +f29d194e03d6bcc78bf883b77e591dbccada02f0 \ No newline at end of file diff --git a/test/insert.test b/test/insert.test index 83168122ab..776bce1146 100644 --- a/test/insert.test +++ b/test/insert.test @@ -403,6 +403,16 @@ ifcapable compound { } {1 {all VALUES must have the same number of terms}} } +# Need for the OP_SoftNull opcode +# +do_execsql_test insert-11.1 { + CREATE TABLE t11a AS SELECT '123456789' AS x; + CREATE TABLE t11b (a INTEGER PRIMARY KEY, b, c); + INSERT INTO t11b SELECT x, x, x FROM t11a; + SELECT quote(a), quote(b), quote(c) FROM t11b; +} {123456789 '123456789' '123456789'} + + integrity_check insert-99.0 finish_test From 688852ab15b7d9f6a3c1f113f25f3c72bcfe3856 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 17 Feb 2014 22:40:43 +0000 Subject: [PATCH 266/276] Add logic to do test coverage measurements on the VDBE code. FossilOrigin-Name: ce184c7bb16988641d37c908d9b3042456d4be3d --- manifest | 48 ++++++++++++++-------------- manifest.uuid | 2 +- src/alter.c | 2 +- src/analyze.c | 8 +++-- src/build.c | 12 +++---- src/delete.c | 12 +++++-- src/expr.c | 46 +++++++++++++++++---------- src/fkey.c | 18 ++++++----- src/insert.c | 54 ++++++++++++++++++-------------- src/main.c | 15 +++++++++ src/pragma.c | 48 +++++++++++++++------------- src/select.c | 83 +++++++++++++++++++++++++++---------------------- src/sqlite.h.in | 3 +- src/sqliteInt.h | 7 +++++ src/trigger.c | 3 +- src/update.c | 19 ++++++++--- src/vdbe.c | 70 ++++++++++++++++++++++++++++++++--------- src/vdbe.h | 15 ++++++++- src/vdbeaux.c | 19 ++++++++++- src/vdbeblob.c | 5 ++- src/where.c | 38 ++++++++++++++++------ 21 files changed, 349 insertions(+), 178 deletions(-) diff --git a/manifest b/manifest index 41fc121645..79158f64cb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\stest\scase\sfor\sOP_SoftNull. -D 2014-02-17T15:40:19.609 +C Add\slogic\sto\sdo\stest\scoverage\smeasurements\son\sthe\sVDBE\scode. +D 2014-02-17T22:40:43.958 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -156,8 +156,8 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 3d8b83c91651f53472ca17599dae3457b8b89494 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c d5348d0f86a5fc8fb3987727402f023953c021cf -F src/analyze.c 3ec444402a5d9ac1018ac8c549f8e82ac23d4122 +F src/alter.c 829d67a359b7c5d37120be994af2c0eac730070c +F src/analyze.c 69761e1677142d180a9f55250dee2952f45e4793 F src/attach.c 3801129015ef59d76bf23c95ef9b0069d18a0c52 F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c a729e63cf5cd1829507cb7b8e89f99b95141bb53 @@ -166,26 +166,26 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btree.c b945df4f0114b4cc71006acc2fbb1333fb33a200 F src/btree.h 9e0f97c01b972f779eb7655cfb4f8727fd6dc26f F src/btreeInt.h 0be66063468a520e4d66b80c7a1dc26d04ee6ea4 -F src/build.c 13b9d82181d95af7b00ec8a8e1304bac096432d4 +F src/build.c 00ce613bc2256e525c9195cb10d0df7bcc48d1f0 F src/callback.c 174e3c8656bc29f91d710ab61550d16eea34be98 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 -F src/delete.c 57a09d3d576dd15cd54d945b7b0b478bac71f379 -F src/expr.c 90bba0ca6ec97d6857458f08a8ad2820130e13cf +F src/delete.c a00bf893bd39868c51020eba1fc5182eb36bfeb7 +F src/expr.c d1a8ccbf7e4dac6198674d33853e8ed01072eca4 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb -F src/fkey.c b3da26dfcd53a68e1b7162a84e0bf70e54092647 +F src/fkey.c 3cd6ce998404fb1b7203d886d6fdff71cf3c8846 F src/func.c f4499b39d66b71825514334ce67b32ff14bd19f5 F src/global.c 1d7bb7ea8254ae6a68ed9bfaf65fcb3d1690b486 F src/hash.c d139319967164f139c8d1bb8a11b14db9c4ba3cd F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c ddc56dc855069ddf530127a346ddc2e67f0396e6 +F src/insert.c 5d5e1d78f74804739b424c92346bdc26c146dfa4 F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b F src/loadext.c 867c7b330b740c6c917af9956b13b81d0a048303 -F src/main.c 07225af6a00be0b7f34ac52e60f99cf5cbb2a475 +F src/main.c e054917b1beb3081b0f23e8bdd3d6c0e12933dd3 F src/malloc.c 0203ebce9152c6a0e5de520140b8ba65187350be F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c0c990fcaddff810ea277b4fb5d9138603dd5d4b @@ -210,18 +210,18 @@ F src/parse.y cce844ccb80b5f969b04c25100c8d94338488efb F src/pcache.c d8eafac28290d4bb80332005435db44991d07fc2 F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222 F src/pcache1.c 102e6f5a2fbc646154463eb856d1fd716867b64c -F src/pragma.c 769d08f10b7848dbd1950d0723bfcb12fb22b7f3 +F src/pragma.c 2635d6bf8b54003ebefd773df2f50258cece2bec F src/prepare.c 677521ab7132615a8a26107a1d1c3132f44ae337 F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c ca8b99d894164435f5c55cb304c1b8121705c51e F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c ebec4d3fad7fd5aa33cd69e2f50e9c109285dc73 +F src/select.c 618b53bd4553bd7a9ef95069396f12a8f28489e7 F src/shell.c 3dd86bf73ccd079f0e32ef5069600586085e8239 -F src/sqlite.h.in eed7f7d66a60daaa7b4a597dcd9bad87aad9611b +F src/sqlite.h.in a2ef671f92747a5a1c8a47bad5c585a8dd9eca80 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h c5ba0868bddac9fdb0df4686ab43150fefb27da5 +F src/sqliteInt.h 004bd50575a05eefba7228c2d0fee432a53200de F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -272,17 +272,17 @@ F src/test_vfs.c e72f555ef7a59080f898fcf1a233deb9eb704ea9 F src/test_vfstrace.c 3a0ab304682fecbceb689e7d9b904211fde11d78 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/tokenize.c 6da2de6e12218ccb0aea5184b56727d011f4bee7 -F src/trigger.c a417d386e214f0abd2e0f756b834b4d9f4d3368a -F src/update.c b126167ee39470b6148fa3f89182e7c855dc15d0 +F src/trigger.c a80036fcbd992729adc7cd34a875d59a71fa10cc +F src/update.c 16d6555a32298da18ce6e2a00637c462d9e3ac97 F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c c46c90459ef9bdc0c6c73803cf4c55425b4771cf F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c e3ba6ad0111dbd4234fef5e119dbe30d0abb3cf1 -F src/vdbe.h e6c4c610fcabad4fa80ebb1efc6822a9367e2b26 +F src/vdbe.c 392f03b25152eb44565a78b8b809743c97e5852b +F src/vdbe.h f429f5e5e14b02acbdffb2b2e8ba6e865e66e320 F src/vdbeInt.h 5286af9067cabdb8ba57b87c0c988a931be6c6c8 F src/vdbeapi.c 5bc41aaea448a7fc250902c418f1795859be3820 -F src/vdbeaux.c 9098973ff22c6fdfd68d061e11c2e64f65eea2d1 -F src/vdbeblob.c 9542e116c1db5ed813977581d506c176e117c0ec +F src/vdbeaux.c 0e01d6fda149c689039caadb8c89b20abb58e21d +F src/vdbeblob.c d939997de046b8fcc607cfee4248f3d33dbcca50 F src/vdbemem.c 06603e8e9d2f3247b68c6bbe4bd37fb6721b5bda F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147 F src/vdbetrace.c 6f52bc0c51e144b7efdcfb2a8f771167a8816767 @@ -290,7 +290,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 76e7fc6de229bea8b30bb2539110f03a494dc3a8 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45 -F src/where.c 7d9c988741c7d0e4a57774ae4b56e59675c4014a +F src/where.c 7825dce3f92d7c7de9329505deefe176cbd5ba43 F src/whereInt.h 921f935af8b684ffb49705610bda7284db1db138 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1151,7 +1151,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 2914e4191121004a3f564b1fbf1c235dcc595503 -R b009af851099e49da0fb1800028a0b8c +P f29d194e03d6bcc78bf883b77e591dbccada02f0 +R 3842d7f2fc20472907a26e6db9a0b24a U drh -Z ba859408f13b87421335d53499aa861e +Z 8a746710251048df8d65813e18590ec6 diff --git a/manifest.uuid b/manifest.uuid index 6e6a7e7211..be861c2b1c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f29d194e03d6bcc78bf883b77e591dbccada02f0 \ No newline at end of file +ce184c7bb16988641d37c908d9b3042456d4be3d \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index 67070a5891..b8bf20cfd9 100644 --- a/src/alter.c +++ b/src/alter.c @@ -604,7 +604,7 @@ void sqlite3MinimumFileFormat(Parse *pParse, int iDb, int minFormat){ sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, r1, BTREE_FILE_FORMAT); sqlite3VdbeUsesBtree(v, iDb); sqlite3VdbeAddOp2(v, OP_Integer, minFormat, r2); - j1 = sqlite3VdbeAddOp3(v, OP_Ge, r2, 0, r1); + j1 = sqlite3VdbeAddOp3(v, OP_Ge, r2, 0, r1); VdbeCoverage(v); sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, r2); sqlite3VdbeJumpHere(v, j1); sqlite3ReleaseTempReg(pParse, r1); diff --git a/src/analyze.c b/src/analyze.c index 8e230f7571..235a2abaf8 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -1077,6 +1077,7 @@ static void analyzeOneTable( ** */ addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur); + VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_Integer, 0, regChng); addrGotoChng0 = sqlite3VdbeAddOp0(v, OP_Goto); @@ -1098,6 +1099,7 @@ static void analyzeOneTable( aGotoChng[i] = sqlite3VdbeAddOp4(v, OP_Ne, regTemp, 0, regPrev+i, pColl, P4_COLLSEQ); sqlite3VdbeChangeP5(v, SQLITE_NULLEQ); + VdbeCoverage(v); } sqlite3VdbeAddOp2(v, OP_Integer, nCol, regChng); aGotoChng[nCol] = sqlite3VdbeAddOp0(v, OP_Goto); @@ -1144,7 +1146,7 @@ static void analyzeOneTable( sqlite3VdbeAddOp3(v, OP_Function, 1, regStat4, regTemp); sqlite3VdbeChangeP4(v, -1, (char*)&statPushFuncdef, P4_FUNCDEF); sqlite3VdbeChangeP5(v, 2+IsStat34); - sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); + sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v); /* Add the entry to the stat1 table. */ callStatGet(v, regStat4, STAT_GET_STAT1, regStat1); @@ -1171,10 +1173,12 @@ static void analyzeOneTable( addrNext = sqlite3VdbeCurrentAddr(v); callStatGet(v, regStat4, STAT_GET_ROWID, regSampleRowid); addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regSampleRowid); + VdbeCoverage(v); callStatGet(v, regStat4, STAT_GET_NEQ, regEq); callStatGet(v, regStat4, STAT_GET_NLT, regLt); callStatGet(v, regStat4, STAT_GET_NDLT, regDLt); sqlite3VdbeAddOp4Int(v, seekOp, iTabCur, addrNext, regSampleRowid, 0); + VdbeCoverage(v); #ifdef SQLITE_ENABLE_STAT3 sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, pIdx->aiColumn[0], regSample); @@ -1205,7 +1209,7 @@ static void analyzeOneTable( if( pOnlyIdx==0 && needTableCnt ){ VdbeComment((v, "%s", pTab->zName)); sqlite3VdbeAddOp2(v, OP_Count, iTabCur, regStat1); - jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, regStat1); + jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, regStat1); VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_Null, 0, regIdxname); sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "aaa", 0); sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid); diff --git a/src/build.c b/src/build.c index 99bba67dd2..5b6c87f220 100644 --- a/src/build.c +++ b/src/build.c @@ -948,7 +948,7 @@ void sqlite3StartTable( reg3 = ++pParse->nMem; sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, reg3, BTREE_FILE_FORMAT); sqlite3VdbeUsesBtree(v, iDb); - j1 = sqlite3VdbeAddOp1(v, OP_If, reg3); + j1 = sqlite3VdbeAddOp1(v, OP_If, reg3); VdbeCoverage(v); fileFormat = (db->flags & SQLITE_LegacyFileFmt)!=0 ? 1 : SQLITE_MAX_FILE_FORMAT; sqlite3VdbeAddOp2(v, OP_Integer, fileFormat, reg3); @@ -2675,27 +2675,27 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ /* Open the table. Loop through all rows of the table, inserting index ** records into the sorter. */ sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead); - addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0); + addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0); VdbeCoverage(v); regRecord = sqlite3GetTempReg(pParse); sqlite3GenerateIndexKey(pParse,pIndex,iTab,regRecord,0,&iPartIdxLabel,0,0); sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord); sqlite3VdbeResolveLabel(v, iPartIdxLabel); - sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1); + sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1); VdbeCoverage(v); sqlite3VdbeJumpHere(v, addr1); if( memRootPage<0 ) sqlite3VdbeAddOp2(v, OP_Clear, tnum, iDb); sqlite3VdbeAddOp4(v, OP_OpenWrite, iIdx, tnum, iDb, (char *)pKey, P4_KEYINFO); sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR|((memRootPage>=0)?OPFLAG_P2ISREG:0)); - addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0); + addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0); VdbeCoverage(v); assert( pKey!=0 || db->mallocFailed || pParse->nErr ); if( pIndex->onError!=OE_None && pKey!=0 ){ int j2 = sqlite3VdbeCurrentAddr(v) + 3; sqlite3VdbeAddOp2(v, OP_Goto, 0, j2); addr2 = sqlite3VdbeCurrentAddr(v); sqlite3VdbeAddOp4Int(v, OP_SorterCompare, iSorter, j2, regRecord, - pKey->nField - pIndex->nKeyCol); + pKey->nField - pIndex->nKeyCol); VdbeCoverage(v); sqlite3UniqueConstraint(pParse, OE_Abort, pIndex); }else{ addr2 = sqlite3VdbeCurrentAddr(v); @@ -2704,7 +2704,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 1); sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); sqlite3ReleaseTempReg(pParse, regRecord); - sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2); + sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2); VdbeCoverage(v); sqlite3VdbeJumpHere(v, addr1); sqlite3VdbeAddOp1(v, OP_Close, iTab); diff --git a/src/delete.c b/src/delete.c index 4ebda1b183..3fa41c53f0 100644 --- a/src/delete.c +++ b/src/delete.c @@ -481,13 +481,15 @@ void sqlite3DeleteFrom( if( aToOpen[iDataCur-iTabCur] ){ assert( pPk!=0 ); sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, addrBypass, iKey, nKey); + VdbeCoverage(v); } }else if( pPk ){ - addrLoop = sqlite3VdbeAddOp1(v, OP_Rewind, iEphCur); + addrLoop = sqlite3VdbeAddOp1(v, OP_Rewind, iEphCur); VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_RowKey, iEphCur, iKey); assert( nKey==0 ); /* OP_Found will use a composite key */ }else{ addrLoop = sqlite3VdbeAddOp3(v, OP_RowSetRead, iRowSet, 0, iKey); + VdbeCoverage(v); assert( nKey==1 ); } @@ -511,7 +513,7 @@ void sqlite3DeleteFrom( if( okOnePass ){ sqlite3VdbeResolveLabel(v, addrBypass); }else if( pPk ){ - sqlite3VdbeAddOp2(v, OP_Next, iEphCur, addrLoop+1); + sqlite3VdbeAddOp2(v, OP_Next, iEphCur, addrLoop+1); VdbeCoverage(v); sqlite3VdbeJumpHere(v, addrLoop); }else{ sqlite3VdbeAddOp2(v, OP_Goto, 0, addrLoop); @@ -609,7 +611,10 @@ void sqlite3GenerateRowDelete( ** not attempt to delete it or fire any DELETE triggers. */ iLabel = sqlite3VdbeMakeLabel(v); opSeek = HasRowid(pTab) ? OP_NotExists : OP_NotFound; - if( !bNoSeek ) sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk); + if( !bNoSeek ){ + sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk); + VdbeCoverage(v); + } /* If there are any triggers to fire, allocate a range of registers to ** use for the old.* references in the triggers. */ @@ -651,6 +656,7 @@ void sqlite3GenerateRowDelete( */ if( addrStartnOnce++); + int addr = sqlite3VdbeAddOp1(v, OP_Once, pParse->nOnce++); + VdbeCoverage(v); + return addr; } /* @@ -1837,6 +1839,7 @@ int sqlite3CodeSubselect( if( isRowid ){ sqlite3VdbeAddOp2(v, OP_MustBeInt, r3, sqlite3VdbeCurrentAddr(v)+2); + VdbeCoverage(v); sqlite3VdbeAddOp3(v, OP_Insert, pExpr->iTable, r2, r3); }else{ sqlite3VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1); @@ -1960,10 +1963,11 @@ static void sqlite3ExprCodeIN( if( destIfNull==destIfFalse ){ /* Shortcut for the common case where the false and NULL outcomes are ** the same. */ - sqlite3VdbeAddOp2(v, OP_IsNull, r1, destIfNull); + sqlite3VdbeAddOp2(v, OP_IsNull, r1, destIfNull); VdbeCoverage(v); }else{ - int addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, r1); + int addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, r1); VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_Rewind, pExpr->iTable, destIfFalse); + VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfNull); sqlite3VdbeJumpHere(v, addr1); } @@ -1971,8 +1975,9 @@ static void sqlite3ExprCodeIN( if( eType==IN_INDEX_ROWID ){ /* In this case, the RHS is the ROWID of table b-tree */ - sqlite3VdbeAddOp2(v, OP_MustBeInt, r1, destIfFalse); + sqlite3VdbeAddOp2(v, OP_MustBeInt, r1, destIfFalse); VdbeCoverage(v); sqlite3VdbeAddOp3(v, OP_NotExists, pExpr->iTable, destIfFalse, r1); + VdbeCoverage(v); }else{ /* In this case, the RHS is an index b-tree. */ @@ -1993,7 +1998,7 @@ static void sqlite3ExprCodeIN( ** for this particular IN operator. */ sqlite3VdbeAddOp4Int(v, OP_NotFound, pExpr->iTable, destIfFalse, r1, 1); - + VdbeCoverage(v); }else{ /* In this branch, the RHS of the IN might contain a NULL and ** the presence of a NULL on the RHS makes a difference in the @@ -2006,6 +2011,7 @@ static void sqlite3ExprCodeIN( ** over all of the code that follows. */ j1 = sqlite3VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0, r1, 1); + VdbeCoverage(v); /* Here we begin generating code that runs if the LHS is not ** contained within the RHS. Generate additional code that @@ -2013,8 +2019,9 @@ static void sqlite3ExprCodeIN( ** jump to destIfNull. If there are no NULLs in the RHS then ** jump to destIfFalse. */ - j2 = sqlite3VdbeAddOp1(v, OP_NotNull, rRhsHasNull); + j2 = sqlite3VdbeAddOp1(v, OP_NotNull, rRhsHasNull); VdbeCoverage(v); j3 = sqlite3VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0, rRhsHasNull, 1); + VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_Integer, -1, rRhsHasNull); sqlite3VdbeJumpHere(v, j3); sqlite3VdbeAddOp2(v, OP_AddImm, rRhsHasNull, 1); @@ -2023,7 +2030,7 @@ static void sqlite3ExprCodeIN( /* Jump to the appropriate target depending on whether or not ** the RHS contains a NULL */ - sqlite3VdbeAddOp2(v, OP_If, rRhsHasNull, destIfNull); + sqlite3VdbeAddOp2(v, OP_If, rRhsHasNull, destIfNull); VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfFalse); /* The OP_Found at the top of this branch jumps here when true, @@ -2560,7 +2567,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, - r1, r2, inReg, SQLITE_STOREP2); + r1, r2, inReg, SQLITE_STOREP2); VdbeCoverage(v); testcase( regFree1==0 ); testcase( regFree2==0 ); break; @@ -2574,6 +2581,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ op = (op==TK_IS) ? TK_EQ : TK_NE; codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, r1, r2, inReg, SQLITE_STOREP2 | SQLITE_NULLEQ); + VdbeCoverage(v); testcase( regFree1==0 ); testcase( regFree2==0 ); break; @@ -2663,7 +2671,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ sqlite3VdbeAddOp2(v, OP_Integer, 1, target); r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); testcase( regFree1==0 ); - addr = sqlite3VdbeAddOp1(v, op, r1); + addr = sqlite3VdbeAddOp1(v, op, r1); VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_AddImm, target, -1); sqlite3VdbeJumpHere(v, addr); break; @@ -2715,6 +2723,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ sqlite3ExprCode(pParse, pFarg->a[0].pExpr, target); for(i=1; ia[i].pExpr, target); @@ -2853,12 +2862,14 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ r4 = sqlite3GetTempReg(pParse); codeCompare(pParse, pLeft, pRight, OP_Ge, r1, r2, r3, SQLITE_STOREP2); + VdbeCoverage(v); pLItem++; pRight = pLItem->pExpr; sqlite3ReleaseTempReg(pParse, regFree2); r2 = sqlite3ExprCodeTemp(pParse, pRight, ®Free2); testcase( regFree2==0 ); codeCompare(pParse, pLeft, pRight, OP_Le, r1, r2, r4, SQLITE_STOREP2); + VdbeCoverage(v); sqlite3VdbeAddOp3(v, OP_And, r3, r4, target); sqlite3ReleaseTempReg(pParse, r3); sqlite3ReleaseTempReg(pParse, r4); @@ -3025,6 +3036,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ if( pExpr->affinity==OE_Ignore ){ sqlite3VdbeAddOp4( v, OP_Halt, SQLITE_OK, OE_Ignore, 0, pExpr->u.zToken,0); + VdbeCoverage(v); }else{ sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_TRIGGER, pExpr->affinity, pExpr->u.zToken, 0, 0); @@ -3613,7 +3625,7 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, - r1, r2, dest, jumpIfNull); + r1, r2, dest, jumpIfNull); VdbeCoverage(v); testcase( regFree1==0 ); testcase( regFree2==0 ); break; @@ -3626,7 +3638,7 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); op = (op==TK_IS) ? TK_EQ : TK_NE; codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, - r1, r2, dest, SQLITE_NULLEQ); + r1, r2, dest, SQLITE_NULLEQ); VdbeCoverage(v); testcase( regFree1==0 ); testcase( regFree2==0 ); break; @@ -3638,7 +3650,7 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ testcase( op==TK_ISNULL ); testcase( op==TK_NOTNULL ); r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); - sqlite3VdbeAddOp2(v, op, r1, dest); + sqlite3VdbeAddOp2(v, op, r1, dest); VdbeCoverage(v); testcase( regFree1==0 ); break; } @@ -3665,6 +3677,7 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ }else{ r1 = sqlite3ExprCodeTemp(pParse, pExpr, ®Free1); sqlite3VdbeAddOp3(v, OP_If, r1, dest, jumpIfNull!=0); + VdbeCoverage(v); testcase( regFree1==0 ); testcase( jumpIfNull==0 ); } @@ -3766,7 +3779,7 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, - r1, r2, dest, jumpIfNull); + r1, r2, dest, jumpIfNull); VdbeCoverage(v); testcase( regFree1==0 ); testcase( regFree2==0 ); break; @@ -3779,7 +3792,7 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); op = (pExpr->op==TK_IS) ? TK_NE : TK_EQ; codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, - r1, r2, dest, SQLITE_NULLEQ); + r1, r2, dest, SQLITE_NULLEQ); VdbeCoverage(v); testcase( regFree1==0 ); testcase( regFree2==0 ); break; @@ -3789,7 +3802,7 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ testcase( op==TK_ISNULL ); testcase( op==TK_NOTNULL ); r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); - sqlite3VdbeAddOp2(v, op, r1, dest); + sqlite3VdbeAddOp2(v, op, r1, dest); VdbeCoverage(v); testcase( regFree1==0 ); break; } @@ -3818,6 +3831,7 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ }else{ r1 = sqlite3ExprCodeTemp(pParse, pExpr, ®Free1); sqlite3VdbeAddOp3(v, OP_IfNot, r1, dest, jumpIfNull!=0); + VdbeCoverage(v); testcase( regFree1==0 ); testcase( jumpIfNull==0 ); } diff --git a/src/fkey.c b/src/fkey.c index c094783a85..c94f969238 100644 --- a/src/fkey.c +++ b/src/fkey.c @@ -340,10 +340,11 @@ static void fkLookupParent( ** search for a matching row in the parent table. */ if( nIncr<0 ){ sqlite3VdbeAddOp2(v, OP_FkIfZero, pFKey->isDeferred, iOk); + VdbeCoverage(v); } for(i=0; inCol; i++){ int iReg = aiCol[i] + regData + 1; - sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iOk); + sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iOk); VdbeCoverage(v); } if( isIgnore==0 ){ @@ -360,17 +361,18 @@ static void fkLookupParent( ** will have INTEGER affinity applied to it, which may not be correct. */ sqlite3VdbeAddOp2(v, OP_SCopy, aiCol[0]+1+regData, regTemp); iMustBeInt = sqlite3VdbeAddOp2(v, OP_MustBeInt, regTemp, 0); + VdbeCoverage(v); /* If the parent table is the same as the child table, and we are about ** to increment the constraint-counter (i.e. this is an INSERT operation), ** then check if the row being inserted matches itself. If so, do not ** increment the constraint-counter. */ if( pTab==pFKey->pFrom && nIncr==1 ){ - sqlite3VdbeAddOp3(v, OP_Eq, regData, iOk, regTemp); + sqlite3VdbeAddOp3(v, OP_Eq, regData, iOk, regTemp); VdbeCoverage(v); } sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead); - sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, regTemp); + sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, regTemp); VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_Goto, 0, iOk); sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2); sqlite3VdbeJumpHere(v, iMustBeInt); @@ -406,7 +408,7 @@ static void fkLookupParent( /* The parent key is a composite key that includes the IPK column */ iParent = regData; } - sqlite3VdbeAddOp3(v, OP_Ne, iChild, iJump, iParent); + sqlite3VdbeAddOp3(v, OP_Ne, iChild, iJump, iParent); VdbeCoverage(v); sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL); } sqlite3VdbeAddOp2(v, OP_Goto, 0, iOk); @@ -414,7 +416,7 @@ static void fkLookupParent( sqlite3VdbeAddOp4(v, OP_MakeRecord, regTemp, nCol, regRec, sqlite3IndexAffinityStr(v,pIdx), nCol); - sqlite3VdbeAddOp4Int(v, OP_Found, iCur, iOk, regRec, 0); + sqlite3VdbeAddOp4Int(v, OP_Found, iCur, iOk, regRec, 0); VdbeCoverage(v); sqlite3ReleaseTempReg(pParse, regRec); sqlite3ReleaseTempRange(pParse, regTemp, nCol); @@ -552,6 +554,7 @@ static void fkScanChildren( if( nIncr<0 ){ iFkIfZero = sqlite3VdbeAddOp2(v, OP_FkIfZero, pFKey->isDeferred, 0); + VdbeCoverage(v); } /* Create an Expr object representing an SQL expression like: @@ -714,7 +717,7 @@ void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTab){ } if( !p ) return; iSkip = sqlite3VdbeMakeLabel(v); - sqlite3VdbeAddOp2(v, OP_FkIfZero, 1, iSkip); + sqlite3VdbeAddOp2(v, OP_FkIfZero, 1, iSkip); VdbeCoverage(v); } pParse->disableTriggers = 1; @@ -732,6 +735,7 @@ void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTab){ */ if( (db->flags & SQLITE_DeferFKs)==0 ){ sqlite3VdbeAddOp2(v, OP_FkIfZero, 0, sqlite3VdbeCurrentAddr(v)+2); + VdbeCoverage(v); sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_FOREIGNKEY, OE_Abort, 0, P4_STATIC, P5_ConstraintFK); } @@ -891,7 +895,7 @@ void sqlite3FkCheck( int iJump = sqlite3VdbeCurrentAddr(v) + pFKey->nCol + 1; for(i=0; inCol; i++){ int iReg = pFKey->aCol[i].iFrom + regOld + 1; - sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iJump); + sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iJump); VdbeCoverage(v); } sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, -1); } diff --git a/src/insert.c b/src/insert.c index a9c0641474..64786ee112 100644 --- a/src/insert.c +++ b/src/insert.c @@ -262,14 +262,14 @@ void sqlite3AutoincrementBegin(Parse *pParse){ sqlite3VdbeAddOp3(v, OP_Null, 0, memId, memId+1); addr = sqlite3VdbeCurrentAddr(v); sqlite3VdbeAddOp4(v, OP_String8, 0, memId-1, 0, p->pTab->zName, 0); - sqlite3VdbeAddOp2(v, OP_Rewind, 0, addr+9); + sqlite3VdbeAddOp2(v, OP_Rewind, 0, addr+9); VdbeCoverage(v); sqlite3VdbeAddOp3(v, OP_Column, 0, 0, memId); - sqlite3VdbeAddOp3(v, OP_Ne, memId-1, addr+7, memId); + sqlite3VdbeAddOp3(v, OP_Ne, memId-1, addr+7, memId); VdbeCoverage(v); sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL); sqlite3VdbeAddOp2(v, OP_Rowid, 0, memId+1); sqlite3VdbeAddOp3(v, OP_Column, 0, 1, memId); sqlite3VdbeAddOp2(v, OP_Goto, 0, addr+9); - sqlite3VdbeAddOp2(v, OP_Next, 0, addr+2); + sqlite3VdbeAddOp2(v, OP_Next, 0, addr+2); VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_Integer, 0, memId); sqlite3VdbeAddOp0(v, OP_Close); } @@ -311,11 +311,11 @@ void sqlite3AutoincrementEnd(Parse *pParse){ iRec = sqlite3GetTempReg(pParse); assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) ); sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenWrite); - j1 = sqlite3VdbeAddOp1(v, OP_NotNull, memId+1); - j2 = sqlite3VdbeAddOp0(v, OP_Rewind); + j1 = sqlite3VdbeAddOp1(v, OP_NotNull, memId+1); VdbeCoverage(v); + j2 = sqlite3VdbeAddOp0(v, OP_Rewind); VdbeCoverage(v); j3 = sqlite3VdbeAddOp3(v, OP_Column, 0, 0, iRec); - j4 = sqlite3VdbeAddOp3(v, OP_Eq, memId-1, 0, iRec); - sqlite3VdbeAddOp2(v, OP_Next, 0, j3); + j4 = sqlite3VdbeAddOp3(v, OP_Eq, memId-1, 0, iRec); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Next, 0, j3); VdbeCoverage(v); sqlite3VdbeJumpHere(v, j2); sqlite3VdbeAddOp2(v, OP_NewRowid, 0, memId+1); j5 = sqlite3VdbeAddOp0(v, OP_Goto); @@ -692,7 +692,7 @@ void sqlite3Insert( regRec = sqlite3GetTempReg(pParse); regTempRowid = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp2(v, OP_OpenEphemeral, srcTab, nColumn); - addrTop = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); + addrTop = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); VdbeCoverage(v); sqlite3VdbeAddOp3(v, OP_MakeRecord, regFromSelect, nColumn, regRec); sqlite3VdbeAddOp2(v, OP_NewRowid, srcTab, regTempRowid); sqlite3VdbeAddOp3(v, OP_Insert, srcTab, regRec, regTempRowid); @@ -777,7 +777,7 @@ void sqlite3Insert( ** end loop ** D: ... */ - addrInsTop = sqlite3VdbeAddOp1(v, OP_Rewind, srcTab); + addrInsTop = sqlite3VdbeAddOp1(v, OP_Rewind, srcTab); VdbeCoverage(v); addrCont = sqlite3VdbeCurrentAddr(v); }else if( pSelect ){ /* This block codes the top of loop only. The complete loop is the @@ -789,6 +789,7 @@ void sqlite3Insert( ** D: ... */ addrInsTop = addrCont = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); + VdbeCoverage(v); } /* Run the BEFORE and INSTEAD OF triggers, if there are any @@ -814,10 +815,10 @@ void sqlite3Insert( assert( pSelect==0 ); /* Otherwise useTempTable is true */ sqlite3ExprCode(pParse, pList->a[ipkColumn].pExpr, regCols); } - j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regCols); + j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regCols); VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_Integer, -1, regCols); sqlite3VdbeJumpHere(v, j1); - sqlite3VdbeAddOp1(v, OP_MustBeInt, regCols); + sqlite3VdbeAddOp1(v, OP_MustBeInt, regCols); VdbeCoverage(v); } /* Cannot have triggers on a virtual table. If it were possible, @@ -892,14 +893,14 @@ void sqlite3Insert( if( !appendFlag ){ int j1; if( !IsVirtual(pTab) ){ - j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regRowid); + j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regRowid); VdbeCoverage(v); sqlite3VdbeAddOp3(v, OP_NewRowid, iDataCur, regRowid, regAutoinc); sqlite3VdbeJumpHere(v, j1); }else{ j1 = sqlite3VdbeCurrentAddr(v); - sqlite3VdbeAddOp2(v, OP_IsNull, regRowid, j1+2); + sqlite3VdbeAddOp2(v, OP_IsNull, regRowid, j1+2); VdbeCoverage(v); } - sqlite3VdbeAddOp1(v, OP_MustBeInt, regRowid); + sqlite3VdbeAddOp1(v, OP_MustBeInt, regRowid); VdbeCoverage(v); } }else if( IsVirtual(pTab) || withoutRowid ){ sqlite3VdbeAddOp2(v, OP_Null, 0, regRowid); @@ -990,7 +991,7 @@ void sqlite3Insert( */ sqlite3VdbeResolveLabel(v, endOfLoop); if( useTempTable ){ - sqlite3VdbeAddOp2(v, OP_Next, srcTab, addrCont); + sqlite3VdbeAddOp2(v, OP_Next, srcTab, addrCont); VdbeCoverage(v); sqlite3VdbeJumpHere(v, addrInsTop); sqlite3VdbeAddOp1(v, OP_Close, srcTab); }else if( pSelect ){ @@ -1212,15 +1213,17 @@ void sqlite3GenerateConstraintChecks( sqlite3VdbeAddOp4(v, OP_HaltIfNull, SQLITE_CONSTRAINT_NOTNULL, onError, regNewData+1+i, zMsg, P4_DYNAMIC); sqlite3VdbeChangeP5(v, P5_ConstraintNotNull); + VdbeCoverage(v); break; } case OE_Ignore: { sqlite3VdbeAddOp2(v, OP_IsNull, regNewData+1+i, ignoreDest); + VdbeCoverage(v); break; } default: { assert( onError==OE_Replace ); - j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regNewData+1+i); + j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regNewData+1+i); VdbeCoverage(v); sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regNewData+1+i); sqlite3VdbeJumpHere(v, j1); break; @@ -1272,6 +1275,7 @@ void sqlite3GenerateConstraintChecks( ** it might have changed. Skip the conflict logic below if the rowid ** is unchanged. */ sqlite3VdbeAddOp3(v, OP_Eq, regNewData, addrRowidOk, regOldData); + VdbeCoverage(v); } /* If the response to a rowid conflict is REPLACE but the response @@ -1291,6 +1295,7 @@ void sqlite3GenerateConstraintChecks( /* Check to see if the new rowid already exists in the table. Skip ** the following conflict logic if it does not. */ sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, addrRowidOk, regNewData); + VdbeCoverage(v); /* Generate code that deals with a rowid collision */ switch( onError ){ @@ -1430,7 +1435,7 @@ void sqlite3GenerateConstraintChecks( /* Check to see if the new index entry will be unique */ sqlite3VdbeAddOp4Int(v, OP_NoConflict, iThisCur, addrUniqueOk, - regIdx, pIdx->nKeyCol); + regIdx, pIdx->nKeyCol); VdbeCoverage(v); /* Generate code to handle collisions */ regR = (pIdx==pPk) ? regIdx : sqlite3GetTempRange(pParse, nPkField); @@ -1441,6 +1446,7 @@ void sqlite3GenerateConstraintChecks( ** is different from old-rowid */ if( isUpdate ){ sqlite3VdbeAddOp3(v, OP_Eq, regR, addrUniqueOk, regOldData); + VdbeCoverage(v); } }else{ int x; @@ -1475,7 +1481,7 @@ void sqlite3GenerateConstraintChecks( } sqlite3VdbeAddOp4(v, op, regOldData+1+x, addrJump, regCmp+i, p4, P4_COLLSEQ - ); + ); VdbeCoverage(v); } } } @@ -1557,6 +1563,7 @@ void sqlite3CompleteInsertion( bAffinityDone = 1; if( pIdx->pPartIdxWhere ){ sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2); + VdbeCoverage(v); } sqlite3VdbeAddOp2(v, OP_IdxInsert, iIdxCur+i, aRegIdx[i]); pik_flags = 0; @@ -1940,16 +1947,17 @@ static int xferOptimization( ** ** (3) onError is something other than OE_Abort and OE_Rollback. */ - addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iDest, 0); + addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iDest, 0); VdbeCoverage(v); emptyDestTest = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0); sqlite3VdbeJumpHere(v, addr1); } if( HasRowid(pSrc) ){ sqlite3OpenTable(pParse, iSrc, iDbSrc, pSrc, OP_OpenRead); - emptySrcTest = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); + emptySrcTest = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v); if( pDest->iPKey>=0 ){ addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid); addr2 = sqlite3VdbeAddOp3(v, OP_NotExists, iDest, 0, regRowid); + VdbeCoverage(v); sqlite3RowidConstraint(pParse, onError, pDest); sqlite3VdbeJumpHere(v, addr2); autoIncStep(pParse, regAutoinc, regRowid); @@ -1963,7 +1971,7 @@ static int xferOptimization( sqlite3VdbeAddOp3(v, OP_Insert, iDest, regData, regRowid); sqlite3VdbeChangeP5(v, OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND); sqlite3VdbeChangeP4(v, -1, pDest->zName, 0); - sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1); + sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1); VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0); sqlite3VdbeAddOp2(v, OP_Close, iDest, 0); }else{ @@ -1982,10 +1990,10 @@ static int xferOptimization( sqlite3VdbeSetP4KeyInfo(pParse, pDestIdx); sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR); VdbeComment((v, "%s", pDestIdx->zName)); - addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); + addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_RowKey, iSrc, regData); sqlite3VdbeAddOp3(v, OP_IdxInsert, iDest, regData, 1); - sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1); + sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1); VdbeCoverage(v); sqlite3VdbeJumpHere(v, addr1); sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0); sqlite3VdbeAddOp2(v, OP_Close, iDest, 0); diff --git a/src/main.c b/src/main.c index 45e31a8076..8b7495dd49 100644 --- a/src/main.c +++ b/src/main.c @@ -3307,6 +3307,21 @@ int sqlite3_test_control(int op, ...){ break; } + + /* sqlite3_test_control(SQLITE_TESTCTRL_VDBE_COVERAGE, xCallback, ptr); + ** + ** Set the VDBE coverage callback function to xCallback with context + ** pointer ptr. + */ + case SQLITE_TESTCTRL_VDBE_COVERAGE: { +#ifdef SQLITE_VDBE_COVERAGE + typedef void (*branch_callback)(void*,int,u8,u8); + sqlite3GlobalConfig.xVdbeBranch = va_arg(ap,branch_callback); + sqlite3GlobalConfig.pVdbeBranchArg = va_arg(ap,void*); +#endif + break; + } + } va_end(ap); #endif /* SQLITE_OMIT_BUILTIN_TEST */ diff --git a/src/pragma.c b/src/pragma.c index 969dce8664..a586370b8d 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -824,6 +824,7 @@ void sqlite3Pragma( ** size of historical compatibility. */ case PragTyp_DEFAULT_CACHE_SIZE: { + static const int iLn = __LINE__+2; static const VdbeOpList getCacheSize[] = { { OP_Transaction, 0, 0, 0}, /* 0 */ { OP_ReadCookie, 0, 1, BTREE_DEFAULT_CACHE_SIZE}, /* 1 */ @@ -841,7 +842,7 @@ void sqlite3Pragma( sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cache_size", SQLITE_STATIC); pParse->nMem += 2; - addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize); + addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize,iLn); sqlite3VdbeChangeP1(v, addr, iDb); sqlite3VdbeChangeP1(v, addr+1, iDb); sqlite3VdbeChangeP1(v, addr+6, SQLITE_DEFAULT_CACHE_SIZE); @@ -1086,6 +1087,7 @@ void sqlite3Pragma( ** file. Before writing to meta[6], check that meta[3] indicates ** that this really is an auto-vacuum capable database. */ + static const int iLn = __LINE__+2; static const VdbeOpList setMeta6[] = { { OP_Transaction, 0, 1, 0}, /* 0 */ { OP_ReadCookie, 0, 1, BTREE_LARGEST_ROOT_PAGE}, @@ -1095,7 +1097,7 @@ void sqlite3Pragma( { OP_SetCookie, 0, BTREE_INCR_VACUUM, 1}, /* 5 */ }; int iAddr; - iAddr = sqlite3VdbeAddOpList(v, ArraySize(setMeta6), setMeta6); + iAddr = sqlite3VdbeAddOpList(v, ArraySize(setMeta6), setMeta6, iLn); sqlite3VdbeChangeP1(v, iAddr, iDb); sqlite3VdbeChangeP1(v, iAddr+1, iDb); sqlite3VdbeChangeP2(v, iAddr+2, iAddr+4); @@ -1121,10 +1123,10 @@ void sqlite3Pragma( } sqlite3BeginWriteOperation(pParse, 0, iDb); sqlite3VdbeAddOp2(v, OP_Integer, iLimit, 1); - addr = sqlite3VdbeAddOp1(v, OP_IncrVacuum, iDb); + addr = sqlite3VdbeAddOp1(v, OP_IncrVacuum, iDb); VdbeCoverage(v); sqlite3VdbeAddOp1(v, OP_ResultRow, 1); sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); - sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr); + sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr); VdbeCoverage(v); sqlite3VdbeJumpHere(v, addr); break; } @@ -1695,7 +1697,7 @@ void sqlite3Pragma( assert( pParse->nErr>0 || pFK==0 ); if( pFK ) break; if( pParse->nTabnTab = i; - addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, 0); + addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, 0); VdbeCoverage(v); for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){ pParent = sqlite3FindTable(db, pFK->zTo, zDb); pIdx = 0; @@ -1711,25 +1713,26 @@ void sqlite3Pragma( if( iKey!=pTab->iPKey ){ sqlite3VdbeAddOp3(v, OP_Column, 0, iKey, regRow); sqlite3ColumnDefault(v, pTab, iKey, regRow); - sqlite3VdbeAddOp2(v, OP_IsNull, regRow, addrOk); - sqlite3VdbeAddOp2(v, OP_MustBeInt, regRow, - sqlite3VdbeCurrentAddr(v)+3); + sqlite3VdbeAddOp2(v, OP_IsNull, regRow, addrOk); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_MustBeInt, regRow, + sqlite3VdbeCurrentAddr(v)+3); VdbeCoverage(v); }else{ sqlite3VdbeAddOp2(v, OP_Rowid, 0, regRow); } - sqlite3VdbeAddOp3(v, OP_NotExists, i, 0, regRow); + sqlite3VdbeAddOp3(v, OP_NotExists, i, 0, regRow); VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_Goto, 0, addrOk); sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2); }else{ for(j=0; jnCol; j++){ sqlite3ExprCodeGetColumnOfTable(v, pTab, 0, aiCols ? aiCols[j] : pFK->aCol[j].iFrom, regRow+j); - sqlite3VdbeAddOp2(v, OP_IsNull, regRow+j, addrOk); + sqlite3VdbeAddOp2(v, OP_IsNull, regRow+j, addrOk); VdbeCoverage(v); } if( pParent ){ sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, pFK->nCol, regKey, sqlite3IndexAffinityStr(v,pIdx), pFK->nCol); sqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regKey, 0); + VdbeCoverage(v); } } sqlite3VdbeAddOp2(v, OP_Rowid, 0, regResult+1); @@ -1740,7 +1743,7 @@ void sqlite3Pragma( sqlite3VdbeResolveLabel(v, addrOk); sqlite3DbFree(db, aiCols); } - sqlite3VdbeAddOp2(v, OP_Next, 0, addrTop+1); + sqlite3VdbeAddOp2(v, OP_Next, 0, addrTop+1); VdbeCoverage(v); sqlite3VdbeJumpHere(v, addrTop); } } @@ -1787,6 +1790,7 @@ void sqlite3Pragma( ** messages have been generated, output OK. Otherwise output the ** error message */ + static const int iLn = __LINE__+2; static const VdbeOpList endCode[] = { { OP_AddImm, 1, 0, 0}, /* 0 */ { OP_IfNeg, 1, 0, 0}, /* 1 */ @@ -1835,6 +1839,7 @@ void sqlite3Pragma( sqlite3CodeVerifySchema(pParse, i); addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Halt if out of errors */ + VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_Halt, 0, 0); sqlite3VdbeJumpHere(v, addr); @@ -1866,7 +1871,7 @@ void sqlite3Pragma( /* Do the b-tree integrity checks */ sqlite3VdbeAddOp3(v, OP_IntegrityCk, 2, cnt, 1); sqlite3VdbeChangeP5(v, (u8)i); - addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2); + addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2); VdbeCoverage(v); sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zName), P4_DYNAMIC); @@ -1888,6 +1893,7 @@ void sqlite3Pragma( if( pTab->pIndex==0 ) continue; pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab); addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Stop if out of errors */ + VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_Halt, 0, 0); sqlite3VdbeJumpHere(v, addr); sqlite3ExprCacheClear(pParse); @@ -1898,7 +1904,7 @@ void sqlite3Pragma( sqlite3VdbeAddOp2(v, OP_Integer, 0, 8+j); /* index entries counter */ } pParse->nMem = MAX(pParse->nMem, 8+j); - sqlite3VdbeAddOp2(v, OP_Rewind, iDataCur, 0); + sqlite3VdbeAddOp2(v, OP_Rewind, iDataCur, 0); VdbeCoverage(v); loopTop = sqlite3VdbeAddOp2(v, OP_AddImm, 7, 1); for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ int jmp2, jmp3, jmp4; @@ -1908,7 +1914,7 @@ void sqlite3Pragma( pPrior = pIdx; sqlite3VdbeAddOp2(v, OP_AddImm, 8+j, 1); /* increment entry count */ jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, iIdxCur+j, 0, r1, - pIdx->nColumn); + pIdx->nColumn); VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */ sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, "row ", P4_STATIC); sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3); @@ -1918,13 +1924,13 @@ void sqlite3Pragma( sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0, pIdx->zName, P4_TRANSIENT); sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3); sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1); - jmp4 = sqlite3VdbeAddOp1(v, OP_IfPos, 1); + jmp4 = sqlite3VdbeAddOp1(v, OP_IfPos, 1); VdbeCoverage(v); sqlite3VdbeAddOp0(v, OP_Halt); sqlite3VdbeJumpHere(v, jmp4); sqlite3VdbeJumpHere(v, jmp2); sqlite3VdbeResolveLabel(v, jmp3); } - sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); + sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v); sqlite3VdbeJumpHere(v, loopTop-1); #ifndef SQLITE_OMIT_BTREECOUNT sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, @@ -1932,10 +1938,10 @@ void sqlite3Pragma( for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ if( pPk==pIdx ) continue; addr = sqlite3VdbeCurrentAddr(v); - sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr+2); + sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr+2); VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_Halt, 0, 0); sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3); - sqlite3VdbeAddOp3(v, OP_Eq, 8+j, addr+8, 3); + sqlite3VdbeAddOp3(v, OP_Eq, 8+j, addr+8, 3); VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pIdx->zName, P4_TRANSIENT); sqlite3VdbeAddOp3(v, OP_Concat, 3, 2, 7); @@ -1944,7 +1950,7 @@ void sqlite3Pragma( #endif /* SQLITE_OMIT_BTREECOUNT */ } } - addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode); + addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode, iLn); sqlite3VdbeChangeP2(v, addr, -mxErr); sqlite3VdbeJumpHere(v, addr+1); sqlite3VdbeChangeP4(v, addr+2, "ok", P4_STATIC); @@ -2082,7 +2088,7 @@ void sqlite3Pragma( { OP_Integer, 0, 1, 0}, /* 1 */ { OP_SetCookie, 0, 0, 1}, /* 2 */ }; - int addr = sqlite3VdbeAddOpList(v, ArraySize(setCookie), setCookie); + int addr = sqlite3VdbeAddOpList(v, ArraySize(setCookie), setCookie, 0); sqlite3VdbeChangeP1(v, addr, iDb); sqlite3VdbeChangeP1(v, addr+1, sqlite3Atoi(zRight)); sqlite3VdbeChangeP1(v, addr+2, iDb); @@ -2094,7 +2100,7 @@ void sqlite3Pragma( { OP_ReadCookie, 0, 1, 0}, /* 1 */ { OP_ResultRow, 1, 1, 0} }; - int addr = sqlite3VdbeAddOpList(v, ArraySize(readCookie), readCookie); + int addr = sqlite3VdbeAddOpList(v, ArraySize(readCookie), readCookie, 0); sqlite3VdbeChangeP1(v, addr, iDb); sqlite3VdbeChangeP1(v, addr+1, iDb); sqlite3VdbeChangeP3(v, addr+1, iCookie); diff --git a/src/select.c b/src/select.c index a41f4a8254..fcd8b7ea0b 100644 --- a/src/select.c +++ b/src/select.c @@ -455,7 +455,7 @@ static void pushOntoSorter( }else{ iLimit = pSelect->iLimit; } - addr1 = sqlite3VdbeAddOp1(v, OP_IfZero, iLimit); + addr1 = sqlite3VdbeAddOp1(v, OP_IfZero, iLimit); VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_AddImm, iLimit, -1); addr2 = sqlite3VdbeAddOp0(v, OP_Goto); sqlite3VdbeJumpHere(v, addr1); @@ -476,7 +476,7 @@ static void codeOffset( if( iOffset>0 && iContinue!=0 ){ int addr; sqlite3VdbeAddOp2(v, OP_AddImm, iOffset, -1); - addr = sqlite3VdbeAddOp1(v, OP_IfNeg, iOffset); + addr = sqlite3VdbeAddOp1(v, OP_IfNeg, iOffset); VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_Goto, 0, iContinue); VdbeComment((v, "skip OFFSET records")); sqlite3VdbeJumpHere(v, addr); @@ -504,7 +504,7 @@ static void codeDistinct( v = pParse->pVdbe; r1 = sqlite3GetTempReg(pParse); - sqlite3VdbeAddOp4Int(v, OP_Found, iTab, addrRepeat, iMem, N); + sqlite3VdbeAddOp4Int(v, OP_Found, iTab, addrRepeat, iMem, N); VdbeCoverage(v); sqlite3VdbeAddOp3(v, OP_MakeRecord, iMem, N, r1); sqlite3VdbeAddOp2(v, OP_IdxInsert, iTab, r1); sqlite3ReleaseTempReg(pParse, r1); @@ -644,9 +644,11 @@ static void selectInnerLoop( CollSeq *pColl = sqlite3ExprCollSeq(pParse, pEList->a[i].pExpr); if( iiLimit ){ - sqlite3VdbeAddOp3(v, OP_IfZero, p->iLimit, iBreak, -1); + sqlite3VdbeAddOp3(v, OP_IfZero, p->iLimit, iBreak, -1); VdbeCoverage(v); } } @@ -1080,12 +1083,13 @@ static void generateSortTail( int ptab2 = pParse->nTab++; sqlite3VdbeAddOp3(v, OP_OpenPseudo, ptab2, regSortOut, pOrderBy->nExpr+2); addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak); + VdbeCoverage(v); codeOffset(v, p->iOffset, addrContinue); sqlite3VdbeAddOp2(v, OP_SorterData, iTab, regSortOut); sqlite3VdbeAddOp3(v, OP_Column, ptab2, pOrderBy->nExpr+1, regRow); sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE); }else{ - addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak); + addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak); VdbeCoverage(v); codeOffset(v, p->iOffset, addrContinue); sqlite3VdbeAddOp3(v, OP_Column, iTab, pOrderBy->nExpr+1, regRow); } @@ -1143,9 +1147,9 @@ static void generateSortTail( */ sqlite3VdbeResolveLabel(v, addrContinue); if( p->selFlags & SF_UseSorter ){ - sqlite3VdbeAddOp2(v, OP_SorterNext, iTab, addr); + sqlite3VdbeAddOp2(v, OP_SorterNext, iTab, addr); VdbeCoverage(v); }else{ - sqlite3VdbeAddOp2(v, OP_Next, iTab, addr); + sqlite3VdbeAddOp2(v, OP_Next, iTab, addr); VdbeCoverage(v); } sqlite3VdbeResolveLabel(v, addrBreak); if( eDest==SRT_Output || eDest==SRT_Coroutine ){ @@ -1693,22 +1697,22 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){ } }else{ sqlite3ExprCode(pParse, p->pLimit, iLimit); - sqlite3VdbeAddOp1(v, OP_MustBeInt, iLimit); + sqlite3VdbeAddOp1(v, OP_MustBeInt, iLimit); VdbeCoverage(v); VdbeComment((v, "LIMIT counter")); - sqlite3VdbeAddOp2(v, OP_IfZero, iLimit, iBreak); + sqlite3VdbeAddOp2(v, OP_IfZero, iLimit, iBreak); VdbeCoverage(v); } if( p->pOffset ){ p->iOffset = iOffset = ++pParse->nMem; pParse->nMem++; /* Allocate an extra register for limit+offset */ sqlite3ExprCode(pParse, p->pOffset, iOffset); - sqlite3VdbeAddOp1(v, OP_MustBeInt, iOffset); + sqlite3VdbeAddOp1(v, OP_MustBeInt, iOffset); VdbeCoverage(v); VdbeComment((v, "OFFSET counter")); - addr1 = sqlite3VdbeAddOp1(v, OP_IfPos, iOffset); + addr1 = sqlite3VdbeAddOp1(v, OP_IfPos, iOffset); VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_Integer, 0, iOffset); sqlite3VdbeJumpHere(v, addr1); sqlite3VdbeAddOp3(v, OP_Add, iLimit, iOffset, iOffset+1); VdbeComment((v, "LIMIT+OFFSET")); - addr1 = sqlite3VdbeAddOp1(v, OP_IfPos, iLimit); + addr1 = sqlite3VdbeAddOp1(v, OP_IfPos, iLimit); VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_Integer, -1, iOffset+1); sqlite3VdbeJumpHere(v, addr1); } @@ -1897,7 +1901,7 @@ static void generateWithRecursiveQuery( if( rc ) goto end_of_recursive_query; /* Find the next row in the Queue and output that row */ - addrTop = sqlite3VdbeAddOp2(v, OP_Rewind, iQueue, addrBreak); + addrTop = sqlite3VdbeAddOp2(v, OP_Rewind, iQueue, addrBreak); VdbeCoverage(v); /* Transfer the next row in Queue over to Current */ sqlite3VdbeAddOp1(v, OP_NullRow, iCurrent); /* To reset column cache */ @@ -1913,7 +1917,10 @@ static void generateWithRecursiveQuery( codeOffset(v, regOffset, addrCont); selectInnerLoop(pParse, p, p->pEList, iCurrent, 0, 0, pDest, addrCont, addrBreak); - if( regLimit ) sqlite3VdbeAddOp3(v, OP_IfZero, regLimit, addrBreak, -1); + if( regLimit ){ + sqlite3VdbeAddOp3(v, OP_IfZero, regLimit, addrBreak, -1); + VdbeCoverage(v); + } sqlite3VdbeResolveLabel(v, addrCont); /* Execute the recursive SELECT taking the single row in Current as @@ -2073,7 +2080,7 @@ static int multiSelect( p->iLimit = pPrior->iLimit; p->iOffset = pPrior->iOffset; if( p->iLimit ){ - addr = sqlite3VdbeAddOp1(v, OP_IfZero, p->iLimit); + addr = sqlite3VdbeAddOp1(v, OP_IfZero, p->iLimit); VdbeCoverage(v); VdbeComment((v, "Jump ahead if LIMIT reached")); } explainSetInteger(iSub2, pParse->iNextSelectId); @@ -2180,12 +2187,12 @@ static int multiSelect( iBreak = sqlite3VdbeMakeLabel(v); iCont = sqlite3VdbeMakeLabel(v); computeLimitRegisters(pParse, p, iBreak); - sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak); + sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak); VdbeCoverage(v); iStart = sqlite3VdbeCurrentAddr(v); selectInnerLoop(pParse, p, p->pEList, unionTab, 0, 0, &dest, iCont, iBreak); sqlite3VdbeResolveLabel(v, iCont); - sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart); + sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart); VdbeCoverage(v); sqlite3VdbeResolveLabel(v, iBreak); sqlite3VdbeAddOp2(v, OP_Close, unionTab, 0); } @@ -2255,15 +2262,15 @@ static int multiSelect( iBreak = sqlite3VdbeMakeLabel(v); iCont = sqlite3VdbeMakeLabel(v); computeLimitRegisters(pParse, p, iBreak); - sqlite3VdbeAddOp2(v, OP_Rewind, tab1, iBreak); + sqlite3VdbeAddOp2(v, OP_Rewind, tab1, iBreak); VdbeCoverage(v); r1 = sqlite3GetTempReg(pParse); iStart = sqlite3VdbeAddOp2(v, OP_RowKey, tab1, r1); - sqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0); + sqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0); VdbeCoverage(v); sqlite3ReleaseTempReg(pParse, r1); selectInnerLoop(pParse, p, p->pEList, tab1, 0, 0, &dest, iCont, iBreak); sqlite3VdbeResolveLabel(v, iCont); - sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart); + sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart); VdbeCoverage(v); sqlite3VdbeResolveLabel(v, iBreak); sqlite3VdbeAddOp2(v, OP_Close, tab2, 0); sqlite3VdbeAddOp2(v, OP_Close, tab1, 0); @@ -2370,10 +2377,10 @@ static int generateOutputSubroutine( */ if( regPrev ){ int j1, j2; - j1 = sqlite3VdbeAddOp1(v, OP_IfNot, regPrev); + j1 = sqlite3VdbeAddOp1(v, OP_IfNot, regPrev); VdbeCoverage(v); j2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iSdst, regPrev+1, pIn->nSdst, (char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO); - sqlite3VdbeAddOp3(v, OP_Jump, j2+2, iContinue, j2+2); + sqlite3VdbeAddOp3(v, OP_Jump, j2+2, iContinue, j2+2); VdbeCoverage(v); sqlite3VdbeJumpHere(v, j1); sqlite3VdbeAddOp3(v, OP_Copy, pIn->iSdst, regPrev+1, pIn->nSdst-1); sqlite3VdbeAddOp2(v, OP_Integer, 1, regPrev); @@ -2474,7 +2481,7 @@ static int generateOutputSubroutine( /* Jump to the end of the loop if the LIMIT is reached. */ if( p->iLimit ){ - sqlite3VdbeAddOp3(v, OP_IfZero, p->iLimit, iBreak, -1); + sqlite3VdbeAddOp3(v, OP_IfZero, p->iLimit, iBreak, -1); VdbeCoverage(v); } /* Generate the subroutine return @@ -2790,6 +2797,7 @@ static int multiSelectOrderBy( VdbeNoopComment((v, "eof-A subroutine")); addrEofA = sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB); addrEofA_noB = sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, labelEnd); + VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_Goto, 0, addrEofA); p->nSelectRow += pPrior->nSelectRow; } @@ -2803,7 +2811,7 @@ static int multiSelectOrderBy( }else{ VdbeNoopComment((v, "eof-B subroutine")); addrEofB = sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA); - sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, labelEnd); + sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, labelEnd); VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_Goto, 0, addrEofB); } @@ -2811,7 +2819,7 @@ static int multiSelectOrderBy( */ VdbeNoopComment((v, "A-lt-B subroutine")); addrAltB = sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA); - sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, addrEofA); + sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, addrEofA); VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_Goto, 0, labelCmpr); /* Generate code to handle the case of A==B @@ -2824,7 +2832,7 @@ static int multiSelectOrderBy( }else{ VdbeNoopComment((v, "A-eq-B subroutine")); addrAeqB = - sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, addrEofA); + sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, addrEofA); VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_Goto, 0, labelCmpr); } @@ -2835,14 +2843,14 @@ static int multiSelectOrderBy( if( op==TK_ALL || op==TK_UNION ){ sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB); } - sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, addrEofB); + sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, addrEofB); VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_Goto, 0, labelCmpr); /* This code runs once to initialize everything. */ sqlite3VdbeJumpHere(v, j1); - sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, addrEofA_noB); - sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, addrEofB); + sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, addrEofA_noB); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, addrEofB); VdbeCoverage(v); /* Implement the main merge loop */ @@ -2851,7 +2859,7 @@ static int multiSelectOrderBy( sqlite3VdbeAddOp4(v, OP_Compare, destA.iSdst, destB.iSdst, nOrderBy, (char*)pKeyMerge, P4_KEYINFO); sqlite3VdbeChangeP5(v, OPFLAG_PERMUTE); - sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB); + sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB); VdbeCoverage(v); /* Jump to the this point in order to terminate the query. */ @@ -4391,7 +4399,7 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){ ** values to an OP_Copy. */ if( regHit ){ - addrHitTest = sqlite3VdbeAddOp1(v, OP_If, regHit); + addrHitTest = sqlite3VdbeAddOp1(v, OP_If, regHit); VdbeCoverage(v); } sqlite3ExprCacheClear(pParse); for(i=0, pC=pAggInfo->aCol; inAccumulator; i++, pC++){ @@ -4925,7 +4933,7 @@ int sqlite3Select( sortOut = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp3(v, OP_OpenPseudo, sortPTab, sortOut, nCol); sqlite3VdbeAddOp2(v, OP_SorterSort, sAggInfo.sortingIdx, addrEnd); - VdbeComment((v, "GROUP BY sort")); + VdbeComment((v, "GROUP BY sort")); VdbeCoverage(v); sAggInfo.useSortingIdx = 1; sqlite3ExprCacheClear(pParse); } @@ -4952,7 +4960,7 @@ int sqlite3Select( sqlite3VdbeAddOp4(v, OP_Compare, iAMem, iBMem, pGroupBy->nExpr, (char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO); j1 = sqlite3VdbeCurrentAddr(v); - sqlite3VdbeAddOp3(v, OP_Jump, j1+1, 0, j1+1); + sqlite3VdbeAddOp3(v, OP_Jump, j1+1, 0, j1+1); VdbeCoverage(v); /* Generate code that runs whenever the GROUP BY changes. ** Changes in the GROUP BY are detected by the previous code @@ -4966,7 +4974,7 @@ int sqlite3Select( sqlite3ExprCodeMove(pParse, iBMem, iAMem, pGroupBy->nExpr); sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow); VdbeComment((v, "output one row")); - sqlite3VdbeAddOp2(v, OP_IfPos, iAbortFlag, addrEnd); + sqlite3VdbeAddOp2(v, OP_IfPos, iAbortFlag, addrEnd); VdbeCoverage(v); VdbeComment((v, "check abort flag")); sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset); VdbeComment((v, "reset accumulator")); @@ -4983,6 +4991,7 @@ int sqlite3Select( */ if( groupBySort ){ sqlite3VdbeAddOp2(v, OP_SorterNext, sAggInfo.sortingIdx, addrTopOfLoop); + VdbeCoverage(v); }else{ sqlite3WhereEnd(pWInfo); sqlite3VdbeChangeToNoop(v, addrSortingIdx); @@ -5010,7 +5019,7 @@ int sqlite3Select( sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); sqlite3VdbeResolveLabel(v, addrOutputRow); addrOutputRow = sqlite3VdbeCurrentAddr(v); - sqlite3VdbeAddOp2(v, OP_IfPos, iUseFlag, addrOutputRow+2); + sqlite3VdbeAddOp2(v, OP_IfPos, iUseFlag, addrOutputRow+2); VdbeCoverage(v); VdbeComment((v, "Groupby result generator entry point")); sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); finalizeAggFunctions(pParse, &sAggInfo); diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 51c864c5e2..5d2c87552c 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -6117,7 +6117,8 @@ int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 #define SQLITE_TESTCTRL_EXPLAIN_STMT 19 #define SQLITE_TESTCTRL_NEVER_CORRUPT 20 -#define SQLITE_TESTCTRL_LAST 20 +#define SQLITE_TESTCTRL_VDBE_COVERAGE 21 +#define SQLITE_TESTCTRL_LAST 21 /* ** CAPI3REF: SQLite Runtime Status diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 392517c8d7..5f5ce63d48 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2657,6 +2657,13 @@ struct Sqlite3Config { void(*xSqllog)(void*,sqlite3*,const char*, int); void *pSqllogArg; #endif +#ifdef SQLITE_VDBE_COVERAGE + /* The following callback (if not NULL) is invoked on every VDBE branch + ** operation. Set the callback using SQLITE_TESTCTRL_VDBE_COVERAGE. + */ + void (*xVdbeBranch)(void*,int iSrcLine,u8 eThis,u8 eMx); /* Callback */ + void *pVdbeBranchArg; /* 1st argument */ +#endif }; /* diff --git a/src/trigger.c b/src/trigger.c index cbc87abf45..dcbaf5d332 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -566,6 +566,7 @@ void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger){ assert( pTable!=0 ); if( (v = sqlite3GetVdbe(pParse))!=0 ){ int base; + static const int iLn = __LINE__+2; static const VdbeOpList dropTrigger[] = { { OP_Rewind, 0, ADDR(9), 0}, { OP_String8, 0, 1, 0}, /* 1 */ @@ -580,7 +581,7 @@ void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger){ sqlite3BeginWriteOperation(pParse, 0, iDb); sqlite3OpenMasterTable(pParse, iDb); - base = sqlite3VdbeAddOpList(v, ArraySize(dropTrigger), dropTrigger); + base = sqlite3VdbeAddOpList(v, ArraySize(dropTrigger), dropTrigger, iLn); sqlite3VdbeChangeP4(v, base+1, pTrigger->zName, P4_TRANSIENT); sqlite3VdbeChangeP4(v, base+4, "trigger", P4_STATIC); sqlite3ChangeCookie(pParse, iDb); diff --git a/src/update.c b/src/update.c index 41ce7f0c77..4c45a4b40d 100644 --- a/src/update.c +++ b/src/update.c @@ -434,18 +434,23 @@ void sqlite3Update( if( aToOpen[iDataCur-iBaseCur] ){ assert( pPk!=0 ); sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey, nKey); + VdbeCoverage(v); } labelContinue = labelBreak; sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak); + VdbeCoverage(v); }else if( pPk ){ labelContinue = sqlite3VdbeMakeLabel(v); - sqlite3VdbeAddOp2(v, OP_Rewind, iEph, labelBreak); + sqlite3VdbeAddOp2(v, OP_Rewind, iEph, labelBreak); VdbeCoverage(v); addrTop = sqlite3VdbeAddOp2(v, OP_RowKey, iEph, regKey); sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue, regKey, 0); + VdbeCoverage(v); }else{ labelContinue = sqlite3VdbeAddOp3(v, OP_RowSetRead, regRowSet, labelBreak, regOldRowid); + VdbeCoverage(v); sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue, regOldRowid); + VdbeCoverage(v); } /* If the record number will change, set register regNewRowid to @@ -455,7 +460,7 @@ void sqlite3Update( assert( chngKey || pTrigger || hasFK || regOldRowid==regNewRowid ); if( chngRowid ){ sqlite3ExprCode(pParse, pRowidExpr, regNewRowid); - sqlite3VdbeAddOp1(v, OP_MustBeInt, regNewRowid); + sqlite3VdbeAddOp1(v, OP_MustBeInt, regNewRowid); VdbeCoverage(v); } /* Compute the old pre-UPDATE content of the row being changed, if that @@ -536,8 +541,10 @@ void sqlite3Update( */ if( pPk ){ sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue,regKey,nKey); + VdbeCoverage(v); }else{ sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue, regOldRowid); + VdbeCoverage(v); } /* If it did not delete it, the row-trigger may still have modified @@ -570,8 +577,10 @@ void sqlite3Update( if( bReplace || chngKey ){ if( pPk ){ j1 = sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, 0, regKey, nKey); + VdbeCoverage(v); }else{ j1 = sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, 0, regOldRowid); + VdbeCoverage(v); } } sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur, aRegIdx); @@ -616,7 +625,7 @@ void sqlite3Update( /* Nothing to do at end-of-loop for a single-pass */ }else if( pPk ){ sqlite3VdbeResolveLabel(v, labelContinue); - sqlite3VdbeAddOp2(v, OP_Next, iEph, addrTop); + sqlite3VdbeAddOp2(v, OP_Next, iEph, addrTop); VdbeCoverage(v); }else{ sqlite3VdbeAddOp2(v, OP_Goto, 0, labelContinue); } @@ -745,7 +754,7 @@ static void updateVirtualTable( /* Generate code to scan the ephemeral table and call VUpdate. */ iReg = ++pParse->nMem; pParse->nMem += pTab->nCol+1; - addr = sqlite3VdbeAddOp2(v, OP_Rewind, ephemTab, 0); + addr = sqlite3VdbeAddOp2(v, OP_Rewind, ephemTab, 0); VdbeCoverage(v); sqlite3VdbeAddOp3(v, OP_Column, ephemTab, 0, iReg); sqlite3VdbeAddOp3(v, OP_Column, ephemTab, (pRowid?1:0), iReg+1); for(i=0; inCol; i++){ @@ -755,7 +764,7 @@ static void updateVirtualTable( sqlite3VdbeAddOp4(v, OP_VUpdate, 0, pTab->nCol+2, iReg, pVTab, P4_VTAB); sqlite3VdbeChangeP5(v, onError==OE_Default ? OE_Abort : onError); sqlite3MayAbort(pParse); - sqlite3VdbeAddOp2(v, OP_Next, ephemTab, addr+1); + sqlite3VdbeAddOp2(v, OP_Next, ephemTab, addr+1); VdbeCoverage(v); sqlite3VdbeJumpHere(v, addr); sqlite3VdbeAddOp2(v, OP_Close, ephemTab, 0); diff --git a/src/vdbe.c b/src/vdbe.c index 5f046a63e2..002309bc3b 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -107,6 +107,18 @@ int sqlite3_found_count = 0; # define UPDATE_MAX_BLOBSIZE(P) #endif +/* +** Invoke the VDBE coverage callback, if defined +*/ +#if !defined(SQLITE_VDBE_COVERAGE) +# define VdbeBranchTaken(I,M) +#else +# define VdbeBranchTaken(I,M) \ + if( sqlite3GlobalConfig.xVdbeBranch!=0 ){ \ + sqlite3GlobalConfig.xVdbeBranch(sqlite3GlobalConfig.pVdbeBranchArg, \ + pOp->iSrcLine,(I),(M)); } +#endif + /* ** Convert the given register into a string if it isn't one ** already. Return non-zero if a malloc() fails. @@ -1638,6 +1650,7 @@ case OP_MustBeInt: { /* jump, in1 */ pIn1 = &aMem[pOp->p1]; if( (pIn1->flags & MEM_Int)==0 ){ applyAffinity(pIn1, SQLITE_AFF_NUMERIC, encoding); + VdbeBranchTaken((pIn1->flags&MEM_Int)==0, 2); if( (pIn1->flags & MEM_Int)==0 ){ if( pOp->p2==0 ){ rc = SQLITE_MISMATCH; @@ -1891,12 +1904,15 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ ** then the result is always NULL. ** The jump is taken if the SQLITE_JUMPIFNULL bit is set. */ - if( pOp->p5 & SQLITE_JUMPIFNULL ){ - pc = pOp->p2-1; - }else if( pOp->p5 & SQLITE_STOREP2 ){ + if( pOp->p5 & SQLITE_STOREP2 ){ pOut = &aMem[pOp->p2]; MemSetTypeFlag(pOut, MEM_Null); REGISTER_TRACE(pOp->p2, pOut); + }else{ + VdbeBranchTaken((pOp->p5 & SQLITE_JUMPIFNULL)?2:3,4); + if( pOp->p5 & SQLITE_JUMPIFNULL ){ + pc = pOp->p2-1; + } } break; } @@ -1929,10 +1945,12 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ MemSetTypeFlag(pOut, MEM_Int); pOut->u.i = res; REGISTER_TRACE(pOp->p2, pOut); - }else if( res ){ - pc = pOp->p2-1; + }else{ + VdbeBranchTaken(res!=0, 4); + if( res ){ + pc = pOp->p2-1; + } } - /* Undo any changes made by applyAffinity() to the input registers. */ pIn1->flags = (pIn1->flags&~MEM_TypeMask) | (flags1&MEM_TypeMask); pIn3->flags = (pIn3->flags&~MEM_TypeMask) | (flags3&MEM_TypeMask); @@ -2029,11 +2047,11 @@ case OP_Compare: { */ case OP_Jump: { /* jump */ if( iCompare<0 ){ - pc = pOp->p1 - 1; + pc = pOp->p1 - 1; VdbeBranchTaken(0,3); }else if( iCompare==0 ){ - pc = pOp->p2 - 1; + pc = pOp->p2 - 1; VdbeBranchTaken(1,3); }else{ - pc = pOp->p3 - 1; + pc = pOp->p3 - 1; VdbeBranchTaken(2,3); } break; } @@ -2137,6 +2155,7 @@ case OP_BitNot: { /* same as TK_BITNOT, in1, out2 */ */ case OP_Once: { /* jump */ assert( pOp->p1nOnceFlag ); + VdbeBranchTaken(p->aOnceFlag[pOp->p1]!=0, 2); if( p->aOnceFlag[pOp->p1] ){ pc = pOp->p2-1; }else{ @@ -2171,6 +2190,7 @@ case OP_IfNot: { /* jump, in1 */ #endif if( pOp->opcode==OP_IfNot ) c = !c; } + VdbeBranchTaken(c!=0, 2); if( c ){ pc = pOp->p2-1; } @@ -2184,6 +2204,7 @@ case OP_IfNot: { /* jump, in1 */ */ case OP_IsNull: { /* same as TK_ISNULL, jump, in1 */ pIn1 = &aMem[pOp->p1]; + VdbeBranchTaken( (pIn1->flags & MEM_Null)!=0, 2); if( (pIn1->flags & MEM_Null)!=0 ){ pc = pOp->p2 - 1; } @@ -2197,6 +2218,7 @@ case OP_IsNull: { /* same as TK_ISNULL, jump, in1 */ */ case OP_NotNull: { /* same as TK_NOTNULL, jump, in1 */ pIn1 = &aMem[pOp->p1]; + VdbeBranchTaken( (pIn1->flags & MEM_Null)==0, 2); if( (pIn1->flags & MEM_Null)==0 ){ pc = pOp->p2 - 1; } @@ -3474,7 +3496,7 @@ case OP_SeekGT: { /* jump, in3 */ if( (pIn3->flags & MEM_Real)==0 ){ /* If the P3 value cannot be converted into any kind of a number, ** then the seek is not possible, so jump to P2 */ - pc = pOp->p2 - 1; + pc = pOp->p2 - 1; VdbeBranchTaken(1,2); break; } @@ -3569,6 +3591,7 @@ case OP_SeekGT: { /* jump, in3 */ } } assert( pOp->p2>0 ); + VdbeBranchTaken(res!=0,2); if( res ){ pc = pOp->p2 - 1; } @@ -3702,7 +3725,7 @@ case OP_Found: { /* jump, in3 */ ** conflict */ for(ii=0; iip2 - 1; + pc = pOp->p2 - 1; VdbeBranchTaken(1,2); break; } } @@ -3720,8 +3743,10 @@ case OP_Found: { /* jump, in3 */ pC->deferredMoveto = 0; pC->cacheStatus = CACHE_STALE; if( pOp->opcode==OP_Found ){ + VdbeBranchTaken(alreadyExists!=0,2); if( alreadyExists ) pc = pOp->p2 - 1; }else{ + VdbeBranchTaken(alreadyExists==0,2); if( !alreadyExists ) pc = pOp->p2 - 1; } break; @@ -3764,6 +3789,7 @@ case OP_NotExists: { /* jump, in3 */ pC->nullRow = 0; pC->cacheStatus = CACHE_STALE; pC->deferredMoveto = 0; + VdbeBranchTaken(res!=0,2); if( res!=0 ){ pc = pOp->p2 - 1; assert( pC->rowidIsValid==0 ); @@ -4138,6 +4164,7 @@ case OP_SorterCompare: { pIn3 = &aMem[pOp->p3]; nIgnore = pOp->p4.i; rc = sqlite3VdbeSorterCompare(pC, pIn3, nIgnore, &res); + VdbeBranchTaken(res!=0,2); if( res ){ pc = pOp->p2-1; } @@ -4337,8 +4364,9 @@ case OP_Last: { /* jump */ pC->deferredMoveto = 0; pC->rowidIsValid = 0; pC->cacheStatus = CACHE_STALE; - if( pOp->p2>0 && res ){ - pc = pOp->p2 - 1; + if( pOp->p2>0 ){ + VdbeBranchTaken(res!=0,2); + if( res ) pc = pOp->p2 - 1; } break; } @@ -4395,6 +4423,7 @@ case OP_Rewind: { /* jump */ } pC->nullRow = (u8)res; assert( pOp->p2>0 && pOp->p2nOp ); + VdbeBranchTaken(res!=0,2); if( res ){ pc = pOp->p2 - 1; } @@ -4485,6 +4514,7 @@ case OP_Next: /* jump */ rc = pOp->p4.xAdvance(pC->pCursor, &res); next_tail: pC->cacheStatus = CACHE_STALE; + VdbeBranchTaken(res==0,2); if( res==0 ){ pC->nullRow = 0; pc = pOp->p2 - 1; @@ -4710,6 +4740,7 @@ case OP_IdxGE: { /* jump */ assert( pOp->opcode==OP_IdxGE || pOp->opcode==OP_IdxGT ); res++; } + VdbeBranchTaken(res>0,2); if( res>0 ){ pc = pOp->p2 - 1 ; } @@ -5071,9 +5102,11 @@ case OP_RowSetRead: { /* jump, in1, out3 */ /* The boolean index is empty */ sqlite3VdbeMemSetNull(pIn1); pc = pOp->p2 - 1; + VdbeBranchTaken(1,2); }else{ /* A value was pulled from the index */ sqlite3VdbeMemSetInt64(&aMem[pOp->p3], val); + VdbeBranchTaken(0,2); } goto check_for_interrupt; } @@ -5125,6 +5158,7 @@ case OP_RowSetTest: { /* jump, in1, in3 */ exists = sqlite3RowSetTest(pIn1->u.pRowSet, (u8)(iSet>=0 ? iSet & 0xf : 0xff), pIn3->u.i); + VdbeBranchTaken(exists!=0,2); if( exists ){ pc = pOp->p2 - 1; break; @@ -5317,8 +5351,10 @@ case OP_FkCounter: { */ case OP_FkIfZero: { /* jump */ if( pOp->p1 ){ + VdbeBranchTaken(db->nDeferredCons==0 && db->nDeferredImmCons==0, 2); if( db->nDeferredCons==0 && db->nDeferredImmCons==0 ) pc = pOp->p2-1; }else{ + VdbeBranchTaken(p->nFkConstraint==0 && db->nDeferredImmCons==0, 2); if( p->nFkConstraint==0 && db->nDeferredImmCons==0 ) pc = pOp->p2-1; } break; @@ -5367,6 +5403,7 @@ case OP_MemMax: { /* in2 */ case OP_IfPos: { /* jump, in1 */ pIn1 = &aMem[pOp->p1]; assert( pIn1->flags&MEM_Int ); + VdbeBranchTaken( pIn1->u.i>0, 2); if( pIn1->u.i>0 ){ pc = pOp->p2 - 1; } @@ -5384,6 +5421,7 @@ case OP_IfPos: { /* jump, in1 */ case OP_IfNeg: { /* jump, in1 */ pIn1 = &aMem[pOp->p1]; assert( pIn1->flags&MEM_Int ); + VdbeBranchTaken(pIn1->u.i<0, 2); if( pIn1->u.i<0 ){ pc = pOp->p2 - 1; } @@ -5403,6 +5441,7 @@ case OP_IfZero: { /* jump, in1 */ pIn1 = &aMem[pOp->p1]; assert( pIn1->flags&MEM_Int ); pIn1->u.i += pOp->p3; + VdbeBranchTaken(pIn1->u.i==0, 2); if( pIn1->u.i==0 ){ pc = pOp->p2 - 1; } @@ -5674,6 +5713,7 @@ case OP_IncrVacuum: { /* jump */ assert( p->readOnly==0 ); pBt = db->aDb[pOp->p1].pBt; rc = sqlite3BtreeIncrVacuum(pBt); + VdbeBranchTaken(rc==SQLITE_DONE,2); if( rc==SQLITE_DONE ){ pc = pOp->p2 - 1; rc = SQLITE_OK; @@ -5880,7 +5920,7 @@ case OP_VFilter: { /* jump */ if( rc==SQLITE_OK ){ res = pModule->xEof(pVtabCursor); } - + VdbeBranchTaken(res!=0,2); if( res ){ pc = pOp->p2 - 1; } @@ -5985,7 +6025,7 @@ case OP_VNext: { /* jump */ if( rc==SQLITE_OK ){ res = pModule->xEof(pCur->pVtabCursor); } - + VdbeBranchTaken(!res,2); if( !res ){ /* If there is data, jump to P2 */ pc = pOp->p2 - 1; diff --git a/src/vdbe.h b/src/vdbe.h index 620f2eaf72..f1f28cb1b5 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -68,6 +68,9 @@ struct VdbeOp { int cnt; /* Number of times this instruction was executed */ u64 cycles; /* Total time spent executing this instruction */ #endif +#ifdef SQLITE_VDBE_COVERAGE + int iSrcLine; /* Source-code line that generated this opcode */ +#endif }; typedef struct VdbeOp VdbeOp; @@ -167,7 +170,7 @@ int sqlite3VdbeAddOp2(Vdbe*,int,int,int); int sqlite3VdbeAddOp3(Vdbe*,int,int,int,int); int sqlite3VdbeAddOp4(Vdbe*,int,int,int,int,const char *zP4,int); int sqlite3VdbeAddOp4Int(Vdbe*,int,int,int,int,int); -int sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp); +int sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp, int iLineno); void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*); void sqlite3VdbeChangeP1(Vdbe*, u32 addr, int P1); void sqlite3VdbeChangeP2(Vdbe*, u32 addr, int P2); @@ -238,4 +241,14 @@ void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *); # define VdbeModuleComment(X) #endif +/* Set the Opcode.iSrcline field of the previous opcode */ +#ifdef SQLITE_VDBE_COVERAGE + void sqlite3VdbeSetLineNumber(Vdbe*,int); +# define VdbeCoverage(v) sqlite3VdbeSetLineNumber(v,__LINE__) +# define VdbeCoverageIf(v,x) if(x)sqlite3VdbeSetLineNumber(v,__LINE__) +#else +# define VdbeCoverage(v) +# define VdbeCoverageIf(v,x) +#endif + #endif diff --git a/src/vdbeaux.c b/src/vdbeaux.c index f7f1d5c288..89bb8975a5 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -173,6 +173,9 @@ int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){ #ifdef VDBE_PROFILE pOp->cycles = 0; pOp->cnt = 0; +#endif +#ifdef SQLITE_VDBE_COVERAGE + pOp->iSrcLine = 0; #endif return i; } @@ -535,7 +538,7 @@ VdbeOp *sqlite3VdbeTakeOpArray(Vdbe *p, int *pnOp, int *pnMaxArg){ ** Add a whole list of operations to the operation stack. Return the ** address of the first operation added. */ -int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp){ +int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp, int iLineno){ int addr; assert( p->magic==VDBE_MAGIC_INIT ); if( p->nOp + nOp > p->pParse->nOpAlloc && growOpArray(p) ){ @@ -563,6 +566,11 @@ int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp){ #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS pOut->zComment = 0; #endif +#ifdef SQLITE_VDBE_COVERAGE + pOut->iSrcLine = iLineno+i; +#else + (void)iLineno; +#endif #ifdef SQLITE_DEBUG if( p->db->flags & SQLITE_VdbeAddopTrace ){ sqlite3VdbePrintOp(0, i+addr, &p->aOp[i+addr]); @@ -851,6 +859,15 @@ void sqlite3VdbeNoopComment(Vdbe *p, const char *zFormat, ...){ } #endif /* NDEBUG */ +#ifdef SQLITE_VDBE_COVERAGE +/* +** Set the value if the iSrcLine field for the previously coded instruction. +*/ +void sqlite3VdbeSetLineNumber(Vdbe *v, int iLine){ + sqlite3VdbeGetOp(v,-1)->iSrcLine = iLine; +} +#endif /* SQLITE_VDBE_COVERAGE */ + /* ** Return the opcode for a given address. If the address is -1, then ** return the most recently inserted opcode. diff --git a/src/vdbeblob.c b/src/vdbeblob.c index 0fbc1ad477..4b34f2c295 100644 --- a/src/vdbeblob.c +++ b/src/vdbeblob.c @@ -133,14 +133,13 @@ int sqlite3_blob_open( ** which closes the b-tree cursor and (possibly) commits the ** transaction. */ + static const int iLn = __LINE__+4; static const VdbeOpList openBlob[] = { /* {OP_Transaction, 0, 0, 0}, // 0: Inserted separately */ {OP_TableLock, 0, 0, 0}, /* 1: Acquire a read or write lock */ - /* One of the following two instructions is replaced by an OP_Noop. */ {OP_OpenRead, 0, 0, 0}, /* 2: Open cursor 0 for reading */ {OP_OpenWrite, 0, 0, 0}, /* 3: Open cursor 0 for read/write */ - {OP_Variable, 1, 1, 1}, /* 4: Push the rowid to the stack */ {OP_NotExists, 0, 10, 1}, /* 5: Seek the cursor */ {OP_Column, 0, 0, 1}, /* 6 */ @@ -265,7 +264,7 @@ int sqlite3_blob_open( pTab->pSchema->schema_cookie, pTab->pSchema->iGeneration); sqlite3VdbeChangeP5(v, 1); - sqlite3VdbeAddOpList(v, sizeof(openBlob)/sizeof(VdbeOpList), openBlob); + sqlite3VdbeAddOpList(v, ArraySize(openBlob), openBlob, iLn); /* Make sure a mutex is held on the table to be accessed */ sqlite3VdbeUsesBtree(v, iDb); diff --git a/src/where.c b/src/where.c index c5bbeea0e1..15bcb1ebde 100644 --- a/src/where.c +++ b/src/where.c @@ -1708,12 +1708,12 @@ static void constructAutomaticIndex( VdbeComment((v, "for %s", pTable->zName)); /* Fill the automatic index with content */ - addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); + addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); VdbeCoverage(v); regRecord = sqlite3GetTempReg(pParse); sqlite3GenerateIndexKey(pParse, pIdx, pLevel->iTabCur, regRecord, 0, 0, 0, 0); sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord); sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); - sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); + sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v); sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX); sqlite3VdbeJumpHere(v, addrTop); sqlite3ReleaseTempReg(pParse, regRecord); @@ -2388,7 +2388,7 @@ static int codeEqualityTerm( bRev = !bRev; } iTab = pX->iTable; - sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iTab, 0); + sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iTab, 0); VdbeCoverage(v); assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 ); pLoop->wsFlags |= WHERE_IN_ABLE; if( pLevel->u.in.nIn==0 ){ @@ -2408,7 +2408,7 @@ static int codeEqualityTerm( pIn->addrInTop = sqlite3VdbeAddOp3(v, OP_Column, iTab, 0, iReg); } pIn->eEndLoopOp = bRev ? OP_PrevIfOpen : OP_NextIfOpen; - sqlite3VdbeAddOp1(v, OP_IsNull, iReg); + sqlite3VdbeAddOp1(v, OP_IsNull, iReg); VdbeCoverage(v); }else{ pLevel->u.in.nIn = 0; } @@ -2502,11 +2502,11 @@ static int codeAllEqualityTerms( if( nSkip ){ int iIdxCur = pLevel->iIdxCur; - sqlite3VdbeAddOp1(v, (bRev?OP_Last:OP_Rewind), iIdxCur); + sqlite3VdbeAddOp1(v, (bRev?OP_Last:OP_Rewind), iIdxCur); VdbeCoverage(v); VdbeComment((v, "begin skip-scan on %s", pIdx->zName)); j = sqlite3VdbeAddOp0(v, OP_Goto); pLevel->addrSkip = sqlite3VdbeAddOp4Int(v, (bRev?OP_SeekLT:OP_SeekGT), - iIdxCur, 0, regBase, nSkip); + iIdxCur, 0, regBase, nSkip); VdbeCoverage(v); sqlite3VdbeJumpHere(v, j); for(j=0; jregReturn; sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub); pLevel->p2 = sqlite3VdbeAddOp2(v, OP_Yield, regYield, addrBrk); + VdbeCoverage(v); VdbeComment((v, "next row of \"%s\"", pTabItem->pTab->zName)); pLevel->op = OP_Goto; }else @@ -2819,6 +2820,7 @@ static Bitmask codeOneLoopStart( sqlite3VdbeAddOp4(v, OP_VFilter, iCur, addrNotFound, iReg, pLoop->u.vtab.idxStr, pLoop->u.vtab.needFree ? P4_MPRINTF : P4_STATIC); + VdbeCoverage(v); pLoop->u.vtab.needFree = 0; for(j=0; ju.vtab.omitMask>>j)&1 ){ @@ -2850,8 +2852,9 @@ static Bitmask codeOneLoopStart( testcase( pTerm->wtFlags & TERM_VIRTUAL ); iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, 0, bRev, iReleaseReg); addrNxt = pLevel->addrNxt; - sqlite3VdbeAddOp2(v, OP_MustBeInt, iRowidReg, addrNxt); + sqlite3VdbeAddOp2(v, OP_MustBeInt, iRowidReg, addrNxt); VdbeCoverage(v); sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addrNxt, iRowidReg); + VdbeCoverage(v); sqlite3ExprCacheAffinityChange(pParse, iRowidReg, 1); sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg); VdbeComment((v, "pk")); @@ -2901,12 +2904,13 @@ static Bitmask codeOneLoopStart( testcase( pStart->leftCursor!=iCur ); /* transitive constraints */ r1 = sqlite3ExprCodeTemp(pParse, pX->pRight, &rTemp); sqlite3VdbeAddOp3(v, aMoveOp[pX->op-TK_GT], iCur, addrBrk, r1); - VdbeComment((v, "pk")); + VdbeComment((v, "pk")); VdbeCoverage(v); sqlite3ExprCacheAffinityChange(pParse, r1, 1); sqlite3ReleaseTempReg(pParse, rTemp); disableTerm(pLevel, pStart); }else{ sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, addrBrk); + VdbeCoverage(v); } if( pEnd ){ Expr *pX; @@ -2934,6 +2938,7 @@ static Bitmask codeOneLoopStart( sqlite3VdbeAddOp2(v, OP_Rowid, iCur, iRowidReg); sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg); sqlite3VdbeAddOp3(v, testOp, memEndValue, addrBrk, iRowidReg); + VdbeCoverage(v); sqlite3VdbeChangeP5(v, SQLITE_AFF_NUMERIC | SQLITE_JUMPIFNULL); } }else if( pLoop->wsFlags & WHERE_INDEXED ){ @@ -3107,6 +3112,13 @@ static Bitmask codeOneLoopStart( testcase( op==OP_SeekLE ); testcase( op==OP_SeekLT ); sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint); + VdbeCoverage(v); + VdbeCoverageIf(v, op==OP_Rewind); + VdbeCoverageIf(v, op==OP_Last); + VdbeCoverageIf(v, op==OP_SeekGT); + VdbeCoverageIf(v, op==OP_SeekGE); + VdbeCoverageIf(v, op==OP_SeekLE); + VdbeCoverageIf(v, op==OP_SeekLT); /* Load the value for the inequality constraint at the end of the ** range (if any). @@ -3144,6 +3156,7 @@ static Bitmask codeOneLoopStart( testcase( op==OP_IdxLT ); testcase( op==OP_IdxLE ); sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint); + VdbeCoverage(v); } /* Seek the table cursor, if required */ @@ -3164,7 +3177,7 @@ static Bitmask codeOneLoopStart( sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, iRowidReg+j); } sqlite3VdbeAddOp4Int(v, OP_NotFound, iCur, addrCont, - iRowidReg, pPk->nKeyCol); + iRowidReg, pPk->nKeyCol); VdbeCoverage(v); } /* Record the instruction used to terminate the loop. Disable @@ -3348,6 +3361,7 @@ static Bitmask codeOneLoopStart( regRowid, 0); sqlite3VdbeAddOp4Int(v, OP_RowSetTest, regRowset, sqlite3VdbeCurrentAddr(v)+2, r, iSet); + VdbeCoverage(v); } sqlite3VdbeAddOp2(v, OP_Gosub, regReturn, iLoopBody); @@ -3416,6 +3430,8 @@ static Bitmask codeOneLoopStart( pLevel->op = aStep[bRev]; pLevel->p1 = iCur; pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrBrk); + VdbeCoverageIf(v, bRev); + VdbeCoverageIf(v, !bRev); pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP; } } @@ -5785,6 +5801,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ if( pLevel->op!=OP_Noop ){ sqlite3VdbeAddOp3(v, pLevel->op, pLevel->p1, pLevel->p2, pLevel->p3); sqlite3VdbeChangeP5(v, pLevel->p5); + VdbeCoverage(v); } if( pLoop->wsFlags & WHERE_IN_ABLE && pLevel->u.in.nIn>0 ){ struct InLoop *pIn; @@ -5793,6 +5810,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ for(j=pLevel->u.in.nIn, pIn=&pLevel->u.in.aInLoop[j-1]; j>0; j--, pIn--){ sqlite3VdbeJumpHere(v, pIn->addrInTop+1); sqlite3VdbeAddOp2(v, pIn->eEndLoopOp, pIn->iCur, pIn->addrInTop); + VdbeCoverage(v); sqlite3VdbeJumpHere(v, pIn->addrInTop-1); } sqlite3DbFree(db, pLevel->u.in.aInLoop); @@ -5805,7 +5823,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ sqlite3VdbeJumpHere(v, pLevel->addrSkip-2); } if( pLevel->iLeftJoin ){ - addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin); + addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin); VdbeCoverage(v); assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 || (pLoop->wsFlags & WHERE_INDEXED)!=0 ); if( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 ){ From 552fd4544162c4ae28dda3ef29a62175c7bf630f Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 18 Feb 2014 01:07:38 +0000 Subject: [PATCH 267/276] Improvements to "NOT IN (SELECT ...)" processing. Only test for NULL values on the RHS on the first iteration, then remember the result. There has been logic to do this for year, but it didn't work right and ended up repeating the NULL test on every iteration. This inefficiency was found using the VDBE coverage testing tools. FossilOrigin-Name: 915f6f1c7aab54583729e60bdc1565f25ecc6f74 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 22 +++++++++------------- 3 files changed, 16 insertions(+), 20 deletions(-) diff --git a/manifest b/manifest index d42c6f04ff..85cf3d05cb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sin\sperformance\senhancements\sfor\sINSERT\soperations,\sespecially\sINSERTs\non\stables\sthat\shave\sno\saffinity\scolumns\sor\sthat\shave\smany\sindices\sor\sINSERTs\nwith\scontent\scoming\sfrom\sa\sSELECT.\s\sAdd\sthe\sSQLITE_TESTCTRL_VDBE_COVERAGE\ntest\scontrol\sand\sthe\sSQLITE_VDBE_COVERAGE\scompile-time\soption\sused\sfor\smeasure\ncoverage\sof\sbranches\sin\sVDBE\sprograms. -D 2014-02-17T23:52:13.448 +C Improvements\sto\s"NOT\sIN\s(SELECT\s...)"\sprocessing.\s\sOnly\stest\sfor\sNULL\svalues\non\sthe\sRHS\son\sthe\sfirst\siteration,\sthen\sremember\sthe\sresult.\s\sThere\shas\sbeen\nlogic\sto\sdo\sthis\sfor\syear,\sbut\sit\sdidn't\swork\sright\sand\sended\sup\srepeating\nthe\sNULL\stest\son\severy\siteration.\s\sThis\sinefficiency\swas\sfound\susing\sthe\nVDBE\scoverage\stesting\stools. +D 2014-02-18T01:07:38.047 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -172,7 +172,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 F src/delete.c a00bf893bd39868c51020eba1fc5182eb36bfeb7 -F src/expr.c d1a8ccbf7e4dac6198674d33853e8ed01072eca4 +F src/expr.c e908787e4728beefdf742db90666248f89b1da01 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 3cd6ce998404fb1b7203d886d6fdff71cf3c8846 F src/func.c f4499b39d66b71825514334ce67b32ff14bd19f5 @@ -1151,7 +1151,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 7adb3da235c8c162c84f05ef4ccf1cc463805d5f ce184c7bb16988641d37c908d9b3042456d4be3d -R 3842d7f2fc20472907a26e6db9a0b24a +P a72687699ba2af2e7383be7371d4121750c7e34f +R babb7ab4a8213aedecd107bc9c2410b3 U drh -Z d2a564f325f5059be0c19074b4cb10b9 +Z 3cb428699d451ff8a4012effde517352 diff --git a/manifest.uuid b/manifest.uuid index ac77c8b312..3fe9659239 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a72687699ba2af2e7383be7371d4121750c7e34f \ No newline at end of file +915f6f1c7aab54583729e60bdc1565f25ecc6f74 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 85354e5860..06fc1a54a8 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1630,11 +1630,11 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){ assert( IN_INDEX_INDEX_DESC == IN_INDEX_INDEX_ASC+1 ); eType = IN_INDEX_INDEX_ASC + pIdx->aSortOrder[0]; - sqlite3VdbeJumpHere(v, iAddr); if( prNotFound && !pTab->aCol[iCol].notNull ){ *prNotFound = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Null, 0, *prNotFound); } + sqlite3VdbeJumpHere(v, iAddr); } } } @@ -2004,7 +2004,7 @@ static void sqlite3ExprCodeIN( ** the presence of a NULL on the RHS makes a difference in the ** outcome. */ - int j1, j2, j3; + int j1, j2; /* First check to see if the LHS is contained in the RHS. If so, ** then the presence of NULLs in the RHS does not matter, so jump @@ -2019,19 +2019,15 @@ static void sqlite3ExprCodeIN( ** jump to destIfNull. If there are no NULLs in the RHS then ** jump to destIfFalse. */ - j2 = sqlite3VdbeAddOp1(v, OP_NotNull, rRhsHasNull); VdbeCoverage(v); - j3 = sqlite3VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0, rRhsHasNull, 1); - VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_Integer, -1, rRhsHasNull); - sqlite3VdbeJumpHere(v, j3); - sqlite3VdbeAddOp2(v, OP_AddImm, rRhsHasNull, 1); - sqlite3VdbeJumpHere(v, j2); - - /* Jump to the appropriate target depending on whether or not - ** the RHS contains a NULL - */ sqlite3VdbeAddOp2(v, OP_If, rRhsHasNull, destIfNull); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_IfNot, rRhsHasNull, destIfFalse); VdbeCoverage(v); + j2 = sqlite3VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0, rRhsHasNull, 1); + VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Integer, 0, rRhsHasNull); sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfFalse); + sqlite3VdbeJumpHere(v, j2); + sqlite3VdbeAddOp2(v, OP_Integer, 1, rRhsHasNull); + sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfNull); /* The OP_Found at the top of this branch jumps here when true, ** causing the overall IN expression evaluation to fall through. From 7d1761059b7818a98c5476e9e2040c78e28bc590 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 18 Feb 2014 03:07:12 +0000 Subject: [PATCH 268/276] Add VdbeCoverage() and VdbeCoverageIf() macros for improved VDBE coverage testing. FossilOrigin-Name: b92d31a97d5fe4606d9ae1393c7f3e052f46bf5a --- manifest | 18 +++--- manifest.uuid | 2 +- src/expr.c | 164 ++++++++++++++++++------------------------------ src/select.c | 2 +- src/sqliteInt.h | 1 - src/where.c | 83 +++++++++++++++--------- 6 files changed, 124 insertions(+), 146 deletions(-) diff --git a/manifest b/manifest index 85cf3d05cb..4606d87635 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvements\sto\s"NOT\sIN\s(SELECT\s...)"\sprocessing.\s\sOnly\stest\sfor\sNULL\svalues\non\sthe\sRHS\son\sthe\sfirst\siteration,\sthen\sremember\sthe\sresult.\s\sThere\shas\sbeen\nlogic\sto\sdo\sthis\sfor\syear,\sbut\sit\sdidn't\swork\sright\sand\sended\sup\srepeating\nthe\sNULL\stest\son\severy\siteration.\s\sThis\sinefficiency\swas\sfound\susing\sthe\nVDBE\scoverage\stesting\stools. -D 2014-02-18T01:07:38.047 +C Add\sVdbeCoverage()\sand\sVdbeCoverageIf()\smacros\sfor\simproved\sVDBE\scoverage\ntesting. +D 2014-02-18T03:07:12.342 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -172,7 +172,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 F src/delete.c a00bf893bd39868c51020eba1fc5182eb36bfeb7 -F src/expr.c e908787e4728beefdf742db90666248f89b1da01 +F src/expr.c 014b8087a15c4c314bdd798cb1cb0b32693f8b40 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 3cd6ce998404fb1b7203d886d6fdff71cf3c8846 F src/func.c f4499b39d66b71825514334ce67b32ff14bd19f5 @@ -216,12 +216,12 @@ F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c ca8b99d894164435f5c55cb304c1b8121705c51e F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c 618b53bd4553bd7a9ef95069396f12a8f28489e7 +F src/select.c 28bff39f9bc5ec618b0719fe3f7b4be9f88b6f02 F src/shell.c 3dd86bf73ccd079f0e32ef5069600586085e8239 F src/sqlite.h.in a2ef671f92747a5a1c8a47bad5c585a8dd9eca80 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h 004bd50575a05eefba7228c2d0fee432a53200de +F src/sqliteInt.h 22111056d7d5c404fef783b13088ef87d98074d0 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -290,7 +290,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 76e7fc6de229bea8b30bb2539110f03a494dc3a8 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45 -F src/where.c 7825dce3f92d7c7de9329505deefe176cbd5ba43 +F src/where.c d622974f30d3347c7b71bfe49ce1f1e9b6570980 F src/whereInt.h 921f935af8b684ffb49705610bda7284db1db138 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1151,7 +1151,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P a72687699ba2af2e7383be7371d4121750c7e34f -R babb7ab4a8213aedecd107bc9c2410b3 +P 915f6f1c7aab54583729e60bdc1565f25ecc6f74 +R d0043e1267f21a1ea521214d42169c3d U drh -Z 3cb428699d451ff8a4012effde517352 +Z f5a439caf79133298419241dae122f4e diff --git a/manifest.uuid b/manifest.uuid index 3fe9659239..2e856727c0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -915f6f1c7aab54583729e60bdc1565f25ecc6f74 \ No newline at end of file +b92d31a97d5fe4606d9ae1393c7f3e052f46bf5a \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 06fc1a54a8..722a77db73 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1369,24 +1369,6 @@ int sqlite3ExprCanBeNull(const Expr *p){ } } -/* -** Generate an OP_IsNull instruction that tests register iReg and jumps -** to location iDest if the value in iReg is NULL. The value in iReg -** was computed by pExpr. If we can look at pExpr at compile-time and -** determine that it can never generate a NULL, then the OP_IsNull operation -** can be omitted. -*/ -void sqlite3ExprCodeIsNullJump( - Vdbe *v, /* The VDBE under construction */ - const Expr *pExpr, /* Only generate OP_IsNull if this expr can be NULL */ - int iReg, /* Test the value in this register for NULL */ - int iDest /* Jump here if the value is null */ -){ - if( sqlite3ExprCanBeNull(pExpr) ){ - sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iDest); VdbeCoverage(v); - } -} - /* ** Return TRUE if the given expression is a constant which would be ** unchanged by OP_Affinity with the affinity given in the second @@ -1486,9 +1468,7 @@ static int isCandidateForInOpt(Select *p){ */ int sqlite3CodeOnce(Parse *pParse){ Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */ - int addr = sqlite3VdbeAddOp1(v, OP_Once, pParse->nOnce++); - VdbeCoverage(v); - return addr; + return sqlite3VdbeAddOp1(v, OP_Once, pParse->nOnce++); } /* @@ -1596,9 +1576,8 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){ */ assert(v); if( iCol<0 ){ - int iAddr; - - iAddr = sqlite3CodeOnce(pParse); + int iAddr = sqlite3CodeOnce(pParse); + VdbeCoverage(v); sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead); eType = IN_INDEX_ROWID; @@ -1623,7 +1602,7 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){ && sqlite3FindCollSeq(db, ENC(db), pIdx->azColl[0], 0)==pReq && (!mustBeUnique || (pIdx->nKeyCol==1 && pIdx->onError!=OE_None)) ){ - int iAddr = sqlite3CodeOnce(pParse); + int iAddr = sqlite3CodeOnce(pParse); VdbeCoverage(v); sqlite3VdbeAddOp3(v, OP_OpenRead, iTab, pIdx->tnum, iDb); sqlite3VdbeSetP4KeyInfo(pParse, pIdx); VdbeComment((v, "%s", pIdx->zName)); @@ -1723,7 +1702,7 @@ int sqlite3CodeSubselect( ** save the results, and reuse the same result on subsequent invocations. */ if( !ExprHasProperty(pExpr, EP_VarSelect) ){ - testAddr = sqlite3CodeOnce(pParse); + testAddr = sqlite3CodeOnce(pParse); VdbeCoverage(v); } #ifndef SQLITE_OMIT_EXPLAIN @@ -2548,22 +2527,16 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ case TK_GE: case TK_NE: case TK_EQ: { - assert( TK_LT==OP_Lt ); - assert( TK_LE==OP_Le ); - assert( TK_GT==OP_Gt ); - assert( TK_GE==OP_Ge ); - assert( TK_EQ==OP_Eq ); - assert( TK_NE==OP_Ne ); - testcase( op==TK_LT ); - testcase( op==TK_LE ); - testcase( op==TK_GT ); - testcase( op==TK_GE ); - testcase( op==TK_EQ ); - testcase( op==TK_NE ); r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, - r1, r2, inReg, SQLITE_STOREP2); VdbeCoverage(v); + r1, r2, inReg, SQLITE_STOREP2); + assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt); + assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le); + assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt); + assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge); + assert(TK_EQ==OP_Eq); testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq); + assert(TK_NE==OP_Ne); testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne); testcase( regFree1==0 ); testcase( regFree2==0 ); break; @@ -2577,7 +2550,8 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ op = (op==TK_IS) ? TK_EQ : TK_NE; codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, r1, r2, inReg, SQLITE_STOREP2 | SQLITE_NULLEQ); - VdbeCoverage(v); + VdbeCoverageIf(v, op==TK_EQ); + VdbeCoverageIf(v, op==TK_NE); testcase( regFree1==0 ); testcase( regFree2==0 ); break; @@ -2594,28 +2568,17 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ case TK_LSHIFT: case TK_RSHIFT: case TK_CONCAT: { - assert( TK_AND==OP_And ); - assert( TK_OR==OP_Or ); - assert( TK_PLUS==OP_Add ); - assert( TK_MINUS==OP_Subtract ); - assert( TK_REM==OP_Remainder ); - assert( TK_BITAND==OP_BitAnd ); - assert( TK_BITOR==OP_BitOr ); - assert( TK_SLASH==OP_Divide ); - assert( TK_LSHIFT==OP_ShiftLeft ); - assert( TK_RSHIFT==OP_ShiftRight ); - assert( TK_CONCAT==OP_Concat ); - testcase( op==TK_AND ); - testcase( op==TK_OR ); - testcase( op==TK_PLUS ); - testcase( op==TK_MINUS ); - testcase( op==TK_REM ); - testcase( op==TK_BITAND ); - testcase( op==TK_BITOR ); - testcase( op==TK_SLASH ); - testcase( op==TK_LSHIFT ); - testcase( op==TK_RSHIFT ); - testcase( op==TK_CONCAT ); + assert( TK_AND==OP_And ); testcase( op==TK_AND ); + assert( TK_OR==OP_Or ); testcase( op==TK_OR ); + assert( TK_PLUS==OP_Add ); testcase( op==TK_PLUS ); + assert( TK_MINUS==OP_Subtract ); testcase( op==TK_MINUS ); + assert( TK_REM==OP_Remainder ); testcase( op==TK_REM ); + assert( TK_BITAND==OP_BitAnd ); testcase( op==TK_BITAND ); + assert( TK_BITOR==OP_BitOr ); testcase( op==TK_BITOR ); + assert( TK_SLASH==OP_Divide ); testcase( op==TK_SLASH ); + assert( TK_LSHIFT==OP_ShiftLeft ); testcase( op==TK_LSHIFT ); + assert( TK_RSHIFT==OP_ShiftRight ); testcase( op==TK_RSHIFT ); + assert( TK_CONCAT==OP_Concat ); testcase( op==TK_CONCAT ); r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); sqlite3VdbeAddOp3(v, op, r2, r1, target); @@ -2647,10 +2610,8 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ } case TK_BITNOT: case TK_NOT: { - assert( TK_BITNOT==OP_BitNot ); - assert( TK_NOT==OP_Not ); - testcase( op==TK_BITNOT ); - testcase( op==TK_NOT ); + assert( TK_BITNOT==OP_BitNot ); testcase( op==TK_BITNOT ); + assert( TK_NOT==OP_Not ); testcase( op==TK_NOT ); r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); testcase( regFree1==0 ); inReg = target; @@ -2660,14 +2621,14 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ case TK_ISNULL: case TK_NOTNULL: { int addr; - assert( TK_ISNULL==OP_IsNull ); - assert( TK_NOTNULL==OP_NotNull ); - testcase( op==TK_ISNULL ); - testcase( op==TK_NOTNULL ); + assert( TK_ISNULL==OP_IsNull ); testcase( op==TK_ISNULL ); + assert( TK_NOTNULL==OP_NotNull ); testcase( op==TK_NOTNULL ); sqlite3VdbeAddOp2(v, OP_Integer, 1, target); r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); testcase( regFree1==0 ); - addr = sqlite3VdbeAddOp1(v, op, r1); VdbeCoverage(v); + addr = sqlite3VdbeAddOp1(v, op, r1); + VdbeCoverageIf(v, op==TK_ISNULL); + VdbeCoverageIf(v, op==TK_NOTNULL); sqlite3VdbeAddOp2(v, OP_AddImm, target, -1); sqlite3VdbeJumpHere(v, addr); break; @@ -2857,8 +2818,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ r3 = sqlite3GetTempReg(pParse); r4 = sqlite3GetTempReg(pParse); codeCompare(pParse, pLeft, pRight, OP_Ge, - r1, r2, r3, SQLITE_STOREP2); - VdbeCoverage(v); + r1, r2, r3, SQLITE_STOREP2); VdbeCoverage(v); pLItem++; pRight = pLItem->pExpr; sqlite3ReleaseTempReg(pParse, regFree2); @@ -3605,23 +3565,17 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ case TK_GE: case TK_NE: case TK_EQ: { - assert( TK_LT==OP_Lt ); - assert( TK_LE==OP_Le ); - assert( TK_GT==OP_Gt ); - assert( TK_GE==OP_Ge ); - assert( TK_EQ==OP_Eq ); - assert( TK_NE==OP_Ne ); - testcase( op==TK_LT ); - testcase( op==TK_LE ); - testcase( op==TK_GT ); - testcase( op==TK_GE ); - testcase( op==TK_EQ ); - testcase( op==TK_NE ); testcase( jumpIfNull==0 ); r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, - r1, r2, dest, jumpIfNull); VdbeCoverage(v); + r1, r2, dest, jumpIfNull); + assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt); + assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le); + assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt); + assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge); + assert(TK_EQ==OP_Eq); testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq); + assert(TK_NE==OP_Ne); testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne); testcase( regFree1==0 ); testcase( regFree2==0 ); break; @@ -3634,19 +3588,21 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); op = (op==TK_IS) ? TK_EQ : TK_NE; codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, - r1, r2, dest, SQLITE_NULLEQ); VdbeCoverage(v); + r1, r2, dest, SQLITE_NULLEQ); + VdbeCoverageIf(v, op==TK_EQ); + VdbeCoverageIf(v, op==TK_NE); testcase( regFree1==0 ); testcase( regFree2==0 ); break; } case TK_ISNULL: case TK_NOTNULL: { - assert( TK_ISNULL==OP_IsNull ); - assert( TK_NOTNULL==OP_NotNull ); - testcase( op==TK_ISNULL ); - testcase( op==TK_NOTNULL ); + assert( TK_ISNULL==OP_IsNull ); testcase( op==TK_ISNULL ); + assert( TK_NOTNULL==OP_NotNull ); testcase( op==TK_NOTNULL ); r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); - sqlite3VdbeAddOp2(v, op, r1, dest); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, op, r1, dest); + VdbeCoverageIf(v, op==TK_ISNULL); + VdbeCoverageIf(v, op==TK_NOTNULL); testcase( regFree1==0 ); break; } @@ -3765,17 +3721,17 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ case TK_GE: case TK_NE: case TK_EQ: { - testcase( op==TK_LT ); - testcase( op==TK_LE ); - testcase( op==TK_GT ); - testcase( op==TK_GE ); - testcase( op==TK_EQ ); - testcase( op==TK_NE ); testcase( jumpIfNull==0 ); r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, - r1, r2, dest, jumpIfNull); VdbeCoverage(v); + r1, r2, dest, jumpIfNull); + assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt); + assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le); + assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt); + assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge); + assert(TK_EQ==OP_Eq); testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq); + assert(TK_NE==OP_Ne); testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne); testcase( regFree1==0 ); testcase( regFree2==0 ); break; @@ -3788,17 +3744,19 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); op = (pExpr->op==TK_IS) ? TK_NE : TK_EQ; codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, - r1, r2, dest, SQLITE_NULLEQ); VdbeCoverage(v); + r1, r2, dest, SQLITE_NULLEQ); + VdbeCoverageIf(v, op==TK_EQ); + VdbeCoverageIf(v, op==TK_NE); testcase( regFree1==0 ); testcase( regFree2==0 ); break; } case TK_ISNULL: case TK_NOTNULL: { - testcase( op==TK_ISNULL ); - testcase( op==TK_NOTNULL ); r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); - sqlite3VdbeAddOp2(v, op, r1, dest); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, op, r1, dest); + testcase( op==TK_ISNULL ); VdbeCoverageIf(v, op==TK_ISNULL); + testcase( op==TK_NOTNULL ); VdbeCoverageIf(v, op==TK_NOTNULL); testcase( regFree1==0 ); break; } diff --git a/src/select.c b/src/select.c index fcd8b7ea0b..93947d56b2 100644 --- a/src/select.c +++ b/src/select.c @@ -4595,7 +4595,7 @@ int sqlite3Select( /* If the subquery is not correlated and if we are not inside of ** a trigger, then we only need to compute the value of the subquery ** once. */ - onceAddr = sqlite3CodeOnce(pParse); + onceAddr = sqlite3CodeOnce(pParse); VdbeCoverage(v); VdbeComment((v, "materialize \"%s\"", pItem->pTab->zName)); }else{ VdbeNoopComment((v, "materialize \"%s\"", pItem->pTab->zName)); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 5f5ce63d48..038215a055 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3087,7 +3087,6 @@ int sqlite3ExprIsConstantNotJoin(Expr*); int sqlite3ExprIsConstantOrFunction(Expr*); int sqlite3ExprIsInteger(Expr*, int*); int sqlite3ExprCanBeNull(const Expr*); -void sqlite3ExprCodeIsNullJump(Vdbe*, const Expr*, int, int); int sqlite3ExprNeedsNoAffinityChange(const Expr*, char); int sqlite3IsRowid(const char*); void sqlite3GenerateRowDelete(Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8); diff --git a/src/where.c b/src/where.c index 15bcb1ebde..d606ba4c18 100644 --- a/src/where.c +++ b/src/where.c @@ -1601,7 +1601,7 @@ static void constructAutomaticIndex( ** transient index on 2nd and subsequent iterations of the loop. */ v = pParse->pVdbe; assert( v!=0 ); - addrInit = sqlite3CodeOnce(pParse); + addrInit = sqlite3CodeOnce(pParse); VdbeCoverage(v); /* Count the number of columns that will be added to the index ** and used to match WHERE clause constraints */ @@ -2388,7 +2388,9 @@ static int codeEqualityTerm( bRev = !bRev; } iTab = pX->iTable; - sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iTab, 0); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iTab, 0); + VdbeCoverageIf(v, bRev); + VdbeCoverageIf(v, !bRev); assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 ); pLoop->wsFlags |= WHERE_IN_ABLE; if( pLevel->u.in.nIn==0 ){ @@ -2502,11 +2504,15 @@ static int codeAllEqualityTerms( if( nSkip ){ int iIdxCur = pLevel->iIdxCur; - sqlite3VdbeAddOp1(v, (bRev?OP_Last:OP_Rewind), iIdxCur); VdbeCoverage(v); + sqlite3VdbeAddOp1(v, (bRev?OP_Last:OP_Rewind), iIdxCur); + VdbeCoverageIf(v, bRev==0); + VdbeCoverageIf(v, bRev!=0); VdbeComment((v, "begin skip-scan on %s", pIdx->zName)); j = sqlite3VdbeAddOp0(v, OP_Goto); pLevel->addrSkip = sqlite3VdbeAddOp4Int(v, (bRev?OP_SeekLT:OP_SeekGT), - iIdxCur, 0, regBase, nSkip); VdbeCoverage(v); + iIdxCur, 0, regBase, nSkip); + VdbeCoverageIf(v, bRev==0); + VdbeCoverageIf(v, bRev!=0); sqlite3VdbeJumpHere(v, j); for(j=0; jeOperator & WO_IN ); if( (pTerm->eOperator & (WO_ISNULL|WO_IN))==0 ){ Expr *pRight = pTerm->pExpr->pRight; - sqlite3ExprCodeIsNullJump(v, pRight, regBase+j, pLevel->addrBrk); + if( sqlite3ExprCanBeNull(pRight) ){ + sqlite3VdbeAddOp2(v, OP_IsNull, regBase+j, pLevel->addrBrk); + VdbeCoverage(v); + } if( zAff ){ if( sqlite3CompareAffinity(pRight, zAff[j])==SQLITE_AFF_NONE ){ zAff[j] = SQLITE_AFF_NONE; @@ -2904,13 +2913,18 @@ static Bitmask codeOneLoopStart( testcase( pStart->leftCursor!=iCur ); /* transitive constraints */ r1 = sqlite3ExprCodeTemp(pParse, pX->pRight, &rTemp); sqlite3VdbeAddOp3(v, aMoveOp[pX->op-TK_GT], iCur, addrBrk, r1); - VdbeComment((v, "pk")); VdbeCoverage(v); + VdbeComment((v, "pk")); + VdbeCoverageIf(v, pX->op==TK_GT); + VdbeCoverageIf(v, pX->op==TK_LE); + VdbeCoverageIf(v, pX->op==TK_LT); + VdbeCoverageIf(v, pX->op==TK_GE); sqlite3ExprCacheAffinityChange(pParse, r1, 1); sqlite3ReleaseTempReg(pParse, rTemp); disableTerm(pLevel, pStart); }else{ sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, addrBrk); - VdbeCoverage(v); + VdbeCoverageIf(v, bRev==0); + VdbeCoverageIf(v, bRev!=0); } if( pEnd ){ Expr *pX; @@ -2938,7 +2952,10 @@ static Bitmask codeOneLoopStart( sqlite3VdbeAddOp2(v, OP_Rowid, iCur, iRowidReg); sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg); sqlite3VdbeAddOp3(v, testOp, memEndValue, addrBrk, iRowidReg); - VdbeCoverage(v); + VdbeCoverageIf(v, testOp==OP_Le); + VdbeCoverageIf(v, testOp==OP_Lt); + VdbeCoverageIf(v, testOp==OP_Ge); + VdbeCoverageIf(v, testOp==OP_Gt); sqlite3VdbeChangeP5(v, SQLITE_AFF_NUMERIC | SQLITE_JUMPIFNULL); } }else if( pLoop->wsFlags & WHERE_INDEXED ){ @@ -3080,8 +3097,11 @@ static Bitmask codeOneLoopStart( if( pRangeStart ){ Expr *pRight = pRangeStart->pExpr->pRight; sqlite3ExprCode(pParse, pRight, regBase+nEq); - if( (pRangeStart->wtFlags & TERM_VNULL)==0 ){ - sqlite3ExprCodeIsNullJump(v, pRight, regBase+nEq, addrNxt); + if( (pRangeStart->wtFlags & TERM_VNULL)==0 + && sqlite3ExprCanBeNull(pRight) + ){ + sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt); + VdbeCoverage(v); } if( zStartAff ){ if( sqlite3CompareAffinity(pRight, zStartAff[nEq])==SQLITE_AFF_NONE){ @@ -3105,20 +3125,14 @@ static Bitmask codeOneLoopStart( codeApplyAffinity(pParse, regBase, nConstraint - bSeekPastNull, zStartAff); op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev]; assert( op!=0 ); - testcase( op==OP_Rewind ); - testcase( op==OP_Last ); - testcase( op==OP_SeekGT ); - testcase( op==OP_SeekGE ); - testcase( op==OP_SeekLE ); - testcase( op==OP_SeekLT ); sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint); VdbeCoverage(v); - VdbeCoverageIf(v, op==OP_Rewind); - VdbeCoverageIf(v, op==OP_Last); - VdbeCoverageIf(v, op==OP_SeekGT); - VdbeCoverageIf(v, op==OP_SeekGE); - VdbeCoverageIf(v, op==OP_SeekLE); - VdbeCoverageIf(v, op==OP_SeekLT); + VdbeCoverageIf(v, op==OP_Rewind); testcase( op==OP_Rewind ); + VdbeCoverageIf(v, op==OP_Last); testcase( op==OP_Last ); + VdbeCoverageIf(v, op==OP_SeekGT); testcase( op==OP_SeekGT ); + VdbeCoverageIf(v, op==OP_SeekGE); testcase( op==OP_SeekGE ); + VdbeCoverageIf(v, op==OP_SeekLE); testcase( op==OP_SeekLE ); + VdbeCoverageIf(v, op==OP_SeekLT); testcase( op==OP_SeekLT ); /* Load the value for the inequality constraint at the end of the ** range (if any). @@ -3128,8 +3142,11 @@ static Bitmask codeOneLoopStart( Expr *pRight = pRangeEnd->pExpr->pRight; sqlite3ExprCacheRemove(pParse, regBase+nEq, 1); sqlite3ExprCode(pParse, pRight, regBase+nEq); - if( (pRangeEnd->wtFlags & TERM_VNULL)==0 ){ - sqlite3ExprCodeIsNullJump(v, pRight, regBase+nEq, addrNxt); + if( (pRangeEnd->wtFlags & TERM_VNULL)==0 + && sqlite3ExprCanBeNull(pRight) + ){ + sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt); + VdbeCoverage(v); } if( sqlite3CompareAffinity(pRight, cEndAff)!=SQLITE_AFF_NONE && !sqlite3ExprNeedsNoAffinityChange(pRight, cEndAff) @@ -3151,12 +3168,11 @@ static Bitmask codeOneLoopStart( /* Check if the index cursor is past the end of the range. */ if( nConstraint ){ op = aEndOp[bRev*2 + endEq]; - testcase( op==OP_IdxGT ); - testcase( op==OP_IdxGE ); - testcase( op==OP_IdxLT ); - testcase( op==OP_IdxLE ); sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint); - VdbeCoverage(v); + testcase( op==OP_IdxGT ); VdbeCoverageIf(v, op==OP_IdxGT ); + testcase( op==OP_IdxGE ); VdbeCoverageIf(v, op==OP_IdxGE ); + testcase( op==OP_IdxLT ); VdbeCoverageIf(v, op==OP_IdxLT ); + testcase( op==OP_IdxLE ); VdbeCoverageIf(v, op==OP_IdxLE ); } /* Seek the table cursor, if required */ @@ -3430,8 +3446,8 @@ static Bitmask codeOneLoopStart( pLevel->op = aStep[bRev]; pLevel->p1 = iCur; pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrBrk); - VdbeCoverageIf(v, bRev); - VdbeCoverageIf(v, !bRev); + VdbeCoverageIf(v, bRev==0); + VdbeCoverageIf(v, bRev!=0); pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP; } } @@ -5802,6 +5818,9 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ sqlite3VdbeAddOp3(v, pLevel->op, pLevel->p1, pLevel->p2, pLevel->p3); sqlite3VdbeChangeP5(v, pLevel->p5); VdbeCoverage(v); + VdbeCoverageIf(v, pLevel->op==OP_Next); + VdbeCoverageIf(v, pLevel->op==OP_Prev); + VdbeCoverageIf(v, pLevel->op==OP_VNext); } if( pLoop->wsFlags & WHERE_IN_ABLE && pLevel->u.in.nIn>0 ){ struct InLoop *pIn; @@ -5811,6 +5830,8 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ sqlite3VdbeJumpHere(v, pIn->addrInTop+1); sqlite3VdbeAddOp2(v, pIn->eEndLoopOp, pIn->iCur, pIn->addrInTop); VdbeCoverage(v); + VdbeCoverageIf(v, pIn->eEndLoopOp==OP_PrevIfOpen); + VdbeCoverageIf(v, pIn->eEndLoopOp==OP_NextIfOpen); sqlite3VdbeJumpHere(v, pIn->addrInTop-1); } sqlite3DbFree(db, pLevel->u.in.aInLoop); From f4345e40a03a4d68dcab0556669573135ebbfd9b Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 18 Feb 2014 11:31:59 +0000 Subject: [PATCH 269/276] Fix VDBE branch accounting on comparison operators. FossilOrigin-Name: b287520c9226f7a9fab98142f5c207bfe959cd7e --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 4606d87635..03e22ae49a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sVdbeCoverage()\sand\sVdbeCoverageIf()\smacros\sfor\simproved\sVDBE\scoverage\ntesting. -D 2014-02-18T03:07:12.342 +C Fix\sVDBE\sbranch\saccounting\son\scomparison\soperators. +D 2014-02-18T11:31:59.914 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -277,7 +277,7 @@ F src/update.c 16d6555a32298da18ce6e2a00637c462d9e3ac97 F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c c46c90459ef9bdc0c6c73803cf4c55425b4771cf F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c 392f03b25152eb44565a78b8b809743c97e5852b +F src/vdbe.c 6e3d5d4c68076c09724c74bc5c39985a204e55a0 F src/vdbe.h f429f5e5e14b02acbdffb2b2e8ba6e865e66e320 F src/vdbeInt.h 5286af9067cabdb8ba57b87c0c988a931be6c6c8 F src/vdbeapi.c 5bc41aaea448a7fc250902c418f1795859be3820 @@ -1151,7 +1151,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 915f6f1c7aab54583729e60bdc1565f25ecc6f74 -R d0043e1267f21a1ea521214d42169c3d +P b92d31a97d5fe4606d9ae1393c7f3e052f46bf5a +R ac3bce6c9f7bb42059d2e404010fd2bc U drh -Z f5a439caf79133298419241dae122f4e +Z fa645aebf1d7fefe7cb4cc20303fc9e2 diff --git a/manifest.uuid b/manifest.uuid index 2e856727c0..5eb83b599d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b92d31a97d5fe4606d9ae1393c7f3e052f46bf5a \ No newline at end of file +b287520c9226f7a9fab98142f5c207bfe959cd7e \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 002309bc3b..966d0431d0 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1909,7 +1909,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ MemSetTypeFlag(pOut, MEM_Null); REGISTER_TRACE(pOp->p2, pOut); }else{ - VdbeBranchTaken((pOp->p5 & SQLITE_JUMPIFNULL)?2:3,4); + VdbeBranchTaken(2,3); if( pOp->p5 & SQLITE_JUMPIFNULL ){ pc = pOp->p2-1; } @@ -1946,7 +1946,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ pOut->u.i = res; REGISTER_TRACE(pOp->p2, pOut); }else{ - VdbeBranchTaken(res!=0, 4); + VdbeBranchTaken(res!=0, (pOp->p5 & SQLITE_NULLEQ)?2:3); if( res ){ pc = pOp->p2-1; } From 49d9ba6354fea331413a5fd21af0e25d63edaaae Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 19 Feb 2014 00:53:46 +0000 Subject: [PATCH 270/276] Tweaks in support of VDBE branch test coverage. FossilOrigin-Name: b97825646996792d0a67b83f135658027c8569ca --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/alter.c | 3 ++- src/delete.c | 6 ++++-- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 03e22ae49a..21d08689e4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sVDBE\sbranch\saccounting\son\scomparison\soperators. -D 2014-02-18T11:31:59.914 +C Tweaks\sin\ssupport\sof\sVDBE\sbranch\stest\scoverage. +D 2014-02-19T00:53:46.757 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -156,7 +156,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 3d8b83c91651f53472ca17599dae3457b8b89494 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c 829d67a359b7c5d37120be994af2c0eac730070c +F src/alter.c 1a630c6579b05d93530d4289182a4e8449e722f2 F src/analyze.c 69761e1677142d180a9f55250dee2952f45e4793 F src/attach.c 3801129015ef59d76bf23c95ef9b0069d18a0c52 F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 @@ -171,7 +171,7 @@ F src/callback.c 174e3c8656bc29f91d710ab61550d16eea34be98 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 -F src/delete.c a00bf893bd39868c51020eba1fc5182eb36bfeb7 +F src/delete.c cdd57149543bb28304d8f717c243f2a86b1fc280 F src/expr.c 014b8087a15c4c314bdd798cb1cb0b32693f8b40 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 3cd6ce998404fb1b7203d886d6fdff71cf3c8846 @@ -1151,7 +1151,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P b92d31a97d5fe4606d9ae1393c7f3e052f46bf5a -R ac3bce6c9f7bb42059d2e404010fd2bc +P b287520c9226f7a9fab98142f5c207bfe959cd7e +R db3eaca30cb3f9a4bcbd920e67b64796 U drh -Z fa645aebf1d7fefe7cb4cc20303fc9e2 +Z 6e0e07262b8661a34d8eb8aae8107f91 diff --git a/manifest.uuid b/manifest.uuid index 5eb83b599d..b1881b184d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b287520c9226f7a9fab98142f5c207bfe959cd7e \ No newline at end of file +b97825646996792d0a67b83f135658027c8569ca \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index b8bf20cfd9..7afce403dc 100644 --- a/src/alter.c +++ b/src/alter.c @@ -604,7 +604,8 @@ void sqlite3MinimumFileFormat(Parse *pParse, int iDb, int minFormat){ sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, r1, BTREE_FILE_FORMAT); sqlite3VdbeUsesBtree(v, iDb); sqlite3VdbeAddOp2(v, OP_Integer, minFormat, r2); - j1 = sqlite3VdbeAddOp3(v, OP_Ge, r2, 0, r1); VdbeCoverage(v); + j1 = sqlite3VdbeAddOp3(v, OP_Ge, r2, 0, r1); + sqlite3VdbeChangeP5(v, SQLITE_NULLEQ); VdbeCoverage(v); sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, r2); sqlite3VdbeJumpHere(v, j1); sqlite3ReleaseTempReg(pParse, r1); diff --git a/src/delete.c b/src/delete.c index 3fa41c53f0..79e83cae52 100644 --- a/src/delete.c +++ b/src/delete.c @@ -613,7 +613,8 @@ void sqlite3GenerateRowDelete( opSeek = HasRowid(pTab) ? OP_NotExists : OP_NotFound; if( !bNoSeek ){ sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk); - VdbeCoverage(v); + VdbeCoverageIf(v, opSeek==OP_NotExists); + VdbeCoverageIf(v, opSeek==OP_NotFound); } /* If there are any triggers to fire, allocate a range of registers to @@ -656,7 +657,8 @@ void sqlite3GenerateRowDelete( */ if( addrStart Date: Wed, 19 Feb 2014 01:31:02 +0000 Subject: [PATCH 271/276] Make sure a multi-row VALUES clause works correctly in a compound SELECT. FossilOrigin-Name: 85b355cfb40e8dbeb171980204ffad897184063f --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/parse.y | 16 ++++++++++++---- test/select4.test | 36 ++++++++++++++++++++++++++++++++++++ 4 files changed, 56 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 21d08689e4..f819451ca7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Tweaks\sin\ssupport\sof\sVDBE\sbranch\stest\scoverage. -D 2014-02-19T00:53:46.757 +C Make\ssure\sa\smulti-row\sVALUES\sclause\sworks\scorrectly\sin\sa\scompound\sSELECT. +D 2014-02-19T01:31:02.841 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -206,7 +206,7 @@ F src/os_unix.c 18f7f95dc6bcb9cf4d4a238d8e2de96611bc2ae5 F src/os_win.c d4284f003445054a26689f1264b1b9bf7261bd1b F src/pager.c 0ffa313a30ed6d061d9c6601b7b175cc50a1cab7 F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428 -F src/parse.y cce844ccb80b5f969b04c25100c8d94338488efb +F src/parse.y 2613ca5d609c2f3d71dd297351f010bcec16e1e0 F src/pcache.c d8eafac28290d4bb80332005435db44991d07fc2 F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222 F src/pcache1.c 102e6f5a2fbc646154463eb856d1fd716867b64c @@ -777,7 +777,7 @@ F test/securedel2.test 2d54c28e46eb1fd6902089958b20b1b056c6f1c5 F test/select1.test fc2a61f226a649393664ad54bc5376631801517c F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56 F test/select3.test 2ce595f8fb8e2ac10071d3b4e424cadd4634a054 -F test/select4.test 00179be44e531fe04c1c3f15df216439dff2519d +F test/select4.test 8c5a60d439e2df824aed56223566877a883c5c84 F test/select5.test e758b8ef94f69b111df4cb819008856655dcd535 F test/select6.test e76bd10a56988f15726c097a5d5a7966fe82d3b2 F test/select7.test 7fd2ef598cfabb6b9ff6ac13973b91d0527df49d @@ -1151,7 +1151,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P b287520c9226f7a9fab98142f5c207bfe959cd7e -R db3eaca30cb3f9a4bcbd920e67b64796 +P b97825646996792d0a67b83f135658027c8569ca +R e0d510b78dfc0d79538a4222d29a9363 U drh -Z 6e0e07262b8661a34d8eb8aae8107f91 +Z f971c993fbd0c297278e42fafe3ac2dc diff --git a/manifest.uuid b/manifest.uuid index b1881b184d..7a4f65bb4a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b97825646996792d0a67b83f135658027c8569ca \ No newline at end of file +85b355cfb40e8dbeb171980204ffad897184063f \ No newline at end of file diff --git a/src/parse.y b/src/parse.y index 373c126a25..ad9bedf0b4 100644 --- a/src/parse.y +++ b/src/parse.y @@ -437,14 +437,22 @@ select(A) ::= with(W) selectnowith(X). { selectnowith(A) ::= oneselect(X). {A = X;} %ifndef SQLITE_OMIT_COMPOUND_SELECT selectnowith(A) ::= selectnowith(X) multiselect_op(Y) oneselect(Z). { - if( Z ){ - Z->op = (u8)Y; - Z->pPrior = X; + Select *pRhs = Z; + if( pRhs && pRhs->pPrior ){ + SrcList *pFrom; + Token x; + x.n = 0; + pFrom = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&x,pRhs,0,0); + pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0,0); + } + if( pRhs ){ + pRhs->op = (u8)Y; + pRhs->pPrior = X; if( Y!=TK_ALL ) pParse->hasCompound = 1; }else{ sqlite3SelectDelete(pParse->db, X); } - A = Z; + A = pRhs; } %type multiselect_op {int} multiselect_op(A) ::= UNION(OP). {A = @OP;} diff --git a/test/select4.test b/test/select4.test index e205b37a4f..8fc200d434 100644 --- a/test/select4.test +++ b/test/select4.test @@ -824,4 +824,40 @@ do_test select4-13.1 { } } {1 2} +# 2014-02-18: Make sure compound SELECTs work with VALUES clauses +# +do_execsql_test select4-14.1 { + CREATE TABLE t14(a,b,c); + INSERT INTO t14 VALUES(1,2,3),(4,5,6); + SELECT * FROM t14 INTERSECT VALUES(3,2,1),(2,3,1),(1,2,3),(2,1,3); +} {1 2 3} +do_execsql_test select4-14.2 { + SELECT * FROM t14 INTERSECT VALUES(1,2,3); +} {1 2 3} +do_execsql_test select4-14.3 { + SELECT * FROM t14 + UNION VALUES(3,2,1),(2,3,1),(1,2,3),(7,8,9),(4,5,6) + UNION SELECT * FROM t14 ORDER BY 1, 2, 3 +} {1 2 3 2 3 1 3 2 1 4 5 6 7 8 9} +do_execsql_test select4-14.4 { + SELECT * FROM t14 + UNION VALUES(3,2,1) + UNION SELECT * FROM t14 ORDER BY 1, 2, 3 +} {1 2 3 3 2 1 4 5 6} +do_execsql_test select4-14.5 { + SELECT * FROM t14 EXCEPT VALUES(3,2,1),(2,3,1),(1,2,3),(2,1,3); +} {4 5 6} +do_execsql_test select4-14.6 { + SELECT * FROM t14 EXCEPT VALUES(1,2,3) +} {4 5 6} +do_execsql_test select4-14.7 { + SELECT * FROM t14 EXCEPT VALUES(1,2,3) EXCEPT VALUES(4,5,6) +} {} +do_execsql_test select4-14.8 { + SELECT * FROM t14 EXCEPT VALUES('a','b','c') EXCEPT VALUES(4,5,6) +} {1 2 3} +do_execsql_test select4-14.9 { + SELECT * FROM t14 UNION ALL VALUES(3,2,1),(2,3,1),(1,2,3),(2,1,3); +} {1 2 3 4 5 6 3 2 1 2 3 1 1 2 3 2 1 3} + finish_test From 3d77dee9356115e817158168ad252592304deb1f Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 19 Feb 2014 14:20:49 +0000 Subject: [PATCH 272/276] Add the SQLITE_NOTNULL P5 code for comparison operations - really a composite of SQLITE_NULLEQ and SQLITE_JUMPIFNULL. This flag indicates that NULL operands are not possible and raises and assert() if NULL operands are seen. Also omit an unnecessary scan of the sqlite_sequence table when writing into an AUTOINCREMENT table. FossilOrigin-Name: d2c047f304848e49864ed8c216b48fd671fa3916 --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/alter.c | 2 +- src/fkey.c | 1 + src/insert.c | 18 +++++++----------- src/sqliteInt.h | 6 ++++++ src/vdbe.c | 2 +- 7 files changed, 27 insertions(+), 24 deletions(-) diff --git a/manifest b/manifest index f819451ca7..9293877a3f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\sa\smulti-row\sVALUES\sclause\sworks\scorrectly\sin\sa\scompound\sSELECT. -D 2014-02-19T01:31:02.841 +C Add\sthe\sSQLITE_NOTNULL\sP5\scode\sfor\scomparison\soperations\s-\sreally\sa\scomposite\nof\sSQLITE_NULLEQ\sand\sSQLITE_JUMPIFNULL.\s\sThis\sflag\sindicates\sthat\sNULL\soperands\nare\snot\spossible\sand\sraises\sand\sassert()\sif\sNULL\soperands\sare\sseen.\nAlso\somit\san\sunnecessary\sscan\sof\sthe\ssqlite_sequence\stable\swhen\swriting\ninto\san\sAUTOINCREMENT\stable. +D 2014-02-19T14:20:49.685 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -156,7 +156,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 3d8b83c91651f53472ca17599dae3457b8b89494 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c 1a630c6579b05d93530d4289182a4e8449e722f2 +F src/alter.c 75a0b861e98968c0f3b27606e7d9462228d04827 F src/analyze.c 69761e1677142d180a9f55250dee2952f45e4793 F src/attach.c 3801129015ef59d76bf23c95ef9b0069d18a0c52 F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 @@ -174,13 +174,13 @@ F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 F src/delete.c cdd57149543bb28304d8f717c243f2a86b1fc280 F src/expr.c 014b8087a15c4c314bdd798cb1cb0b32693f8b40 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb -F src/fkey.c 3cd6ce998404fb1b7203d886d6fdff71cf3c8846 +F src/fkey.c 5269ef07b100763134f71b889327c333bd0989cf F src/func.c f4499b39d66b71825514334ce67b32ff14bd19f5 F src/global.c 1d7bb7ea8254ae6a68ed9bfaf65fcb3d1690b486 F src/hash.c d139319967164f139c8d1bb8a11b14db9c4ba3cd F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c 5d5e1d78f74804739b424c92346bdc26c146dfa4 +F src/insert.c 429adb670176eb5471be9867ff7c88a190b23cb3 F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b @@ -221,7 +221,7 @@ F src/shell.c 3dd86bf73ccd079f0e32ef5069600586085e8239 F src/sqlite.h.in a2ef671f92747a5a1c8a47bad5c585a8dd9eca80 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h 22111056d7d5c404fef783b13088ef87d98074d0 +F src/sqliteInt.h 616f8a225bfd6cf09f7f5906c7b91b29a3591b34 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -277,7 +277,7 @@ F src/update.c 16d6555a32298da18ce6e2a00637c462d9e3ac97 F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c c46c90459ef9bdc0c6c73803cf4c55425b4771cf F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c 6e3d5d4c68076c09724c74bc5c39985a204e55a0 +F src/vdbe.c 16c220ae23bbd6755f66bb32eb4c8c0fadda6c8f F src/vdbe.h f429f5e5e14b02acbdffb2b2e8ba6e865e66e320 F src/vdbeInt.h 5286af9067cabdb8ba57b87c0c988a931be6c6c8 F src/vdbeapi.c 5bc41aaea448a7fc250902c418f1795859be3820 @@ -1151,7 +1151,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P b97825646996792d0a67b83f135658027c8569ca -R e0d510b78dfc0d79538a4222d29a9363 +P 85b355cfb40e8dbeb171980204ffad897184063f +R 6054409536840db43eb58dd38378a2df U drh -Z f971c993fbd0c297278e42fafe3ac2dc +Z 59cedb1de1bf2e430d47d82062cddf85 diff --git a/manifest.uuid b/manifest.uuid index 7a4f65bb4a..30fa60d6f1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -85b355cfb40e8dbeb171980204ffad897184063f \ No newline at end of file +d2c047f304848e49864ed8c216b48fd671fa3916 \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index 7afce403dc..e9f06a9f72 100644 --- a/src/alter.c +++ b/src/alter.c @@ -605,7 +605,7 @@ void sqlite3MinimumFileFormat(Parse *pParse, int iDb, int minFormat){ sqlite3VdbeUsesBtree(v, iDb); sqlite3VdbeAddOp2(v, OP_Integer, minFormat, r2); j1 = sqlite3VdbeAddOp3(v, OP_Ge, r2, 0, r1); - sqlite3VdbeChangeP5(v, SQLITE_NULLEQ); VdbeCoverage(v); + sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); VdbeCoverage(v); sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, r2); sqlite3VdbeJumpHere(v, j1); sqlite3ReleaseTempReg(pParse, r1); diff --git a/src/fkey.c b/src/fkey.c index c94f969238..336256e0f3 100644 --- a/src/fkey.c +++ b/src/fkey.c @@ -369,6 +369,7 @@ static void fkLookupParent( ** increment the constraint-counter. */ if( pTab==pFKey->pFrom && nIncr==1 ){ sqlite3VdbeAddOp3(v, OP_Eq, regData, iOk, regTemp); VdbeCoverage(v); + sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); } sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead); diff --git a/src/insert.c b/src/insert.c index 64786ee112..7aa9329b8d 100644 --- a/src/insert.c +++ b/src/insert.c @@ -304,7 +304,7 @@ void sqlite3AutoincrementEnd(Parse *pParse){ assert( v ); for(p = pParse->pAinc; p; p = p->pNext){ Db *pDb = &db->aDb[p->iDb]; - int j1, j2, j3, j4, j5; + int j1; int iRec; int memId = p->regCtr; @@ -312,17 +312,8 @@ void sqlite3AutoincrementEnd(Parse *pParse){ assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) ); sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenWrite); j1 = sqlite3VdbeAddOp1(v, OP_NotNull, memId+1); VdbeCoverage(v); - j2 = sqlite3VdbeAddOp0(v, OP_Rewind); VdbeCoverage(v); - j3 = sqlite3VdbeAddOp3(v, OP_Column, 0, 0, iRec); - j4 = sqlite3VdbeAddOp3(v, OP_Eq, memId-1, 0, iRec); VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_Next, 0, j3); VdbeCoverage(v); - sqlite3VdbeJumpHere(v, j2); sqlite3VdbeAddOp2(v, OP_NewRowid, 0, memId+1); - j5 = sqlite3VdbeAddOp0(v, OP_Goto); - sqlite3VdbeJumpHere(v, j4); - sqlite3VdbeAddOp2(v, OP_Rowid, 0, memId+1); sqlite3VdbeJumpHere(v, j1); - sqlite3VdbeJumpHere(v, j5); sqlite3VdbeAddOp3(v, OP_MakeRecord, memId-1, 2, iRec); sqlite3VdbeAddOp3(v, OP_Insert, 0, iRec, memId+1); sqlite3VdbeChangeP5(v, OPFLAG_APPEND); @@ -1275,6 +1266,7 @@ void sqlite3GenerateConstraintChecks( ** it might have changed. Skip the conflict logic below if the rowid ** is unchanged. */ sqlite3VdbeAddOp3(v, OP_Eq, regNewData, addrRowidOk, regOldData); + sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); VdbeCoverage(v); } @@ -1446,6 +1438,7 @@ void sqlite3GenerateConstraintChecks( ** is different from old-rowid */ if( isUpdate ){ sqlite3VdbeAddOp3(v, OP_Eq, regR, addrUniqueOk, regOldData); + sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); VdbeCoverage(v); } }else{ @@ -1481,7 +1474,10 @@ void sqlite3GenerateConstraintChecks( } sqlite3VdbeAddOp4(v, op, regOldData+1+x, addrJump, regCmp+i, p4, P4_COLLSEQ - ); VdbeCoverage(v); + ); + sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); + VdbeCoverageIf(v, op==OP_Eq); + VdbeCoverageIf(v, op==OP_Ne); } } } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 038215a055..a6663ff679 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1314,10 +1314,16 @@ struct CollSeq { /* ** Additional bit values that can be ORed with an affinity without ** changing the affinity. +** +** The SQLITE_NOTNULL flag is a combination of NULLEQ and JUMPIFNULL. +** It causes an assert() to fire if either operand to a comparison +** operator is NULL. It is added to certain comparison operators to +** prove that the operands are always NOT NULL. */ #define SQLITE_JUMPIFNULL 0x08 /* jumps if either operand is NULL */ #define SQLITE_STOREP2 0x10 /* Store result in reg[P2] rather than jump */ #define SQLITE_NULLEQ 0x80 /* NULL=NULL */ +#define SQLITE_NOTNULL 0x88 /* Assert that operands are never NULL */ /* ** An object of this type is created for each virtual table present in diff --git a/src/vdbe.c b/src/vdbe.c index 966d0431d0..1e9e31116f 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1891,6 +1891,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ */ assert( pOp->opcode==OP_Eq || pOp->opcode==OP_Ne ); assert( (flags1 & MEM_Cleared)==0 ); + assert( (pOp->p5 & SQLITE_JUMPIFNULL)==0 ); if( (flags1&MEM_Null)!=0 && (flags3&MEM_Null)!=0 && (flags3&MEM_Cleared)==0 @@ -4833,7 +4834,6 @@ case OP_Clear: { nChange = 0; assert( p->readOnly==0 ); - assert( pOp->p1!=1 ); assert( (p->btreeMask & (((yDbMask)1)<p2))!=0 ); rc = sqlite3BtreeClearTable( db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &nChange : 0) From 5655c549aa202c957cf3610d9faa99aac5996475 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 19 Feb 2014 19:14:34 +0000 Subject: [PATCH 273/276] Add the VdbeCoverageNeverTaken() macro, and comments that better describe how the VDBE branch coverage measurement works. Add some tags to provide 100% VDBE branch coverage. FossilOrigin-Name: c1e94169dd8eb80b4d18c73be9f81585330d11ad --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/pragma.c | 1 + src/update.c | 5 ++--- src/vdbe.c | 26 +++++++++++++++++++++----- src/vdbe.h | 27 ++++++++++++++++++++++++++- 6 files changed, 60 insertions(+), 19 deletions(-) diff --git a/manifest b/manifest index 9293877a3f..2b91bf1936 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sSQLITE_NOTNULL\sP5\scode\sfor\scomparison\soperations\s-\sreally\sa\scomposite\nof\sSQLITE_NULLEQ\sand\sSQLITE_JUMPIFNULL.\s\sThis\sflag\sindicates\sthat\sNULL\soperands\nare\snot\spossible\sand\sraises\sand\sassert()\sif\sNULL\soperands\sare\sseen.\nAlso\somit\san\sunnecessary\sscan\sof\sthe\ssqlite_sequence\stable\swhen\swriting\ninto\san\sAUTOINCREMENT\stable. -D 2014-02-19T14:20:49.685 +C Add\sthe\sVdbeCoverageNeverTaken()\smacro,\sand\scomments\sthat\sbetter\sdescribe\show\nthe\sVDBE\sbranch\scoverage\smeasurement\sworks.\s\sAdd\ssome\stags\sto\sprovide\s100%\nVDBE\sbranch\scoverage. +D 2014-02-19T19:14:34.983 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -210,7 +210,7 @@ F src/parse.y 2613ca5d609c2f3d71dd297351f010bcec16e1e0 F src/pcache.c d8eafac28290d4bb80332005435db44991d07fc2 F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222 F src/pcache1.c 102e6f5a2fbc646154463eb856d1fd716867b64c -F src/pragma.c 2635d6bf8b54003ebefd773df2f50258cece2bec +F src/pragma.c a46ee83671f5c95f53d2ceeb5e1a818d7b1df99a F src/prepare.c 677521ab7132615a8a26107a1d1c3132f44ae337 F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece @@ -273,12 +273,12 @@ F src/test_vfstrace.c 3a0ab304682fecbceb689e7d9b904211fde11d78 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/tokenize.c 6da2de6e12218ccb0aea5184b56727d011f4bee7 F src/trigger.c a80036fcbd992729adc7cd34a875d59a71fa10cc -F src/update.c 16d6555a32298da18ce6e2a00637c462d9e3ac97 +F src/update.c 5b3e74a03b3811e586b4f2b4cbd7c49f01c93115 F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c c46c90459ef9bdc0c6c73803cf4c55425b4771cf F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c 16c220ae23bbd6755f66bb32eb4c8c0fadda6c8f -F src/vdbe.h f429f5e5e14b02acbdffb2b2e8ba6e865e66e320 +F src/vdbe.c b82ffb8ca4a7b163f0d4450dce353259cbb12240 +F src/vdbe.h 6c703ccef97f4504bd0d79cc09180185a60ae8ad F src/vdbeInt.h 5286af9067cabdb8ba57b87c0c988a931be6c6c8 F src/vdbeapi.c 5bc41aaea448a7fc250902c418f1795859be3820 F src/vdbeaux.c 0e01d6fda149c689039caadb8c89b20abb58e21d @@ -1151,7 +1151,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 85b355cfb40e8dbeb171980204ffad897184063f -R 6054409536840db43eb58dd38378a2df +P d2c047f304848e49864ed8c216b48fd671fa3916 +R 290109175fc6aecf9e37def55ff4d8d1 U drh -Z 59cedb1de1bf2e430d47d82062cddf85 +Z 8351cefc3ed205778666dc9ef6e2430a diff --git a/manifest.uuid b/manifest.uuid index 30fa60d6f1..a6ed2e8a06 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d2c047f304848e49864ed8c216b48fd671fa3916 \ No newline at end of file +c1e94169dd8eb80b4d18c73be9f81585330d11ad \ No newline at end of file diff --git a/src/pragma.c b/src/pragma.c index a586370b8d..a211633f23 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1942,6 +1942,7 @@ void sqlite3Pragma( sqlite3VdbeAddOp2(v, OP_Halt, 0, 0); sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3); sqlite3VdbeAddOp3(v, OP_Eq, 8+j, addr+8, 3); VdbeCoverage(v); + sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pIdx->zName, P4_TRANSIENT); sqlite3VdbeAddOp3(v, OP_Concat, 3, 2, 7); diff --git a/src/update.c b/src/update.c index 4c45a4b40d..4138749f80 100644 --- a/src/update.c +++ b/src/update.c @@ -434,7 +434,7 @@ void sqlite3Update( if( aToOpen[iDataCur-iBaseCur] ){ assert( pPk!=0 ); sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey, nKey); - VdbeCoverage(v); + VdbeCoverageNeverTaken(v); } labelContinue = labelBreak; sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak); @@ -577,11 +577,10 @@ void sqlite3Update( if( bReplace || chngKey ){ if( pPk ){ j1 = sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, 0, regKey, nKey); - VdbeCoverage(v); }else{ j1 = sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, 0, regOldRowid); - VdbeCoverage(v); } + VdbeCoverageNeverTaken(v); } sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur, aRegIdx); diff --git a/src/vdbe.c b/src/vdbe.c index 1e9e31116f..2b3396223c 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -108,15 +108,31 @@ int sqlite3_found_count = 0; #endif /* -** Invoke the VDBE coverage callback, if defined +** Invoke the VDBE coverage callback, if that callback is defined. This +** feature is used for test suite validation only and does not appear an +** production builds. +** +** M is an integer, 2 or 3, that indices how many different ways the +** branch can go. It is usually 2. "I" is the direction the branch +** goes. 0 means falls through. 1 means branch is taken. 2 means the +** second alternative branch is taken. */ #if !defined(SQLITE_VDBE_COVERAGE) # define VdbeBranchTaken(I,M) #else -# define VdbeBranchTaken(I,M) \ - if( sqlite3GlobalConfig.xVdbeBranch!=0 ){ \ - sqlite3GlobalConfig.xVdbeBranch(sqlite3GlobalConfig.pVdbeBranchArg, \ - pOp->iSrcLine,(I),(M)); } +# define VdbeBranchTaken(I,M) vdbeTakeBranch(pOp->iSrcLine,I,M) + static void vdbeTakeBranch(int iSrcLine, u8 I, u8 M){ + if( iSrcLine<=2 && ALWAYS(iSrcLine>0) ){ + M = iSrcLine; + /* Assert the truth of VdbeCoverageAlwaysTaken() and + ** VdbeCoverageNeverTaken() */ + assert( (M & I)==I ); + }else{ + if( sqlite3GlobalConfig.xVdbeBranch==0 ) return; /*NO_TEST*/ + sqlite3GlobalConfig.xVdbeBranch(sqlite3GlobalConfig.pVdbeBranchArg, + iSrcLine,I,M); + } + } #endif /* diff --git a/src/vdbe.h b/src/vdbe.h index f1f28cb1b5..44cd9123aa 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -241,14 +241,39 @@ void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *); # define VdbeModuleComment(X) #endif -/* Set the Opcode.iSrcline field of the previous opcode */ +/* +** The VdbeCoverage macros are used to set a coverage testing point +** for VDBE branch instructions. The coverage testing points are line +** numbers in the sqlite3.c source file. VDBE branch coverage testing +** only works with an amalagmation build. That's ok since a VDBE branch +** coverage build designed for testing the test suite only. No application +** should ever ship with VDBE branch coverage measuring turned on. +** +** VdbeCoverage(v) // Mark the previously coded instruction +** // as a branch +** +** VdbeCoverageIf(v, conditional) // Mark previous if conditional true +** +** VdbeCoverageAlwaysTaken(v) // Previous branch is always taken +** +** VdbeCoverageNeverTaken(v) // Previous branch is never taken +** +** Every VDBE branch operation must be tagged with one of the macros above. +** If not, then when "make test" is run with -DSQLITE_VDBE_COVERAGE and +** -DSQLITE_DEBUG then an ALWAYS() will fail in the vdbeTakeBranch() +** routine in vdbe.c, alerting the developer to the missed tag. +*/ #ifdef SQLITE_VDBE_COVERAGE void sqlite3VdbeSetLineNumber(Vdbe*,int); # define VdbeCoverage(v) sqlite3VdbeSetLineNumber(v,__LINE__) # define VdbeCoverageIf(v,x) if(x)sqlite3VdbeSetLineNumber(v,__LINE__) +# define VdbeCoverageAlwaysTaken(v) sqlite3VdbeSetLineNumber(v,2); +# define VdbeCoverageNeverTaken(v) sqlite3VdbeSetLineNumber(v,1); #else # define VdbeCoverage(v) # define VdbeCoverageIf(v,x) +# define VdbeCoverageAlwaysTaken(v) +# define VdbeCoverageNeverTaken(v) #endif #endif From 4300c1ae3b5464e2a11c20eec3cf1139f161799a Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 20 Feb 2014 19:23:15 +0000 Subject: [PATCH 274/276] Make sure that the difference between two string pointers is passed into sqlite3_mprintf() as type "int". FossilOrigin-Name: d5d973fedcf5a2eea219f10e11ba3dacdd0593f0 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/alter.c | 10 +++++----- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 2b91bf1936..e726d97238 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sVdbeCoverageNeverTaken()\smacro,\sand\scomments\sthat\sbetter\sdescribe\show\nthe\sVDBE\sbranch\scoverage\smeasurement\sworks.\s\sAdd\ssome\stags\sto\sprovide\s100%\nVDBE\sbranch\scoverage. -D 2014-02-19T19:14:34.983 +C Make\ssure\sthat\sthe\sdifference\sbetween\stwo\sstring\spointers\sis\spassed\sinto\nsqlite3_mprintf()\sas\stype\s"int". +D 2014-02-20T19:23:15.279 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -156,7 +156,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 3d8b83c91651f53472ca17599dae3457b8b89494 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c 75a0b861e98968c0f3b27606e7d9462228d04827 +F src/alter.c 5d99edbac5bc416032772b723ee30182ee6e5de0 F src/analyze.c 69761e1677142d180a9f55250dee2952f45e4793 F src/attach.c 3801129015ef59d76bf23c95ef9b0069d18a0c52 F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 @@ -1151,7 +1151,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P d2c047f304848e49864ed8c216b48fd671fa3916 -R 290109175fc6aecf9e37def55ff4d8d1 +P c1e94169dd8eb80b4d18c73be9f81585330d11ad +R 09bf9547df25315bb17290d72fbff966 U drh -Z 8351cefc3ed205778666dc9ef6e2430a +Z 6fdf325f579b53033b4ff3e16a9cc3b3 diff --git a/manifest.uuid b/manifest.uuid index a6ed2e8a06..1b31602821 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c1e94169dd8eb80b4d18c73be9f81585330d11ad \ No newline at end of file +d5d973fedcf5a2eea219f10e11ba3dacdd0593f0 \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index e9f06a9f72..1a83e570db 100644 --- a/src/alter.c +++ b/src/alter.c @@ -77,8 +77,8 @@ static void renameTableFunc( assert( len>0 ); } while( token!=TK_LP && token!=TK_USING ); - zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", ((u8*)tname.z) - zSql, zSql, - zTableName, tname.z+tname.n); + zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", (int)(((u8*)tname.z) - zSql), + zSql, zTableName, tname.z+tname.n); sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC); } } @@ -130,7 +130,7 @@ static void renameParentFunc( sqlite3Dequote(zParent); if( 0==sqlite3StrICmp((const char *)zOld, zParent) ){ char *zOut = sqlite3MPrintf(db, "%s%.*s\"%w\"", - (zOutput?zOutput:""), z-zInput, zInput, (const char *)zNew + (zOutput?zOutput:""), (int)(z-zInput), zInput, (const char *)zNew ); sqlite3DbFree(db, zOutput); zOutput = zOut; @@ -216,8 +216,8 @@ static void renameTriggerFunc( /* Variable tname now contains the token that is the old table-name ** in the CREATE TRIGGER statement. */ - zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", ((u8*)tname.z) - zSql, zSql, - zTableName, tname.z+tname.n); + zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", (int)(((u8*)tname.z) - zSql), + zSql, zTableName, tname.z+tname.n); sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC); } } From 06280ee58293795b94f03b830d83db3d72e901cc Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 20 Feb 2014 19:32:38 +0000 Subject: [PATCH 275/276] Fix a harmless shadowed-variable warning. FossilOrigin-Name: 824029090d1c4c4c608f67dd197961eba29c039d --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/insert.c | 8 ++++---- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index e726d97238..260e627beb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\sthat\sthe\sdifference\sbetween\stwo\sstring\spointers\sis\spassed\sinto\nsqlite3_mprintf()\sas\stype\s"int". -D 2014-02-20T19:23:15.279 +C Fix\sa\sharmless\sshadowed-variable\swarning. +D 2014-02-20T19:32:38.618 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -180,7 +180,7 @@ F src/global.c 1d7bb7ea8254ae6a68ed9bfaf65fcb3d1690b486 F src/hash.c d139319967164f139c8d1bb8a11b14db9c4ba3cd F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c 429adb670176eb5471be9867ff7c88a190b23cb3 +F src/insert.c d3d1164299faa53b5347f8ff676d3787537fa9e5 F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b @@ -1151,7 +1151,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P c1e94169dd8eb80b4d18c73be9f81585330d11ad -R 09bf9547df25315bb17290d72fbff966 +P d5d973fedcf5a2eea219f10e11ba3dacdd0593f0 +R 76d0c1c651bb2a560b0883244ae73572 U drh -Z 6fdf325f579b53033b4ff3e16a9cc3b3 +Z 5adb32a47d049f70cd5fc6a5768d989a diff --git a/manifest.uuid b/manifest.uuid index 1b31602821..d04a194920 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d5d973fedcf5a2eea219f10e11ba3dacdd0593f0 \ No newline at end of file +824029090d1c4c4c608f67dd197961eba29c039d \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index 7aa9329b8d..1d29da3092 100644 --- a/src/insert.c +++ b/src/insert.c @@ -677,18 +677,18 @@ void sqlite3Insert( */ int regRec; /* Register to hold packed record */ int regTempRowid; /* Register to hold temp table ROWID */ - int addrTop; /* Label "L" */ + int addrL; /* Label "L" */ srcTab = pParse->nTab++; regRec = sqlite3GetTempReg(pParse); regTempRowid = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp2(v, OP_OpenEphemeral, srcTab, nColumn); - addrTop = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); VdbeCoverage(v); + addrL = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); VdbeCoverage(v); sqlite3VdbeAddOp3(v, OP_MakeRecord, regFromSelect, nColumn, regRec); sqlite3VdbeAddOp2(v, OP_NewRowid, srcTab, regTempRowid); sqlite3VdbeAddOp3(v, OP_Insert, srcTab, regRec, regTempRowid); - sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop); - sqlite3VdbeJumpHere(v, addrTop); + sqlite3VdbeAddOp2(v, OP_Goto, 0, addrL); + sqlite3VdbeJumpHere(v, addrL); sqlite3ReleaseTempReg(pParse, regRec); sqlite3ReleaseTempReg(pParse, regTempRowid); } From 4d87aaed5668ffa435da8e81631f3331fe94d3fe Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 20 Feb 2014 19:42:00 +0000 Subject: [PATCH 276/276] Fix the text of a comment used to generate VDBE opcode documentation so that it omits symbols that can be mistaken for a hyperlink by the parser. FossilOrigin-Name: b46d4e8923e6e367412bba7aeac07039bbcbabd1 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 260e627beb..419633cc87 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sharmless\sshadowed-variable\swarning. -D 2014-02-20T19:32:38.618 +C Fix\sthe\stext\sof\sa\scomment\sused\sto\sgenerate\sVDBE\sopcode\sdocumentation\sso\sthat\nit\somits\ssymbols\sthat\scan\sbe\smistaken\sfor\sa\shyperlink\sby\sthe\sparser. +D 2014-02-20T19:42:00.531 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -277,7 +277,7 @@ F src/update.c 5b3e74a03b3811e586b4f2b4cbd7c49f01c93115 F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c c46c90459ef9bdc0c6c73803cf4c55425b4771cf F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c b82ffb8ca4a7b163f0d4450dce353259cbb12240 +F src/vdbe.c c5ff7b384ed108be747220d4c47fcea6a36b062b F src/vdbe.h 6c703ccef97f4504bd0d79cc09180185a60ae8ad F src/vdbeInt.h 5286af9067cabdb8ba57b87c0c988a931be6c6c8 F src/vdbeapi.c 5bc41aaea448a7fc250902c418f1795859be3820 @@ -1151,7 +1151,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P d5d973fedcf5a2eea219f10e11ba3dacdd0593f0 -R 76d0c1c651bb2a560b0883244ae73572 +P 824029090d1c4c4c608f67dd197961eba29c039d +R 819e2e4df777a2f59b5f5445b2831eb5 U drh -Z 5adb32a47d049f70cd5fc6a5768d989a +Z c4d587ace814e560a6dc901fdec24d15 diff --git a/manifest.uuid b/manifest.uuid index d04a194920..32d13dfb30 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -824029090d1c4c4c608f67dd197961eba29c039d \ No newline at end of file +b46d4e8923e6e367412bba7aeac07039bbcbabd1 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 2b3396223c..2253af4719 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1175,7 +1175,7 @@ case OP_SCopy: { /* out2 */ ** The registers P1 through P1+P2-1 contain a single row of ** results. This opcode causes the sqlite3_step() call to terminate ** with an SQLITE_ROW return code and it sets up the sqlite3_stmt -** structure to provide access to the r[P1]..r[P1+P2-1] values as +** structure to provide access to the r(P1)..r(P1+P2-1) values as ** the result row. */ case OP_ResultRow: {