Merge the latest trunk changes into the sessions branch.
FossilOrigin-Name: 83705e90a54bad462a5b7fbca70cc129998f871c
This commit is contained in:
commit
9e3fbc0157
60
manifest
60
manifest
@ -1,5 +1,5 @@
|
||||
C Add\sa\smissing\s"extern\sC"\sterminator\sto\sthe\send\sof\ssqlite3session.h.
|
||||
D 2011-04-06T23:40:28.737
|
||||
C Merge\sthe\slatest\strunk\schanges\sinto\sthe\ssessions\sbranch.
|
||||
D 2011-04-09T18:07:51.034
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in 7a4d9524721d40ef9ee26f93f9bd6a51dba106f2
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
@ -124,19 +124,19 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
|
||||
F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc
|
||||
F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad
|
||||
F src/alter.c 280f5c04b11b492703a342222b3de0a999445280
|
||||
F src/analyze.c a1ad9f4d8aac055c4a4bbd99073e2e78fe66129c
|
||||
F src/attach.c 7cae2cf0c14762ce14c074a860ec52890a973a56
|
||||
F src/analyze.c a425d62e8fa9ebcb4359ab84ff0c62c6563d2e2a
|
||||
F src/attach.c 7f97ca76ef2453440170929531a9c778267c0830
|
||||
F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
|
||||
F src/backup.c b7529a6691f0fd534ae8ff622203c46a7f1b626b
|
||||
F src/backup.c 986c15232757f2873dff35ee3b35cbf935fc573c
|
||||
F src/bitvec.c af50f1c8c0ff54d6bdb7a80e2fceca5a93670bef
|
||||
F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
|
||||
F src/btree.c 4fcad108b612a4d33dac568b11d26e4d38ccbe35
|
||||
F src/btree.c 6a9164af8a2ef4612ee30b253635a9bd8e5e1b1b
|
||||
F src/btree.h 11753dd46597a20702bca8746cb4caa4486a82b5
|
||||
F src/btreeInt.h 67978c014fa4f7cc874032dd3aacadd8db656bc3
|
||||
F src/build.c b7c993274ee2a029937b0bc4815bdef80b330017
|
||||
F src/build.c f09c46c66a1e7668c6ee25c9a2518aaa6842044c
|
||||
F src/callback.c 0425c6320730e6d3981acfb9202c1bed9016ad1a
|
||||
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
|
||||
F src/ctime.c 52ff72f966cee3087e0138a3ec69371c22be3c01
|
||||
F src/ctime.c 7deec4534f3b5a0c3b4a4cbadf809d321f64f9c4
|
||||
F src/date.c 1548fdac51377e4e7833251de878b4058c148e1b
|
||||
F src/delete.c ad9fa1cbf91a83ec6990d0aecb7e21cd5ff07e71
|
||||
F src/expr.c e3cf0957c6b8faaaf7386a3bc69e53c0dc9705be
|
||||
@ -147,12 +147,12 @@ F src/global.c 02335177cf6946fe5525c6f0755cf181140debf3
|
||||
F src/hash.c 458488dcc159c301b8e7686280ab209f1fb915af
|
||||
F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970
|
||||
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
|
||||
F src/insert.c ef33ce1522a77f6d8077f0bdb6ab22d306900950
|
||||
F src/insert.c 8796ca3f9209b699cb8120fc44290fc97ac26abe
|
||||
F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e
|
||||
F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f
|
||||
F src/lempar.c 7f026423f4d71d989e719a743f98a1cbd4e6d99e
|
||||
F src/loadext.c 3ae0d52da013a6326310655be6473fd472347b85
|
||||
F src/main.c 37608a8346394e52690368742d734f7b01330aaa
|
||||
F src/main.c 8b97db74cb876bf34ca4fb3720b18e4ffdcf9fd5
|
||||
F src/malloc.c 788f2ed928786dfe305b6783d551d6b1a9080976
|
||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
F src/mem1.c 00bd8265c81abb665c48fea1e0c234eb3b922206
|
||||
@ -180,16 +180,16 @@ F src/pcache.c 09d38c44ab275db581f7a2f6ff8b9bc7f8c0faaa
|
||||
F src/pcache.h c683390d50f856d4cd8e24342ae62027d1bb6050
|
||||
F src/pcache1.c d548e31beafa792d1994b663a29a5303569efc4e
|
||||
F src/pragma.c 49c90ab27a4339d4b5bc0b03c08cbcf20ed8d454
|
||||
F src/prepare.c 206e1f06479fb5f756592bded468bd3ece3f41d4
|
||||
F src/prepare.c e64261559a3187698a3e7e6c8b001a4f4f98dab4
|
||||
F src/printf.c 585a36b6a963df832cfb69505afa3a34ed5ef8a1
|
||||
F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
|
||||
F src/resolve.c 1c0f32b64f8e3f555fe1f732f9d6f501a7f05706
|
||||
F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697
|
||||
F src/select.c 649a6f10f7eb7b52a5a28847773cb9968a828ae8
|
||||
F src/shell.c a73b30067ec15f116d5d0c28880179898fbe3d0b
|
||||
F src/sqlite.h.in 235300cdca517ce148385d3ab816e7e8cf9e1ff3
|
||||
F src/shell.c 9c8389796764f65d4506bcd614ac8061f4160d5c
|
||||
F src/sqlite.h.in 9cff46ef60540f044c1b665db606aa63ba67048f
|
||||
F src/sqlite3ext.h c90bd5507099f62043832d73f6425d8d5c5da754
|
||||
F src/sqliteInt.h 0873a71099f763cdf24cfabf04a237ad100e20d0
|
||||
F src/sqliteInt.h 9a29e5bb82f3abef6b4af91e18d637050fa3c883
|
||||
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
|
||||
F src/status.c 7ac64842c86cec2fc1a1d0e5c16d3beb8ad332bf
|
||||
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
|
||||
@ -207,7 +207,7 @@ F src/test_async.c 0612a752896fad42d55c3999a5122af10dcf22ad
|
||||
F src/test_autoext.c 30e7bd98ab6d70a62bb9ba572e4c7df347fe645e
|
||||
F src/test_backup.c c129c91127e9b46e335715ae2e75756e25ba27de
|
||||
F src/test_btree.c 47cd771250f09cdc6e12dda5bc71bc0b3abc96e2
|
||||
F src/test_config.c 3050df9faf023fb52937f7e9998004c2415d4122
|
||||
F src/test_config.c 25a4128c2dc9e1dbebafcb7e8c61d45f09f7fbc3
|
||||
F src/test_demovfs.c 31050680fa6925b4f677cfd4fa965b5f19195e50
|
||||
F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc
|
||||
F src/test_func.c cbdec5cededa0761daedde5baf06004a9bf416b5
|
||||
@ -239,7 +239,7 @@ F src/test_vfstrace.c 2265c9895f350c8d3c39b079998fbe7481505cc1
|
||||
F src/test_wholenumber.c 6129adfbe7c7444f2e60cc785927f3aa74e12290
|
||||
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
|
||||
F src/tokenize.c 604607d6813e9551cf5189d899e0a25c12681080
|
||||
F src/trigger.c d5bc8b9ffa2b54569ce635084765c6e41aa9d174
|
||||
F src/trigger.c 144cc18bb701f3286484aae4292a9531f09278c8
|
||||
F src/update.c 3f3f3bb734a0da1dffd0ed33e504642b35ed3605
|
||||
F src/utf.c d83650c3ea08f7407bd9d0839d9885241c209c60
|
||||
F src/util.c cd997077bad039efc0597eb027c929658f93c018
|
||||
@ -256,7 +256,7 @@ F src/vtab.c b0abc931f95af94c9ffdf9f747eb191cda953123
|
||||
F src/wal.c 7334009b396285b658a95a3b6bc6d2b016a1f794
|
||||
F src/wal.h 7a5fbb00114b7f2cd40c7e1003d4c41ce9d26840
|
||||
F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f
|
||||
F src/where.c 71e6808f74b9df913b5cdf242419b0edaf768310
|
||||
F src/where.c 55403ce19c506be6a321c7f129aff693d6103db5
|
||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||
F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87
|
||||
F test/all.test 51756962d522e474338e9b2ebb26e7364d4aa125
|
||||
@ -269,9 +269,9 @@ F test/analyze.test c8cb89e8736336f1f0646c8123e6028a14c7b55e
|
||||
F test/analyze2.test 8f2b1534d43f5547ce9a6b736c021d4192c75be3
|
||||
F test/analyze3.test d61f55d8b472fc6e713160b1e577f7a68e63f38b
|
||||
F test/analyze4.test 757b37875cf9bb528d46f74497bc789c88365045
|
||||
F test/analyze5.test adc89b92fc9fee5ca1cb0bc8512f3206ad0fe5aa
|
||||
F test/analyze5.test 1de8d66b11aae5a1453aa042d62e834a476bac9c
|
||||
F test/analyze6.test c125622a813325bba1b4999040ddc213773c2290
|
||||
F test/analyze7.test 9cbca440bebc5142a875ad23947797ff52f7b37c
|
||||
F test/analyze7.test 5508e7828164ea0b518ed219bed7320a481863d4
|
||||
F test/async.test ad4ba51b77cd118911a3fe1356b0809da9c108c3
|
||||
F test/async2.test bf5e2ca2c96763b4cba3d016249ad7259a5603b6
|
||||
F test/async3.test 93edaa9122f498e56ea98c36c72abc407f4fb11e
|
||||
@ -280,7 +280,7 @@ F test/async5.test f3592d79c84d6e83a5f50d3fd500445f7d97dfdf
|
||||
F test/attach.test 2bb09073d7d5499127db00f50780766dcea913e1
|
||||
F test/attach2.test a295d2d7061adcee5884ef4a93c7c96a82765437
|
||||
F test/attach3.test bd9830bc3a0d22ed1310c9bff6896927937017dc
|
||||
F test/attach4.test d58859e62e0a70f17481eed01bf94995f72fea7f
|
||||
F test/attach4.test 31f9eb0ca7bdbc393cc4657b877903a226a83d4b
|
||||
F test/attachmalloc.test 1d5b821a676f7bf0b00d87cc106b78966789ba57
|
||||
F test/auth.test b047105c32da7db70b842fd24056723125ecc2ff
|
||||
F test/auth2.test 270baddc8b9c273682760cffba6739d907bd2882
|
||||
@ -290,7 +290,7 @@ F test/autoindex1.test 860fc83f4fefb0c68ad062afc3ff43faa1534fc4
|
||||
F test/autovacuum.test bb7c0885e6f8f1d633045de48f2b66082162766d
|
||||
F test/autovacuum_ioerr2.test 598b0663074d3673a9c1bc9a16e80971313bafe6
|
||||
F test/avtrans.test 0252654f4295ddda3b2cce0e894812259e655a85
|
||||
F test/backcompat.test 541314d69ec9db3e03630b7616696ddc5048efb1
|
||||
F test/backcompat.test 0f23ff8d516acdf42f3d866a66d85306de2d02bc
|
||||
F test/backup.test 004d3b78bffd990741ab50133ed4347c25c172b1
|
||||
F test/backup2.test b7c69f937c912e85ac8a5dbd1e1cf290302b2d49
|
||||
F test/backup_ioerr.test 1f012e692f42c0442ae652443258f70e9f20fa38
|
||||
@ -397,6 +397,7 @@ F test/eval.test bc269c365ba877554948441e91ad5373f9f91be3
|
||||
F test/exclusive.test 53e1841b422e554cecf0160f937c473d6d0e3062
|
||||
F test/exclusive2.test 343d55130c12c67b8bf10407acec043a6c26c86b
|
||||
F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7
|
||||
F test/exists.test 81363f6982ea49dfd820a50845466390e60a4a0c
|
||||
F test/expr.test 19e8ac40313e2282a47b586d11c4892040990d3a
|
||||
F test/fallocate.test 43dc34b8c24be6baffadc3b4401ee15710ce83c6
|
||||
F test/filectrl.test 97003734290887566e01dded09dc9e99cb937e9e
|
||||
@ -503,7 +504,7 @@ F test/incrblob3.test aedbb35ea1b6450c33b98f2b6ed98e5020be8dc7
|
||||
F test/incrblob_err.test c577c91d4ed9e8336cdb188b15d6ee2a6fe9604e
|
||||
F test/incrblobfault.test 917c0292224c64a56ef7215fd633a3a82f805be0
|
||||
F test/incrvacuum.test 453d1e490d8f5ad2c9b3a54282a0690d6ae56462
|
||||
F test/incrvacuum2.test 9e22a794899c91b7d8c8e12eaacac8df249faafe
|
||||
F test/incrvacuum2.test ae04573b73ad52179f56e194fff0fbe43b509d23
|
||||
F test/incrvacuum_ioerr.test 57d2f5777ab13fa03b87b262a4ea1bad5cfc0291
|
||||
F test/index.test b5429732b3b983fa810e3ac867d7ca85dae35097
|
||||
F test/index2.test ee83c6b5e3173a3d7137140d945d9a5d4fdfb9d6
|
||||
@ -602,7 +603,6 @@ F test/notify2.test 195a467e021f74197be2c4fb02d6dee644b8d8db
|
||||
F test/notify3.test d60923e186e0900f4812a845fcdfd8eea096e33a
|
||||
F test/notnull.test cc7c78340328e6112a13c3e311a9ab3127114347
|
||||
F test/null.test a8b09b8ed87852742343b33441a9240022108993
|
||||
F test/omitunique.test bbb2ec4345d9125d9ee21cd9488d97a163020d5f
|
||||
F test/openv2.test af02ed0a9cbc0d2a61b8f35171d4d117e588e4ec
|
||||
F test/oserror.test 498d8337e9d15543eb7b004fef8594bf204ff43c
|
||||
F test/pager1.test d8672fd0af5f4f9b99b06283d00f01547809bebe
|
||||
@ -702,9 +702,9 @@ F test/thread002.test afd20095e6e845b405df4f2c920cb93301ca69db
|
||||
F test/thread003.test b824d4f52b870ae39fc5bae4d8070eca73085dca
|
||||
F test/thread004.test f51dfc3936184aaf73ee85f315224baad272a87f
|
||||
F test/thread005.test bf5c374ca65dd89fd56c8fe511ccfb46875bda5e
|
||||
F test/thread1.test 862dd006d189e8b0946935db17399dcac2f8ef91
|
||||
F test/thread2.test e08034b83fe9693ade77049732518e5b3d2d700d
|
||||
F test/thread_common.tcl 2aa6f2fdcd4d6e461169c3e5ca098eebf643b863
|
||||
F test/thread1.test df115faa10a4ba1d456e9d4d9ec165016903eae4
|
||||
F test/thread2.test f35d2106452b77523b3a2b7d1dcde2e5ee8f9e46
|
||||
F test/thread_common.tcl 334639cadcb9f912bf82aa73f49efd5282e6cadd
|
||||
F test/threadtest1.c 6029d9c5567db28e6dc908a0c63099c3ba6c383b
|
||||
F test/threadtest2.c ace893054fa134af3fc8d6e7cfecddb8e3acefb9
|
||||
F test/threadtest3.c 0ed13e09690f6204d7455fac3b0e8ece490f6eef
|
||||
@ -871,7 +871,7 @@ F test/vtabE.test 7c4693638d7797ce2eda17af74292b97e705cc61
|
||||
F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5
|
||||
F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8
|
||||
F test/vtab_shared.test 0eff9ce4f19facbe0a3e693f6c14b80711a4222d
|
||||
F test/wal.test bac92a13276ce9b65d3d5c9ff3411d24c795826c
|
||||
F test/wal.test 5617ad308bfdb8a8885220d8a261a6096a8d7e57
|
||||
F test/wal2.test e561a8c6fdd1c2cd1876f3e39757934e7b7361f8
|
||||
F test/wal3.test 5c396cc22497244d627306f4c1d360167353f8dd
|
||||
F test/wal4.test 3404b048fa5e10605facaf70384e6d2943412e30
|
||||
@ -937,7 +937,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||
F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c
|
||||
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
||||
P 7b7c8d366c51e89aefc6efc9dcffe3f62c7e1d25
|
||||
R 35a03a7ffb44f2b52e4ebaca11ffd944
|
||||
P 29090b695a95feaba1b74f9894997083a060263a 1c2f0f8477bcf251fe874a2cfae4d7a403cb88ff
|
||||
R a40e5f171b5b8b5d469c7b8e3eba3790
|
||||
U drh
|
||||
Z efe884ab8aaf8c7e1eec316d7a2437f1
|
||||
Z 7e220d1108384435c7d9af48b2056273
|
||||
|
@ -1 +1 @@
|
||||
29090b695a95feaba1b74f9894997083a060263a
|
||||
83705e90a54bad462a5b7fbca70cc129998f871c
|
@ -548,6 +548,10 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){
|
||||
if( pIndex==0 ) break;
|
||||
pIndex->aiRowEst[i] = v;
|
||||
if( *z==' ' ) z++;
|
||||
if( memcmp(z, "unordered", 10)==0 ){
|
||||
pIndex->bUnordered = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -176,7 +176,9 @@ static void attachFunc(
|
||||
case SQLITE_NULL:
|
||||
/* No key specified. Use the key from the main database */
|
||||
sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);
|
||||
rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
|
||||
if( nKey>0 || sqlite3BtreeGetReserve(db->aDb[0].pBt)>0 ){
|
||||
rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
23
src/backup.c
23
src/backup.c
@ -219,6 +219,10 @@ static int backupOnePage(sqlite3_backup *p, Pgno iSrcPg, const u8 *zSrcData){
|
||||
int nDestPgsz = sqlite3BtreeGetPageSize(p->pDest);
|
||||
const int nCopy = MIN(nSrcPgsz, nDestPgsz);
|
||||
const i64 iEnd = (i64)iSrcPg*(i64)nSrcPgsz;
|
||||
#ifdef SQLITE_HAS_CODEC
|
||||
int nSrcReserve = sqlite3BtreeGetReserve(p->pSrc);
|
||||
int nDestReserve = sqlite3BtreeGetReserve(p->pDest);
|
||||
#endif
|
||||
|
||||
int rc = SQLITE_OK;
|
||||
i64 iOff;
|
||||
@ -237,11 +241,22 @@ static int backupOnePage(sqlite3_backup *p, Pgno iSrcPg, const u8 *zSrcData){
|
||||
|
||||
#ifdef SQLITE_HAS_CODEC
|
||||
/* Backup is not possible if the page size of the destination is changing
|
||||
** a a codec is in use.
|
||||
** and a codec is in use.
|
||||
*/
|
||||
if( nSrcPgsz!=nDestPgsz && sqlite3PagerGetCodec(pDestPager)!=0 ){
|
||||
rc = SQLITE_READONLY;
|
||||
}
|
||||
|
||||
/* Backup is not possible if the number of bytes of reserve space differ
|
||||
** between source and destination. If there is a difference, try to
|
||||
** fix the destination to agree with the source. If that is not possible,
|
||||
** then the backup cannot proceed.
|
||||
*/
|
||||
if( nSrcReserve!=nDestReserve ){
|
||||
u32 newPgsz = nSrcPgsz;
|
||||
rc = sqlite3PagerSetPagesize(pDestPager, &newPgsz, nSrcReserve);
|
||||
if( rc==SQLITE_OK && newPgsz!=nSrcPgsz ) rc = SQLITE_READONLY;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* This loop runs once for each destination page spanned by the source
|
||||
@ -607,7 +622,11 @@ void sqlite3BackupUpdate(sqlite3_backup *pBackup, Pgno iPage, const u8 *aData){
|
||||
** has been modified by a transaction on the source pager. Copy
|
||||
** the new data into the backup.
|
||||
*/
|
||||
int rc = backupOnePage(p, iPage, aData);
|
||||
int rc;
|
||||
assert( p->pDestDb );
|
||||
sqlite3_mutex_enter(p->pDestDb->mutex);
|
||||
rc = backupOnePage(p, iPage, aData);
|
||||
sqlite3_mutex_leave(p->pDestDb->mutex);
|
||||
assert( rc!=SQLITE_BUSY && rc!=SQLITE_LOCKED );
|
||||
if( rc!=SQLITE_OK ){
|
||||
p->rc = rc;
|
||||
|
10
src/btree.c
10
src/btree.c
@ -4819,7 +4819,7 @@ static int allocateBtreePage(
|
||||
goto end_allocate_page;
|
||||
}
|
||||
|
||||
k = get4byte(&pTrunk->aData[4]);
|
||||
k = get4byte(&pTrunk->aData[4]); /* # of leaves on this trunk page */
|
||||
if( k==0 && !searchList ){
|
||||
/* The trunk has no leaves and the list is not being searched.
|
||||
** So extract the trunk page itself and use it as the newly
|
||||
@ -4904,10 +4904,6 @@ static int allocateBtreePage(
|
||||
u32 closest;
|
||||
Pgno iPage;
|
||||
unsigned char *aData = pTrunk->aData;
|
||||
rc = sqlite3PagerWrite(pTrunk->pDbPage);
|
||||
if( rc ){
|
||||
goto end_allocate_page;
|
||||
}
|
||||
if( nearby>0 ){
|
||||
u32 i;
|
||||
int dist;
|
||||
@ -4937,11 +4933,12 @@ static int allocateBtreePage(
|
||||
TRACE(("ALLOCATE: %d was leaf %d of %d on trunk %d"
|
||||
": %d more free pages\n",
|
||||
*pPgno, closest+1, k, pTrunk->pgno, n-1));
|
||||
rc = sqlite3PagerWrite(pTrunk->pDbPage);
|
||||
if( rc ) goto end_allocate_page;
|
||||
if( closest<k-1 ){
|
||||
memcpy(&aData[8+closest*4], &aData[4+k*4], 4);
|
||||
}
|
||||
put4byte(&aData[4], k-1);
|
||||
assert( sqlite3PagerIswriteable(pTrunk->pDbPage) );
|
||||
noContent = !btreeGetHasContent(pBt, *pPgno);
|
||||
rc = btreeGetPage(pBt, *pPgno, ppPage, noContent);
|
||||
if( rc==SQLITE_OK ){
|
||||
@ -5010,6 +5007,7 @@ end_allocate_page:
|
||||
}else{
|
||||
*ppPage = 0;
|
||||
}
|
||||
assert( rc!=SQLITE_OK || sqlite3PagerIswriteable((*ppPage)->pDbPage) );
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
24
src/build.c
24
src/build.c
@ -813,6 +813,9 @@ void sqlite3StartTable(
|
||||
if( pTable ){
|
||||
if( !noErr ){
|
||||
sqlite3ErrorMsg(pParse, "table %T already exists", pName);
|
||||
}else{
|
||||
assert( !db->init.busy );
|
||||
sqlite3CodeVerifySchema(pParse, iDb);
|
||||
}
|
||||
goto begin_table_error;
|
||||
}
|
||||
@ -2000,6 +2003,7 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){
|
||||
if( noErr ) db->suppressErr--;
|
||||
|
||||
if( pTab==0 ){
|
||||
if( noErr ) sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase);
|
||||
goto exit_drop_table;
|
||||
}
|
||||
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
|
||||
@ -2518,6 +2522,9 @@ Index *sqlite3CreateIndex(
|
||||
if( sqlite3FindIndex(db, zName, pDb->zName)!=0 ){
|
||||
if( !ifNotExist ){
|
||||
sqlite3ErrorMsg(pParse, "index %s already exists", zName);
|
||||
}else{
|
||||
assert( !db->init.busy );
|
||||
sqlite3CodeVerifySchema(pParse, iDb);
|
||||
}
|
||||
goto exit_create_index;
|
||||
}
|
||||
@ -2911,6 +2918,8 @@ void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists){
|
||||
if( pIndex==0 ){
|
||||
if( !ifExists ){
|
||||
sqlite3ErrorMsg(pParse, "no such index: %S", pName, 0);
|
||||
}else{
|
||||
sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase);
|
||||
}
|
||||
pParse->checkSchema = 1;
|
||||
goto exit_drop_index;
|
||||
@ -3500,6 +3509,21 @@ void sqlite3CodeVerifySchema(Parse *pParse, int iDb){
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** If argument zDb is NULL, then call sqlite3CodeVerifySchema() for each
|
||||
** attached database. Otherwise, invoke it for the database named zDb only.
|
||||
*/
|
||||
void sqlite3CodeVerifyNamedSchema(Parse *pParse, const char *zDb){
|
||||
sqlite3 *db = pParse->db;
|
||||
int i;
|
||||
for(i=0; i<db->nDb; i++){
|
||||
Db *pDb = &db->aDb[i];
|
||||
if( pDb->pBt && (!zDb || 0==sqlite3StrICmp(zDb, pDb->zName)) ){
|
||||
sqlite3CodeVerifySchema(pParse, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Generate VDBE code that prepares for doing an operation that
|
||||
** might change the database.
|
||||
|
@ -302,9 +302,6 @@ static const char * const azCompileOpt[] = {
|
||||
#ifdef SQLITE_OMIT_TRUNCATE_OPTIMIZATION
|
||||
"OMIT_TRUNCATE_OPTIMIZATION",
|
||||
#endif
|
||||
#ifdef SQLITE_OMIT_UNIQUE_ENFORCEMENT
|
||||
"OMIT_UNIQUE_ENFORCEMENT",
|
||||
#endif
|
||||
#ifdef SQLITE_OMIT_UTF16
|
||||
"OMIT_UTF16",
|
||||
#endif
|
||||
|
@ -1322,9 +1322,8 @@ void sqlite3GenerateConstraintChecks(
|
||||
*/
|
||||
for(iCur=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCur++){
|
||||
int regIdx;
|
||||
#ifndef SQLITE_OMIT_UNIQUE_ENFORCEMENT
|
||||
int regR;
|
||||
#endif
|
||||
|
||||
if( aRegIdx[iCur]==0 ) continue; /* Skip unused indices */
|
||||
|
||||
/* Create a key for accessing the index entry */
|
||||
@ -1342,11 +1341,6 @@ void sqlite3GenerateConstraintChecks(
|
||||
sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v, pIdx), P4_TRANSIENT);
|
||||
sqlite3ExprCacheAffinityChange(pParse, regIdx, pIdx->nColumn+1);
|
||||
|
||||
#ifdef SQLITE_OMIT_UNIQUE_ENFORCEMENT
|
||||
sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn+1);
|
||||
continue; /* Treat pIdx as if it is not a UNIQUE index */
|
||||
#else
|
||||
|
||||
/* Find out what action to take in case there is an indexing conflict */
|
||||
onError = pIdx->onError;
|
||||
if( onError==OE_None ){
|
||||
@ -1420,7 +1414,6 @@ void sqlite3GenerateConstraintChecks(
|
||||
}
|
||||
sqlite3VdbeJumpHere(v, j3);
|
||||
sqlite3ReleaseTempReg(pParse, regR);
|
||||
#endif
|
||||
}
|
||||
|
||||
if( pbMayReplace ){
|
||||
|
@ -515,7 +515,7 @@ int sqlite3_db_config(sqlite3 *db, int op, ...){
|
||||
va_start(ap, op);
|
||||
switch( op ){
|
||||
case SQLITE_DBCONFIG_LOOKASIDE: {
|
||||
void *pBuf = va_arg(ap, void*); /* IMP: R-21112-12275 */
|
||||
void *pBuf = va_arg(ap, void*); /* IMP: R-26835-10964 */
|
||||
int sz = va_arg(ap, int); /* IMP: R-47871-25994 */
|
||||
int cnt = va_arg(ap, int); /* IMP: R-04460-53386 */
|
||||
rc = setupLookaside(db, pBuf, sz, cnt);
|
||||
|
@ -34,7 +34,7 @@ static void corruptSchema(
|
||||
"%s - %s", *pData->pzErrMsg, zExtra);
|
||||
}
|
||||
}
|
||||
pData->rc = db->mallocFailed ? SQLITE_NOMEM : SQLITE_CORRUPT;
|
||||
pData->rc = db->mallocFailed ? SQLITE_NOMEM : SQLITE_CORRUPT_BKPT;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2199,7 +2199,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
|
||||
|
||||
/* convert testctrl text option to value. allow any unique prefix
|
||||
** of the option name, or a numerical value. */
|
||||
n = strlen(azArg[1]);
|
||||
n = strlen30(azArg[1]);
|
||||
for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){
|
||||
if( strncmp(azArg[1], aCtrl[i].zCtrlName, n)==0 ){
|
||||
if( testctrl<0 ){
|
||||
|
@ -727,7 +727,7 @@ struct sqlite3_io_methods {
|
||||
** 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 specilized VFSes
|
||||
** opcode as doing so may disrupt the operation of the specialized VFSes
|
||||
** that do require it.
|
||||
*/
|
||||
#define SQLITE_FCNTL_LOCKSTATE 1
|
||||
@ -1309,7 +1309,7 @@ struct sqlite3_mem_methods {
|
||||
** <dt>SQLITE_CONFIG_SCRATCH</dt>
|
||||
** <dd> ^This option specifies a static memory buffer that SQLite can use for
|
||||
** scratch memory. There are three arguments: A pointer an 8-byte
|
||||
** aligned memory buffer from which the scrach allocations will be
|
||||
** aligned memory buffer from which the scratch allocations will be
|
||||
** drawn, the size of each scratch allocation (sz),
|
||||
** and the maximum number of scratch allocations (N). The sz
|
||||
** argument must be a multiple of 16.
|
||||
@ -1461,7 +1461,7 @@ struct sqlite3_mem_methods {
|
||||
** <dd> ^This option takes three additional arguments that determine the
|
||||
** [lookaside memory allocator] configuration for the [database connection].
|
||||
** ^The first argument (the third parameter to [sqlite3_db_config()] is a
|
||||
** pointer to an memory buffer to use for lookaside memory.
|
||||
** pointer to a memory buffer to use for lookaside memory.
|
||||
** ^The first argument after the SQLITE_DBCONFIG_LOOKASIDE verb
|
||||
** may be NULL in which case SQLite will allocate the
|
||||
** lookaside buffer itself using [sqlite3_malloc()]. ^The second argument is the
|
||||
@ -1493,7 +1493,7 @@ struct sqlite3_mem_methods {
|
||||
** <dd> ^This option is used to enable or disable [CREATE TRIGGER | triggers].
|
||||
** There should be two additional arguments.
|
||||
** The first argument is an integer which is 0 to disable triggers,
|
||||
** positive to enable trigers or negative to leave the setting unchanged.
|
||||
** positive to enable triggers or negative to leave the setting unchanged.
|
||||
** The second parameter is a pointer to an integer into which
|
||||
** is written 0 or 1 to indicate whether triggers are disabled or enabled
|
||||
** following this call. The second parameter may be a NULL pointer, in
|
||||
@ -2105,7 +2105,7 @@ void sqlite3_randomness(int N, void *P);
|
||||
/*
|
||||
** CAPI3REF: Compile-Time Authorization Callbacks
|
||||
**
|
||||
** ^This routine registers a authorizer callback with a particular
|
||||
** ^This routine registers an authorizer callback with a particular
|
||||
** [database connection], supplied in the first argument.
|
||||
** ^The authorizer callback is invoked as SQL statements are being compiled
|
||||
** by [sqlite3_prepare()] or its variants [sqlite3_prepare_v2()],
|
||||
@ -2751,7 +2751,7 @@ int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
|
||||
** whether or not it requires a protected sqlite3_value.
|
||||
**
|
||||
** The terms "protected" and "unprotected" refer to whether or not
|
||||
** a mutex is held. A internal mutex is held for a protected
|
||||
** a mutex is held. An internal mutex is held for a protected
|
||||
** sqlite3_value object but no mutex is held for an unprotected
|
||||
** sqlite3_value object. If SQLite is compiled to be single-threaded
|
||||
** (with [SQLITE_THREADSAFE=0] and with [sqlite3_threadsafe()] returning 0)
|
||||
@ -3437,7 +3437,7 @@ int sqlite3_reset(sqlite3_stmt *pStmt);
|
||||
** are used to add SQL functions or aggregates or to redefine the behavior
|
||||
** of existing SQL functions or aggregates. The only differences between
|
||||
** these routines are the text encoding expected for
|
||||
** the the second parameter (the name of the function being created)
|
||||
** the second parameter (the name of the function being created)
|
||||
** and the presence or absence of a destructor callback for
|
||||
** the application data pointer.
|
||||
**
|
||||
@ -3482,7 +3482,7 @@ int sqlite3_reset(sqlite3_stmt *pStmt);
|
||||
** callback only; NULL pointers must be passed as the xStep and xFinal
|
||||
** parameters. ^An aggregate SQL function requires an implementation of xStep
|
||||
** and xFinal and NULL pointer must be passed for xFunc. ^To delete an existing
|
||||
** SQL function or aggregate, pass NULL poiners for all three function
|
||||
** SQL function or aggregate, pass NULL pointers for all three function
|
||||
** callbacks.
|
||||
**
|
||||
** ^(If the ninth parameter to sqlite3_create_function_v2() is not NULL,
|
||||
@ -3916,7 +3916,7 @@ void sqlite3_result_zeroblob(sqlite3_context*, int n);
|
||||
** ^The [SQLITE_UTF16_ALIGNED] value for eTextRep forces strings to begin
|
||||
** on an even byte address.
|
||||
**
|
||||
** ^The fourth argument, pArg, is a application data pointer that is passed
|
||||
** ^The fourth argument, pArg, is an application data pointer that is passed
|
||||
** through as the first argument to the collating function callback.
|
||||
**
|
||||
** ^The fifth argument, xCallback, is a pointer to the collating function.
|
||||
@ -3932,7 +3932,7 @@ void sqlite3_result_zeroblob(sqlite3_context*, int n);
|
||||
** by the eTextRep argument. The collating function must return an
|
||||
** integer that is negative, zero, or positive
|
||||
** if the first string is less than, equal to, or greater than the second,
|
||||
** respectively. A collating function must alway return the same answer
|
||||
** respectively. A collating function must always return the same answer
|
||||
** given the same inputs. If two or more collating functions are registered
|
||||
** to the same collation name (using different eTextRep values) then all
|
||||
** must give an equivalent answer when invoked with equivalent strings.
|
||||
@ -4344,7 +4344,7 @@ int sqlite3_release_memory(int);
|
||||
** <li> Memory accounting is disabled using a combination of the
|
||||
** [sqlite3_config]([SQLITE_CONFIG_MEMSTATUS],...) start-time option and
|
||||
** the [SQLITE_DEFAULT_MEMSTATUS] compile-time option.
|
||||
** <li> An alternative page cache implementation is specifed using
|
||||
** <li> An alternative page cache implementation is specified using
|
||||
** [sqlite3_config]([SQLITE_CONFIG_PCACHE],...).
|
||||
** <li> The page cache allocates from its own memory pool supplied
|
||||
** by [sqlite3_config]([SQLITE_CONFIG_PAGECACHE],...) rather than
|
||||
@ -4565,7 +4565,7 @@ typedef struct sqlite3_module sqlite3_module;
|
||||
** CAPI3REF: Virtual Table Object
|
||||
** KEYWORDS: sqlite3_module {virtual table module}
|
||||
**
|
||||
** This structure, sometimes called a a "virtual table module",
|
||||
** This structure, sometimes called a "virtual table module",
|
||||
** defines the implementation of a [virtual tables].
|
||||
** This structure consists mostly of methods for the module.
|
||||
**
|
||||
@ -4877,7 +4877,7 @@ typedef struct sqlite3_blob sqlite3_blob;
|
||||
** This is true if any column of the row is changed, even a column
|
||||
** other than the one the BLOB handle is open on.)^
|
||||
** ^Calls to [sqlite3_blob_read()] and [sqlite3_blob_write()] for
|
||||
** a expired BLOB handle fail with an return code of [SQLITE_ABORT].
|
||||
** an expired BLOB handle fail with a return code of [SQLITE_ABORT].
|
||||
** ^(Changes written into a BLOB prior to the BLOB expiring are not
|
||||
** rolled back by the expiration of the BLOB. Such changes will eventually
|
||||
** commit if the transaction continues to completion.)^
|
||||
|
@ -1484,6 +1484,7 @@ struct Index {
|
||||
int tnum; /* Page containing root of this index in database file */
|
||||
u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
|
||||
u8 autoIndex; /* True if is automatically created (ex: by UNIQUE) */
|
||||
u8 bUnordered; /* Use this index for == or IN queries only */
|
||||
char *zColAff; /* String defining the affinity of each column */
|
||||
Index *pNext; /* The next index associated with the same table */
|
||||
Schema *pSchema; /* Schema containing this index */
|
||||
@ -2776,6 +2777,7 @@ void sqlite3PrngRestoreState(void);
|
||||
void sqlite3PrngResetState(void);
|
||||
void sqlite3RollbackAll(sqlite3*);
|
||||
void sqlite3CodeVerifySchema(Parse*, int);
|
||||
void sqlite3CodeVerifyNamedSchema(Parse*, const char *zDb);
|
||||
void sqlite3BeginTransaction(Parse*, int);
|
||||
void sqlite3CommitTransaction(Parse*);
|
||||
void sqlite3RollbackTransaction(Parse*);
|
||||
|
@ -97,6 +97,12 @@ static void set_options(Tcl_Interp *interp){
|
||||
Tcl_SetVar2(interp, "sqlite_options", "mutex", "1", TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_MUTEX_NOOP
|
||||
Tcl_SetVar2(interp, "sqlite_options", "mutex_noop", "1", TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
Tcl_SetVar2(interp, "sqlite_options", "mutex_noop", "0", TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_OMIT_ALTERTABLE
|
||||
Tcl_SetVar2(interp, "sqlite_options", "altertable", "0", TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
@ -487,12 +493,6 @@ Tcl_SetVar2(interp, "sqlite_options", "long_double",
|
||||
Tcl_SetVar2(interp, "sqlite_options", "truncate_opt", "1", TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_OMIT_UNIQUE_ENFORCEMENT
|
||||
Tcl_SetVar2(interp, "sqlite_options", "unique_enforcement", "0", TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
Tcl_SetVar2(interp, "sqlite_options", "unique_enforcement", "1", TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_OMIT_UTF16
|
||||
Tcl_SetVar2(interp, "sqlite_options", "utf16", "0", TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
|
@ -171,6 +171,9 @@ void sqlite3BeginTrigger(
|
||||
zName, sqlite3Strlen30(zName)) ){
|
||||
if( !noErr ){
|
||||
sqlite3ErrorMsg(pParse, "trigger %T already exists", pName);
|
||||
}else{
|
||||
assert( !db->init.busy );
|
||||
sqlite3CodeVerifySchema(pParse, iDb);
|
||||
}
|
||||
goto trigger_cleanup;
|
||||
}
|
||||
@ -499,6 +502,8 @@ void sqlite3DropTrigger(Parse *pParse, SrcList *pName, int noErr){
|
||||
if( !pTrigger ){
|
||||
if( !noErr ){
|
||||
sqlite3ErrorMsg(pParse, "no such trigger: %S", pName, 0);
|
||||
}else{
|
||||
sqlite3CodeVerifyNamedSchema(pParse, zDb);
|
||||
}
|
||||
pParse->checkSchema = 1;
|
||||
goto drop_trigger_cleanup;
|
||||
|
12
src/where.c
12
src/where.c
@ -1342,7 +1342,10 @@ static void exprAnalyze(
|
||||
** of the loop. Without the TERM_VNULL flag, the not-null check at
|
||||
** the start of the loop will prevent any results from being returned.
|
||||
*/
|
||||
if( pExpr->op==TK_NOTNULL && pExpr->pLeft->iColumn>=0 ){
|
||||
if( pExpr->op==TK_NOTNULL
|
||||
&& pExpr->pLeft->op==TK_COLUMN
|
||||
&& pExpr->pLeft->iColumn>=0
|
||||
){
|
||||
Expr *pNewExpr;
|
||||
Expr *pLeft = pExpr->pLeft;
|
||||
int idxNew;
|
||||
@ -2532,7 +2535,7 @@ range_est_fallback:
|
||||
** for a UTF conversion required for comparison. The error is stored
|
||||
** in the pParse structure.
|
||||
*/
|
||||
int whereEqualScanEst(
|
||||
static int whereEqualScanEst(
|
||||
Parse *pParse, /* Parsing & code generating context */
|
||||
Index *p, /* The index whose left-most column is pTerm */
|
||||
Expr *pExpr, /* Expression for VALUE in the x=VALUE constraint */
|
||||
@ -2589,7 +2592,7 @@ whereEqualScanEst_cancel:
|
||||
** for a UTF conversion required for comparison. The error is stored
|
||||
** in the pParse structure.
|
||||
*/
|
||||
int whereInScanEst(
|
||||
static int whereInScanEst(
|
||||
Parse *pParse, /* Parsing & code generating context */
|
||||
Index *p, /* The index whose left-most column is pTerm */
|
||||
ExprList *pList, /* The value list on the RHS of "x IN (v1,v2,v3,...)" */
|
||||
@ -2860,7 +2863,7 @@ static void bestBtreeIndex(
|
||||
}
|
||||
|
||||
/* Determine the value of estBound. */
|
||||
if( nEq<pProbe->nColumn ){
|
||||
if( nEq<pProbe->nColumn && pProbe->bUnordered==0 ){
|
||||
int j = pProbe->aiColumn[nEq];
|
||||
if( findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE|WO_GT|WO_GE, pIdx) ){
|
||||
WhereTerm *pTop = findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE, pIdx);
|
||||
@ -2892,6 +2895,7 @@ static void bestBtreeIndex(
|
||||
** will scan rows in a different order, set the bSort variable. */
|
||||
if( pOrderBy ){
|
||||
if( (wsFlags & WHERE_COLUMN_IN)==0
|
||||
&& pProbe->bUnordered==0
|
||||
&& isSortingIndex(pParse, pWC->pMaskSet, pProbe, iCur, pOrderBy,
|
||||
nEq, wsFlags, &rev)
|
||||
){
|
||||
|
@ -209,6 +209,8 @@ foreach {testid where index rows} {
|
||||
502 {x IS NULL} {} 100
|
||||
503 {x=1} t1x 50
|
||||
504 {x IS NOT NULL} t1x 25
|
||||
505 {+x IS NOT NULL} {} 500
|
||||
506 {upper(x) IS NOT NULL} {} 500
|
||||
|
||||
} {
|
||||
# Verify that the expected index is used with the expected row count
|
||||
|
@ -87,7 +87,7 @@ ifcapable stat2 {
|
||||
# row count for (c=2) than it does for (c=?).
|
||||
do_test analyze7-3.2.2 {
|
||||
execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=2;}
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1cd (c=?) (~102 rows)}}
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1cd (c=?) (~51 rows)}}
|
||||
} else {
|
||||
# If ENABLE_STAT2 is not defined, the expected row count for (c=2) is the
|
||||
# same as that for (c=?).
|
||||
|
@ -74,7 +74,11 @@ do_test 1.4 {
|
||||
set L [list]
|
||||
set S ""
|
||||
foreach {name f} $files {
|
||||
lappend L wal
|
||||
if {[permutation] == "journaltest"} {
|
||||
lappend L delete
|
||||
} else {
|
||||
lappend L wal
|
||||
}
|
||||
append S "
|
||||
PRAGMA $name.journal_mode = WAL;
|
||||
UPDATE $name.tbl SET x = '$name';
|
||||
|
@ -369,4 +369,77 @@ do_allbackcompat_test {
|
||||
}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Test that Rtree tables may be read/written by different versions of
|
||||
# SQLite.
|
||||
#
|
||||
set contents {
|
||||
CREATE VIRTUAL TABLE t1 USING rtree(id, x1, x2, y1, y2);
|
||||
}
|
||||
foreach {id x1 x2 y1 y2} {
|
||||
1 -47.64 43.87 33.86 34.42 2 -21.51 17.32 2.05 31.04
|
||||
3 -43.67 -38.33 -19.79 3.43 4 32.41 35.16 9.12 19.82
|
||||
5 33.28 34.87 14.78 28.26 6 49.31 116.59 -9.87 75.09
|
||||
7 -14.93 34.51 -17.64 64.09 8 -43.05 23.43 -1.19 69.44
|
||||
9 44.79 133.56 28.09 80.30 10 -2.66 81.47 -41.38 -10.46
|
||||
11 -42.89 -3.54 15.76 71.63 12 -3.50 84.96 -11.64 64.95
|
||||
13 -45.69 26.25 11.14 55.06 14 -44.09 11.23 17.52 44.45
|
||||
15 36.23 133.49 -19.38 53.67 16 -17.89 81.54 14.64 50.61
|
||||
17 -41.97 -24.04 -39.43 28.95 18 -5.85 7.76 -6.38 47.02
|
||||
19 18.82 27.10 42.82 100.09 20 39.17 113.45 26.14 73.47
|
||||
21 22.31 103.17 49.92 106.05 22 -43.06 40.38 -1.75 76.08
|
||||
23 2.43 57.27 -14.19 -3.83 24 -47.57 -4.35 8.93 100.06
|
||||
25 -37.47 49.14 -29.11 8.81 26 -7.86 75.72 49.34 107.42
|
||||
27 1.53 45.49 20.36 49.74 28 -48.48 32.54 28.81 54.45
|
||||
29 2.67 39.77 -4.05 13.67 30 4.11 62.88 -47.44 -5.72
|
||||
31 -21.47 51.75 37.25 116.09 32 45.59 111.37 -6.43 43.64
|
||||
33 35.23 48.29 23.54 113.33 34 16.61 68.35 -14.69 65.97
|
||||
35 13.98 16.60 48.66 102.87 36 19.74 23.84 31.15 77.27
|
||||
37 -27.61 24.43 7.96 94.91 38 -34.77 12.05 -22.60 -6.29
|
||||
39 -25.83 8.71 -13.48 -12.53 40 -17.11 -1.01 18.06 67.89
|
||||
41 14.13 71.72 -3.78 39.25 42 23.75 76.00 -16.30 8.23
|
||||
43 -39.15 28.63 38.12 125.88 44 48.62 86.09 36.49 102.95
|
||||
45 -31.39 -21.98 2.52 89.78 46 5.65 56.04 15.94 89.10
|
||||
47 18.28 95.81 46.46 143.08 48 30.93 102.82 -20.08 37.36
|
||||
49 -20.78 -3.48 -5.58 35.46 50 49.85 90.58 -24.48 46.29
|
||||
} {
|
||||
if {$x1 >= $x2 || $y1 >= $y2} { error "$x1 $x2 $y1 $y2" }
|
||||
append contents "INSERT INTO t1 VALUES($id, $x1, $x2, $y1, $y2);"
|
||||
}
|
||||
set queries {
|
||||
1 "SELECT id FROM t1 WHERE x1>10 AND x2<44"
|
||||
2 "SELECT id FROM t1 WHERE y1<100"
|
||||
3 "SELECT id FROM t1 WHERE y1<100 AND x1>0"
|
||||
4 "SELECT id FROM t1 WHERE y1>10 AND x1>0 AND x2<50 AND y2<550"
|
||||
}
|
||||
do_allbackcompat_test {
|
||||
if {[code1 {set ::sqlite_options(fts3)}]
|
||||
&& [code2 {set ::sqlite_options(fts3)}]
|
||||
} {
|
||||
|
||||
do_test backcompat-4.1 { sql1 $contents } {}
|
||||
|
||||
foreach {n q} $::queries {
|
||||
do_test backcompat-4.2.$n [list sql1 $q] [sql2 $q]
|
||||
}
|
||||
|
||||
do_test backcompat-4.3 { sql1 {
|
||||
INSERT INTO t1 SELECT id+100, x1+10.0, x2+10.0, y1-10.0, y2-10.0 FROM t1;
|
||||
} } {}
|
||||
|
||||
foreach {n q} $::queries {
|
||||
do_test backcompat-4.4.$n [list sql1 $q] [sql2 $q]
|
||||
}
|
||||
|
||||
do_test backcompat-4.5 { sql2 {
|
||||
INSERT INTO t1 SELECT id+200, x1+20.0, x2+20.0, y1-20.0, y2-20.0 FROM t1;
|
||||
} } {}
|
||||
|
||||
foreach {n q} $::queries {
|
||||
do_test backcompat-4.6.$n [list sql1 $q] [sql2 $q]
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
192
test/exists.test
Normal file
192
test/exists.test
Normal file
@ -0,0 +1,192 @@
|
||||
# 2011 April 9
|
||||
#
|
||||
# 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 various schema modification statements
|
||||
# that feature "IF EXISTS" or "IF NOT EXISTS" clauses.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
source $testdir/lock_common.tcl
|
||||
|
||||
set testprefix exists
|
||||
|
||||
# This block of tests is targeted at CREATE XXX IF NOT EXISTS statements.
|
||||
#
|
||||
do_multiclient_test tn {
|
||||
|
||||
# TABLE objects.
|
||||
#
|
||||
do_test 1.$tn.1.1 {
|
||||
sql2 { CREATE TABLE t1(x) }
|
||||
sql1 { CREATE TABLE IF NOT EXISTS t1(a, b) }
|
||||
sql2 { DROP TABLE t1 }
|
||||
sql1 { CREATE TABLE IF NOT EXISTS t1(a, b) }
|
||||
sql2 { SELECT name FROM sqlite_master WHERE type = 'table' }
|
||||
} {t1}
|
||||
|
||||
do_test 1.$tn.1.2 {
|
||||
sql2 { CREATE TABLE t2(x) }
|
||||
sql1 { CREATE TABLE IF NOT EXISTS t2 AS SELECT * FROM t1 }
|
||||
sql2 { DROP TABLE t2 }
|
||||
sql1 { CREATE TABLE IF NOT EXISTS t2 AS SELECT * FROM t1 }
|
||||
sql2 { SELECT name FROM sqlite_master WHERE type = 'table' }
|
||||
} {t1 t2}
|
||||
|
||||
|
||||
# INDEX objects.
|
||||
#
|
||||
do_test 1.$tn.2 {
|
||||
sql2 { CREATE INDEX i1 ON t1(a) }
|
||||
sql1 { CREATE INDEX IF NOT EXISTS i1 ON t1(a, b) }
|
||||
sql2 { DROP INDEX i1 }
|
||||
sql1 { CREATE INDEX IF NOT EXISTS i1 ON t1(a, b) }
|
||||
sql2 { SELECT name FROM sqlite_master WHERE type = 'index' }
|
||||
} {i1}
|
||||
|
||||
# VIEW objects.
|
||||
#
|
||||
do_test 1.$tn.3 {
|
||||
sql2 { CREATE VIEW v1 AS SELECT * FROM t1 }
|
||||
sql1 { CREATE VIEW IF NOT EXISTS v1 AS SELECT * FROM t1 }
|
||||
sql2 { DROP VIEW v1 }
|
||||
sql1 { CREATE VIEW IF NOT EXISTS v1 AS SELECT * FROM t1 }
|
||||
sql2 { SELECT name FROM sqlite_master WHERE type = 'view' }
|
||||
} {v1}
|
||||
|
||||
# TRIGGER objects.
|
||||
#
|
||||
do_test $tn.4 {
|
||||
sql2 { CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN SELECT 1; END }
|
||||
sql1 { CREATE TRIGGER IF NOT EXISTS tr1 AFTER INSERT ON t1 BEGIN SELECT 1; END }
|
||||
sql2 { DROP TRIGGER tr1 }
|
||||
sql1 { CREATE TRIGGER IF NOT EXISTS tr1 AFTER INSERT ON t1 BEGIN SELECT 1; END }
|
||||
sql2 { SELECT name FROM sqlite_master WHERE type = 'trigger' }
|
||||
} {tr1}
|
||||
}
|
||||
|
||||
# This block of tests is targeted at DROP XXX IF EXISTS statements.
|
||||
#
|
||||
do_multiclient_test tn {
|
||||
|
||||
# TABLE objects.
|
||||
#
|
||||
do_test 2.$tn.1 {
|
||||
sql1 { DROP TABLE IF EXISTS t1 }
|
||||
sql2 { CREATE TABLE t1(x) }
|
||||
sql1 { DROP TABLE IF EXISTS t1 }
|
||||
sql2 { SELECT name FROM sqlite_master WHERE type = 'table' }
|
||||
} {}
|
||||
|
||||
# INDEX objects.
|
||||
#
|
||||
do_test 2.$tn.2 {
|
||||
sql1 { CREATE TABLE t2(x) }
|
||||
sql1 { DROP INDEX IF EXISTS i2 }
|
||||
sql2 { CREATE INDEX i2 ON t2(x) }
|
||||
sql1 { DROP INDEX IF EXISTS i2 }
|
||||
sql2 { SELECT name FROM sqlite_master WHERE type = 'index' }
|
||||
} {}
|
||||
|
||||
# VIEW objects.
|
||||
#
|
||||
do_test 2.$tn.3 {
|
||||
sql1 { DROP VIEW IF EXISTS v1 }
|
||||
sql2 { CREATE VIEW v1 AS SELECT * FROM t2 }
|
||||
sql1 { DROP VIEW IF EXISTS v1 }
|
||||
sql2 { SELECT name FROM sqlite_master WHERE type = 'view' }
|
||||
} {}
|
||||
|
||||
# TRIGGER objects.
|
||||
#
|
||||
do_test 2.$tn.4 {
|
||||
sql1 { DROP TRIGGER IF EXISTS tr1 }
|
||||
sql2 { CREATE TRIGGER tr1 AFTER INSERT ON t2 BEGIN SELECT 1; END }
|
||||
sql1 { DROP TRIGGER IF EXISTS tr1 }
|
||||
sql2 { SELECT name FROM sqlite_master WHERE type = 'trigger' }
|
||||
} {}
|
||||
}
|
||||
|
||||
# This block of tests is targeted at DROP XXX IF EXISTS statements with
|
||||
# attached databases.
|
||||
#
|
||||
do_multiclient_test tn {
|
||||
|
||||
forcedelete test.db2
|
||||
do_test 3.$tn.0 {
|
||||
sql1 { ATTACH 'test.db2' AS aux }
|
||||
sql2 { ATTACH 'test.db2' AS aux }
|
||||
} {}
|
||||
|
||||
# TABLE objects.
|
||||
#
|
||||
do_test 3.$tn.1.1 {
|
||||
sql1 { DROP TABLE IF EXISTS aux.t1 }
|
||||
sql2 { CREATE TABLE aux.t1(x) }
|
||||
sql1 { DROP TABLE IF EXISTS aux.t1 }
|
||||
sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'table' }
|
||||
} {}
|
||||
do_test 3.$tn.1.2 {
|
||||
sql1 { DROP TABLE IF EXISTS t1 }
|
||||
sql2 { CREATE TABLE aux.t1(x) }
|
||||
sql1 { DROP TABLE IF EXISTS t1 }
|
||||
sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'table' }
|
||||
} {}
|
||||
|
||||
# INDEX objects.
|
||||
#
|
||||
do_test 3.$tn.2.1 {
|
||||
sql1 { CREATE TABLE aux.t2(x) }
|
||||
sql1 { DROP INDEX IF EXISTS aux.i2 }
|
||||
sql2 { CREATE INDEX aux.i2 ON t2(x) }
|
||||
sql1 { DROP INDEX IF EXISTS aux.i2 }
|
||||
sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'index' }
|
||||
} {}
|
||||
do_test 3.$tn.2.2 {
|
||||
sql1 { DROP INDEX IF EXISTS i2 }
|
||||
sql2 { CREATE INDEX aux.i2 ON t2(x) }
|
||||
sql1 { DROP INDEX IF EXISTS i2 }
|
||||
sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'index' }
|
||||
} {}
|
||||
|
||||
# VIEW objects.
|
||||
#
|
||||
do_test 3.$tn.3.1 {
|
||||
sql1 { DROP VIEW IF EXISTS aux.v1 }
|
||||
sql2 { CREATE VIEW aux.v1 AS SELECT * FROM t2 }
|
||||
sql1 { DROP VIEW IF EXISTS aux.v1 }
|
||||
sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'view' }
|
||||
} {}
|
||||
do_test 3.$tn.3.2 {
|
||||
sql1 { DROP VIEW IF EXISTS v1 }
|
||||
sql2 { CREATE VIEW aux.v1 AS SELECT * FROM t2 }
|
||||
sql1 { DROP VIEW IF EXISTS v1 }
|
||||
sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'view' }
|
||||
} {}
|
||||
|
||||
# TRIGGER objects.
|
||||
#
|
||||
do_test 3.$tn.4.1 {
|
||||
sql1 { DROP TRIGGER IF EXISTS aux.tr1 }
|
||||
sql2 { CREATE TRIGGER aux.tr1 AFTER INSERT ON t2 BEGIN SELECT 1; END }
|
||||
sql1 { DROP TRIGGER IF EXISTS aux.tr1 }
|
||||
sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'trigger' }
|
||||
} {}
|
||||
do_test 3.$tn.4.2 {
|
||||
sql1 { DROP TRIGGER IF EXISTS tr1 }
|
||||
sql2 { CREATE TRIGGER aux.tr1 AFTER INSERT ON t2 BEGIN SELECT 1; END }
|
||||
sql1 { DROP TRIGGER IF EXISTS tr1 }
|
||||
sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'trigger' }
|
||||
} {}
|
||||
}
|
||||
|
||||
|
||||
finish_test
|
@ -23,6 +23,7 @@ ifcapable {!autovacuum || !pragma} {
|
||||
return
|
||||
}
|
||||
|
||||
set testprefix incrvacuum2
|
||||
|
||||
# Create a database in incremental vacuum mode that has many
|
||||
# pages on the freelist.
|
||||
@ -131,6 +132,80 @@ do_test incrvacuum2-3.2 {
|
||||
}
|
||||
} {}
|
||||
|
||||
integrity_check incremental2-3.3
|
||||
integrity_check incrvacuum2-3.3
|
||||
|
||||
ifcapable wal {
|
||||
# At one point, when a specific page was being extracted from the b-tree
|
||||
# free-list (e.g. during an incremental-vacuum), all trunk pages that
|
||||
# occurred before the specific page in the free-list trunk were being
|
||||
# written to the journal or wal file. This is not necessary. Only the
|
||||
# extracted page and the page that contains the pointer to it need to
|
||||
# be journalled.
|
||||
#
|
||||
# This problem was fixed by [d03d63d77e] (just before 3.7.6 release).
|
||||
#
|
||||
# This test case builds a database containing many free pages. Then runs
|
||||
# "PRAGMA incremental_vacuum(1)" until the db contains zero free pages.
|
||||
# Each "PRAGMA incremental_vacuum(1)" should modify at most 4 pages. The
|
||||
# worst case is when a trunk page is removed from the end of the db file.
|
||||
# In this case pages written are:
|
||||
#
|
||||
# 1. The previous trunk page (that contains a pointer to the recycled
|
||||
# trunk page), and
|
||||
# 2. The leaf page transformed into a trunk page to replace the recycled
|
||||
# page, and
|
||||
# 3. The trunk page that contained a pointer to the leaf page used
|
||||
# in (2), and
|
||||
# 4. Page 1. Page 1 is always updated, even in WAL mode, since it contains
|
||||
# the "number of free-list pages" field.
|
||||
#
|
||||
db close
|
||||
forcedelete test.db
|
||||
sqlite3 db test.db
|
||||
|
||||
do_execsql_test 4.1 {
|
||||
PRAGMA page_size = 512;
|
||||
PRAGMA auto_vacuum = 2;
|
||||
CREATE TABLE t1(x);
|
||||
INSERT INTO t1 VALUES(randomblob(400));
|
||||
INSERT INTO t1 SELECT * FROM t1; -- 2
|
||||
INSERT INTO t1 SELECT * FROM t1; -- 4
|
||||
INSERT INTO t1 SELECT * FROM t1; -- 8
|
||||
INSERT INTO t1 SELECT * FROM t1; -- 16
|
||||
INSERT INTO t1 SELECT * FROM t1; -- 32
|
||||
INSERT INTO t1 SELECT * FROM t1; -- 128
|
||||
INSERT INTO t1 SELECT * FROM t1; -- 256
|
||||
INSERT INTO t1 SELECT * FROM t1; -- 512
|
||||
INSERT INTO t1 SELECT * FROM t1; -- 1024
|
||||
INSERT INTO t1 SELECT * FROM t1; -- 2048
|
||||
INSERT INTO t1 SELECT * FROM t1; -- 4096
|
||||
INSERT INTO t1 SELECT * FROM t1; -- 8192
|
||||
DELETE FROM t1 WHERE oid>512;
|
||||
DELETE FROM t1;
|
||||
}
|
||||
|
||||
do_test 4.2 {
|
||||
execsql {
|
||||
PRAGMA journal_mode = WAL;
|
||||
PRAGMA incremental_vacuum(1);
|
||||
PRAGMA wal_checkpoint;
|
||||
}
|
||||
file size test.db-wal
|
||||
} {1640}
|
||||
|
||||
do_test 4.3 {
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
set maxsz 0
|
||||
while {[file size test.db] > [expr 512*3]} {
|
||||
execsql { PRAGMA journal_mode = WAL }
|
||||
execsql { PRAGMA wal_checkpoint }
|
||||
execsql { PRAGMA incremental_vacuum(1) }
|
||||
set newsz [file size test.db-wal]
|
||||
if {$newsz>$maxsz} {set maxsz $newsz}
|
||||
}
|
||||
set maxsz
|
||||
} {2176}
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
@ -1,170 +0,0 @@
|
||||
# 2011 March 10
|
||||
#
|
||||
# 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 SQLITE_OMIT_UNIQUE_ENFORCEMENT
|
||||
# compiler option.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
set uniq_enforced 1
|
||||
ifcapable !unique_enforcement {
|
||||
set uniq_enforced 0
|
||||
}
|
||||
|
||||
# table with UNIQUE keyword on column
|
||||
do_test omitunique-1.1 {
|
||||
catchsql { CREATE TABLE t1(a TEXT UNIQUE); }
|
||||
} {0 {}}
|
||||
|
||||
# table with UNIQUE clause on column
|
||||
do_test omitunique-1.2 {
|
||||
catchsql { CREATE TABLE t2(a TEXT, UNIQUE(a)); }
|
||||
} {0 {}}
|
||||
|
||||
# table with UNIQUE index on column
|
||||
do_test omitunique-1.3 {
|
||||
catchsql {
|
||||
CREATE TABLE t3(a TEXT);
|
||||
CREATE UNIQUE INDEX t3a ON t3(a);
|
||||
}
|
||||
} {0 {}}
|
||||
|
||||
# table with regular index on column
|
||||
do_test omitunique-1.4 {
|
||||
catchsql {
|
||||
CREATE TABLE t4(a TEXT);
|
||||
CREATE INDEX t4a ON t4(a);
|
||||
}
|
||||
} {0 {}}
|
||||
|
||||
# table with no index on column
|
||||
do_test omitunique-1.5 {
|
||||
catchsql { CREATE TABLE t5(a TEXT); }
|
||||
} {0 {}}
|
||||
|
||||
# run our tests using several table/index forms
|
||||
foreach {j tbl uniq cnt qp_est stat_enforce stat_omit } {
|
||||
1 {t1} 1 1 1 {2 1} {9 9}
|
||||
2 {t2} 1 1 1 {2 1} {9 9}
|
||||
3 {t3} 1 1 1 {2 1} {9 9}
|
||||
4 {t4} 0 9 10 {9 9} {9 9}
|
||||
5 {t5} 0 9 100000 9 9
|
||||
} {
|
||||
|
||||
do_test omitunique-2.0.$j.1 {
|
||||
catchsql [ subst {INSERT INTO $tbl (a) VALUES('abc'); }]
|
||||
} {0 {}}
|
||||
do_test omitunique-2.0.$j.2 {
|
||||
catchsql [ subst {INSERT INTO $tbl (a) VALUES('123'); }]
|
||||
} {0 {}}
|
||||
|
||||
# check various INSERT commands
|
||||
foreach {i cmd err} {
|
||||
1 {INSERT} 1
|
||||
2 {INSERT OR IGNORE} 0
|
||||
3 {INSERT OR REPLACE} 0
|
||||
4 {REPLACE} 0
|
||||
5 {INSERT OR FAIL} 1
|
||||
6 {INSERT OR ABORT} 1
|
||||
7 {INSERT OR ROLLBACK} 1
|
||||
} {
|
||||
|
||||
ifcapable explain {
|
||||
set x [execsql [ subst { EXPLAIN $cmd INTO $tbl (a) VALUES('abc'); }]]
|
||||
ifcapable unique_enforcement {
|
||||
do_test omitunique-2.1.$j.$i.1 {
|
||||
regexp { IsUnique } $x
|
||||
} $uniq
|
||||
}
|
||||
ifcapable !unique_enforcement {
|
||||
do_test omitunique-2.1.$j.$i.1 {
|
||||
regexp { IsUnique } $x
|
||||
} {0}
|
||||
}
|
||||
}
|
||||
|
||||
if { $uniq_enforced==0 || $uniq==0 || $err==0 } {
|
||||
set msg {0 {}}
|
||||
} {
|
||||
set msg {1 {column a is not unique}}
|
||||
}
|
||||
do_test omitunique-2.1.$j.$i.3 {
|
||||
catchsql [ subst {$cmd INTO $tbl (a) VALUES('abc'); }]
|
||||
} $msg
|
||||
|
||||
}
|
||||
# end foreach cmd
|
||||
|
||||
# check UPDATE command
|
||||
ifcapable explain {
|
||||
set x [execsql [ subst { EXPLAIN UPDATE $tbl SET a='abc'; }]]
|
||||
ifcapable unique_enforcement {
|
||||
do_test omitunique-2.2.$j.1 {
|
||||
regexp { IsUnique } $x
|
||||
} $uniq
|
||||
}
|
||||
ifcapable !unique_enforcement {
|
||||
do_test omitunique-2.2.$j.1 {
|
||||
regexp { IsUnique } $x
|
||||
} {0}
|
||||
}
|
||||
}
|
||||
if { $uniq_enforced==0 || $uniq==0 } {
|
||||
set msg {0 {}}
|
||||
} {
|
||||
set msg {1 {column a is not unique}}
|
||||
}
|
||||
do_test omitunique-2.2.$j.3 {
|
||||
catchsql [ subst { UPDATE $tbl SET a='abc'; }]
|
||||
} $msg
|
||||
|
||||
# check record counts
|
||||
do_test omitunique-2.3.$j {
|
||||
execsql [ subst { SELECT count(*) FROM $tbl WHERE a='abc'; }]
|
||||
} $cnt
|
||||
|
||||
# make sure the query planner row estimate not affected because of omit enforcement
|
||||
ifcapable explain {
|
||||
do_test omitunique-2.4.$j {
|
||||
set x [ execsql [ subst { EXPLAIN QUERY PLAN SELECT count(*) FROM $tbl WHERE a='abc'; }]]
|
||||
set y [ subst {~$qp_est row} ]
|
||||
regexp $y $x
|
||||
} {1}
|
||||
}
|
||||
|
||||
# make sure we omit extra OP_Next opcodes when the UNIQUE constraints
|
||||
# mean there will only be a single pass through the code
|
||||
ifcapable explain {
|
||||
set x [execsql [ subst { EXPLAIN SELECT * FROM $tbl WHERE a='abc'; }]]
|
||||
do_test omitunique-2.5.$j {
|
||||
if { [ regexp { Next } $x ] } { expr { 0 } } { expr { 1 } }
|
||||
} $uniq
|
||||
}
|
||||
|
||||
# make sure analyze index stats correct
|
||||
ifcapable analyze {
|
||||
if { $uniq_enforced==0 } {
|
||||
set msg [ list $stat_omit ]
|
||||
} {
|
||||
set msg [ list $stat_enforce ]
|
||||
}
|
||||
do_test omitunique-2.6.$j {
|
||||
execsql [ subst { ANALYZE $tbl; } ]
|
||||
execsql [ subst { SELECT stat FROM sqlite_stat1 WHERE tbl='$tbl'; } ]
|
||||
} $msg
|
||||
}
|
||||
|
||||
}
|
||||
# end foreach tbl
|
||||
|
||||
finish_test
|
@ -19,10 +19,7 @@ source $testdir/tester.tcl
|
||||
|
||||
# Skip this whole file if the thread testing code is not enabled
|
||||
#
|
||||
ifcapable !mutex {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
if {[run_thread_tests]==0} { finish_test ; return }
|
||||
if {[llength [info command thread_step]]==0 || [sqlite3 -has-codec]} {
|
||||
finish_test
|
||||
return
|
||||
|
@ -17,11 +17,7 @@
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
ifcapable !mutex {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
if {[run_thread_tests]==0} { finish_test ; return }
|
||||
|
||||
# Skip this whole file if the thread testing code is not enabled
|
||||
#
|
||||
|
@ -89,6 +89,9 @@ proc run_thread_tests {{print_warning 0}} {
|
||||
ifcapable !mutex {
|
||||
set zProblem "SQLite build is not threadsafe"
|
||||
}
|
||||
ifcapable mutex_noop {
|
||||
set zProblem "SQLite build uses SQLITE_MUTEX_NOOP"
|
||||
}
|
||||
if {[info commands sqlthread] eq ""} {
|
||||
set zProblem "SQLite build is not threadsafe"
|
||||
}
|
||||
|
@ -1544,6 +1544,7 @@ ifcapable autovacuum {
|
||||
} [expr 84 * 1024]
|
||||
do_test 24.4 {
|
||||
execsql {
|
||||
PRAGMA cache_size = 200;
|
||||
PRAGMA incremental_vacuum;
|
||||
PRAGMA wal_checkpoint;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user