]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Merge in all of the logging enhancements. This is a cherrypick merge of
authordrh <drh@noemail.net>
Thu, 25 Feb 2010 02:32:28 +0000 (02:32 +0000)
committerdrh <drh@noemail.net>
Thu, 25 Feb 2010 02:32:28 +0000 (02:32 +0000)
the following check-ins: [103321e37a], [a8076aede3], [6d910245ad],
[7c4cca6d1a], [edea3bb740], [1a6d4bb130], [a8c984c1d6], [69a493182f], and
[1168763d2c].

FossilOrigin-Name: 46f406b2022b534f396491c04adad8a2012b8fcb

35 files changed:
manifest
manifest.uuid
src/analyze.c
src/attach.c
src/backup.c
src/btree.c
src/build.c
src/complete.c
src/global.c
src/main.c
src/mem1.c
src/mem5.c
src/os_unix.c
src/os_win.c
src/pager.c
src/prepare.c
src/printf.c
src/resolve.c
src/shell.c
src/sqlite.h.in
src/sqliteInt.h
src/status.c
src/tokenize.c
src/util.c
src/vacuum.c
src/vdbe.c
src/vdbeapi.c
src/vdbeaux.c
src/vdbeblob.c
src/vtab.c
src/where.c
test/analyze3.test
test/capi3c.test
test/safety.test [deleted file]
test/schema.test

index f9eccbca0c167ce4381daf746226d5abac04cb5a..d734054ab96426ea1f5d5aa2f2ab23ca70f0cd5f 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,8 +1,8 @@
 -----BEGIN PGP SIGNED MESSAGE-----
 Hash: SHA1
 
-C Fix\sa\ssegfault\sthat\sis\spossible\sfor\san\sOOM\sfault\sin\sATTACH\swhen\sin\nshared-cache\smode.\s\sThis\sis\sa\scherrypick\smerge\sof\scheck-in\s[e37137376a].
-D 2010-02-25T02:11:22
+C Merge\sin\sall\sof\sthe\slogging\senhancements.\s\sThis\sis\sa\scherrypick\smerge\sof\nthe\sfollowing\scheck-ins:\s[103321e37a],\s[a8076aede3],\s[6d910245ad],\s\n[7c4cca6d1a],\s[edea3bb740],\s[1a6d4bb130],\s[a8c984c1d6],\s[69a493182f],\sand\n[1168763d2c].
+D 2010-02-25T02:32:29
 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
 F Makefile.in c5827ead754ab32b9585487177c93bb00b9497b3
 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -105,25 +105,25 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
 F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc
 F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad
 F src/alter.c 92ba938565d7cc6bfe92aad6cc90c00800ff21d3
-F src/analyze.c 55155f05ee9ab4ce33b7a4d19c449053f8935200
-F src/attach.c 508d431e52e16a1a1ec7644b6fc4d95d4442d15b
+F src/analyze.c 92a65a5a402898a52b03695c7f0cd383724d711f
+F src/attach.c ba4a14632976e26d121fe6015c41f768cd6920dc
 F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
-F src/backup.c 744e98359dfc79fed43e8dec911e33e108b06aae
+F src/backup.c b293534bc2df23c57668a585b17ee7faaaef0939
 F src/bitvec.c 06ad2c36a9c3819c0b9cbffec7b15f58d5d834e0
 F src/btmutex.c 96a12f50f7a17475155971a241d85ec5171573ff
-F src/btree.c e9ded8d7791fccb3343d9aafd3bda680796adbef
+F src/btree.c 5f00d6dd5c20de6ce82f39b62416ead4889afcdc
 F src/btree.h 7944a9dac59eb3e541aad45fd2747f1051e7c63d
 F src/btreeInt.h 54f4245decd0409ea52cf9aee422d3d761d7ac10
-F src/build.c 6ab7f8d8fa5b0ac6bfdce359e85f580b7a9b2e86
+F src/build.c ffad52833f5fb513b4eb0c751d06da22ec387ae2
 F src/callback.c 908f3e0172c3d4058f4ca0acd42c637c52e9669f
-F src/complete.c 4c8a742c4a4a6d9c835912648f5c8f032ea36c7b
+F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
 F src/date.c a79c0a8f219370b972e320741f995a3bef9df33f
 F src/delete.c 610dc008e88a9599f905f5cbe9577ac9c36e0581
 F src/expr.c d695300ba8b7a42d6b27a52d0288b974c89bf698
 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
 F src/fkey.c e2116672a6bd610dc888e27df292ebc7999c9bb0
 F src/func.c 69906340991919b4933dd8630774ad069e4d582e
-F src/global.c 75946a4a2ab41c6ae58f10ca0ed31b3449694b26
+F src/global.c 5a9c1e3c93213ca574786ac1caa976ce8f709105
 F src/hash.c 458488dcc159c301b8e7686280ab209f1fb915af
 F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970
 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
@@ -132,13 +132,13 @@ F src/journal.c b0ea6b70b532961118ab70301c00a33089f9315c
 F src/legacy.c 9304428e71b1d622b764913e1432e69156814755
 F src/lempar.c 7f026423f4d71d989e719a743f98a1cbd4e6d99e
 F src/loadext.c 1c7a61ce1281041f437333f366a96aa0d29bb581
-F src/main.c a0f6dfbdd79e01baf75ad62bdbfdeae9e560eb96
+F src/main.c 0d9826f7376f3b3692ec467d3af72172785d6bac
 F src/malloc.c 5fa175797f982b178eaf38afba9c588a866be729
 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
-F src/mem1.c 552f7e11486272f27948d2de9c012884d1f52908
+F src/mem1.c 07a57cbdffb8cbc83979e6edd8dd1fa60f5f3828
 F src/mem2.c 92b4f772b1ee7469e256f1c2eff0b51a0ba19460
 F src/mem3.c 9b237d911ba9904142a804be727cc6664873f8a3
-F src/mem5.c 4837b795ebdecc0cfe1522cd0c8b2c5d84ea490d
+F src/mem5.c eb7a5cb98915dd7a086fa415ce3a5a0f20d0acff
 F src/memjournal.c 5bfc2f33c914946e2f77ed3f882aff14dfc9355d
 F src/mutex.c 581a272e09098040ca3ef543cb5f3d643eff7d50
 F src/mutex.h 6fde601e55fa6c3fae768783c439797ab84c87c6
@@ -151,27 +151,27 @@ F src/os.c 4500ff276e277730776fe9b6c6c5930383ec4000
 F src/os.h 534b082c3cb349ad05fa6fa0b06087e022af282c
 F src/os_common.h 240c88b163b02c21a9f21f87d49678a0aa21ff30
 F src/os_os2.c 75a8c7b9a00a2cf1a65f9fa4afbc27d46634bb2f
-F src/os_unix.c b24510792108ffee0c8175c1d2fc644913b241d2
-F src/os_win.c 5ffab20249a61e0625f869efe157fa009747039b
-F src/pager.c 3250440da3ba886123d7f5976818d89e35b758f6
+F src/os_unix.c bf7f66b06d9f507b049de647fc725fcd20bb647f
+F src/os_win.c 1c7453c2df4dab26d90ff6f91272aea18bcf7053
+F src/pager.c 71d2a70723f3b44bc1ebe65419b56f079a91d0c9
 F src/pager.h 1b32faf2e578ac3e7bcf9c9d11217128261c5c54
 F src/parse.y ace5c7a125d9f2a410e431ee3209034105045f7e
 F src/pcache.c 815bcb3cf0e14b23212efd3f4981f667a5fd633e
 F src/pcache.h c683390d50f856d4cd8e24342ae62027d1bb6050
 F src/pcache1.c 2bb2261190b42a348038f5b1c285c8cef415fcc8
 F src/pragma.c 6936d7df5e04b9f996f8f320d15e65b6944b2caa
-F src/prepare.c 170bd953058efe1c46b8ad9020d49cd6f40f0b45
-F src/printf.c 644bc7d59df3dc56d6d8b9a510914bfc6b51bc69
+F src/prepare.c dede8f2d7f5810cea08ab7a4ced02fcc2d6478e9
+F src/printf.c ed476ea406ce79dec397268ef9035f914ee40453
 F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
-F src/resolve.c 69a45df25039eb58e321653914ad670ffe49d486
+F src/resolve.c 8e51ac017123b86f35de30ccdb0f18c73963c979
 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697
 F src/select.c 0109b993c360d649857523abb72919e1794f9b45
-F src/shell.c b95c5fcfe458027f192914a47474652969a1ec0f
-F src/sqlite.h.in d493cf5029de67fe7252324473d89140a007a6c4
+F src/shell.c 546fe4b6df101c6cc3d08aa7b7b414136ce03ffc
+F src/sqlite.h.in 37d8930135ae33ac8f122351df0bc6c4d979ab61
 F src/sqlite3ext.h 69dfb8116af51b84a029cddb3b35062354270c89
-F src/sqliteInt.h d6c48b1a5cd6485151e1d1b071dbe0a85ceb70fe
+F src/sqliteInt.h 4d7df175023a23232cc0abc07b51081ef9a61cec
 F src/sqliteLimit.h 3afab2291762b5d09ae20c18feb8e9fa935a60a6
-F src/status.c e651be6b30d397d86384c6867bc016e4913bcac7
+F src/status.c d329385a2cba3ea49d9d68af0ad84b22d46b4f40
 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
 F src/tclsqlite.c bad6570a005b234ea670b9f7b48256da19a032d3
 F src/test1.c db4d8fd2849ab9aca0f27fd3773b8d68d078cf86
@@ -206,23 +206,23 @@ F src/test_server.c bbba05c144b5fc4b52ff650a4328027b3fa5fcc6
 F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa
 F src/test_thread.c 00fed80690ae7f1525483a35861511c48bc579f2
 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
-F src/tokenize.c e7f3606cc1b51a819a2bfee99100648d35bc791d
+F src/tokenize.c 25ceb0f0a746ea1d0f9553787f3f0a56853cfaeb
 F src/trigger.c d46f9389e3bf3dd1cc1d288aba2f289c96b34200
 F src/update.c c0dc6b75ad28b76b619042d934f337b02acee208
 F src/utf.c dad16adcc0c35ef2437dca125a4b07419d361052
-F src/util.c ad4f03079ba0fe83590d1cc9197e8e4844e38592
-F src/vacuum.c db6415fd0f1be191e16228457a6deb9f232e6ad6
-F src/vdbe.c e65ccd13dce8843fe617884feab7e2c8422e4032
+F src/util.c 56008ded7b0695939f1127b47c195525fde10276
+F src/vacuum.c 1f3f6d608c976752822bc6e2aac01181e9438b1f
+F src/vdbe.c 1a07ddbd03ff7f8334da9467214fe9dab7176e98
 F src/vdbe.h bea1f0cd530775bdb58a340265f3cf3ee920e9b2
 F src/vdbeInt.h d7ea821ac7813c9bea0fe87558c35e07b2c7c44d
-F src/vdbeapi.c fc3787eb2f5487d4cc3444de42d56f2e39d311f5
-F src/vdbeaux.c 2e4a421bd3771ecd3b6c9a1c7abc7270a787a01b
-F src/vdbeblob.c 84f924700a7a889152aeebef77ca5f4e3875ffb4
+F src/vdbeapi.c 95e66cf3cb0841134154f1d05b0de58ddaec5553
+F src/vdbeaux.c ef5b18224f20b5d61718531f68e21bebc85f10c6
+F src/vdbeblob.c 5327132a42a91e8b7acfb60b9d2c3b1c5c863e0e
 F src/vdbemem.c 1e16e3a16e55f4c3452834f0e041726021aa66e0
 F src/vdbetrace.c 864cef96919323482ebd9986f2132435115e9cc2
-F src/vtab.c 7c7713d66cda699f16bf1cc601d8d4f5070ab935
+F src/vtab.c 606adf51cd6d4ba51a8c6dccede06a6f7b0dd72d
 F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f
-F src/where.c 43b11af016ac50724a95397c0ca447cae88f3c11
+F src/where.c 0fab05c99228e3d4c1fed231d02860a14f5ec0f2
 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
 F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87
 F test/all.test 14165b3e32715b700b5f0cbf8f6e3833dda0be45
@@ -233,7 +233,7 @@ F test/alter4.test 9386ffd1e9c7245f43eca412b2058d747509cc1f
 F test/altermalloc.test e81ac9657ed25c6c5bb09bebfa5a047cd8e4acfc
 F test/analyze.test ad5329098fe4de4a96852231d53e3e9e6283ad4b
 F test/analyze2.test a2ad7b0a4e13801ee3968fe70f22aff52326569c
-F test/analyze3.test ae06e0f8b3eaae0dd644ac9ac9d617058b5ac131
+F test/analyze3.test 506203875258ffd8ffa879b9c3c5432022d2b6d8
 F test/async.test 8c75d31b8330f8b70cf2571b014d4476a063efdb
 F test/async2.test bf5e2ca2c96763b4cba3d016249ad7259a5603b6
 F test/async3.test 93edaa9122f498e56ea98c36c72abc407f4fb11e
@@ -275,7 +275,7 @@ F test/cache.test 3ff445c445742a7b6b9ba6e1d62a25263f9424b9
 F test/capi2.test 172c717ed101e78e0798dd21b9896a22366f35b4
 F test/capi3.test 168e2cd66c58c510955b0f299750e4de73b8d952
 F test/capi3b.test 664eb55318132f292f2c436f90906f578cad6b97
-F test/capi3c.test d9d293ce8fd4dc2944ce2dae5718fc7a6184a567
+F test/capi3c.test 493385107dcedfaf4f2b1c3738c8c1fa00362006
 F test/capi3d.test 57d83b690d7364bde02cddbf8339a4b50d80ce23
 F test/cast.test 166951664a0b0a2e0f8fb5997a152490c6363932
 F test/check.test db2b29d557544347d28e25b8406f5d5ecc3d1bc3
@@ -540,14 +540,13 @@ F test/rollback.test 73355ad4492ff9a3a31e61c7e5eb5e01a1de94ca
 F test/rowhash.test 97f56043ba11f0679920416c0cdbc72e5272267b
 F test/rowid.test e58e0acef38b527ed1b0b70d3ada588f804af287
 F test/rtree.test 55466a200af3591946c5da77ad5dbfbc1e5e05f9
-F test/safety.test b69e2b2dd5d52a3f78e216967086884bbc1a09c6
 F test/savepoint.test f2ede4b643ad87ead36c041c72d774a1f5c8a564
 F test/savepoint2.test 427c8b20f43d3edf17a290c6788ae9e2703ac51c
 F test/savepoint3.test e328085853b14898d78ceea00dfe7db18bb6a9ec
 F test/savepoint4.test c8f8159ade6d2acd9128be61e1230f1c1edc6cc0
 F test/savepoint5.test 0735db177e0ebbaedc39812c8d065075d563c4fd
 F test/savepoint6.test 2df1d093e59e78d688c64eb20e0457aaea7d08f9
-F test/schema.test 23a2909d2b1f8494d28d355c1254f075b0af8ffc
+F test/schema.test 8f7999be894260f151adf15c2c7540f1c6d6a481
 F test/schema2.test 906408621ea881fdb496d878b1822572a34e32c5
 F test/select1.test f67ca2dfc05df41c7b86eb32ca409b427a5f43b0
 F test/select2.test 9735da20ccd41e42bf2b4c19fd939141b591adae
@@ -788,14 +787,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P ecd22ef34d5cd516d2b6138f8b80c39daad3519d
-R 5907b699b02304d204faf8b1c233d9e6
+P f73cc0e9af5e4b7a15e8947c412966f9e9935f8b
+R 316485e2fe4563eea5154af59938712a
 U drh
-Z 3b54ce47ea74c6e99a2a4c19d25d0720
+Z 377a396b70965d31743b5084dc4460d7
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.6 (GNU/Linux)
 
-iD8DBQFLhdxOoxKgR168RlERAijbAJ9X02LFH0XMk7+viR+H9LRDw87XgQCeNaZ2
-dz9U50KJLRq3IXujEMbataY=
-=gdto
+iD8DBQFLheFAoxKgR168RlERAvnQAJoCUSbZVVfxBneYQSLLRqw1a3vUiACeODvf
+y44fx2BsreFXydGTPuT+vfs=
+=F+zo
 -----END PGP SIGNATURE-----
index 1616b28a792571b7049ee408eaaccc387447d37f..a1c867be54bb5ade10075247292acee4270267a1 100644 (file)
@@ -1 +1 @@
-f73cc0e9af5e4b7a15e8947c412966f9e9935f8b
\ No newline at end of file
+46f406b2022b534f396491c04adad8a2012b8fcb
\ No newline at end of file
index 2e2e1d896c865310b6d65f3c6422c3f88de9baed..283a0e9d1e528fb3122d52e4e0e619b89cbebdbb 100644 (file)
@@ -559,9 +559,7 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
   if( zSql==0 ){
     rc = SQLITE_NOMEM;
   }else{
-    (void)sqlite3SafetyOff(db);
     rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0);
-    (void)sqlite3SafetyOn(db);
     sqlite3DbFree(db, zSql);
   }
 
@@ -579,14 +577,11 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
     if( !zSql ){
       rc = SQLITE_NOMEM;
     }else{
-      (void)sqlite3SafetyOff(db);
       rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
-      (void)sqlite3SafetyOn(db);
       sqlite3DbFree(db, zSql);
     }
 
     if( rc==SQLITE_OK ){
-      (void)sqlite3SafetyOff(db);
       while( sqlite3_step(pStmt)==SQLITE_ROW ){
         char *zIndex = (char *)sqlite3_column_text(pStmt, 0);
         Index *pIdx = sqlite3FindIndex(db, zIndex, sInfo.zDatabase);
@@ -636,7 +631,6 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
         }
       }
       rc = sqlite3_finalize(pStmt);
-      (void)sqlite3SafetyOn(db);
     }
   }
 #endif
index d7d3177b288c74f8966f9d95769e4a84c8ac882c..2ee1bd34dd56c1b72b02c1f4dceef7ae3dc61972 100644 (file)
@@ -188,11 +188,9 @@ static void attachFunc(
   ** we found it.
   */
   if( rc==SQLITE_OK ){
-    (void)sqlite3SafetyOn(db);
     sqlite3BtreeEnterAll(db);
     rc = sqlite3Init(db, &zErrDyn);
     sqlite3BtreeLeaveAll(db);
-    (void)sqlite3SafetyOff(db);
   }
   if( rc ){
     int iDb = db->nDb - 1;
index 422198bfa6e3723e9dad9fbd3f1ea7901dd5e9d1..2d01ddbb58fdc64bbdc471b665c74138f8dfb4d2 100644 (file)
@@ -98,10 +98,10 @@ static Btree *findBtree(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){
     }else{
       pParse->db = pDb;
       if( sqlite3OpenTempDatabase(pParse) ){
-        sqlite3ErrorClear(pParse);
         sqlite3Error(pErrorDb, pParse->rc, "%s", pParse->zErrMsg);
         rc = SQLITE_ERROR;
       }
+      sqlite3DbFree(pErrorDb, pParse->zErrMsg);
       sqlite3StackFree(pErrorDb, pParse);
     }
     if( rc ){
index 3dda02afc397dc24263b14d1949afede396a2736..c9cccf73d5a84c84ee8637c42997c0dd0bcc97df 100644 (file)
@@ -5901,7 +5901,7 @@ static int balance_nonroot(
       if( leafData ){ i--; }
       subtotal = 0;
       k++;
-      if( k>NB+1 ){ rc = SQLITE_CORRUPT; goto balance_cleanup; }
+      if( k>NB+1 ){ rc = SQLITE_CORRUPT_BKPT; goto balance_cleanup; }
     }
   }
   szNew[k] = subtotal;
@@ -5955,7 +5955,7 @@ static int balance_nonroot(
   ** Allocate k new pages.  Reuse old pages where possible.
   */
   if( apOld[0]->pgno<=1 ){
-    rc = SQLITE_CORRUPT;
+    rc = SQLITE_CORRUPT_BKPT;
     goto balance_cleanup;
   }
   pageFlags = apOld[0]->aData[0];
@@ -7538,7 +7538,7 @@ static int checkTreePage(
       }
     }
   }
+
   /* Check for complete coverage of the page
   */
   data = pPage->aData;
index b385e44ef1344ce9524c12e14494076f36a354d2..8817ac861539c71b5015978bda9b831f87fa3873 100644 (file)
@@ -1974,13 +1974,12 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){
   }
   assert( pParse->nErr==0 );
   assert( pName->nSrc==1 );
+  if( noErr ) db->suppressErr++;
   pTab = sqlite3LocateTable(pParse, isView, 
                             pName->a[0].zName, pName->a[0].zDatabase);
+  if( noErr ) db->suppressErr--;
 
   if( pTab==0 ){
-    if( noErr ){
-      sqlite3ErrorClear(pParse);
-    }
     goto exit_drop_table;
   }
   iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
index 9799a6ae3079abe941cc95110e9e5fdcd5afdc58..9e9140085c0046ed3bf6f4485220692dca1743c5 100644 (file)
-/*\r
-** 2001 September 15\r
-**\r
-** The author disclaims copyright to this source code.  In place of\r
-** a legal notice, here is a blessing:\r
-**\r
-**    May you do good and not evil.\r
-**    May you find forgiveness for yourself and forgive others.\r
-**    May you share freely, never taking more than you give.\r
-**\r
-*************************************************************************\r
-** An tokenizer for SQL\r
-**\r
-** This file contains C code that implements the sqlite3_complete() API.\r
-** This code used to be part of the tokenizer.c source file.  But by\r
-** separating it out, the code will be automatically omitted from\r
-** static links that do not use it.\r
-*/\r
-#include "sqliteInt.h"\r
-#ifndef SQLITE_OMIT_COMPLETE\r
-\r
-/*\r
-** This is defined in tokenize.c.  We just have to import the definition.\r
-*/\r
-#ifndef SQLITE_AMALGAMATION\r
-#ifdef SQLITE_ASCII\r
-#define IdChar(C)  ((sqlite3CtypeMap[(unsigned char)C]&0x46)!=0)\r
-#endif\r
-#ifdef SQLITE_EBCDIC\r
-extern const char sqlite3IsEbcdicIdChar[];\r
-#define IdChar(C)  (((c=C)>=0x42 && sqlite3IsEbcdicIdChar[c-0x40]))\r
-#endif\r
-#endif /* SQLITE_AMALGAMATION */\r
-\r
-\r
-/*\r
-** Token types used by the sqlite3_complete() routine.  See the header\r
-** comments on that procedure for additional information.\r
-*/\r
-#define tkSEMI    0\r
-#define tkWS      1\r
-#define tkOTHER   2\r
-#ifndef SQLITE_OMIT_TRIGGER\r
-#define tkEXPLAIN 3\r
-#define tkCREATE  4\r
-#define tkTEMP    5\r
-#define tkTRIGGER 6\r
-#define tkEND     7\r
-#endif\r
-\r
-/*\r
-** Return TRUE if the given SQL string ends in a semicolon.\r
-**\r
-** Special handling is require for CREATE TRIGGER statements.\r
-** Whenever the CREATE TRIGGER keywords are seen, the statement\r
-** must end with ";END;".\r
-**\r
-** This implementation uses a state machine with 8 states:\r
-**\r
-**   (0) INVALID   We have not yet seen a non-whitespace character.\r
-**\r
-**   (1) START     At the beginning or end of an SQL statement.  This routine\r
-**                 returns 1 if it ends in the START state and 0 if it ends\r
-**                 in any other state.\r
-**\r
-**   (2) NORMAL    We are in the middle of statement which ends with a single\r
-**                 semicolon.\r
-**\r
-**   (3) EXPLAIN   The keyword EXPLAIN has been seen at the beginning of \r
-**                 a statement.\r
-**\r
-**   (4) CREATE    The keyword CREATE has been seen at the beginning of a\r
-**                 statement, possibly preceeded by EXPLAIN and/or followed by\r
-**                 TEMP or TEMPORARY\r
-**\r
-**   (5) TRIGGER   We are in the middle of a trigger definition that must be\r
-**                 ended by a semicolon, the keyword END, and another semicolon.\r
-**\r
-**   (6) SEMI      We've seen the first semicolon in the ";END;" that occurs at\r
-**                 the end of a trigger definition.\r
-**\r
-**   (7) END       We've seen the ";END" of the ";END;" that occurs at the end\r
-**                 of a trigger difinition.\r
-**\r
-** Transitions between states above are determined by tokens extracted\r
-** from the input.  The following tokens are significant:\r
-**\r
-**   (0) tkSEMI      A semicolon.\r
-**   (1) tkWS        Whitespace.\r
-**   (2) tkOTHER     Any other SQL token.\r
-**   (3) tkEXPLAIN   The "explain" keyword.\r
-**   (4) tkCREATE    The "create" keyword.\r
-**   (5) tkTEMP      The "temp" or "temporary" keyword.\r
-**   (6) tkTRIGGER   The "trigger" keyword.\r
-**   (7) tkEND       The "end" keyword.\r
-**\r
-** Whitespace never causes a state transition and is always ignored.\r
-** This means that a SQL string of all whitespace is invalid.\r
-**\r
-** If we compile with SQLITE_OMIT_TRIGGER, all of the computation needed\r
-** to recognize the end of a trigger can be omitted.  All we have to do\r
-** is look for a semicolon that is not part of an string or comment.\r
-*/\r
-int sqlite3_complete(const char *zSql){\r
-  u8 state = 0;   /* Current state, using numbers defined in header comment */\r
-  u8 token;       /* Value of the next token */\r
-\r
-#ifndef SQLITE_OMIT_TRIGGER\r
-  /* A complex statement machine used to detect the end of a CREATE TRIGGER\r
-  ** statement.  This is the normal case.\r
-  */\r
-  static const u8 trans[8][8] = {\r
-                     /* Token:                                                */\r
-     /* State:       **  SEMI  WS  OTHER  EXPLAIN  CREATE  TEMP  TRIGGER  END */\r
-     /* 0 INVALID: */ {    1,  0,     2,       3,      4,    2,       2,   2, },\r
-     /* 1   START: */ {    1,  1,     2,       3,      4,    2,       2,   2, },\r
-     /* 2  NORMAL: */ {    1,  2,     2,       2,      2,    2,       2,   2, },\r
-     /* 3 EXPLAIN: */ {    1,  3,     3,       2,      4,    2,       2,   2, },\r
-     /* 4  CREATE: */ {    1,  4,     2,       2,      2,    4,       5,   2, },\r
-     /* 5 TRIGGER: */ {    6,  5,     5,       5,      5,    5,       5,   5, },\r
-     /* 6    SEMI: */ {    6,  6,     5,       5,      5,    5,       5,   7, },\r
-     /* 7     END: */ {    1,  7,     5,       5,      5,    5,       5,   5, },\r
-  };\r
-#else\r
-  /* If triggers are not supported by this compile then the statement machine\r
-  ** used to detect the end of a statement is much simplier\r
-  */\r
-  static const u8 trans[3][3] = {\r
-                     /* Token:           */\r
-     /* State:       **  SEMI  WS  OTHER */\r
-     /* 0 INVALID: */ {    1,  0,     2, },\r
-     /* 1   START: */ {    1,  1,     2, },\r
-     /* 2  NORMAL: */ {    1,  2,     2, },\r
-  };\r
-#endif /* SQLITE_OMIT_TRIGGER */\r
-\r
-  while( *zSql ){\r
-    switch( *zSql ){\r
-      case ';': {  /* A semicolon */\r
-        token = tkSEMI;\r
-        break;\r
-      }\r
-      case ' ':\r
-      case '\r':\r
-      case '\t':\r
-      case '\n':\r
-      case '\f': {  /* White space is ignored */\r
-        token = tkWS;\r
-        break;\r
-      }\r
-      case '/': {   /* C-style comments */\r
-        if( zSql[1]!='*' ){\r
-          token = tkOTHER;\r
-          break;\r
-        }\r
-        zSql += 2;\r
-        while( zSql[0] && (zSql[0]!='*' || zSql[1]!='/') ){ zSql++; }\r
-        if( zSql[0]==0 ) return 0;\r
-        zSql++;\r
-        token = tkWS;\r
-        break;\r
-      }\r
-      case '-': {   /* SQL-style comments from "--" to end of line */\r
-        if( zSql[1]!='-' ){\r
-          token = tkOTHER;\r
-          break;\r
-        }\r
-        while( *zSql && *zSql!='\n' ){ zSql++; }\r
-        if( *zSql==0 ) return state==1;\r
-        token = tkWS;\r
-        break;\r
-      }\r
-      case '[': {   /* Microsoft-style identifiers in [...] */\r
-        zSql++;\r
-        while( *zSql && *zSql!=']' ){ zSql++; }\r
-        if( *zSql==0 ) return 0;\r
-        token = tkOTHER;\r
-        break;\r
-      }\r
-      case '`':     /* Grave-accent quoted symbols used by MySQL */\r
-      case '"':     /* single- and double-quoted strings */\r
-      case '\'': {\r
-        int c = *zSql;\r
-        zSql++;\r
-        while( *zSql && *zSql!=c ){ zSql++; }\r
-        if( *zSql==0 ) return 0;\r
-        token = tkOTHER;\r
-        break;\r
-      }\r
-      default: {\r
-#ifdef SQLITE_EBCDIC\r
-        unsigned char c;\r
-#endif\r
-        if( IdChar((u8)*zSql) ){\r
-          /* Keywords and unquoted identifiers */\r
-          int nId;\r
-          for(nId=1; IdChar(zSql[nId]); nId++){}\r
-#ifdef SQLITE_OMIT_TRIGGER\r
-          token = tkOTHER;\r
-#else\r
-          switch( *zSql ){\r
-            case 'c': case 'C': {\r
-              if( nId==6 && sqlite3StrNICmp(zSql, "create", 6)==0 ){\r
-                token = tkCREATE;\r
-              }else{\r
-                token = tkOTHER;\r
-              }\r
-              break;\r
-            }\r
-            case 't': case 'T': {\r
-              if( nId==7 && sqlite3StrNICmp(zSql, "trigger", 7)==0 ){\r
-                token = tkTRIGGER;\r
-              }else if( nId==4 && sqlite3StrNICmp(zSql, "temp", 4)==0 ){\r
-                token = tkTEMP;\r
-              }else if( nId==9 && sqlite3StrNICmp(zSql, "temporary", 9)==0 ){\r
-                token = tkTEMP;\r
-              }else{\r
-                token = tkOTHER;\r
-              }\r
-              break;\r
-            }\r
-            case 'e':  case 'E': {\r
-              if( nId==3 && sqlite3StrNICmp(zSql, "end", 3)==0 ){\r
-                token = tkEND;\r
-              }else\r
-#ifndef SQLITE_OMIT_EXPLAIN\r
-              if( nId==7 && sqlite3StrNICmp(zSql, "explain", 7)==0 ){\r
-                token = tkEXPLAIN;\r
-              }else\r
-#endif\r
-              {\r
-                token = tkOTHER;\r
-              }\r
-              break;\r
-            }\r
-            default: {\r
-              token = tkOTHER;\r
-              break;\r
-            }\r
-          }\r
-#endif /* SQLITE_OMIT_TRIGGER */\r
-          zSql += nId-1;\r
-        }else{\r
-          /* Operators and special symbols */\r
-          token = tkOTHER;\r
-        }\r
-        break;\r
-      }\r
-    }\r
-    state = trans[state][token];\r
-    zSql++;\r
-  }\r
-  return state==1;\r
-}\r
-\r
-#ifndef SQLITE_OMIT_UTF16\r
-/*\r
-** This routine is the same as the sqlite3_complete() routine described\r
-** above, except that the parameter is required to be UTF-16 encoded, not\r
-** UTF-8.\r
-*/\r
-int sqlite3_complete16(const void *zSql){\r
-  sqlite3_value *pVal;\r
-  char const *zSql8;\r
-  int rc = SQLITE_NOMEM;\r
-\r
-#ifndef SQLITE_OMIT_AUTOINIT\r
-  rc = sqlite3_initialize();\r
-  if( rc ) return rc;\r
-#endif\r
-  pVal = sqlite3ValueNew(0);\r
-  sqlite3ValueSetStr(pVal, -1, zSql, SQLITE_UTF16NATIVE, SQLITE_STATIC);\r
-  zSql8 = sqlite3ValueText(pVal, SQLITE_UTF8);\r
-  if( zSql8 ){\r
-    rc = sqlite3_complete(zSql8);\r
-  }else{\r
-    rc = SQLITE_NOMEM;\r
-  }\r
-  sqlite3ValueFree(pVal);\r
-  return sqlite3ApiExit(0, rc);\r
-}\r
-#endif /* SQLITE_OMIT_UTF16 */\r
-#endif /* SQLITE_OMIT_COMPLETE */\r
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code.  In place of
+** a legal notice, here is a blessing:
+**
+**    May you do good and not evil.
+**    May you find forgiveness for yourself and forgive others.
+**    May you share freely, never taking more than you give.
+**
+*************************************************************************
+** An tokenizer for SQL
+**
+** This file contains C code that implements the sqlite3_complete() API.
+** This code used to be part of the tokenizer.c source file.  But by
+** separating it out, the code will be automatically omitted from
+** static links that do not use it.
+*/
+#include "sqliteInt.h"
+#ifndef SQLITE_OMIT_COMPLETE
+
+/*
+** This is defined in tokenize.c.  We just have to import the definition.
+*/
+#ifndef SQLITE_AMALGAMATION
+#ifdef SQLITE_ASCII
+#define IdChar(C)  ((sqlite3CtypeMap[(unsigned char)C]&0x46)!=0)
+#endif
+#ifdef SQLITE_EBCDIC
+extern const char sqlite3IsEbcdicIdChar[];
+#define IdChar(C)  (((c=C)>=0x42 && sqlite3IsEbcdicIdChar[c-0x40]))
+#endif
+#endif /* SQLITE_AMALGAMATION */
+
+
+/*
+** Token types used by the sqlite3_complete() routine.  See the header
+** comments on that procedure for additional information.
+*/
+#define tkSEMI    0
+#define tkWS      1
+#define tkOTHER   2
+#ifndef SQLITE_OMIT_TRIGGER
+#define tkEXPLAIN 3
+#define tkCREATE  4
+#define tkTEMP    5
+#define tkTRIGGER 6
+#define tkEND     7
+#endif
+
+/*
+** Return TRUE if the given SQL string ends in a semicolon.
+**
+** Special handling is require for CREATE TRIGGER statements.
+** Whenever the CREATE TRIGGER keywords are seen, the statement
+** must end with ";END;".
+**
+** This implementation uses a state machine with 8 states:
+**
+**   (0) INVALID   We have not yet seen a non-whitespace character.
+**
+**   (1) START     At the beginning or end of an SQL statement.  This routine
+**                 returns 1 if it ends in the START state and 0 if it ends
+**                 in any other state.
+**
+**   (2) NORMAL    We are in the middle of statement which ends with a single
+**                 semicolon.
+**
+**   (3) EXPLAIN   The keyword EXPLAIN has been seen at the beginning of 
+**                 a statement.
+**
+**   (4) CREATE    The keyword CREATE has been seen at the beginning of a
+**                 statement, possibly preceeded by EXPLAIN and/or followed by
+**                 TEMP or TEMPORARY
+**
+**   (5) TRIGGER   We are in the middle of a trigger definition that must be
+**                 ended by a semicolon, the keyword END, and another semicolon.
+**
+**   (6) SEMI      We've seen the first semicolon in the ";END;" that occurs at
+**                 the end of a trigger definition.
+**
+**   (7) END       We've seen the ";END" of the ";END;" that occurs at the end
+**                 of a trigger difinition.
+**
+** Transitions between states above are determined by tokens extracted
+** from the input.  The following tokens are significant:
+**
+**   (0) tkSEMI      A semicolon.
+**   (1) tkWS        Whitespace.
+**   (2) tkOTHER     Any other SQL token.
+**   (3) tkEXPLAIN   The "explain" keyword.
+**   (4) tkCREATE    The "create" keyword.
+**   (5) tkTEMP      The "temp" or "temporary" keyword.
+**   (6) tkTRIGGER   The "trigger" keyword.
+**   (7) tkEND       The "end" keyword.
+**
+** Whitespace never causes a state transition and is always ignored.
+** This means that a SQL string of all whitespace is invalid.
+**
+** If we compile with SQLITE_OMIT_TRIGGER, all of the computation needed
+** to recognize the end of a trigger can be omitted.  All we have to do
+** is look for a semicolon that is not part of an string or comment.
+*/
+int sqlite3_complete(const char *zSql){
+  u8 state = 0;   /* Current state, using numbers defined in header comment */
+  u8 token;       /* Value of the next token */
+
+#ifndef SQLITE_OMIT_TRIGGER
+  /* A complex statement machine used to detect the end of a CREATE TRIGGER
+  ** statement.  This is the normal case.
+  */
+  static const u8 trans[8][8] = {
+                     /* Token:                                                */
+     /* State:       **  SEMI  WS  OTHER  EXPLAIN  CREATE  TEMP  TRIGGER  END */
+     /* 0 INVALID: */ {    1,  0,     2,       3,      4,    2,       2,   2, },
+     /* 1   START: */ {    1,  1,     2,       3,      4,    2,       2,   2, },
+     /* 2  NORMAL: */ {    1,  2,     2,       2,      2,    2,       2,   2, },
+     /* 3 EXPLAIN: */ {    1,  3,     3,       2,      4,    2,       2,   2, },
+     /* 4  CREATE: */ {    1,  4,     2,       2,      2,    4,       5,   2, },
+     /* 5 TRIGGER: */ {    6,  5,     5,       5,      5,    5,       5,   5, },
+     /* 6    SEMI: */ {    6,  6,     5,       5,      5,    5,       5,   7, },
+     /* 7     END: */ {    1,  7,     5,       5,      5,    5,       5,   5, },
+  };
+#else
+  /* If triggers are not supported by this compile then the statement machine
+  ** used to detect the end of a statement is much simplier
+  */
+  static const u8 trans[3][3] = {
+                     /* Token:           */
+     /* State:       **  SEMI  WS  OTHER */
+     /* 0 INVALID: */ {    1,  0,     2, },
+     /* 1   START: */ {    1,  1,     2, },
+     /* 2  NORMAL: */ {    1,  2,     2, },
+  };
+#endif /* SQLITE_OMIT_TRIGGER */
+
+  while( *zSql ){
+    switch( *zSql ){
+      case ';': {  /* A semicolon */
+        token = tkSEMI;
+        break;
+      }
+      case ' ':
+      case '\r':
+      case '\t':
+      case '\n':
+      case '\f': {  /* White space is ignored */
+        token = tkWS;
+        break;
+      }
+      case '/': {   /* C-style comments */
+        if( zSql[1]!='*' ){
+          token = tkOTHER;
+          break;
+        }
+        zSql += 2;
+        while( zSql[0] && (zSql[0]!='*' || zSql[1]!='/') ){ zSql++; }
+        if( zSql[0]==0 ) return 0;
+        zSql++;
+        token = tkWS;
+        break;
+      }
+      case '-': {   /* SQL-style comments from "--" to end of line */
+        if( zSql[1]!='-' ){
+          token = tkOTHER;
+          break;
+        }
+        while( *zSql && *zSql!='\n' ){ zSql++; }
+        if( *zSql==0 ) return state==1;
+        token = tkWS;
+        break;
+      }
+      case '[': {   /* Microsoft-style identifiers in [...] */
+        zSql++;
+        while( *zSql && *zSql!=']' ){ zSql++; }
+        if( *zSql==0 ) return 0;
+        token = tkOTHER;
+        break;
+      }
+      case '`':     /* Grave-accent quoted symbols used by MySQL */
+      case '"':     /* single- and double-quoted strings */
+      case '\'': {
+        int c = *zSql;
+        zSql++;
+        while( *zSql && *zSql!=c ){ zSql++; }
+        if( *zSql==0 ) return 0;
+        token = tkOTHER;
+        break;
+      }
+      default: {
+#ifdef SQLITE_EBCDIC
+        unsigned char c;
+#endif
+        if( IdChar((u8)*zSql) ){
+          /* Keywords and unquoted identifiers */
+          int nId;
+          for(nId=1; IdChar(zSql[nId]); nId++){}
+#ifdef SQLITE_OMIT_TRIGGER
+          token = tkOTHER;
+#else
+          switch( *zSql ){
+            case 'c': case 'C': {
+              if( nId==6 && sqlite3StrNICmp(zSql, "create", 6)==0 ){
+                token = tkCREATE;
+              }else{
+                token = tkOTHER;
+              }
+              break;
+            }
+            case 't': case 'T': {
+              if( nId==7 && sqlite3StrNICmp(zSql, "trigger", 7)==0 ){
+                token = tkTRIGGER;
+              }else if( nId==4 && sqlite3StrNICmp(zSql, "temp", 4)==0 ){
+                token = tkTEMP;
+              }else if( nId==9 && sqlite3StrNICmp(zSql, "temporary", 9)==0 ){
+                token = tkTEMP;
+              }else{
+                token = tkOTHER;
+              }
+              break;
+            }
+            case 'e':  case 'E': {
+              if( nId==3 && sqlite3StrNICmp(zSql, "end", 3)==0 ){
+                token = tkEND;
+              }else
+#ifndef SQLITE_OMIT_EXPLAIN
+              if( nId==7 && sqlite3StrNICmp(zSql, "explain", 7)==0 ){
+                token = tkEXPLAIN;
+              }else
+#endif
+              {
+                token = tkOTHER;
+              }
+              break;
+            }
+            default: {
+              token = tkOTHER;
+              break;
+            }
+          }
+#endif /* SQLITE_OMIT_TRIGGER */
+          zSql += nId-1;
+        }else{
+          /* Operators and special symbols */
+          token = tkOTHER;
+        }
+        break;
+      }
+    }
+    state = trans[state][token];
+    zSql++;
+  }
+  return state==1;
+}
+
+#ifndef SQLITE_OMIT_UTF16
+/*
+** This routine is the same as the sqlite3_complete() routine described
+** above, except that the parameter is required to be UTF-16 encoded, not
+** UTF-8.
+*/
+int sqlite3_complete16(const void *zSql){
+  sqlite3_value *pVal;
+  char const *zSql8;
+  int rc = SQLITE_NOMEM;
+
+#ifndef SQLITE_OMIT_AUTOINIT
+  rc = sqlite3_initialize();
+  if( rc ) return rc;
+#endif
+  pVal = sqlite3ValueNew(0);
+  sqlite3ValueSetStr(pVal, -1, zSql, SQLITE_UTF16NATIVE, SQLITE_STATIC);
+  zSql8 = sqlite3ValueText(pVal, SQLITE_UTF8);
+  if( zSql8 ){
+    rc = sqlite3_complete(zSql8);
+  }else{
+    rc = SQLITE_NOMEM;
+  }
+  sqlite3ValueFree(pVal);
+  return sqlite3ApiExit(0, rc);
+}
+#endif /* SQLITE_OMIT_UTF16 */
+#endif /* SQLITE_OMIT_COMPLETE */
index bdfd1ff29330476ff713fc55be67b629d7932f93..673a274cccaaacb30d7d251915a9ec929f07e9f5 100644 (file)
@@ -164,6 +164,8 @@ SQLITE_WSD struct Sqlite3Config sqlite3Config = {
    0,                         /* isPCacheInit */
    0,                         /* pInitMutex */
    0,                         /* nRefInitMutex */
+   0,                         /* xLog */
+   0,                         /* pLogArg */
 };
 
 
index 07fe15ce726f1e1ab82700f47d5d931e3a95b206..3d219fb8a566ce8e7c5746fc116dc95da91b7974 100644 (file)
@@ -257,7 +257,7 @@ int sqlite3_config(int op, ...){
 
   /* sqlite3_config() shall return SQLITE_MISUSE if it is invoked while
   ** the SQLite library is in use. */
-  if( sqlite3GlobalConfig.isInit ) return SQLITE_MISUSE;
+  if( sqlite3GlobalConfig.isInit ) return SQLITE_MISUSE_BKPT;
 
   va_start(ap, op);
   switch( op ){
@@ -378,6 +378,16 @@ int sqlite3_config(int op, ...){
       sqlite3GlobalConfig.nLookaside = va_arg(ap, int);
       break;
     }
+    
+    /* Record a pointer to the logger funcction and its first argument.
+    ** The default is NULL.  Logging is disabled if the function pointer is
+    ** NULL.
+    */
+    case SQLITE_CONFIG_LOG: {
+      sqlite3GlobalConfig.xLog = va_arg(ap, void(*)(void*,int,const char*));
+      sqlite3GlobalConfig.pLogArg = va_arg(ap, void*);
+      break;
+    }
 
     default: {
       rc = SQLITE_ERROR;
@@ -591,7 +601,7 @@ int sqlite3_close(sqlite3 *db){
     return SQLITE_OK;
   }
   if( !sqlite3SafetyCheckSickOrOk(db) ){
-    return SQLITE_MISUSE;
+    return SQLITE_MISUSE_BKPT;
   }
   sqlite3_mutex_enter(db->mutex);
 
@@ -938,7 +948,7 @@ int sqlite3CreateFunc(
       (!xFunc && (!xFinal && xStep)) ||
       (nArg<-1 || nArg>SQLITE_MAX_FUNCTION_ARG) ||
       (255<(nName = sqlite3Strlen30( zFunctionName))) ){
-    return SQLITE_MISUSE;
+    return SQLITE_MISUSE_BKPT;
   }
   
 #ifndef SQLITE_OMIT_UTF16
@@ -1269,7 +1279,7 @@ const char *sqlite3_errmsg(sqlite3 *db){
     return sqlite3ErrStr(SQLITE_NOMEM);
   }
   if( !sqlite3SafetyCheckSickOrOk(db) ){
-    return sqlite3ErrStr(SQLITE_MISUSE);
+    return sqlite3ErrStr(SQLITE_MISUSE_BKPT);
   }
   sqlite3_mutex_enter(db->mutex);
   if( db->mallocFailed ){
@@ -1338,7 +1348,7 @@ const void *sqlite3_errmsg16(sqlite3 *db){
 */
 int sqlite3_errcode(sqlite3 *db){
   if( db && !sqlite3SafetyCheckSickOrOk(db) ){
-    return SQLITE_MISUSE;
+    return SQLITE_MISUSE_BKPT;
   }
   if( !db || db->mallocFailed ){
     return SQLITE_NOMEM;
@@ -1347,7 +1357,7 @@ int sqlite3_errcode(sqlite3 *db){
 }
 int sqlite3_extended_errcode(sqlite3 *db){
   if( db && !sqlite3SafetyCheckSickOrOk(db) ){
-    return SQLITE_MISUSE;
+    return SQLITE_MISUSE_BKPT;
   }
   if( !db || db->mallocFailed ){
     return SQLITE_NOMEM;
@@ -1385,7 +1395,7 @@ static int createCollation(
     enc2 = SQLITE_UTF16NATIVE;
   }
   if( enc2<SQLITE_UTF8 || enc2>SQLITE_UTF16BE ){
-    return SQLITE_MISUSE;
+    return SQLITE_MISUSE_BKPT;
   }
 
   /* Check if this call is removing or replacing an existing collation 
@@ -1929,16 +1939,34 @@ int sqlite3_get_autocommit(sqlite3 *db){
   return db->autoCommit;
 }
 
-#ifdef SQLITE_DEBUG
 /*
-** The following routine is subtituted for constant SQLITE_CORRUPT in
-** debugging builds.  This provides a way to set a breakpoint for when
-** corruption is first detected.
+** The following routines are subtitutes for constants SQLITE_CORRUPT,
+** SQLITE_MISUSE, SQLITE_CANTOPEN, SQLITE_IOERR and possibly other error
+** constants.  They server two purposes:
+**
+**   1.  Serve as a convenient place to set a breakpoint in a debugger
+**       to detect when version error conditions occurs.
+**
+**   2.  Invoke sqlite3_log() to provide the source code location where
+**       a low-level error is first detected.
 */
-int sqlite3Corrupt(void){
+int sqlite3CorruptError(int lineno){
+  testcase( sqlite3GlobalConfig.xLog!=0 );
+  sqlite3_log(SQLITE_CORRUPT,
+              "database corruption found by source line %d", lineno);
   return SQLITE_CORRUPT;
 }
-#endif
+int sqlite3MisuseError(int lineno){
+  testcase( sqlite3GlobalConfig.xLog!=0 );
+  sqlite3_log(SQLITE_MISUSE, "misuse detected by source line %d", lineno);
+  return SQLITE_MISUSE;
+}
+int sqlite3CantopenError(int lineno){
+  testcase( sqlite3GlobalConfig.xLog!=0 );
+  sqlite3_log(SQLITE_CANTOPEN, "cannot open file at source line %d", lineno);
+  return SQLITE_CANTOPEN;
+}
+
 
 #ifndef SQLITE_OMIT_DEPRECATED
 /*
@@ -1982,7 +2010,6 @@ int sqlite3_table_column_metadata(
 
   /* Ensure the database schema has been loaded */
   sqlite3_mutex_enter(db->mutex);
-  (void)sqlite3SafetyOn(db);
   sqlite3BtreeEnterAll(db);
   rc = sqlite3Init(db, &zErrMsg);
   if( SQLITE_OK!=rc ){
@@ -2041,7 +2068,6 @@ int sqlite3_table_column_metadata(
 
 error_out:
   sqlite3BtreeLeaveAll(db);
-  (void)sqlite3SafetyOff(db);
 
   /* Whether the function call succeeded or failed, set the output parameters
   ** to whatever their local counterparts contain. If an error did occur,
index fbfa35eb9158dfa95fff401b57d65f17ed82b961..ad523c80c87cce708e73d27d5230d189578e0102 100644 (file)
@@ -42,6 +42,9 @@ static void *sqlite3MemMalloc(int nByte){
   if( p ){
     p[0] = nByte;
     p++;
+  }else{
+    testcase( sqlite3GlobalConfig.xLog!=0 );
+    sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte);
   }
   return (void *)p;
 }
@@ -61,6 +64,18 @@ static void sqlite3MemFree(void *pPrior){
   free(p);
 }
 
+/*
+** Report the allocated size of a prior return from xMalloc()
+** or xRealloc().
+*/
+static int sqlite3MemSize(void *pPrior){
+  sqlite3_int64 *p;
+  if( pPrior==0 ) return 0;
+  p = (sqlite3_int64*)pPrior;
+  p--;
+  return (int)p[0];
+}
+
 /*
 ** Like realloc().  Resize an allocation previously obtained from
 ** sqlite3MemMalloc().
@@ -81,22 +96,15 @@ static void *sqlite3MemRealloc(void *pPrior, int nByte){
   if( p ){
     p[0] = nByte;
     p++;
+  }else{
+    testcase( sqlite3GlobalConfig.xLog!=0 );
+    sqlite3_log(SQLITE_NOMEM,
+      "failed memory resize %u to %u bytes",
+      sqlite3MemSize(pPrior), nByte);
   }
   return (void*)p;
 }
 
-/*
-** Report the allocated size of a prior return from xMalloc()
-** or xRealloc().
-*/
-static int sqlite3MemSize(void *pPrior){
-  sqlite3_int64 *p;
-  if( pPrior==0 ) return 0;
-  p = (sqlite3_int64*)pPrior;
-  p--;
-  return (int)p[0];
-}
-
 /*
 ** Round up a request size to the next valid allocation size.
 */
index 3fe04e24552cd4d5724e7398d9547fc1fe7a218f..a828cf812e119f185b3bc75f5752bd8934230a15 100644 (file)
@@ -268,7 +268,11 @@ static void *memsys5MallocUnsafe(int nByte){
   ** two in order to create a new free block of size iLogsize.
   */
   for(iBin=iLogsize; mem5.aiFreelist[iBin]<0 && iBin<=LOGMAX; iBin++){}
-  if( iBin>LOGMAX ) return 0;
+  if( iBin>LOGMAX ){
+    testcase( sqlite3GlobalConfig.xLog!=0 );
+    sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes", nByte);
+    return 0;
+  }
   i = memsys5UnlinkFirst(iBin);
   while( iBin>iLogsize ){
     int newSize;
index 4dd451fedcfec54034bcf8c39ef9c2f2871a9be9..c4da1089791a70a6d45339be2ad011c90ea4bf4e 100644 (file)
@@ -1096,7 +1096,7 @@ static int transferOwnership(unixFile *pFile){
   }
   if( pFile->locktype!=NO_LOCK ){
     /* We cannot change ownership while we are holding a lock! */
-    return SQLITE_MISUSE;
+    return SQLITE_MISUSE_BKPT;
   }
   OSTRACE4("Transfer ownership of %d from %d to %d\n",
             pFile->h, pFile->tid, hSelf);
@@ -1543,7 +1543,7 @@ static int unixUnlock(sqlite3_file *id, int locktype){
     return SQLITE_OK;
   }
   if( CHECK_THREADID(pFile) ){
-    return SQLITE_MISUSE;
+    return SQLITE_MISUSE_BKPT;
   }
   unixEnterMutex();
   h = pFile->h;
@@ -2645,7 +2645,7 @@ static int afpUnlock(sqlite3_file *id, int locktype) {
     return SQLITE_OK;
   }
   if( CHECK_THREADID(pFile) ){
-    return SQLITE_MISUSE;
+    return SQLITE_MISUSE_BKPT;
   }
   unixEnterMutex();
   if( pFile->locktype>SHARED_LOCK ){
@@ -3695,7 +3695,7 @@ static int openDirectory(const char *zFilename, int *pFd){
     }
   }
   *pFd = fd;
-  return (fd>=0?SQLITE_OK:SQLITE_CANTOPEN);
+  return (fd>=0?SQLITE_OK:SQLITE_CANTOPEN_BKPT);
 }
 
 /*
@@ -3955,7 +3955,7 @@ static int unixOpen(
       fd = open(zName, openFlags, openMode);
     }
     if( fd<0 ){
-      rc = SQLITE_CANTOPEN;
+      rc = SQLITE_CANTOPEN_BKPT;
       goto open_finished;
     }
   }
@@ -4154,7 +4154,7 @@ static int unixFullPathname(
   }else{
     int nCwd;
     if( getcwd(zOut, nOut-1)==0 ){
-      return SQLITE_CANTOPEN;
+      return SQLITE_CANTOPEN_BKPT;
     }
     nCwd = (int)strlen(zOut);
     sqlite3_snprintf(nOut-nCwd, &zOut[nCwd], "/%s", zPath);
@@ -4740,6 +4740,50 @@ static int proxyCreateUnixFile(const char *path, unixFile **ppFile) {
   ** unixOpen() is NULL. This tells unixOpen() may try to open a proxy-file 
   ** for the proxy-file (creating a potential infinite loop).
   */
+  pUnused = findReusableFd(path, openFlags);
+  if( pUnused ){
+    fd = pUnused->fd;
+  }else{
+    pUnused = sqlite3_malloc(sizeof(*pUnused));
+    if( !pUnused ){
+      return SQLITE_NOMEM;
+    }
+  }
+  if( fd<0 ){
+    fd = open(path, openFlags, SQLITE_DEFAULT_FILE_PERMISSIONS);
+    terrno = errno;
+    if( fd<0 && errno==ENOENT && islockfile ){
+      if( proxyCreateLockPath(path) == SQLITE_OK ){
+        fd = open(path, openFlags, SQLITE_DEFAULT_FILE_PERMISSIONS);
+      }
+    }
+  }
+  if( fd<0 ){
+    openFlags = O_RDONLY;
+    fd = open(path, openFlags, SQLITE_DEFAULT_FILE_PERMISSIONS);
+    terrno = errno;
+  }
+  if( fd<0 ){
+    if( islockfile ){
+      return SQLITE_BUSY;
+    }
+    switch (terrno) {
+      case EACCES:
+        return SQLITE_PERM;
+      case EIO: 
+        return SQLITE_IOERR_LOCK; /* even though it is the conch */
+      default:
+        return SQLITE_CANTOPEN_BKPT;
+    }
+  }
+  
+  pNew = (unixFile *)sqlite3_malloc(sizeof(*pNew));
+  if( pNew==NULL ){
+    rc = SQLITE_NOMEM;
+    goto end_create_proxy;
+  }
+  memset(pNew, 0, sizeof(unixFile));
+  pNew->openFlags = openFlags;
   dummyVfs.pAppData = (void*)&autolockIoFinder;
   dummyVfs.xOpen = 0;
   rc = unixOpen(&dummyVfs, path, (sqlite3_file *)pNew, flags, &flags);
@@ -4904,11 +4948,150 @@ end_takeconch:
                      pCtx->lockProxyPath;
         }
       }
+>>>>>>> BEGIN MERGE CONFLICT
+      
+      /* if the conch isn't writable and doesn't match, we can't take it */
+      if( (conchFile->openFlags&O_RDWR) == 0 ){
+        rc = SQLITE_BUSY;
+        goto end_takeconch;
+      }
+      
+      /* either the conch didn't match or we need to create a new one */
+      if( !pCtx->lockProxyPath ){
+        proxyGetLockPath(pCtx->dbPath, lockPath, MAXPATHLEN);
+        tempLockPath = lockPath;
+        /* create a copy of the lock path _only_ if the conch is taken */
+      }
+      
+      /* update conch with host and path (this will fail if other process
+      ** has a shared lock already), if the host id matches, use the big
+      ** stick.
+      */
+      futimes(conchFile->h, NULL);
+      if( hostIdMatch && !createConch ){
+        if( conchFile->pLock && conchFile->pLock->cnt>1 ){
+          /* We are trying for an exclusive lock but another thread in this
+           ** same process is still holding a shared lock. */
+          rc = SQLITE_BUSY;
+        } else {          
+          rc = proxyConchLock(pFile, myHostID, EXCLUSIVE_LOCK);
+        }
+      }else{
+        rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, EXCLUSIVE_LOCK);
+      }
+      if( rc==SQLITE_OK ){
+        char writeBuffer[PROXY_MAXCONCHLEN];
+        int writeSize = 0;
+        
+        writeBuffer[0] = (char)PROXY_CONCHVERSION;
+        memcpy(&writeBuffer[PROXY_HEADERLEN], myHostID, PROXY_HOSTIDLEN);
+        if( pCtx->lockProxyPath!=NULL ){
+          strlcpy(&writeBuffer[PROXY_PATHINDEX], pCtx->lockProxyPath, MAXPATHLEN);
+        }else{
+          strlcpy(&writeBuffer[PROXY_PATHINDEX], tempLockPath, MAXPATHLEN);
+        }
+        writeSize = PROXY_PATHINDEX + strlen(&writeBuffer[PROXY_PATHINDEX]);
+        ftruncate(conchFile->h, writeSize);
+        rc = unixWrite((sqlite3_file *)conchFile, writeBuffer, writeSize, 0);
+        fsync(conchFile->h);
+        /* If we created a new conch file (not just updated the contents of a 
+         ** valid conch file), try to match the permissions of the database 
+         */
+        if( rc==SQLITE_OK && createConch ){
+          struct stat buf;
+          int err = fstat(pFile->h, &buf);
+          if( err==0 ){
+            mode_t cmode = buf.st_mode&(S_IRUSR|S_IWUSR | S_IRGRP|S_IWGRP |
+                                        S_IROTH|S_IWOTH);
+            /* try to match the database file R/W permissions, ignore failure */
+#ifndef SQLITE_PROXY_DEBUG
+            fchmod(conchFile->h, cmode);
+#else
+            if( fchmod(conchFile->h, cmode)!=0 ){
+              int code = errno;
+              fprintf(stderr, "fchmod %o FAILED with %d %s\n",
+                      cmode, code, strerror(code));
+            } else {
+              fprintf(stderr, "fchmod %o SUCCEDED\n",cmode);
+            }
+          }else{
+            int code = errno;
+            fprintf(stderr, "STAT FAILED[%d] with %d %s\n", 
+                    err, code, strerror(code));
+#endif
+          }
+        }
+      }
+      conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, SHARED_LOCK);
+      
+    end_takeconch:
+      OSTRACE2("TRANSPROXY: CLOSE  %d\n", pFile->h);
+      if( rc==SQLITE_OK && pFile->openFlags ){
+        if( pFile->h>=0 ){
+#ifdef STRICT_CLOSE_ERROR
+          if( close(pFile->h) ){
+            pFile->lastErrno = errno;
+            return SQLITE_IOERR_CLOSE;
+          }
+#else
+          close(pFile->h); /* silently leak fd if fail */
+#endif
+        }
+        pFile->h = -1;
+        int fd = open(pCtx->dbPath, pFile->openFlags,
+                      SQLITE_DEFAULT_FILE_PERMISSIONS);
+        OSTRACE2("TRANSPROXY: OPEN  %d\n", fd);
+        if( fd>=0 ){
+          pFile->h = fd;
+        }else{
+          rc=SQLITE_CANTOPEN_BKPT; /* SQLITE_BUSY? proxyTakeConch called
+           during locking */
+        }
+      }
+      if( rc==SQLITE_OK && !pCtx->lockProxy ){
+        char *path = tempLockPath ? tempLockPath : pCtx->lockProxyPath;
+        rc = proxyCreateUnixFile(path, &pCtx->lockProxy, 1);
+        if( rc!=SQLITE_OK && rc!=SQLITE_NOMEM && tryOldLockPath ){
+          /* we couldn't create the proxy lock file with the old lock file path
+           ** so try again via auto-naming 
+           */
+          forceNewLockPath = 1;
+          tryOldLockPath = 0;
+          continue; /* go back to the do {} while start point, try again */
+        }
+      }
+      if( rc==SQLITE_OK ){
+        /* Need to make a copy of path if we extracted the value
+         ** from the conch file or the path was allocated on the stack
+         */
+        if( tempLockPath ){
+          pCtx->lockProxyPath = sqlite3DbStrDup(0, tempLockPath);
+          if( !pCtx->lockProxyPath ){
+            rc = SQLITE_NOMEM;
+          }
+        }
+      }
+      if( rc==SQLITE_OK ){
+        pCtx->conchHeld = 1;
+        
+        if( pCtx->lockProxy->pMethod == &afpIoMethods ){
+          afpLockingContext *afpCtx;
+          afpCtx = (afpLockingContext *)pCtx->lockProxy->lockingContext;
+          afpCtx->dbPath = pCtx->lockProxyPath;
+        }
+      } else {
+        conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, NO_LOCK);
+      }
+      OSTRACE3("TAKECONCH  %d %s\n", conchFile->h, rc==SQLITE_OK?"ok":"failed");
+      return rc;
+    } while (1); /* in case we need to retry the :auto: lock file - we should never get here except via the 'continue' call. */
+============================
     } else {
       conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, NO_LOCK);
     }
     OSTRACE3("TAKECONCH  %d %s\n", conchFile->h, rc==SQLITE_OK?"ok":"failed");
     return rc;
+<<<<<<< END MERGE CONFLICT
   }
 }
 
index bd23a848d3e3de7d74723be8ff5fe449a332bced..4721eadff85bb0bdb55a71ddd874208c69da5d00 100644 (file)
@@ -1417,7 +1417,7 @@ static int winOpen(
       return winOpen(pVfs, zName, id, 
              ((flags|SQLITE_OPEN_READONLY)&~SQLITE_OPEN_READWRITE), pOutFlags);
     }else{
-      return SQLITE_CANTOPEN;
+      return SQLITE_CANTOPEN_BKPT;
     }
   }
   if( pOutFlags ){
@@ -1439,7 +1439,7 @@ static int winOpen(
   ){
     CloseHandle(h);
     free(zConverted);
-    return SQLITE_CANTOPEN;
+    return SQLITE_CANTOPEN_BKPT;
   }
   if( isTemp ){
     pFile->zDeleteOnClose = zConverted;
index a79537ab132a8f3b11b4471015d74b9cb7ad2755..70bba0fab99ff5e78ab4f074261a6bbb9f37d899 100644 (file)
@@ -3164,7 +3164,7 @@ int sqlite3PagerOpen(
       ** as it will not be possible to open the journal file or even
       ** check for a hot-journal before reading.
       */
-      rc = SQLITE_CANTOPEN;
+      rc = SQLITE_CANTOPEN_BKPT;
     }
     if( rc!=SQLITE_OK ){
       sqlite3_free(zPathname);
@@ -3623,7 +3623,7 @@ int sqlite3PagerSharedLock(Pager *pPager){
             rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &fout);
             assert( rc!=SQLITE_OK || isOpen(pPager->jfd) );
             if( rc==SQLITE_OK && fout&SQLITE_OPEN_READONLY ){
-              rc = SQLITE_CANTOPEN;
+              rc = SQLITE_CANTOPEN_BKPT;
               sqlite3OsClose(pPager->jfd);
             }
           }else{
index 29f83e580880909accbf2fd8d811cb8ce9757861..01f010c9e87a0405a05646495be97b33bdab059c 100644 (file)
@@ -192,9 +192,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
   initData.iDb = iDb;
   initData.rc = SQLITE_OK;
   initData.pzErrMsg = pzErrMsg;
-  (void)sqlite3SafetyOff(db);
   sqlite3InitCallback(&initData, 3, (char **)azArg, 0);
-  (void)sqlite3SafetyOn(db);
   if( initData.rc ){
     rc = initData.rc;
     goto error_out;
@@ -317,7 +315,6 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
     zSql = sqlite3MPrintf(db, 
         "SELECT name, rootpage, sql FROM '%q'.%s",
         db->aDb[iDb].zName, zMasterName);
-    (void)sqlite3SafetyOff(db);
 #ifndef SQLITE_OMIT_AUTHORIZATION
     {
       int (*xAuth)(void*,int,const char*,const char*,const char*,const char*);
@@ -330,7 +327,6 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
     }
 #endif
     if( rc==SQLITE_OK ) rc = initData.rc;
-    (void)sqlite3SafetyOn(db);
     sqlite3DbFree(db, zSql);
 #ifndef SQLITE_OMIT_ANALYZE
     if( rc==SQLITE_OK ){
@@ -539,11 +535,6 @@ static int sqlite3Prepare(
     goto end_prepare;
   }
   pParse->pReprepare = pReprepare;
-
-  if( sqlite3SafetyOn(db) ){
-    rc = SQLITE_MISUSE;
-    goto end_prepare;
-  }
   assert( ppStmt && *ppStmt==0 );
   assert( !db->mallocFailed );
   assert( sqlite3_mutex_held(db->mutex) );
@@ -579,7 +570,6 @@ static int sqlite3Prepare(
       if( rc ){
         const char *zDb = db->aDb[i].zName;
         sqlite3Error(db, rc, "database schema is locked: %s", zDb);
-        (void)sqlite3SafetyOff(db);
         testcase( db->flags & SQLITE_ReadUncommitted );
         goto end_prepare;
       }
@@ -596,7 +586,6 @@ static int sqlite3Prepare(
     testcase( nBytes==mxLen+1 );
     if( nBytes>mxLen ){
       sqlite3Error(db, SQLITE_TOOBIG, "statement too long");
-      (void)sqlite3SafetyOff(db);
       rc = sqlite3ApiExit(db, SQLITE_TOOBIG);
       goto end_prepare;
     }
@@ -653,10 +642,6 @@ static int sqlite3Prepare(
   }
 #endif
 
-  if( sqlite3SafetyOff(db) ){
-    rc = SQLITE_MISUSE;
-  }
-
   assert( db->init.busy==0 || saveSqlFlag==0 );
   if( db->init.busy==0 ){
     Vdbe *pVdbe = pParse->pVdbe;
@@ -704,7 +689,7 @@ static int sqlite3LockAndPrepare(
   assert( ppStmt!=0 );
   *ppStmt = 0;
   if( !sqlite3SafetyCheckOk(db) ){
-    return SQLITE_MISUSE;
+    return SQLITE_MISUSE_BKPT;
   }
   sqlite3_mutex_enter(db->mutex);
   sqlite3BtreeEnterAll(db);
@@ -743,7 +728,7 @@ int sqlite3Reprepare(Vdbe *p){
       db->mallocFailed = 1;
     }
     assert( pNew==0 );
-    return (rc==SQLITE_LOCKED) ? SQLITE_LOCKED : SQLITE_SCHEMA;
+    return rc;
   }else{
     assert( pNew!=0 );
   }
@@ -812,7 +797,7 @@ static int sqlite3Prepare16(
   assert( ppStmt );
   *ppStmt = 0;
   if( !sqlite3SafetyCheckOk(db) ){
-    return SQLITE_MISUSE;
+    return SQLITE_MISUSE_BKPT;
   }
   sqlite3_mutex_enter(db->mutex);
   zSql8 = sqlite3Utf16to8(db, zSql, nBytes);
index 17edb0907045b878226343dd073711c9b71f776a..497aaf61943548bdb335c95f1a1b8996612c7126 100644 (file)
@@ -937,6 +937,28 @@ char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){
   return z;
 }
 
+/*
+** Format and write a message to the log if logging is enabled.
+*/
+void sqlite3_log(int iErrCode, const char *zFormat, ...){
+  void (*xLog)(void*, int, const char*);  /* The global logger function */
+  void *pLogArg;                          /* First argument to the logger */
+  va_list ap;                             /* Vararg list */
+  char *zMsg;                             /* Complete log message */
+  
+  xLog = sqlite3GlobalConfig.xLog;
+  if( xLog && zFormat ){
+    va_start(ap, zFormat);
+    sqlite3BeginBenignMalloc();
+    zMsg = sqlite3_vmprintf(zFormat, ap);
+    sqlite3EndBenignMalloc();
+    va_end(ap);
+    pLogArg = sqlite3GlobalConfig.pLogArg;
+    xLog(pLogArg, iErrCode, zMsg ? zMsg : zFormat);
+    sqlite3_free(zMsg);
+  }
+}
+
 #if defined(SQLITE_DEBUG)
 /*
 ** A version of printf() that understands %lld.  Used for debugging.
index 26a6cc03eb34872bbff6013d4cabe8f27f19862d..6628b02d73df2b8f34cfa09450fde2b4b54b787f 100644 (file)
@@ -664,6 +664,9 @@ static int resolveOrderByTermToExprList(
   int i;             /* Loop counter */
   ExprList *pEList;  /* The columns of the result set */
   NameContext nc;    /* Name context for resolving pE */
+  sqlite3 *db;       /* Database connection */
+  int rc;            /* Return code from subprocedures */
+  u8 savedSuppErr;   /* Saved value of db->suppressErr */
 
   assert( sqlite3ExprIsInteger(pE, &i)==0 );
   pEList = pSelect->pEList;
@@ -676,10 +679,12 @@ static int resolveOrderByTermToExprList(
   nc.pEList = pEList;
   nc.allowAgg = 1;
   nc.nErr = 0;
-  if( sqlite3ResolveExprNames(&nc, pE) ){
-    sqlite3ErrorClear(pParse);
-    return 0;
-  }
+  db = pParse->db;
+  savedSuppErr = db->suppressErr;
+  db->suppressErr = 1;
+  rc = sqlite3ResolveExprNames(&nc, pE);
+  db->suppressErr = savedSuppErr;
+  if( rc ) return 0;
 
   /* Try to match the ORDER BY expression against an expression
   ** in the result set.  Return an 1-based index of the matching
index 8c7a91f08da60c3bf72abb4dc6dc764c2fe94065..c72b78d194371090756c64c628b9e613934d628e 100644 (file)
@@ -1277,6 +1277,7 @@ struct callback_data {
   char outfile[FILENAME_MAX]; /* Filename for *out */
   const char *zDbFilename;    /* name of the database file */
   sqlite3_stmt *pStmt;   /* Current statement if any. */
+  FILE *pLog;            /* Write log output here */
 };
 
 /*
@@ -1319,6 +1320,16 @@ static int strlen30(const char *z){
   return 0x3fffffff & (int)(z2 - z);
 }
 
+/*
+** A callback for the sqlite3_log() interface.
+*/
+static void shellLog(void *pArg, int iErrCode, const char *zMsg){
+  struct callback_data *p = (struct callback_data*)pArg;
+  if( p->pLog==0 ) return;
+  fprintf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
+  fflush(p->pLog);
+}
+
 /*
 ** Output the given string as a hex-encoded blob (eg. X'1234' )
 */
@@ -2147,6 +2158,7 @@ static char zHelp[] =
 #ifndef SQLITE_OMIT_LOAD_EXTENSION
   ".load FILE ?ENTRY?     Load an extension library\n"
 #endif
+  ".log FILE|off          Turn logging on or off.  FILE can be stderr/stdout\n"
   ".mode MODE ?TABLE?     Set output mode where MODE is one of:\n"
   "                         csv      Comma-separated values\n"
   "                         column   Left-aligned columns.  (See .width)\n"
@@ -2673,6 +2685,26 @@ static int do_meta_command(char *zLine, struct callback_data *p){
   }else
 #endif
 
+  if( c=='l' && strncmp(azArg[0], "log", n)==0 && nArg>=1 ){
+    const char *zFile = azArg[1];
+    if( p->pLog && p->pLog!=stdout && p->pLog!=stderr ){
+      fclose(p->pLog);
+      p->pLog = 0;
+    }
+    if( strcmp(zFile,"stdout")==0 ){
+      p->pLog = stdout;
+    }else if( strcmp(zFile, "stderr")==0 ){
+      p->pLog = stderr;
+    }else if( strcmp(zFile, "off")==0 ){
+      p->pLog = 0;
+    }else{
+      p->pLog = fopen(zFile, "w");
+      if( p->pLog==0 ){
+        fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
+      }
+    }
+  }else
+
   if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==2 ){
     int n2 = strlen30(azArg[1]);
     if( (n2==4 && strncmp(azArg[1],"line",n2)==0)
@@ -3318,6 +3350,7 @@ static void main_init(struct callback_data *data) {
   data->mode = MODE_List;
   memcpy(data->separator,"|", 2);
   data->showHeader = 0;
+  sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
   sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
   sqlite3_snprintf(sizeof(continuePrompt), continuePrompt,"   ...> ");
 }
index 3bbb714588113aeae9d72fb21f4185555fb7f887..bbeafa9d3cb4f9ad8abec67224fae66432ec9bae 100644 (file)
@@ -913,7 +913,6 @@ int sqlite3_os_end(void);
 
 /*
 ** CAPI3REF: Configuring The SQLite Library
-** EXPERIMENTAL
 **
 ** The sqlite3_config() interface is used to make global configuration
 ** changes to SQLite in order to tune SQLite to the specific needs of
@@ -1254,6 +1253,7 @@ struct sqlite3_mem_methods {
 #define SQLITE_CONFIG_LOOKASIDE    13  /* int int */
 #define SQLITE_CONFIG_PCACHE       14  /* sqlite3_pcache_methods* */
 #define SQLITE_CONFIG_GETPCACHE    15  /* sqlite3_pcache_methods* */
+#define SQLITE_CONFIG_LOG          16  /* xFunc, void* */
 
 /*
 ** CAPI3REF: Configuration Options
@@ -5642,6 +5642,20 @@ int sqlite3_unlock_notify(
 */
 int sqlite3_strnicmp(const char *, const char *, int);
 
+/*
+** CAPI3REF: Error Logging Interface
+** EXPERIMENTAL
+**
+** ^The [sqlite3_log()] interface writes a message into the error log
+** established by the [SQLITE_CONFIG_ERRORLOG] option to [sqlite3_config()].
+**
+** The sqlite3_log() interface is intended for use by extensions such as
+** virtual tables, collating functions, and SQL functions.  While there is
+** nothing to prevent an application from calling sqlite3_log(), doing so
+** is considered bad form.
+*/
+void sqlite3_log(int iErrCode, const char *zFormat, ...);
+
 /*
 ** Undo the hack that converts floating point types to integer for
 ** builds on processors without floating point support.
index f9a732cabb6d65abb6b08d766b0ffd1a1c70a85b..8620d2d2ec531c56a6d02f7165eb99a21eec3cb0 100644 (file)
@@ -804,6 +804,7 @@ struct sqlite3 {
   u8 dfltLockMode;              /* Default locking-mode for attached dbs */
   u8 dfltJournalMode;           /* Default journal mode for attached dbs */
   signed char nextAutovac;      /* Autovac setting after VACUUM if >=0 */
+  u8 suppressErr;               /* Do not issue error messages if true */
   int nextPagesize;             /* Pagesize after VACUUM if >0 */
   int nTable;                   /* Number of tables in the database */
   CollSeq *pDfltColl;           /* The default collating sequence (BINARY) */
@@ -2380,6 +2381,8 @@ struct Sqlite3Config {
   int isPCacheInit;                 /* True after malloc is initialized */
   sqlite3_mutex *pInitMutex;        /* Mutex used by sqlite3_initialize() */
   int nRefInitMutex;                /* Number of users of pInitMutex */
+  void (*xLog)(void*,int,const char*); /* Function for logging */
+  void *pLogArg;                       /* First argument to xLog() */
 };
 
 /*
@@ -2421,17 +2424,19 @@ int sqlite3WalkSelectFrom(Walker*, Select*);
 }
 
 /*
-** The SQLITE_CORRUPT_BKPT macro can be either a constant (for production
-** builds) or a function call (for debugging).  If it is a function call,
-** it allows the operator to set a breakpoint at the spot where database
-** corruption is first detected.
+** The SQLITE_*_BKPT macros are substitutes for the error codes with
+** the same name but without the _BKPT suffix.  These macros invoke
+** routines that report the line-number on which the error originated
+** using sqlite3_log().  The routines also provide a convenient place
+** to set a debugger breakpoint.
 */
-#ifdef SQLITE_DEBUG
-  int sqlite3Corrupt(void);
-# define SQLITE_CORRUPT_BKPT sqlite3Corrupt()
-#else
-# define SQLITE_CORRUPT_BKPT SQLITE_CORRUPT
-#endif
+int sqlite3CorruptError(int);
+int sqlite3MisuseError(int);
+int sqlite3CantopenError(int);
+#define SQLITE_CORRUPT_BKPT sqlite3CorruptError(__LINE__)
+#define SQLITE_MISUSE_BKPT sqlite3MisuseError(__LINE__)
+#define SQLITE_CANTOPEN_BKPT sqlite3CantopenError(__LINE__)
+
 
 /*
 ** The ctype.h header is needed for non-ASCII systems.  It is also
@@ -2549,7 +2554,6 @@ char *sqlite3MAppendf(sqlite3*,char*,const char*,...);
 #endif
 void sqlite3SetString(char **, sqlite3*, const char*, ...);
 void sqlite3ErrorMsg(Parse*, const char*, ...);
-void sqlite3ErrorClear(Parse*);
 int sqlite3Dequote(char*);
 int sqlite3KeywordCode(const unsigned char*, int);
 int sqlite3RunParser(Parse*, const char*, char **);
@@ -2719,13 +2723,6 @@ FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,int,u8,int);
 void sqlite3RegisterBuiltinFunctions(sqlite3*);
 void sqlite3RegisterDateTimeFunctions(void);
 void sqlite3RegisterGlobalFunctions(void);
-#ifdef SQLITE_DEBUG
-  int sqlite3SafetyOn(sqlite3*);
-  int sqlite3SafetyOff(sqlite3*);
-#else
-# define sqlite3SafetyOn(A) 0
-# define sqlite3SafetyOff(A) 0
-#endif
 int sqlite3SafetyCheckOk(sqlite3*);
 int sqlite3SafetyCheckSickOrOk(sqlite3*);
 void sqlite3ChangeCookie(Parse*, int);
index 58a7e68c19e16cb96663574c70610be18fa7f852..f4c77a910959ff01e3273a62ab4c1ca0c4016e5d 100644 (file)
@@ -83,7 +83,7 @@ void sqlite3StatusSet(int op, int X){
 int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag){
   wsdStatInit;
   if( op<0 || op>=ArraySize(wsdStat.nowValue) ){
-    return SQLITE_MISUSE;
+    return SQLITE_MISUSE_BKPT;
   }
   *pCurrent = wsdStat.nowValue[op];
   *pHighwater = wsdStat.mxValue[op];
index a93eeaa7819f241e074f024551ced5587230fe94..4b40770d53fd0ab5fb109633a29b60b32e277b2d 100644 (file)
@@ -480,6 +480,7 @@ abort_parse:
   assert( pzErrMsg!=0 );
   if( pParse->zErrMsg ){
     *pzErrMsg = pParse->zErrMsg;
+    sqlite3_log(pParse->rc, "%s", *pzErrMsg);
     pParse->zErrMsg = 0;
     nErr++;
   }
index 81e42b4ae500a786c0a19b3424509a42ea49695d..3a6cef9f62d509af950585038a48ff36a45f465a 100644 (file)
@@ -146,23 +146,20 @@ void sqlite3Error(sqlite3 *db, int err_code, const char *zFormat, ...){
 ** (sqlite3_step() etc.).
 */
 void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){
+  char *zMsg;
   va_list ap;
   sqlite3 *db = pParse->db;
-  pParse->nErr++;
-  sqlite3DbFree(db, pParse->zErrMsg);
   va_start(ap, zFormat);
-  pParse->zErrMsg = sqlite3VMPrintf(db, zFormat, ap);
+  zMsg = sqlite3VMPrintf(db, zFormat, ap);
   va_end(ap);
-  pParse->rc = SQLITE_ERROR;
-}
-
-/*
-** Clear the error message in pParse, if any
-*/
-void sqlite3ErrorClear(Parse *pParse){
-  sqlite3DbFree(pParse->db, pParse->zErrMsg);
-  pParse->zErrMsg = 0;
-  pParse->nErr = 0;
+  if( db->suppressErr ){
+    sqlite3DbFree(db, zMsg);
+  }else{
+    pParse->nErr++;
+    sqlite3DbFree(db, pParse->zErrMsg);
+    pParse->zErrMsg = zMsg;
+    pParse->rc = SQLITE_ERROR;
+  }
 }
 
 /*
@@ -997,64 +994,17 @@ void *sqlite3HexToBlob(sqlite3 *db, const char *z, int n){
 }
 #endif /* !SQLITE_OMIT_BLOB_LITERAL || SQLITE_HAS_CODEC */
 
-
-/*
-** Change the sqlite.magic from SQLITE_MAGIC_OPEN to SQLITE_MAGIC_BUSY.
-** Return an error (non-zero) if the magic was not SQLITE_MAGIC_OPEN
-** when this routine is called.
-**
-** This routine is called when entering an SQLite API.  The SQLITE_MAGIC_OPEN
-** value indicates that the database connection passed into the API is
-** open and is not being used by another thread.  By changing the value
-** to SQLITE_MAGIC_BUSY we indicate that the connection is in use.
-** sqlite3SafetyOff() below will change the value back to SQLITE_MAGIC_OPEN
-** when the API exits. 
-**
-** This routine is a attempt to detect if two threads use the
-** same sqlite* pointer at the same time.  There is a race 
-** condition so it is possible that the error is not detected.
-** But usually the problem will be seen.  The result will be an
-** error which can be used to debug the application that is
-** using SQLite incorrectly.
-**
-** Ticket #202:  If db->magic is not a valid open value, take care not
-** to modify the db structure at all.  It could be that db is a stale
-** pointer.  In other words, it could be that there has been a prior
-** call to sqlite3_close(db) and db has been deallocated.  And we do
-** not want to write into deallocated memory.
-*/
-#ifdef SQLITE_DEBUG
-int sqlite3SafetyOn(sqlite3 *db){
-  if( db->magic==SQLITE_MAGIC_OPEN ){
-    db->magic = SQLITE_MAGIC_BUSY;
-    assert( sqlite3_mutex_held(db->mutex) );
-    return 0;
-  }else if( db->magic==SQLITE_MAGIC_BUSY ){
-    db->magic = SQLITE_MAGIC_ERROR;
-    db->u1.isInterrupted = 1;
-  }
-  return 1;
-}
-#endif
-
 /*
-** Change the magic from SQLITE_MAGIC_BUSY to SQLITE_MAGIC_OPEN.
-** Return an error (non-zero) if the magic was not SQLITE_MAGIC_BUSY
-** when this routine is called.
+** Log an error that is an API call on a connection pointer that should
+** not have been used.  The "type" of connection pointer is given as the
+** argument.  The zType is a word like "NULL" or "closed" or "invalid".
 */
-#ifdef SQLITE_DEBUG
-int sqlite3SafetyOff(sqlite3 *db){
-  if( db->magic==SQLITE_MAGIC_BUSY ){
-    db->magic = SQLITE_MAGIC_OPEN;
-    assert( sqlite3_mutex_held(db->mutex) );
-    return 0;
-  }else{
-    db->magic = SQLITE_MAGIC_ERROR;
-    db->u1.isInterrupted = 1;
-    return 1;
-  }
+static void logBadConnection(const char *zType){
+  sqlite3_log(SQLITE_MISUSE, 
+     "API call with %s database connection pointer",
+     zType
+  );
 }
-#endif
 
 /*
 ** Check to make sure we have a valid db pointer.  This test is not
@@ -1072,13 +1022,15 @@ int sqlite3SafetyOff(sqlite3 *db){
 */
 int sqlite3SafetyCheckOk(sqlite3 *db){
   u32 magic;
-  if( db==0 ) return 0;
+  if( db==0 ){
+    logBadConnection("NULL");
+    return 0;
+  }
   magic = db->magic;
-  if( magic!=SQLITE_MAGIC_OPEN 
-#ifdef SQLITE_DEBUG
-     && magic!=SQLITE_MAGIC_BUSY
-#endif
-  ){
+  if( magic!=SQLITE_MAGIC_OPEN ){
+    if( !sqlite3SafetyCheckSickOrOk(db) ){
+      logBadConnection("unopened");
+    }
     return 0;
   }else{
     return 1;
@@ -1089,6 +1041,10 @@ int sqlite3SafetyCheckSickOrOk(sqlite3 *db){
   magic = db->magic;
   if( magic!=SQLITE_MAGIC_SICK &&
       magic!=SQLITE_MAGIC_OPEN &&
-      magic!=SQLITE_MAGIC_BUSY ) return 0;
-  return 1;
+      magic!=SQLITE_MAGIC_BUSY ){
+    logBadConnection("invalid");
+    return 0;
+  }else{
+    return 1;
+  }
 }
index c44a236def1afaede3f9ab8f90b00f18debfcebd..3140ab633f775b794391d9a486266fd5e2369841 100644 (file)
 #include "vdbeInt.h"
 
 #if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH)
+/*
+** Finalize a prepared statement.  If there was an error, store the
+** text of the error message in *pzErrMsg.  Return the result code.
+*/
+static int vacuumFinalize(sqlite3 *db, sqlite3_stmt *pStmt, char **pzErrMsg){
+  int rc;
+  rc = sqlite3VdbeFinalize((Vdbe*)pStmt);
+  if( rc ){
+    sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db));
+  }
+  return rc;
+}
+
 /*
 ** Execute zSql on database db. Return an error code.
 */
-static int execSql(sqlite3 *db, const char *zSql){
+static int execSql(sqlite3 *db, char **pzErrMsg, const char *zSql){
   sqlite3_stmt *pStmt;
   VVA_ONLY( int rc; )
   if( !zSql ){
     return SQLITE_NOMEM;
   }
   if( SQLITE_OK!=sqlite3_prepare(db, zSql, -1, &pStmt, 0) ){
+    sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db));
     return sqlite3_errcode(db);
   }
   VVA_ONLY( rc = ) sqlite3_step(pStmt);
   assert( rc!=SQLITE_ROW );
-  return sqlite3_finalize(pStmt);
+  return vacuumFinalize(db, pStmt, pzErrMsg);
 }
 
 /*
 ** Execute zSql on database db. The statement returns exactly
 ** one column. Execute this as SQL on the same database.
 */
-static int execExecSql(sqlite3 *db, const char *zSql){
+static int execExecSql(sqlite3 *db, char **pzErrMsg, const char *zSql){
   sqlite3_stmt *pStmt;
   int rc;
 
@@ -47,14 +61,14 @@ static int execExecSql(sqlite3 *db, const char *zSql){
   if( rc!=SQLITE_OK ) return rc;
 
   while( SQLITE_ROW==sqlite3_step(pStmt) ){
-    rc = execSql(db, (char*)sqlite3_column_text(pStmt, 0));
+    rc = execSql(db, pzErrMsg, (char*)sqlite3_column_text(pStmt, 0));
     if( rc!=SQLITE_OK ){
-      sqlite3_finalize(pStmt);
+      vacuumFinalize(db, pStmt, pzErrMsg);
       return rc;
     }
   }
 
-  return sqlite3_finalize(pStmt);
+  return vacuumFinalize(db, pStmt, pzErrMsg);
 }
 
 /*
@@ -125,7 +139,7 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
   ** to write the journal header file.
   */
   zSql = "ATTACH '' AS vacuum_db;";
-  rc = execSql(db, zSql);
+  rc = execSql(db, pzErrMsg, zSql);
   if( rc!=SQLITE_OK ) goto end_of_vacuum;
   pDb = &db->aDb[db->nDb-1];
   assert( strcmp(db->aDb[db->nDb-1].zName,"vacuum_db")==0 );
@@ -157,7 +171,7 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
     rc = SQLITE_NOMEM;
     goto end_of_vacuum;
   }
-  rc = execSql(db, "PRAGMA vacuum_db.synchronous=OFF");
+  rc = execSql(db, pzErrMsg, "PRAGMA vacuum_db.synchronous=OFF");
   if( rc!=SQLITE_OK ){
     goto end_of_vacuum;
   }
@@ -168,23 +182,23 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
 #endif
 
   /* Begin a transaction */
-  rc = execSql(db, "BEGIN EXCLUSIVE;");
+  rc = execSql(db, pzErrMsg, "BEGIN EXCLUSIVE;");
   if( rc!=SQLITE_OK ) goto end_of_vacuum;
 
   /* Query the schema of the main database. Create a mirror schema
   ** in the temporary database.
   */
-  rc = execExecSql(db, 
+  rc = execExecSql(db, pzErrMsg,
       "SELECT 'CREATE TABLE vacuum_db.' || substr(sql,14) "
       "  FROM sqlite_master WHERE type='table' AND name!='sqlite_sequence'"
       "   AND rootpage>0"
   );
   if( rc!=SQLITE_OK ) goto end_of_vacuum;
-  rc = execExecSql(db, 
+  rc = execExecSql(db, pzErrMsg,
       "SELECT 'CREATE INDEX vacuum_db.' || substr(sql,14)"
       "  FROM sqlite_master WHERE sql LIKE 'CREATE INDEX %' ");
   if( rc!=SQLITE_OK ) goto end_of_vacuum;
-  rc = execExecSql(db, 
+  rc = execExecSql(db, pzErrMsg,
       "SELECT 'CREATE UNIQUE INDEX vacuum_db.' || substr(sql,21) "
       "  FROM sqlite_master WHERE sql LIKE 'CREATE UNIQUE INDEX %'");
   if( rc!=SQLITE_OK ) goto end_of_vacuum;
@@ -193,24 +207,23 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
   ** an "INSERT INTO vacuum_db.xxx SELECT * FROM main.xxx;" to copy
   ** the contents to the temporary database.
   */
-  rc = execExecSql(db, 
+  rc = execExecSql(db, pzErrMsg,
       "SELECT 'INSERT INTO vacuum_db.' || quote(name) "
       "|| ' SELECT * FROM main.' || quote(name) || ';'"
       "FROM main.sqlite_master "
       "WHERE type = 'table' AND name!='sqlite_sequence' "
       "  AND rootpage>0"
-
   );
   if( rc!=SQLITE_OK ) goto end_of_vacuum;
 
   /* Copy over the sequence table
   */
-  rc = execExecSql(db, 
+  rc = execExecSql(db, pzErrMsg,
       "SELECT 'DELETE FROM vacuum_db.' || quote(name) || ';' "
       "FROM vacuum_db.sqlite_master WHERE name='sqlite_sequence' "
   );
   if( rc!=SQLITE_OK ) goto end_of_vacuum;
-  rc = execExecSql(db, 
+  rc = execExecSql(db, pzErrMsg,
       "SELECT 'INSERT INTO vacuum_db.' || quote(name) "
       "|| ' SELECT * FROM main.' || quote(name) || ';' "
       "FROM vacuum_db.sqlite_master WHERE name=='sqlite_sequence';"
@@ -223,7 +236,7 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
   ** associated storage, so all we have to do is copy their entries
   ** from the SQLITE_MASTER table.
   */
-  rc = execSql(db,
+  rc = execSql(db, pzErrMsg,
       "INSERT INTO vacuum_db.sqlite_master "
       "  SELECT type, name, tbl_name, rootpage, sql"
       "    FROM main.sqlite_master"
index 504d05593e517443e8c768182f34b1d75fb65d0d..c7288257025e4fc96e483bbb9aedf314b718ebce 100644 (file)
@@ -563,7 +563,6 @@ int sqlite3VdbeExec(
   /*** INSERT STACK UNION HERE ***/
 
   assert( p->magic==VDBE_MAGIC_RUN );  /* sqlite3_step() verifies this */
-  assert( db->magic==SQLITE_MAGIC_BUSY );
   sqlite3VdbeMutexArrayEnter(p);
   if( p->rc==SQLITE_NOMEM ){
     /* This happens if a malloc() inside a call to sqlite3_column_text() or
@@ -648,9 +647,7 @@ int sqlite3VdbeExec(
     if( checkProgress ){
       if( db->nProgressOps==nProgressOps ){
         int prc;
-        if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
-        prc =db->xProgress(db->pProgressArg);
-        if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
+        prc = db->xProgress(db->pProgressArg);
         if( prc!=0 ){
           rc = SQLITE_INTERRUPT;
           goto vdbe_error_halt;
@@ -850,7 +847,13 @@ case OP_Halt: {
   p->errorAction = (u8)pOp->p2;
   p->pc = pc;
   if( pOp->p4.z ){
+    assert( p->rc!=SQLITE_OK );
     sqlite3SetString(&p->zErrMsg, db, "%s", pOp->p4.z);
+    testcase( sqlite3GlobalConfig.xLog!=0 );
+    sqlite3_log(pOp->p1, "abort at %d in [%s]: %s", pc, p->zSql, pOp->p4.z);
+  }else if( p->rc ){
+    testcase( sqlite3GlobalConfig.xLog!=0 );
+    sqlite3_log(pOp->p1, "constraint failed at %d in [%s]", pc, p->zSql);
   }
   rc = sqlite3VdbeHalt(p);
   assert( rc==SQLITE_BUSY || rc==SQLITE_OK || rc==SQLITE_ERROR );
@@ -1393,21 +1396,12 @@ case OP_Function: {
     assert( pOp[-1].opcode==OP_CollSeq );
     ctx.pColl = pOp[-1].p4.pColl;
   }
-  if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
   (*ctx.pFunc->xFunc)(&ctx, n, apVal);
-  if( sqlite3SafetyOn(db) ){
-    sqlite3VdbeMemRelease(&ctx.s);
-    goto abort_due_to_misuse;
-  }
   if( db->mallocFailed ){
     /* Even though a malloc() has failed, the implementation of the
     ** user function may have called an sqlite3_result_XXX() function
     ** to return a value. The following call releases any resources
     ** associated with such a value.
-    **
-    ** Note: Maybe MemRelease() should be called if sqlite3SafetyOn()
-    ** fails also (the if(...) statement above). But if people are
-    ** misusing sqlite, they have bigger problems than a leaked value.
     */
     sqlite3VdbeMemRelease(&ctx.s);
     goto no_mem;
@@ -4040,12 +4034,10 @@ case OP_Rowid: {                 /* out2-prerelease */
     pVtab = pC->pVtabCursor->pVtab;
     pModule = pVtab->pModule;
     assert( pModule->xRowid );
-    if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
     rc = pModule->xRowid(pC->pVtabCursor, &v);
     sqlite3DbFree(db, p->zErrMsg);
     p->zErrMsg = pVtab->zErrMsg;
     pVtab->zErrMsg = 0;
-    if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
 #endif /* SQLITE_OMIT_VIRTUALTABLE */
   }else{
     assert( pC->pCursor!=0 );
@@ -4581,7 +4573,6 @@ case OP_ParseSchema: {
     if( zSql==0 ){
       rc = SQLITE_NOMEM;
     }else{
-      (void)sqlite3SafetyOff(db);
       assert( db->init.busy==0 );
       db->init.busy = 1;
       initData.rc = SQLITE_OK;
@@ -4590,7 +4581,6 @@ case OP_ParseSchema: {
       if( rc==SQLITE_OK ) rc = initData.rc;
       sqlite3DbFree(db, zSql);
       db->init.busy = 0;
-      (void)sqlite3SafetyOn(db);
     }
   }
   sqlite3BtreeLeaveAll(db);
@@ -5160,9 +5150,7 @@ case OP_AggFinal: {
 ** a transaction.
 */
 case OP_Vacuum: {
-  if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; 
   rc = sqlite3RunVacuum(&p->zErrMsg, db);
-  if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
   break;
 }
 #endif
@@ -5306,12 +5294,10 @@ case OP_VOpen: {
   pVtab = pOp->p4.pVtab->pVtab;
   pModule = (sqlite3_module *)pVtab->pModule;
   assert(pVtab && pModule);
-  if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
   rc = pModule->xOpen(pVtab, &pVtabCursor);
   sqlite3DbFree(db, p->zErrMsg);
   p->zErrMsg = pVtab->zErrMsg;
   pVtab->zErrMsg = 0;
-  if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
   if( SQLITE_OK==rc ){
     /* Initialize sqlite3_vtab_cursor base class */
     pVtabCursor->pVtab = pVtab;
@@ -5385,7 +5371,6 @@ case OP_VFilter: {   /* jump */
       sqlite3VdbeMemStoreType(apArg[i]);
     }
 
-    if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
     p->inVtabMethod = 1;
     rc = pModule->xFilter(pVtabCursor, iQuery, pOp->p4.z, nArg, apArg);
     p->inVtabMethod = 0;
@@ -5395,7 +5380,6 @@ case OP_VFilter: {   /* jump */
     if( rc==SQLITE_OK ){
       res = pModule->xEof(pVtabCursor);
     }
-    if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
 
     if( res ){
       pc = pOp->p2 - 1;
@@ -5441,7 +5425,6 @@ case OP_VColumn: {
   sqlite3VdbeMemMove(&sContext.s, pDest);
   MemSetTypeFlag(&sContext.s, MEM_Null);
 
-  if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
   rc = pModule->xColumn(pCur->pVtabCursor, &sContext, pOp->p2);
   sqlite3DbFree(db, p->zErrMsg);
   p->zErrMsg = pVtab->zErrMsg;
@@ -5459,9 +5442,6 @@ case OP_VColumn: {
   REGISTER_TRACE(pOp->p3, pDest);
   UPDATE_MAX_BLOBSIZE(pDest);
 
-  if( sqlite3SafetyOn(db) ){
-    goto abort_due_to_misuse;
-  }
   if( sqlite3VdbeMemTooBig(pDest) ){
     goto too_big;
   }
@@ -5498,7 +5478,6 @@ case OP_VNext: {   /* jump */
   ** data is available) and the error code returned when xColumn or
   ** some other method is next invoked on the save virtual table cursor.
   */
-  if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
   p->inVtabMethod = 1;
   rc = pModule->xNext(pCur->pVtabCursor);
   p->inVtabMethod = 0;
@@ -5508,7 +5487,6 @@ case OP_VNext: {   /* jump */
   if( rc==SQLITE_OK ){
     res = pModule->xEof(pCur->pVtabCursor);
   }
-  if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
 
   if( !res ){
     /* If there is data, jump to P2 */
@@ -5534,12 +5512,10 @@ case OP_VRename: {
   assert( pVtab->pModule->xRename );
   REGISTER_TRACE(pOp->p1, pName);
   assert( pName->flags & MEM_Str );
-  if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
   rc = pVtab->pModule->xRename(pVtab, pName->z);
   sqlite3DbFree(db, p->zErrMsg);
   p->zErrMsg = pVtab->zErrMsg;
   pVtab->zErrMsg = 0;
-  if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
 
   break;
 }
@@ -5590,12 +5566,10 @@ case OP_VUpdate: {
       apArg[i] = pX;
       pX++;
     }
-    if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
     rc = pModule->xUpdate(pVtab, nArg, apArg, &rowid);
     sqlite3DbFree(db, p->zErrMsg);
     p->zErrMsg = pVtab->zErrMsg;
     pVtab->zErrMsg = 0;
-    if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
     if( rc==SQLITE_OK && pOp->p1 ){
       assert( nArg>1 && apArg[0] && (apArg[0]->flags&MEM_Null) );
       db->lastRowid = rowid;
@@ -5719,6 +5693,7 @@ default: {          /* This is really OP_Noop and OP_Explain */
 vdbe_error_halt:
   assert( rc );
   p->rc = rc;
+  sqlite3_log(rc, "prepared statement aborts at %d: [%s]", pc, p->zSql);
   sqlite3VdbeHalt(p);
   if( rc==SQLITE_IOERR_NOMEM ) db->mallocFailed = 1;
   rc = SQLITE_ERROR;
@@ -5747,12 +5722,6 @@ no_mem:
   rc = SQLITE_NOMEM;
   goto vdbe_error_halt;
 
-  /* Jump to here for an SQLITE_MISUSE error.
-  */
-abort_due_to_misuse:
-  rc = SQLITE_MISUSE;
-  /* Fall thru into abort_due_to_error */
-
   /* Jump to here for any other kind of fatal error.  The "rc" variable
   ** should hold the error number.
   */
index 428a3230e389fa90ad6841258cfe03078b3b4347..80f48f5c59c4787d8209774f4e33ddf8d69741cc 100644 (file)
@@ -31,6 +31,28 @@ int sqlite3_expired(sqlite3_stmt *pStmt){
 }
 #endif
 
+/*
+** Check on a Vdbe to make sure it has not been finalized.  Log
+** an error and return true if it has been finalized (or is otherwise
+** invalid).  Return false if it is ok.
+*/
+static int vdbeSafety(Vdbe *p){
+  if( p->db==0 ){
+    sqlite3_log(SQLITE_MISUSE, "API called with finalized prepared statement");
+    return 1;
+  }else{
+    return 0;
+  }
+}
+static int vdbeSafetyNotNull(Vdbe *p){
+  if( p==0 ){
+    sqlite3_log(SQLITE_MISUSE, "API called with NULL prepared statement");
+    return 1;
+  }else{
+    return vdbeSafety(p);
+  }
+}
+
 /*
 ** The following routine destroys a virtual machine that is created by
 ** the sqlite3_compile() routine. The integer returned is an SQLITE_
@@ -48,7 +70,11 @@ int sqlite3_finalize(sqlite3_stmt *pStmt){
     Vdbe *v = (Vdbe*)pStmt;
     sqlite3 *db = v->db;
 #if SQLITE_THREADSAFE
-    sqlite3_mutex *mutex = v->db->mutex;
+    sqlite3_mutex *mutex;
+#endif
+    if( vdbeSafety(v) ) return SQLITE_MISUSE_BKPT;
+#if SQLITE_THREADSAFE
+    mutex = v->db->mutex;
 #endif
     sqlite3_mutex_enter(mutex);
     rc = sqlite3VdbeFinalize(v);
@@ -295,7 +321,9 @@ static int sqlite3Step(Vdbe *p){
 
   assert(p);
   if( p->magic!=VDBE_MAGIC_RUN ){
-    return SQLITE_MISUSE;
+    sqlite3_log(SQLITE_MISUSE, 
+          "attempt to step a halted statement: [%s]", p->zSql);
+    return SQLITE_MISUSE_BKPT;
   }
 
   /* Assert that malloc() has not failed */
@@ -305,16 +333,12 @@ static int sqlite3Step(Vdbe *p){
   }
 
   if( p->pc<=0 && p->expired ){
-    if( ALWAYS(p->rc==SQLITE_OK || p->rc==SQLITE_SCHEMA) ){
+    if( p->rc==SQLITE_OK ){
       p->rc = SQLITE_SCHEMA;
     }
     rc = SQLITE_ERROR;
     goto end_of_step;
   }
-  if( sqlite3SafetyOn(db) ){
-    p->rc = SQLITE_MISUSE;
-    return SQLITE_MISUSE;
-  }
   if( p->pc<0 ){
     /* If there are no other statements currently running, then
     ** reset the interrupt flag.  This prevents a call to sqlite3_interrupt
@@ -347,10 +371,6 @@ static int sqlite3Step(Vdbe *p){
     rc = sqlite3VdbeExec(p);
   }
 
-  if( sqlite3SafetyOff(db) ){
-    rc = SQLITE_MISUSE;
-  }
-
 #ifndef SQLITE_OMIT_TRACE
   /* Invoke the profile callback if there is one
   */
@@ -397,39 +417,44 @@ end_of_step:
 ** call sqlite3Reprepare() and try again.
 */
 int sqlite3_step(sqlite3_stmt *pStmt){
-  int rc = SQLITE_MISUSE;
-  if( pStmt ){
-    int cnt = 0;
-    Vdbe *v = (Vdbe*)pStmt;
-    sqlite3 *db = v->db;
-    sqlite3_mutex_enter(db->mutex);
-    while( (rc = sqlite3Step(v))==SQLITE_SCHEMA
-           && cnt++ < 5
-           && (rc = sqlite3Reprepare(v))==SQLITE_OK ){
-      sqlite3_reset(pStmt);
-      v->expired = 0;
-    }
-    if( rc==SQLITE_SCHEMA && ALWAYS(v->isPrepareV2) && ALWAYS(db->pErr) ){
-      /* 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 
-      ** from the database handle into the statement and sets the statement
-      ** program counter to 0 to ensure that when the statement is 
-      ** finalized or reset the parser error message is available via
-      ** sqlite3_errmsg() and sqlite3_errcode().
-      */
-      const char *zErr = (const char *)sqlite3_value_text(db->pErr); 
-      sqlite3DbFree(db, v->zErrMsg);
-      if( !db->mallocFailed ){
-        v->zErrMsg = sqlite3DbStrDup(db, zErr);
-      } else {
-        v->zErrMsg = 0;
-        v->rc = SQLITE_NOMEM;
-      }
+  int rc = SQLITE_OK;      /* Result from sqlite3Step() */
+  int rc2 = SQLITE_OK;     /* Result from sqlite3Reprepare() */
+  Vdbe *v = (Vdbe*)pStmt;  /* the prepared statement */
+  int cnt = 0;             /* Counter to prevent infinite loop of reprepares */
+  sqlite3 *db;             /* The database connection */
+
+  if( vdbeSafetyNotNull(v) ){
+    return SQLITE_MISUSE_BKPT;
+  }
+  db = v->db;
+  sqlite3_mutex_enter(db->mutex);
+  while( (rc = sqlite3Step(v))==SQLITE_SCHEMA
+         && cnt++ < 5
+         && (rc2 = rc = sqlite3Reprepare(v))==SQLITE_OK ){
+    sqlite3_reset(pStmt);
+    v->expired = 0;
+  }
+  if( rc2!=SQLITE_OK && v->isPrepareV2 && db->pErr ){
+    /* 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 
+    ** from the database handle into the statement and sets the statement
+    ** program counter to 0 to ensure that when the statement is 
+    ** finalized or reset the parser error message is available via
+    ** sqlite3_errmsg() and sqlite3_errcode().
+    */
+    const char *zErr = (const char *)sqlite3_value_text(db->pErr); 
+    sqlite3DbFree(db, v->zErrMsg);
+    if( !db->mallocFailed ){
+      v->zErrMsg = sqlite3DbStrDup(db, zErr);
+      v->rc = rc2;
+    } else {
+      v->zErrMsg = 0;
+      v->rc = rc = SQLITE_NOMEM;
     }
-    rc = sqlite3ApiExit(db, rc);
-    sqlite3_mutex_leave(db->mutex);
   }
+  rc = sqlite3ApiExit(db, rc);
+  sqlite3_mutex_leave(db->mutex);
   return rc;
 }
 
@@ -899,12 +924,16 @@ const void *sqlite3_column_origin_name16(sqlite3_stmt *pStmt, int N){
 */
 static int vdbeUnbind(Vdbe *p, int i){
   Mem *pVar;
-  if( p==0 ) return SQLITE_MISUSE;
+  if( vdbeSafetyNotNull(p) ){
+    return SQLITE_MISUSE_BKPT;
+  }
   sqlite3_mutex_enter(p->db->mutex);
   if( p->magic!=VDBE_MAGIC_RUN || p->pc>=0 ){
     sqlite3Error(p->db, SQLITE_MISUSE, 0);
     sqlite3_mutex_leave(p->db->mutex);
-    return SQLITE_MISUSE;
+    sqlite3_log(SQLITE_MISUSE, 
+        "bind on a busy prepared statement: [%s]", p->zSql);
+    return SQLITE_MISUSE_BKPT;
   }
   if( i<1 || i>p->nVar ){
     sqlite3Error(p->db, SQLITE_RANGE, 0);
index d7c162524216db3522e9227f22a6f422cbfd2e41..6bda380e84851a9b17259b066e902f81e0efa67e 100644 (file)
@@ -1059,7 +1059,6 @@ int sqlite3VdbeList(
 
   assert( p->explain );
   assert( p->magic==VDBE_MAGIC_RUN );
-  assert( db->magic==SQLITE_MAGIC_BUSY );
   assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY || p->rc==SQLITE_NOMEM );
 
   /* Even though this opcode does not use dynamic strings for
@@ -1474,9 +1473,7 @@ void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){
     sqlite3_vtab_cursor *pVtabCursor = pCx->pVtabCursor;
     const sqlite3_module *pModule = pCx->pModule;
     p->inVtabMethod = 1;
-    (void)sqlite3SafetyOff(p->db);
     pModule->xClose(pVtabCursor);
-    (void)sqlite3SafetyOn(p->db);
     p->inVtabMethod = 0;
   }
 #endif
@@ -1657,9 +1654,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
 
   /* If there are any write-transactions at all, invoke the commit hook */
   if( needXcommit && db->xCommitCallback ){
-    (void)sqlite3SafetyOff(db);
     rc = db->xCommitCallback(db->pCommitArg);
-    (void)sqlite3SafetyOn(db);
     if( rc ){
       return SQLITE_CONSTRAINT;
     }
@@ -2213,9 +2208,7 @@ int sqlite3VdbeReset(Vdbe *p){
   ** error, then it might not have been halted properly.  So halt
   ** it now.
   */
-  (void)sqlite3SafetyOn(db);
   sqlite3VdbeHalt(p);
-  (void)sqlite3SafetyOff(db);
 
   /* If the VDBE has be run even partially, then transfer the error code
   ** and error message from the VDBE into the main database structure.  But
@@ -3016,7 +3009,7 @@ int sqlite3VdbeIdxKeyCompare(
   ** that btreeParseCellPtr() and sqlite3GetVarint32() are implemented */
   if( nCellKey<=0 || nCellKey>0x7fffffff ){
     *res = 0;
-    return SQLITE_CORRUPT;
+    return SQLITE_CORRUPT_BKPT;
   }
   memset(&m, 0, sizeof(m));
   rc = sqlite3VdbeMemFromBtree(pC->pCursor, 0, (int)nCellKey, 1, &m);
index 6a6c6a71fcbbf15c426215f44d022c286d7e5e60..829b6de6ddc04c138ff52eab60ce42cc86fa17b9 100644 (file)
@@ -95,13 +95,6 @@ int sqlite3_blob_open(
     memset(pParse, 0, sizeof(Parse));
     pParse->db = db;
 
-    if( sqlite3SafetyOn(db) ){
-      sqlite3DbFree(db, zErr);
-      sqlite3StackFree(db, pParse);
-      sqlite3_mutex_leave(db->mutex);
-      return SQLITE_MISUSE;
-    }
-
     sqlite3BtreeEnterAll(db);
     pTab = sqlite3LocateTable(pParse, 0, zTable, zDb);
     if( pTab && IsVirtual(pTab) ){
@@ -121,7 +114,6 @@ int sqlite3_blob_open(
         pParse->zErrMsg = 0;
       }
       rc = SQLITE_ERROR;
-      (void)sqlite3SafetyOff(db);
       sqlite3BtreeLeaveAll(db);
       goto blob_open_out;
     }
@@ -136,7 +128,6 @@ int sqlite3_blob_open(
       sqlite3DbFree(db, zErr);
       zErr = sqlite3MPrintf(db, "no such column: \"%s\"", zColumn);
       rc = SQLITE_ERROR;
-      (void)sqlite3SafetyOff(db);
       sqlite3BtreeLeaveAll(db);
       goto blob_open_out;
     }
@@ -177,7 +168,6 @@ int sqlite3_blob_open(
         sqlite3DbFree(db, zErr);
         zErr = sqlite3MPrintf(db, "cannot open %s column for writing", zFault);
         rc = SQLITE_ERROR;
-        (void)sqlite3SafetyOff(db);
         sqlite3BtreeLeaveAll(db);
         goto blob_open_out;
       }
@@ -227,8 +217,7 @@ int sqlite3_blob_open(
     }
    
     sqlite3BtreeLeaveAll(db);
-    rc = sqlite3SafetyOff(db);
-    if( NEVER(rc!=SQLITE_OK) || db->mallocFailed ){
+    if( db->mallocFailed ){
       goto blob_open_out;
     }
 
@@ -329,7 +318,7 @@ static int blobReadWrite(
   Vdbe *v;
   sqlite3 *db;
 
-  if( p==0 ) return SQLITE_MISUSE;
+  if( p==0 ) return SQLITE_MISUSE_BKPT;
   db = p->db;
   sqlite3_mutex_enter(db->mutex);
   v = (Vdbe*)p->pStmt;
index d0bc22dcee4d5ad894d2c186256ac96c2a1d4bfc..cbb7523549d24758edf0d42d055d925026e858cb 100644 (file)
@@ -123,16 +123,7 @@ void sqlite3VtabUnlock(VTable *pVTab){
   if( pVTab->nRef==0 ){
     sqlite3_vtab *p = pVTab->pVtab;
     if( p ){
-#ifdef SQLITE_DEBUG
-      if( pVTab->db->magic==SQLITE_MAGIC_BUSY ){
-        (void)sqlite3SafetyOff(db);
-        p->pModule->xDisconnect(p);
-        (void)sqlite3SafetyOn(db);
-      } else
-#endif
-      {
-        p->pModule->xDisconnect(p);
-      }
+      p->pModule->xDisconnect(p);
     }
     sqlite3DbFree(db, pVTab);
   }
@@ -468,9 +459,7 @@ static int vtabCallConstructor(
   db->pVTab = pTab;
 
   /* Invoke the virtual table constructor */
-  (void)sqlite3SafetyOff(db);
   rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr);
-  (void)sqlite3SafetyOn(db);
   if( rc==SQLITE_NOMEM ) db->mallocFailed = 1;
 
   if( SQLITE_OK!=rc ){
@@ -658,7 +647,7 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
   if( !pTab ){
     sqlite3Error(db, SQLITE_MISUSE, 0);
     sqlite3_mutex_leave(db->mutex);
-    return SQLITE_MISUSE;
+    return SQLITE_MISUSE_BKPT;
   }
   assert( (pTab->tabFlags & TF_Virtual)!=0 );
 
@@ -717,10 +706,8 @@ int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab){
   if( ALWAYS(pTab!=0 && pTab->pVTable!=0) ){
     VTable *p = vtabDisconnectAll(db, pTab);
 
-    rc = sqlite3SafetyOff(db);
     assert( rc==SQLITE_OK );
     rc = p->pMod->pModule->xDestroy(p->pVtab);
-    (void)sqlite3SafetyOn(db);
 
     /* Remove the sqlite3_vtab* from the aVTrans[] array, if applicable */
     if( rc==SQLITE_OK ){
@@ -772,10 +759,8 @@ static void callFinaliser(sqlite3 *db, int offset){
 int sqlite3VtabSync(sqlite3 *db, char **pzErrmsg){
   int i;
   int rc = SQLITE_OK;
-  int rcsafety;
   VTable **aVTrans = db->aVTrans;
 
-  rc = sqlite3SafetyOff(db);
   db->aVTrans = 0;
   for(i=0; rc==SQLITE_OK && i<db->nVTrans; i++){
     int (*x)(sqlite3_vtab *);
@@ -788,11 +773,6 @@ int sqlite3VtabSync(sqlite3 *db, char **pzErrmsg){
     }
   }
   db->aVTrans = aVTrans;
-  rcsafety = sqlite3SafetyOn(db);
-
-  if( rc==SQLITE_OK ){
-    rc = rcsafety;
-  }
   return rc;
 }
 
index e9a0e0c16ef8a1a7284a93ac96c180578b3a5935..39013dd2be79663a5b25d50274b6dca292cbca02 100644 (file)
@@ -1758,12 +1758,10 @@ static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){
   int i;
   int rc;
 
-  (void)sqlite3SafetyOff(pParse->db);
   WHERETRACE(("xBestIndex for %s\n", pTab->zName));
   TRACE_IDX_INPUTS(p);
   rc = pVtab->pModule->xBestIndex(pVtab, p);
   TRACE_IDX_OUTPUTS(p);
-  (void)sqlite3SafetyOn(pParse->db);
 
   if( rc!=SQLITE_OK ){
     if( rc==SQLITE_NOMEM ){
index f623f987a499177bec37cccc3d3baa1379089338..438ecd7b2b71218f35acb1eed873cbd68fab6c64 100644 (file)
@@ -481,10 +481,10 @@ do_test analyze3-4.1.2 {
   sqlite3_bind_text $S 2 "abc" 3
   execsql { DROP TABLE t1 }
   sqlite3_step $S
-} {SQLITE_SCHEMA}
+} {SQLITE_ERROR}
 do_test analyze3-4.1.3 {
   sqlite3_finalize $S
-} {SQLITE_SCHEMA}
+} {SQLITE_ERROR}
 
 # Check an authorization error.
 #
@@ -511,10 +511,10 @@ do_test analyze3-4.2.2 {
   sqlite3_reset $S
   sqlite3_bind_text $S 2 "abc" 3
   sqlite3_step $S
-} {SQLITE_SCHEMA}
+} {SQLITE_AUTH}
 do_test analyze3-4.2.4 {
   sqlite3_finalize $S
-} {SQLITE_SCHEMA}
+} {SQLITE_AUTH}
 
 # Check the effect of an authorization error that occurs in a re-prepare
 # performed by sqlite3_step() is the same as one that occurs within
@@ -526,10 +526,10 @@ do_test analyze3-4.3.1 {
   execsql { CREATE TABLE t2(d, e, f) }
   db auth auth
   sqlite3_step $S
-} {SQLITE_SCHEMA}
+} {SQLITE_AUTH}
 do_test analyze3-4.3.2 {
   sqlite3_finalize $S
-} {SQLITE_SCHEMA}
+} {SQLITE_AUTH}
 db auth {}
 
 #-------------------------------------------------------------------------
index 1bcc4373c2a578043de5337758afb54af76c8262..55f4667e15dfbc6d712fcdae01a39c7aa5dcc589 100644 (file)
@@ -1176,7 +1176,7 @@ do_test capi3c-19.4 {
   sqlite3_reset $STMT
   db eval {DROP TABLE t3}
   sqlite3_step $STMT
-} SQLITE_SCHEMA
+} SQLITE_ERROR
 do_test capi3c-19.4.1 {
   sqlite3_errmsg $DB
 } {no such table: t3}
diff --git a/test/safety.test b/test/safety.test
deleted file mode 100644 (file)
index 9cca57c..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-# 2005 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 sqlite3SafetyOn and sqlite3SafetyOff
-# functions.  Those routines are not strictly necessary - they are
-# designed to detect misuse of the library.
-#
-# $Id: safety.test,v 1.4 2008/03/18 13:46:53 drh Exp $
-
-set testdir [file dirname $argv0]
-source $testdir/tester.tcl
-
-ifcapable !debug {
-  puts "Skipping safety tests since SQLITE_DEBUG is off"
-  finish_test
-  return
-}
-
-# Return the UTF-8 representation of the supplied UTF-16 string $str. 
-proc utf8 {str} {
-  # If $str ends in two 0x00 0x00 bytes, knock these off before
-  # converting to UTF-8 using TCL.
-  binary scan $str \c* vals
-  if {[lindex $vals end]==0 && [lindex $vals end-1]==0} {
-    set str [binary format \c* [lrange $vals 0 end-2]]
-  }
-
-  set r [encoding convertfrom unicode $str]
-  return $r
-}
-
-
-do_test safety-1.1 {
-  set DB [sqlite3_connection_pointer db]
-  db eval {CREATE TABLE t1(a)}
-  sqlite_set_magic $DB SQLITE_MAGIC_BUSY
-  catchsql {
-    SELECT name FROM sqlite_master;
-  }
-} {1 {library routine called out of sequence}}
-do_test safety-1.2 {
-  sqlite_set_magic $DB SQLITE_MAGIC_OPEN
-  catchsql {
-    SELECT name FROM sqlite_master
-  }
-} {0 t1}
-
-do_test safety-2.1 {
-  proc safety_on {} "sqlite_set_magic $DB SQLITE_MAGIC_BUSY"
-  db function safety_on safety_on
-  catchsql {
-    SELECT safety_on(), name FROM sqlite_master
-  }
-} {1 {library routine called out of sequence}}
-ifcapable {utf16} {
-  do_test safety-2.1.1 {
-    utf8 [sqlite3_errmsg16 db]
-  } {library routine called out of sequence}
-}
-do_test safety-2.2 {
-  catchsql {
-    SELECT 'hello'
-  }
-} {1 {library routine called out of sequence}}
-do_test safety-2.3 {
-  sqlite3_close $DB
-} {SQLITE_MISUSE}
-do_test safety-2.4 {
-  sqlite_set_magic $DB SQLITE_MAGIC_OPEN
-  execsql {
-    SELECT name FROM sqlite_master
-  }
-} {t1}
-
-do_test safety-3.1 {
-  set rc [catch {
-    db eval {SELECT name FROM sqlite_master} {
-      sqlite_set_magic $DB SQLITE_MAGIC_BUSY
-    }
-  } msg]
-  lappend rc $msg
-} {1 {library routine called out of sequence}}
-sqlite_set_magic $DB SQLITE_MAGIC_OPEN
-
-finish_test
index 5e9f17573f43c99369c414e59ff2801eab01e3e0..afca39ed60a484b3b3c2ff72e4351c3c26b9eeb0 100644 (file)
@@ -376,15 +376,15 @@ do_test schema-13.1 {
     return SQLITE_OK
   }
   sqlite3_step $S
-} {SQLITE_SCHEMA}
+} {SQLITE_AUTH}
 
 do_test schema-13.2 {
   sqlite3_step $S
-} {SQLITE_SCHEMA}
+} {SQLITE_AUTH}
 
 do_test schema-13.3 {
   sqlite3_finalize $S
-} {SQLITE_SCHEMA}
+} {SQLITE_AUTH}
 
 }