mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
Remove the obsolete sqlite3SafetyOn() mechanism. Add additional logging
output for CORRUPT, and CANTOPEN errors. FossilOrigin-Name: 7c4cca6d1a23a6d1591b62f58c3716a944969947
This commit is contained in:
51
manifest
51
manifest
@@ -1,8 +1,8 @@
|
|||||||
-----BEGIN PGP SIGNED MESSAGE-----
|
-----BEGIN PGP SIGNED MESSAGE-----
|
||||||
Hash: SHA1
|
Hash: SHA1
|
||||||
|
|
||||||
C Add\sthe\s".log"\scommand\sto\sthe\sshell.\s\sThis\sshows\sthat\ssome\serrors\sare\slogged\nmultiple\stimes\sand\sother\serrors\sare\snever\slogged\sat\sall.
|
C Remove\sthe\sobsolete\ssqlite3SafetyOn()\smechanism.\s\sAdd\sadditional\slogging\noutput\sfor\sCORRUPT,\sand\sCANTOPEN\serrors.
|
||||||
D 2010-02-23T01:47:00
|
D 2010-02-23T17:36:33
|
||||||
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
||||||
F Makefile.in c5827ead754ab32b9585487177c93bb00b9497b3
|
F Makefile.in c5827ead754ab32b9585487177c93bb00b9497b3
|
||||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||||
@@ -106,18 +106,18 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
|
|||||||
F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc
|
F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc
|
||||||
F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad
|
F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad
|
||||||
F src/alter.c e6f4d11b1c0b23642fc46bac9abe0753c4294e05
|
F src/alter.c e6f4d11b1c0b23642fc46bac9abe0753c4294e05
|
||||||
F src/analyze.c 55155f05ee9ab4ce33b7a4d19c449053f8935200
|
F src/analyze.c 92a65a5a402898a52b03695c7f0cd383724d711f
|
||||||
F src/attach.c f6d33268019460724e4c57aeec543eaaa55d8310
|
F src/attach.c d855b36c7ebe31643bb64b8f2a4f799599f57f97
|
||||||
F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
|
F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
|
||||||
F src/backup.c b293534bc2df23c57668a585b17ee7faaaef0939
|
F src/backup.c b293534bc2df23c57668a585b17ee7faaaef0939
|
||||||
F src/bitvec.c 06ad2c36a9c3819c0b9cbffec7b15f58d5d834e0
|
F src/bitvec.c 06ad2c36a9c3819c0b9cbffec7b15f58d5d834e0
|
||||||
F src/btmutex.c 96a12f50f7a17475155971a241d85ec5171573ff
|
F src/btmutex.c 96a12f50f7a17475155971a241d85ec5171573ff
|
||||||
F src/btree.c b7ac4420d10662259ad3421145eab16a279f5bd3
|
F src/btree.c ae804d16fb1ed8d3a0087b0fba2dcf37f312275c
|
||||||
F src/btree.h 0e193b7e90f1d78b79c79474040e3d66a553a4fa
|
F src/btree.h 0e193b7e90f1d78b79c79474040e3d66a553a4fa
|
||||||
F src/btreeInt.h 71ed5e7f009caf17b7dc304350b3cb64b5970135
|
F src/btreeInt.h 71ed5e7f009caf17b7dc304350b3cb64b5970135
|
||||||
F src/build.c 254a273acb8923f3bdecc933d787f4f67737c489
|
F src/build.c 254a273acb8923f3bdecc933d787f4f67737c489
|
||||||
F src/callback.c 908f3e0172c3d4058f4ca0acd42c637c52e9669f
|
F src/callback.c 908f3e0172c3d4058f4ca0acd42c637c52e9669f
|
||||||
F src/complete.c 4c8a742c4a4a6d9c835912648f5c8f032ea36c7b
|
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
|
||||||
F src/date.c 485a4409a384310e6d93fd1104a9d0a8658becd9
|
F src/date.c 485a4409a384310e6d93fd1104a9d0a8658becd9
|
||||||
F src/delete.c 610dc008e88a9599f905f5cbe9577ac9c36e0581
|
F src/delete.c 610dc008e88a9599f905f5cbe9577ac9c36e0581
|
||||||
F src/expr.c d0a345e1d8995e142bc5d9f39a97b9981d7d8f23
|
F src/expr.c d0a345e1d8995e142bc5d9f39a97b9981d7d8f23
|
||||||
@@ -133,7 +133,7 @@ F src/journal.c b0ea6b70b532961118ab70301c00a33089f9315c
|
|||||||
F src/legacy.c 16f385490f377c2c80a6c7357391d499087defed
|
F src/legacy.c 16f385490f377c2c80a6c7357391d499087defed
|
||||||
F src/lempar.c 7f026423f4d71d989e719a743f98a1cbd4e6d99e
|
F src/lempar.c 7f026423f4d71d989e719a743f98a1cbd4e6d99e
|
||||||
F src/loadext.c 1c7a61ce1281041f437333f366a96aa0d29bb581
|
F src/loadext.c 1c7a61ce1281041f437333f366a96aa0d29bb581
|
||||||
F src/main.c 36c1c11ee2677ae247e0c947f9293749ee5ac85f
|
F src/main.c fb31256305eb419c9d9ab3092cce4e8c6a065610
|
||||||
F src/malloc.c 5fa175797f982b178eaf38afba9c588a866be729
|
F src/malloc.c 5fa175797f982b178eaf38afba9c588a866be729
|
||||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||||
F src/mem1.c 86f33483a343873bab8ae1b648c2eac55462da74
|
F src/mem1.c 86f33483a343873bab8ae1b648c2eac55462da74
|
||||||
@@ -152,16 +152,16 @@ F src/os.c 8bc63cf91e9802e2b807198e54e50227fa889306
|
|||||||
F src/os.h 534b082c3cb349ad05fa6fa0b06087e022af282c
|
F src/os.h 534b082c3cb349ad05fa6fa0b06087e022af282c
|
||||||
F src/os_common.h 240c88b163b02c21a9f21f87d49678a0aa21ff30
|
F src/os_common.h 240c88b163b02c21a9f21f87d49678a0aa21ff30
|
||||||
F src/os_os2.c 75a8c7b9a00a2cf1a65f9fa4afbc27d46634bb2f
|
F src/os_os2.c 75a8c7b9a00a2cf1a65f9fa4afbc27d46634bb2f
|
||||||
F src/os_unix.c 0af0a55e2dd55bc4f4c3ccf04cc8f1f4a2e2e65f
|
F src/os_unix.c 13b5d1ffc04cc420ff9fab2938d0093e62a327bf
|
||||||
F src/os_win.c 5ffab20249a61e0625f869efe157fa009747039b
|
F src/os_win.c 1c7453c2df4dab26d90ff6f91272aea18bcf7053
|
||||||
F src/pager.c d0e53cd301c82d3b67ee69c7b900b56e5b17070d
|
F src/pager.c ace73a84f53a551fb8b9334205af210a29874b2c
|
||||||
F src/pager.h 1b32faf2e578ac3e7bcf9c9d11217128261c5c54
|
F src/pager.h 1b32faf2e578ac3e7bcf9c9d11217128261c5c54
|
||||||
F src/parse.y ace5c7a125d9f2a410e431ee3209034105045f7e
|
F src/parse.y ace5c7a125d9f2a410e431ee3209034105045f7e
|
||||||
F src/pcache.c 815bcb3cf0e14b23212efd3f4981f667a5fd633e
|
F src/pcache.c 815bcb3cf0e14b23212efd3f4981f667a5fd633e
|
||||||
F src/pcache.h c683390d50f856d4cd8e24342ae62027d1bb6050
|
F src/pcache.h c683390d50f856d4cd8e24342ae62027d1bb6050
|
||||||
F src/pcache1.c 2bb2261190b42a348038f5b1c285c8cef415fcc8
|
F src/pcache1.c 2bb2261190b42a348038f5b1c285c8cef415fcc8
|
||||||
F src/pragma.c 5febf8b5d88cc331effb3f2e14d0473488649b1e
|
F src/pragma.c 5febf8b5d88cc331effb3f2e14d0473488649b1e
|
||||||
F src/prepare.c d4cd38ccfb51f1424d0e61d4878a810b7e1ebb60
|
F src/prepare.c bd9e778f46d2cff460b5f238a3cc13ee0ffe1300
|
||||||
F src/printf.c f5c160b471e4a4dd22b756cb4ffe0c6979fd6d24
|
F src/printf.c f5c160b471e4a4dd22b756cb4ffe0c6979fd6d24
|
||||||
F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
|
F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
|
||||||
F src/resolve.c a1648d98e869937b29f4f697461fe4d60f220a7b
|
F src/resolve.c a1648d98e869937b29f4f697461fe4d60f220a7b
|
||||||
@@ -170,7 +170,7 @@ F src/select.c 0109b993c360d649857523abb72919e1794f9b45
|
|||||||
F src/shell.c 31cd555125a1fda4a6d8dce019690f043a8e5d75
|
F src/shell.c 31cd555125a1fda4a6d8dce019690f043a8e5d75
|
||||||
F src/sqlite.h.in 16f33c1ceb971bfa7a04a73039947630f445146e
|
F src/sqlite.h.in 16f33c1ceb971bfa7a04a73039947630f445146e
|
||||||
F src/sqlite3ext.h 69dfb8116af51b84a029cddb3b35062354270c89
|
F src/sqlite3ext.h 69dfb8116af51b84a029cddb3b35062354270c89
|
||||||
F src/sqliteInt.h d5fe1c8335b5bf376639837fa42124327cdb6767
|
F src/sqliteInt.h 32e6eb47d2f6fad587e16b0abbbfe3f7d55f2ec0
|
||||||
F src/sqliteLimit.h 3afab2291762b5d09ae20c18feb8e9fa935a60a6
|
F src/sqliteLimit.h 3afab2291762b5d09ae20c18feb8e9fa935a60a6
|
||||||
F src/status.c e651be6b30d397d86384c6867bc016e4913bcac7
|
F src/status.c e651be6b30d397d86384c6867bc016e4913bcac7
|
||||||
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
|
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
|
||||||
@@ -211,19 +211,19 @@ F src/tokenize.c e7f3606cc1b51a819a2bfee99100648d35bc791d
|
|||||||
F src/trigger.c 340c9eca0fb24b1197468d96ba059f867c9834c7
|
F src/trigger.c 340c9eca0fb24b1197468d96ba059f867c9834c7
|
||||||
F src/update.c c0dc6b75ad28b76b619042d934f337b02acee208
|
F src/update.c c0dc6b75ad28b76b619042d934f337b02acee208
|
||||||
F src/utf.c dad16adcc0c35ef2437dca125a4b07419d361052
|
F src/utf.c dad16adcc0c35ef2437dca125a4b07419d361052
|
||||||
F src/util.c 5b5353ff9427422b0bb89a5bc8ddf818399c0401
|
F src/util.c 32a7a4ce395b818b5659ff9c1fc7eff09932ccad
|
||||||
F src/vacuum.c 28ee5a4963d16cf2477075d85966c0f461cd79de
|
F src/vacuum.c 28ee5a4963d16cf2477075d85966c0f461cd79de
|
||||||
F src/vdbe.c 428411c6fbd49e9a4ce043dad87a0b079d403714
|
F src/vdbe.c b0769a0751cdf7eb52311ef94d44f379ea103a72
|
||||||
F src/vdbe.h bea1f0cd530775bdb58a340265f3cf3ee920e9b2
|
F src/vdbe.h bea1f0cd530775bdb58a340265f3cf3ee920e9b2
|
||||||
F src/vdbeInt.h e276691b6835da5c0008cc5beaaecedcd7bdba8e
|
F src/vdbeInt.h e276691b6835da5c0008cc5beaaecedcd7bdba8e
|
||||||
F src/vdbeapi.c a8b6a6617fc9a0492e4f7d6626d3afe994ddd3f2
|
F src/vdbeapi.c c1432e2aaa97e918901a55186199e23aa9047805
|
||||||
F src/vdbeaux.c 8f30e619a8077ee516fa1494fa603550fa951726
|
F src/vdbeaux.c 417ee0c5677188b3b72a0ccdda5668183e28bb51
|
||||||
F src/vdbeblob.c 84f924700a7a889152aeebef77ca5f4e3875ffb4
|
F src/vdbeblob.c 94d4715bb782b91ef183c999a4b81f4dd5494ab5
|
||||||
F src/vdbemem.c aeba77b59f3553d3cc5b72c18a8267c6fba546b9
|
F src/vdbemem.c aeba77b59f3553d3cc5b72c18a8267c6fba546b9
|
||||||
F src/vdbetrace.c 864cef96919323482ebd9986f2132435115e9cc2
|
F src/vdbetrace.c 864cef96919323482ebd9986f2132435115e9cc2
|
||||||
F src/vtab.c 7c7713d66cda699f16bf1cc601d8d4f5070ab935
|
F src/vtab.c 08df673f3341a0376037f795afbeb669d30d30a2
|
||||||
F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f
|
F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f
|
||||||
F src/where.c 1041ef1174ad36679d078188510f56f2801737a5
|
F src/where.c 9269ec75e1e36e69748fd918ac5a636020c85e7e
|
||||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||||
F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87
|
F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87
|
||||||
F test/all.test 14165b3e32715b700b5f0cbf8f6e3833dda0be45
|
F test/all.test 14165b3e32715b700b5f0cbf8f6e3833dda0be45
|
||||||
@@ -543,7 +543,6 @@ F test/rollback.test 73355ad4492ff9a3a31e61c7e5eb5e01a1de94ca
|
|||||||
F test/rowhash.test 97f56043ba11f0679920416c0cdbc72e5272267b
|
F test/rowhash.test 97f56043ba11f0679920416c0cdbc72e5272267b
|
||||||
F test/rowid.test e58e0acef38b527ed1b0b70d3ada588f804af287
|
F test/rowid.test e58e0acef38b527ed1b0b70d3ada588f804af287
|
||||||
F test/rtree.test 55466a200af3591946c5da77ad5dbfbc1e5e05f9
|
F test/rtree.test 55466a200af3591946c5da77ad5dbfbc1e5e05f9
|
||||||
F test/safety.test b69e2b2dd5d52a3f78e216967086884bbc1a09c6
|
|
||||||
F test/savepoint.test f2ede4b643ad87ead36c041c72d774a1f5c8a564
|
F test/savepoint.test f2ede4b643ad87ead36c041c72d774a1f5c8a564
|
||||||
F test/savepoint2.test 427c8b20f43d3edf17a290c6788ae9e2703ac51c
|
F test/savepoint2.test 427c8b20f43d3edf17a290c6788ae9e2703ac51c
|
||||||
F test/savepoint3.test e328085853b14898d78ceea00dfe7db18bb6a9ec
|
F test/savepoint3.test e328085853b14898d78ceea00dfe7db18bb6a9ec
|
||||||
@@ -794,14 +793,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
|||||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||||
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
||||||
P c4401fc93b66c5339422d7e765a4a32b1ef96bdb
|
P 6d910245ad0097521cf1619449cc3d202137b8b8
|
||||||
R 1b44bf57e7d9a663688d30603c70b44c
|
R 4a55fdf9e3eb291dfcc82c0590d9deb7
|
||||||
U drh
|
U drh
|
||||||
Z 75784795cda6fd26f0b8feb0805d2536
|
Z 26147ac467d0ee1674ecf48b84753d80
|
||||||
-----BEGIN PGP SIGNATURE-----
|
-----BEGIN PGP SIGNATURE-----
|
||||||
Version: GnuPG v1.4.6 (GNU/Linux)
|
Version: GnuPG v1.4.6 (GNU/Linux)
|
||||||
|
|
||||||
iD8DBQFLgzOYoxKgR168RlERAgluAJ9q3mIeRrQvfpzpmiNDDWtRun1WrQCeME9w
|
iD8DBQFLhBIkoxKgR168RlERAl/sAJ9uSxPewxWPXcY00iSJJIp+Q1yjKQCcCt45
|
||||||
x+Fdmmhc/ksLrbX58/ixhCk=
|
2X5N2P2VUOeqI8eEiWATH4s=
|
||||||
=d2xc
|
=TuL6
|
||||||
-----END PGP SIGNATURE-----
|
-----END PGP SIGNATURE-----
|
||||||
|
@@ -1 +1 @@
|
|||||||
6d910245ad0097521cf1619449cc3d202137b8b8
|
7c4cca6d1a23a6d1591b62f58c3716a944969947
|
@@ -559,9 +559,7 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
|
|||||||
if( zSql==0 ){
|
if( zSql==0 ){
|
||||||
rc = SQLITE_NOMEM;
|
rc = SQLITE_NOMEM;
|
||||||
}else{
|
}else{
|
||||||
(void)sqlite3SafetyOff(db);
|
|
||||||
rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0);
|
rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0);
|
||||||
(void)sqlite3SafetyOn(db);
|
|
||||||
sqlite3DbFree(db, zSql);
|
sqlite3DbFree(db, zSql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -579,14 +577,11 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
|
|||||||
if( !zSql ){
|
if( !zSql ){
|
||||||
rc = SQLITE_NOMEM;
|
rc = SQLITE_NOMEM;
|
||||||
}else{
|
}else{
|
||||||
(void)sqlite3SafetyOff(db);
|
|
||||||
rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
|
rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
|
||||||
(void)sqlite3SafetyOn(db);
|
|
||||||
sqlite3DbFree(db, zSql);
|
sqlite3DbFree(db, zSql);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
(void)sqlite3SafetyOff(db);
|
|
||||||
while( sqlite3_step(pStmt)==SQLITE_ROW ){
|
while( sqlite3_step(pStmt)==SQLITE_ROW ){
|
||||||
char *zIndex = (char *)sqlite3_column_text(pStmt, 0);
|
char *zIndex = (char *)sqlite3_column_text(pStmt, 0);
|
||||||
Index *pIdx = sqlite3FindIndex(db, zIndex, sInfo.zDatabase);
|
Index *pIdx = sqlite3FindIndex(db, zIndex, sInfo.zDatabase);
|
||||||
@@ -636,7 +631,6 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
rc = sqlite3_finalize(pStmt);
|
rc = sqlite3_finalize(pStmt);
|
||||||
(void)sqlite3SafetyOn(db);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -186,11 +186,9 @@ static void attachFunc(
|
|||||||
** we found it.
|
** we found it.
|
||||||
*/
|
*/
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
(void)sqlite3SafetyOn(db);
|
|
||||||
sqlite3BtreeEnterAll(db);
|
sqlite3BtreeEnterAll(db);
|
||||||
rc = sqlite3Init(db, &zErrDyn);
|
rc = sqlite3Init(db, &zErrDyn);
|
||||||
sqlite3BtreeLeaveAll(db);
|
sqlite3BtreeLeaveAll(db);
|
||||||
(void)sqlite3SafetyOff(db);
|
|
||||||
}
|
}
|
||||||
if( rc ){
|
if( rc ){
|
||||||
int iDb = db->nDb - 1;
|
int iDb = db->nDb - 1;
|
||||||
|
@@ -5919,7 +5919,7 @@ static int balance_nonroot(
|
|||||||
if( leafData ){ i--; }
|
if( leafData ){ i--; }
|
||||||
subtotal = 0;
|
subtotal = 0;
|
||||||
k++;
|
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;
|
szNew[k] = subtotal;
|
||||||
@@ -5973,7 +5973,7 @@ static int balance_nonroot(
|
|||||||
** Allocate k new pages. Reuse old pages where possible.
|
** Allocate k new pages. Reuse old pages where possible.
|
||||||
*/
|
*/
|
||||||
if( apOld[0]->pgno<=1 ){
|
if( apOld[0]->pgno<=1 ){
|
||||||
rc = SQLITE_CORRUPT;
|
rc = SQLITE_CORRUPT_BKPT;
|
||||||
goto balance_cleanup;
|
goto balance_cleanup;
|
||||||
}
|
}
|
||||||
pageFlags = apOld[0]->aData[0];
|
pageFlags = apOld[0]->aData[0];
|
||||||
|
566
src/complete.c
566
src/complete.c
@@ -1,283 +1,283 @@
|
|||||||
/*
|
/*
|
||||||
** 2001 September 15
|
** 2001 September 15
|
||||||
**
|
**
|
||||||
** The author disclaims copyright to this source code. In place of
|
** The author disclaims copyright to this source code. In place of
|
||||||
** a legal notice, here is a blessing:
|
** a legal notice, here is a blessing:
|
||||||
**
|
**
|
||||||
** May you do good and not evil.
|
** May you do good and not evil.
|
||||||
** May you find forgiveness for yourself and forgive others.
|
** May you find forgiveness for yourself and forgive others.
|
||||||
** May you share freely, never taking more than you give.
|
** May you share freely, never taking more than you give.
|
||||||
**
|
**
|
||||||
*************************************************************************
|
*************************************************************************
|
||||||
** An tokenizer for SQL
|
** An tokenizer for SQL
|
||||||
**
|
**
|
||||||
** This file contains C code that implements the sqlite3_complete() API.
|
** 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
|
** This code used to be part of the tokenizer.c source file. But by
|
||||||
** separating it out, the code will be automatically omitted from
|
** separating it out, the code will be automatically omitted from
|
||||||
** static links that do not use it.
|
** static links that do not use it.
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#ifndef SQLITE_OMIT_COMPLETE
|
#ifndef SQLITE_OMIT_COMPLETE
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** This is defined in tokenize.c. We just have to import the definition.
|
** This is defined in tokenize.c. We just have to import the definition.
|
||||||
*/
|
*/
|
||||||
#ifndef SQLITE_AMALGAMATION
|
#ifndef SQLITE_AMALGAMATION
|
||||||
#ifdef SQLITE_ASCII
|
#ifdef SQLITE_ASCII
|
||||||
#define IdChar(C) ((sqlite3CtypeMap[(unsigned char)C]&0x46)!=0)
|
#define IdChar(C) ((sqlite3CtypeMap[(unsigned char)C]&0x46)!=0)
|
||||||
#endif
|
#endif
|
||||||
#ifdef SQLITE_EBCDIC
|
#ifdef SQLITE_EBCDIC
|
||||||
extern const char sqlite3IsEbcdicIdChar[];
|
extern const char sqlite3IsEbcdicIdChar[];
|
||||||
#define IdChar(C) (((c=C)>=0x42 && sqlite3IsEbcdicIdChar[c-0x40]))
|
#define IdChar(C) (((c=C)>=0x42 && sqlite3IsEbcdicIdChar[c-0x40]))
|
||||||
#endif
|
#endif
|
||||||
#endif /* SQLITE_AMALGAMATION */
|
#endif /* SQLITE_AMALGAMATION */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Token types used by the sqlite3_complete() routine. See the header
|
** Token types used by the sqlite3_complete() routine. See the header
|
||||||
** comments on that procedure for additional information.
|
** comments on that procedure for additional information.
|
||||||
*/
|
*/
|
||||||
#define tkSEMI 0
|
#define tkSEMI 0
|
||||||
#define tkWS 1
|
#define tkWS 1
|
||||||
#define tkOTHER 2
|
#define tkOTHER 2
|
||||||
#ifndef SQLITE_OMIT_TRIGGER
|
#ifndef SQLITE_OMIT_TRIGGER
|
||||||
#define tkEXPLAIN 3
|
#define tkEXPLAIN 3
|
||||||
#define tkCREATE 4
|
#define tkCREATE 4
|
||||||
#define tkTEMP 5
|
#define tkTEMP 5
|
||||||
#define tkTRIGGER 6
|
#define tkTRIGGER 6
|
||||||
#define tkEND 7
|
#define tkEND 7
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Return TRUE if the given SQL string ends in a semicolon.
|
** Return TRUE if the given SQL string ends in a semicolon.
|
||||||
**
|
**
|
||||||
** Special handling is require for CREATE TRIGGER statements.
|
** Special handling is require for CREATE TRIGGER statements.
|
||||||
** Whenever the CREATE TRIGGER keywords are seen, the statement
|
** Whenever the CREATE TRIGGER keywords are seen, the statement
|
||||||
** must end with ";END;".
|
** must end with ";END;".
|
||||||
**
|
**
|
||||||
** This implementation uses a state machine with 8 states:
|
** This implementation uses a state machine with 8 states:
|
||||||
**
|
**
|
||||||
** (0) INVALID We have not yet seen a non-whitespace character.
|
** (0) INVALID We have not yet seen a non-whitespace character.
|
||||||
**
|
**
|
||||||
** (1) START At the beginning or end of an SQL statement. This routine
|
** (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
|
** returns 1 if it ends in the START state and 0 if it ends
|
||||||
** in any other state.
|
** in any other state.
|
||||||
**
|
**
|
||||||
** (2) NORMAL We are in the middle of statement which ends with a single
|
** (2) NORMAL We are in the middle of statement which ends with a single
|
||||||
** semicolon.
|
** semicolon.
|
||||||
**
|
**
|
||||||
** (3) EXPLAIN The keyword EXPLAIN has been seen at the beginning of
|
** (3) EXPLAIN The keyword EXPLAIN has been seen at the beginning of
|
||||||
** a statement.
|
** a statement.
|
||||||
**
|
**
|
||||||
** (4) CREATE The keyword CREATE has been seen at the beginning of a
|
** (4) CREATE The keyword CREATE has been seen at the beginning of a
|
||||||
** statement, possibly preceeded by EXPLAIN and/or followed by
|
** statement, possibly preceeded by EXPLAIN and/or followed by
|
||||||
** TEMP or TEMPORARY
|
** TEMP or TEMPORARY
|
||||||
**
|
**
|
||||||
** (5) TRIGGER We are in the middle of a trigger definition that must be
|
** (5) TRIGGER We are in the middle of a trigger definition that must be
|
||||||
** ended by a semicolon, the keyword END, and another semicolon.
|
** ended by a semicolon, the keyword END, and another semicolon.
|
||||||
**
|
**
|
||||||
** (6) SEMI We've seen the first semicolon in the ";END;" that occurs at
|
** (6) SEMI We've seen the first semicolon in the ";END;" that occurs at
|
||||||
** the end of a trigger definition.
|
** the end of a trigger definition.
|
||||||
**
|
**
|
||||||
** (7) END We've seen the ";END" of the ";END;" that occurs at the end
|
** (7) END We've seen the ";END" of the ";END;" that occurs at the end
|
||||||
** of a trigger difinition.
|
** of a trigger difinition.
|
||||||
**
|
**
|
||||||
** Transitions between states above are determined by tokens extracted
|
** Transitions between states above are determined by tokens extracted
|
||||||
** from the input. The following tokens are significant:
|
** from the input. The following tokens are significant:
|
||||||
**
|
**
|
||||||
** (0) tkSEMI A semicolon.
|
** (0) tkSEMI A semicolon.
|
||||||
** (1) tkWS Whitespace.
|
** (1) tkWS Whitespace.
|
||||||
** (2) tkOTHER Any other SQL token.
|
** (2) tkOTHER Any other SQL token.
|
||||||
** (3) tkEXPLAIN The "explain" keyword.
|
** (3) tkEXPLAIN The "explain" keyword.
|
||||||
** (4) tkCREATE The "create" keyword.
|
** (4) tkCREATE The "create" keyword.
|
||||||
** (5) tkTEMP The "temp" or "temporary" keyword.
|
** (5) tkTEMP The "temp" or "temporary" keyword.
|
||||||
** (6) tkTRIGGER The "trigger" keyword.
|
** (6) tkTRIGGER The "trigger" keyword.
|
||||||
** (7) tkEND The "end" keyword.
|
** (7) tkEND The "end" keyword.
|
||||||
**
|
**
|
||||||
** Whitespace never causes a state transition and is always ignored.
|
** Whitespace never causes a state transition and is always ignored.
|
||||||
** This means that a SQL string of all whitespace is invalid.
|
** This means that a SQL string of all whitespace is invalid.
|
||||||
**
|
**
|
||||||
** If we compile with SQLITE_OMIT_TRIGGER, all of the computation needed
|
** 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
|
** 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.
|
** is look for a semicolon that is not part of an string or comment.
|
||||||
*/
|
*/
|
||||||
int sqlite3_complete(const char *zSql){
|
int sqlite3_complete(const char *zSql){
|
||||||
u8 state = 0; /* Current state, using numbers defined in header comment */
|
u8 state = 0; /* Current state, using numbers defined in header comment */
|
||||||
u8 token; /* Value of the next token */
|
u8 token; /* Value of the next token */
|
||||||
|
|
||||||
#ifndef SQLITE_OMIT_TRIGGER
|
#ifndef SQLITE_OMIT_TRIGGER
|
||||||
/* A complex statement machine used to detect the end of a CREATE TRIGGER
|
/* A complex statement machine used to detect the end of a CREATE TRIGGER
|
||||||
** statement. This is the normal case.
|
** statement. This is the normal case.
|
||||||
*/
|
*/
|
||||||
static const u8 trans[8][8] = {
|
static const u8 trans[8][8] = {
|
||||||
/* Token: */
|
/* Token: */
|
||||||
/* State: ** SEMI WS OTHER EXPLAIN CREATE TEMP TRIGGER END */
|
/* State: ** SEMI WS OTHER EXPLAIN CREATE TEMP TRIGGER END */
|
||||||
/* 0 INVALID: */ { 1, 0, 2, 3, 4, 2, 2, 2, },
|
/* 0 INVALID: */ { 1, 0, 2, 3, 4, 2, 2, 2, },
|
||||||
/* 1 START: */ { 1, 1, 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, },
|
/* 2 NORMAL: */ { 1, 2, 2, 2, 2, 2, 2, 2, },
|
||||||
/* 3 EXPLAIN: */ { 1, 3, 3, 2, 4, 2, 2, 2, },
|
/* 3 EXPLAIN: */ { 1, 3, 3, 2, 4, 2, 2, 2, },
|
||||||
/* 4 CREATE: */ { 1, 4, 2, 2, 2, 4, 5, 2, },
|
/* 4 CREATE: */ { 1, 4, 2, 2, 2, 4, 5, 2, },
|
||||||
/* 5 TRIGGER: */ { 6, 5, 5, 5, 5, 5, 5, 5, },
|
/* 5 TRIGGER: */ { 6, 5, 5, 5, 5, 5, 5, 5, },
|
||||||
/* 6 SEMI: */ { 6, 6, 5, 5, 5, 5, 5, 7, },
|
/* 6 SEMI: */ { 6, 6, 5, 5, 5, 5, 5, 7, },
|
||||||
/* 7 END: */ { 1, 7, 5, 5, 5, 5, 5, 5, },
|
/* 7 END: */ { 1, 7, 5, 5, 5, 5, 5, 5, },
|
||||||
};
|
};
|
||||||
#else
|
#else
|
||||||
/* If triggers are not supported by this compile then the statement machine
|
/* If triggers are not supported by this compile then the statement machine
|
||||||
** used to detect the end of a statement is much simplier
|
** used to detect the end of a statement is much simplier
|
||||||
*/
|
*/
|
||||||
static const u8 trans[3][3] = {
|
static const u8 trans[3][3] = {
|
||||||
/* Token: */
|
/* Token: */
|
||||||
/* State: ** SEMI WS OTHER */
|
/* State: ** SEMI WS OTHER */
|
||||||
/* 0 INVALID: */ { 1, 0, 2, },
|
/* 0 INVALID: */ { 1, 0, 2, },
|
||||||
/* 1 START: */ { 1, 1, 2, },
|
/* 1 START: */ { 1, 1, 2, },
|
||||||
/* 2 NORMAL: */ { 1, 2, 2, },
|
/* 2 NORMAL: */ { 1, 2, 2, },
|
||||||
};
|
};
|
||||||
#endif /* SQLITE_OMIT_TRIGGER */
|
#endif /* SQLITE_OMIT_TRIGGER */
|
||||||
|
|
||||||
while( *zSql ){
|
while( *zSql ){
|
||||||
switch( *zSql ){
|
switch( *zSql ){
|
||||||
case ';': { /* A semicolon */
|
case ';': { /* A semicolon */
|
||||||
token = tkSEMI;
|
token = tkSEMI;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ' ':
|
case ' ':
|
||||||
case '\r':
|
case '\r':
|
||||||
case '\t':
|
case '\t':
|
||||||
case '\n':
|
case '\n':
|
||||||
case '\f': { /* White space is ignored */
|
case '\f': { /* White space is ignored */
|
||||||
token = tkWS;
|
token = tkWS;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case '/': { /* C-style comments */
|
case '/': { /* C-style comments */
|
||||||
if( zSql[1]!='*' ){
|
if( zSql[1]!='*' ){
|
||||||
token = tkOTHER;
|
token = tkOTHER;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
zSql += 2;
|
zSql += 2;
|
||||||
while( zSql[0] && (zSql[0]!='*' || zSql[1]!='/') ){ zSql++; }
|
while( zSql[0] && (zSql[0]!='*' || zSql[1]!='/') ){ zSql++; }
|
||||||
if( zSql[0]==0 ) return 0;
|
if( zSql[0]==0 ) return 0;
|
||||||
zSql++;
|
zSql++;
|
||||||
token = tkWS;
|
token = tkWS;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case '-': { /* SQL-style comments from "--" to end of line */
|
case '-': { /* SQL-style comments from "--" to end of line */
|
||||||
if( zSql[1]!='-' ){
|
if( zSql[1]!='-' ){
|
||||||
token = tkOTHER;
|
token = tkOTHER;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
while( *zSql && *zSql!='\n' ){ zSql++; }
|
while( *zSql && *zSql!='\n' ){ zSql++; }
|
||||||
if( *zSql==0 ) return state==1;
|
if( *zSql==0 ) return state==1;
|
||||||
token = tkWS;
|
token = tkWS;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case '[': { /* Microsoft-style identifiers in [...] */
|
case '[': { /* Microsoft-style identifiers in [...] */
|
||||||
zSql++;
|
zSql++;
|
||||||
while( *zSql && *zSql!=']' ){ zSql++; }
|
while( *zSql && *zSql!=']' ){ zSql++; }
|
||||||
if( *zSql==0 ) return 0;
|
if( *zSql==0 ) return 0;
|
||||||
token = tkOTHER;
|
token = tkOTHER;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case '`': /* Grave-accent quoted symbols used by MySQL */
|
case '`': /* Grave-accent quoted symbols used by MySQL */
|
||||||
case '"': /* single- and double-quoted strings */
|
case '"': /* single- and double-quoted strings */
|
||||||
case '\'': {
|
case '\'': {
|
||||||
int c = *zSql;
|
int c = *zSql;
|
||||||
zSql++;
|
zSql++;
|
||||||
while( *zSql && *zSql!=c ){ zSql++; }
|
while( *zSql && *zSql!=c ){ zSql++; }
|
||||||
if( *zSql==0 ) return 0;
|
if( *zSql==0 ) return 0;
|
||||||
token = tkOTHER;
|
token = tkOTHER;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
#ifdef SQLITE_EBCDIC
|
#ifdef SQLITE_EBCDIC
|
||||||
unsigned char c;
|
unsigned char c;
|
||||||
#endif
|
#endif
|
||||||
if( IdChar((u8)*zSql) ){
|
if( IdChar((u8)*zSql) ){
|
||||||
/* Keywords and unquoted identifiers */
|
/* Keywords and unquoted identifiers */
|
||||||
int nId;
|
int nId;
|
||||||
for(nId=1; IdChar(zSql[nId]); nId++){}
|
for(nId=1; IdChar(zSql[nId]); nId++){}
|
||||||
#ifdef SQLITE_OMIT_TRIGGER
|
#ifdef SQLITE_OMIT_TRIGGER
|
||||||
token = tkOTHER;
|
token = tkOTHER;
|
||||||
#else
|
#else
|
||||||
switch( *zSql ){
|
switch( *zSql ){
|
||||||
case 'c': case 'C': {
|
case 'c': case 'C': {
|
||||||
if( nId==6 && sqlite3StrNICmp(zSql, "create", 6)==0 ){
|
if( nId==6 && sqlite3StrNICmp(zSql, "create", 6)==0 ){
|
||||||
token = tkCREATE;
|
token = tkCREATE;
|
||||||
}else{
|
}else{
|
||||||
token = tkOTHER;
|
token = tkOTHER;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 't': case 'T': {
|
case 't': case 'T': {
|
||||||
if( nId==7 && sqlite3StrNICmp(zSql, "trigger", 7)==0 ){
|
if( nId==7 && sqlite3StrNICmp(zSql, "trigger", 7)==0 ){
|
||||||
token = tkTRIGGER;
|
token = tkTRIGGER;
|
||||||
}else if( nId==4 && sqlite3StrNICmp(zSql, "temp", 4)==0 ){
|
}else if( nId==4 && sqlite3StrNICmp(zSql, "temp", 4)==0 ){
|
||||||
token = tkTEMP;
|
token = tkTEMP;
|
||||||
}else if( nId==9 && sqlite3StrNICmp(zSql, "temporary", 9)==0 ){
|
}else if( nId==9 && sqlite3StrNICmp(zSql, "temporary", 9)==0 ){
|
||||||
token = tkTEMP;
|
token = tkTEMP;
|
||||||
}else{
|
}else{
|
||||||
token = tkOTHER;
|
token = tkOTHER;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'e': case 'E': {
|
case 'e': case 'E': {
|
||||||
if( nId==3 && sqlite3StrNICmp(zSql, "end", 3)==0 ){
|
if( nId==3 && sqlite3StrNICmp(zSql, "end", 3)==0 ){
|
||||||
token = tkEND;
|
token = tkEND;
|
||||||
}else
|
}else
|
||||||
#ifndef SQLITE_OMIT_EXPLAIN
|
#ifndef SQLITE_OMIT_EXPLAIN
|
||||||
if( nId==7 && sqlite3StrNICmp(zSql, "explain", 7)==0 ){
|
if( nId==7 && sqlite3StrNICmp(zSql, "explain", 7)==0 ){
|
||||||
token = tkEXPLAIN;
|
token = tkEXPLAIN;
|
||||||
}else
|
}else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
token = tkOTHER;
|
token = tkOTHER;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
token = tkOTHER;
|
token = tkOTHER;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* SQLITE_OMIT_TRIGGER */
|
#endif /* SQLITE_OMIT_TRIGGER */
|
||||||
zSql += nId-1;
|
zSql += nId-1;
|
||||||
}else{
|
}else{
|
||||||
/* Operators and special symbols */
|
/* Operators and special symbols */
|
||||||
token = tkOTHER;
|
token = tkOTHER;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
state = trans[state][token];
|
state = trans[state][token];
|
||||||
zSql++;
|
zSql++;
|
||||||
}
|
}
|
||||||
return state==1;
|
return state==1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef SQLITE_OMIT_UTF16
|
#ifndef SQLITE_OMIT_UTF16
|
||||||
/*
|
/*
|
||||||
** This routine is the same as the sqlite3_complete() routine described
|
** This routine is the same as the sqlite3_complete() routine described
|
||||||
** above, except that the parameter is required to be UTF-16 encoded, not
|
** above, except that the parameter is required to be UTF-16 encoded, not
|
||||||
** UTF-8.
|
** UTF-8.
|
||||||
*/
|
*/
|
||||||
int sqlite3_complete16(const void *zSql){
|
int sqlite3_complete16(const void *zSql){
|
||||||
sqlite3_value *pVal;
|
sqlite3_value *pVal;
|
||||||
char const *zSql8;
|
char const *zSql8;
|
||||||
int rc = SQLITE_NOMEM;
|
int rc = SQLITE_NOMEM;
|
||||||
|
|
||||||
#ifndef SQLITE_OMIT_AUTOINIT
|
#ifndef SQLITE_OMIT_AUTOINIT
|
||||||
rc = sqlite3_initialize();
|
rc = sqlite3_initialize();
|
||||||
if( rc ) return rc;
|
if( rc ) return rc;
|
||||||
#endif
|
#endif
|
||||||
pVal = sqlite3ValueNew(0);
|
pVal = sqlite3ValueNew(0);
|
||||||
sqlite3ValueSetStr(pVal, -1, zSql, SQLITE_UTF16NATIVE, SQLITE_STATIC);
|
sqlite3ValueSetStr(pVal, -1, zSql, SQLITE_UTF16NATIVE, SQLITE_STATIC);
|
||||||
zSql8 = sqlite3ValueText(pVal, SQLITE_UTF8);
|
zSql8 = sqlite3ValueText(pVal, SQLITE_UTF8);
|
||||||
if( zSql8 ){
|
if( zSql8 ){
|
||||||
rc = sqlite3_complete(zSql8);
|
rc = sqlite3_complete(zSql8);
|
||||||
}else{
|
}else{
|
||||||
rc = SQLITE_NOMEM;
|
rc = SQLITE_NOMEM;
|
||||||
}
|
}
|
||||||
sqlite3ValueFree(pVal);
|
sqlite3ValueFree(pVal);
|
||||||
return sqlite3ApiExit(0, rc);
|
return sqlite3ApiExit(0, rc);
|
||||||
}
|
}
|
||||||
#endif /* SQLITE_OMIT_UTF16 */
|
#endif /* SQLITE_OMIT_UTF16 */
|
||||||
#endif /* SQLITE_OMIT_COMPLETE */
|
#endif /* SQLITE_OMIT_COMPLETE */
|
||||||
|
29
src/main.c
29
src/main.c
@@ -1939,16 +1939,31 @@ int sqlite3_get_autocommit(sqlite3 *db){
|
|||||||
return db->autoCommit;
|
return db->autoCommit;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SQLITE_DEBUG
|
|
||||||
/*
|
/*
|
||||||
** The following routine is subtituted for constant SQLITE_CORRUPT in
|
** The following routines are subtitutes for constants SQLITE_CORRUPT,
|
||||||
** debugging builds. This provides a way to set a breakpoint for when
|
** SQLITE_MISUSE, SQLITE_CANTOPEN, SQLITE_IOERR and possibly other error
|
||||||
** corruption is first detected.
|
** 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){
|
||||||
|
sqlite3_log(SQLITE_CORRUPT,
|
||||||
|
"database corruption found by source line %d", lineno);
|
||||||
return SQLITE_CORRUPT;
|
return SQLITE_CORRUPT;
|
||||||
}
|
}
|
||||||
#endif
|
int sqlite3MisuseError(int lineno){
|
||||||
|
sqlite3_log(SQLITE_MISUSE, "misuse detected by source line %d", lineno);
|
||||||
|
return SQLITE_MISUSE;
|
||||||
|
}
|
||||||
|
int sqlite3CantopenError(int lineno){
|
||||||
|
sqlite3_log(SQLITE_CANTOPEN, "cannot open file at source line %d", lineno);
|
||||||
|
return SQLITE_CANTOPEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifndef SQLITE_OMIT_DEPRECATED
|
#ifndef SQLITE_OMIT_DEPRECATED
|
||||||
/*
|
/*
|
||||||
@@ -1992,7 +2007,6 @@ int sqlite3_table_column_metadata(
|
|||||||
|
|
||||||
/* Ensure the database schema has been loaded */
|
/* Ensure the database schema has been loaded */
|
||||||
sqlite3_mutex_enter(db->mutex);
|
sqlite3_mutex_enter(db->mutex);
|
||||||
(void)sqlite3SafetyOn(db);
|
|
||||||
sqlite3BtreeEnterAll(db);
|
sqlite3BtreeEnterAll(db);
|
||||||
rc = sqlite3Init(db, &zErrMsg);
|
rc = sqlite3Init(db, &zErrMsg);
|
||||||
if( SQLITE_OK!=rc ){
|
if( SQLITE_OK!=rc ){
|
||||||
@@ -2051,7 +2065,6 @@ int sqlite3_table_column_metadata(
|
|||||||
|
|
||||||
error_out:
|
error_out:
|
||||||
sqlite3BtreeLeaveAll(db);
|
sqlite3BtreeLeaveAll(db);
|
||||||
(void)sqlite3SafetyOff(db);
|
|
||||||
|
|
||||||
/* Whether the function call succeeded or failed, set the output parameters
|
/* Whether the function call succeeded or failed, set the output parameters
|
||||||
** to whatever their local counterparts contain. If an error did occur,
|
** to whatever their local counterparts contain. If an error did occur,
|
||||||
|
@@ -3867,7 +3867,7 @@ static int openDirectory(const char *zFilename, int *pFd){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
*pFd = fd;
|
*pFd = fd;
|
||||||
return (fd>=0?SQLITE_OK:SQLITE_CANTOPEN);
|
return (fd>=0?SQLITE_OK:SQLITE_CANTOPEN_BKPT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -4130,7 +4130,7 @@ static int unixOpen(
|
|||||||
fd = open(zName, openFlags, openMode);
|
fd = open(zName, openFlags, openMode);
|
||||||
}
|
}
|
||||||
if( fd<0 ){
|
if( fd<0 ){
|
||||||
rc = SQLITE_CANTOPEN;
|
rc = SQLITE_CANTOPEN_BKPT;
|
||||||
goto open_finished;
|
goto open_finished;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4354,7 +4354,7 @@ static int unixFullPathname(
|
|||||||
}else{
|
}else{
|
||||||
int nCwd;
|
int nCwd;
|
||||||
if( getcwd(zOut, nOut-1)==0 ){
|
if( getcwd(zOut, nOut-1)==0 ){
|
||||||
return SQLITE_CANTOPEN;
|
return SQLITE_CANTOPEN_BKPT;
|
||||||
}
|
}
|
||||||
nCwd = (int)strlen(zOut);
|
nCwd = (int)strlen(zOut);
|
||||||
sqlite3_snprintf(nOut-nCwd, &zOut[nCwd], "/%s", zPath);
|
sqlite3_snprintf(nOut-nCwd, &zOut[nCwd], "/%s", zPath);
|
||||||
@@ -4865,7 +4865,7 @@ static int proxyCreateUnixFile(
|
|||||||
case EIO:
|
case EIO:
|
||||||
return SQLITE_IOERR_LOCK; /* even though it is the conch */
|
return SQLITE_IOERR_LOCK; /* even though it is the conch */
|
||||||
default:
|
default:
|
||||||
return SQLITE_CANTOPEN;
|
return SQLITE_CANTOPEN_BKPT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5249,7 +5249,7 @@ static int proxyTakeConch(unixFile *pFile){
|
|||||||
if( fd>=0 ){
|
if( fd>=0 ){
|
||||||
pFile->h = fd;
|
pFile->h = fd;
|
||||||
}else{
|
}else{
|
||||||
rc=SQLITE_CANTOPEN; /* SQLITE_BUSY? proxyTakeConch called
|
rc=SQLITE_CANTOPEN_BKPT; /* SQLITE_BUSY? proxyTakeConch called
|
||||||
during locking */
|
during locking */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1417,7 +1417,7 @@ static int winOpen(
|
|||||||
return winOpen(pVfs, zName, id,
|
return winOpen(pVfs, zName, id,
|
||||||
((flags|SQLITE_OPEN_READONLY)&~SQLITE_OPEN_READWRITE), pOutFlags);
|
((flags|SQLITE_OPEN_READONLY)&~SQLITE_OPEN_READWRITE), pOutFlags);
|
||||||
}else{
|
}else{
|
||||||
return SQLITE_CANTOPEN;
|
return SQLITE_CANTOPEN_BKPT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( pOutFlags ){
|
if( pOutFlags ){
|
||||||
@@ -1439,7 +1439,7 @@ static int winOpen(
|
|||||||
){
|
){
|
||||||
CloseHandle(h);
|
CloseHandle(h);
|
||||||
free(zConverted);
|
free(zConverted);
|
||||||
return SQLITE_CANTOPEN;
|
return SQLITE_CANTOPEN_BKPT;
|
||||||
}
|
}
|
||||||
if( isTemp ){
|
if( isTemp ){
|
||||||
pFile->zDeleteOnClose = zConverted;
|
pFile->zDeleteOnClose = zConverted;
|
||||||
|
@@ -3162,7 +3162,7 @@ int sqlite3PagerOpen(
|
|||||||
** as it will not be possible to open the journal file or even
|
** as it will not be possible to open the journal file or even
|
||||||
** check for a hot-journal before reading.
|
** check for a hot-journal before reading.
|
||||||
*/
|
*/
|
||||||
rc = SQLITE_CANTOPEN;
|
rc = SQLITE_CANTOPEN_BKPT;
|
||||||
}
|
}
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
sqlite3_free(zPathname);
|
sqlite3_free(zPathname);
|
||||||
@@ -3621,7 +3621,7 @@ int sqlite3PagerSharedLock(Pager *pPager){
|
|||||||
rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &fout);
|
rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &fout);
|
||||||
assert( rc!=SQLITE_OK || isOpen(pPager->jfd) );
|
assert( rc!=SQLITE_OK || isOpen(pPager->jfd) );
|
||||||
if( rc==SQLITE_OK && fout&SQLITE_OPEN_READONLY ){
|
if( rc==SQLITE_OK && fout&SQLITE_OPEN_READONLY ){
|
||||||
rc = SQLITE_CANTOPEN;
|
rc = SQLITE_CANTOPEN_BKPT;
|
||||||
sqlite3OsClose(pPager->jfd);
|
sqlite3OsClose(pPager->jfd);
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
|
@@ -192,9 +192,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
|
|||||||
initData.iDb = iDb;
|
initData.iDb = iDb;
|
||||||
initData.rc = SQLITE_OK;
|
initData.rc = SQLITE_OK;
|
||||||
initData.pzErrMsg = pzErrMsg;
|
initData.pzErrMsg = pzErrMsg;
|
||||||
(void)sqlite3SafetyOff(db);
|
|
||||||
sqlite3InitCallback(&initData, 3, (char **)azArg, 0);
|
sqlite3InitCallback(&initData, 3, (char **)azArg, 0);
|
||||||
(void)sqlite3SafetyOn(db);
|
|
||||||
if( initData.rc ){
|
if( initData.rc ){
|
||||||
rc = initData.rc;
|
rc = initData.rc;
|
||||||
goto error_out;
|
goto error_out;
|
||||||
@@ -317,7 +315,6 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
|
|||||||
zSql = sqlite3MPrintf(db,
|
zSql = sqlite3MPrintf(db,
|
||||||
"SELECT name, rootpage, sql FROM '%q'.%s ORDER BY rowid",
|
"SELECT name, rootpage, sql FROM '%q'.%s ORDER BY rowid",
|
||||||
db->aDb[iDb].zName, zMasterName);
|
db->aDb[iDb].zName, zMasterName);
|
||||||
(void)sqlite3SafetyOff(db);
|
|
||||||
#ifndef SQLITE_OMIT_AUTHORIZATION
|
#ifndef SQLITE_OMIT_AUTHORIZATION
|
||||||
{
|
{
|
||||||
int (*xAuth)(void*,int,const char*,const char*,const char*,const char*);
|
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
|
#endif
|
||||||
if( rc==SQLITE_OK ) rc = initData.rc;
|
if( rc==SQLITE_OK ) rc = initData.rc;
|
||||||
(void)sqlite3SafetyOn(db);
|
|
||||||
sqlite3DbFree(db, zSql);
|
sqlite3DbFree(db, zSql);
|
||||||
#ifndef SQLITE_OMIT_ANALYZE
|
#ifndef SQLITE_OMIT_ANALYZE
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
@@ -539,11 +535,6 @@ static int sqlite3Prepare(
|
|||||||
goto end_prepare;
|
goto end_prepare;
|
||||||
}
|
}
|
||||||
pParse->pReprepare = pReprepare;
|
pParse->pReprepare = pReprepare;
|
||||||
|
|
||||||
if( sqlite3SafetyOn(db) ){
|
|
||||||
rc = SQLITE_MISUSE;
|
|
||||||
goto end_prepare;
|
|
||||||
}
|
|
||||||
assert( ppStmt && *ppStmt==0 );
|
assert( ppStmt && *ppStmt==0 );
|
||||||
assert( !db->mallocFailed );
|
assert( !db->mallocFailed );
|
||||||
assert( sqlite3_mutex_held(db->mutex) );
|
assert( sqlite3_mutex_held(db->mutex) );
|
||||||
@@ -579,7 +570,6 @@ static int sqlite3Prepare(
|
|||||||
if( rc ){
|
if( rc ){
|
||||||
const char *zDb = db->aDb[i].zName;
|
const char *zDb = db->aDb[i].zName;
|
||||||
sqlite3Error(db, rc, "database schema is locked: %s", zDb);
|
sqlite3Error(db, rc, "database schema is locked: %s", zDb);
|
||||||
(void)sqlite3SafetyOff(db);
|
|
||||||
testcase( db->flags & SQLITE_ReadUncommitted );
|
testcase( db->flags & SQLITE_ReadUncommitted );
|
||||||
goto end_prepare;
|
goto end_prepare;
|
||||||
}
|
}
|
||||||
@@ -596,7 +586,6 @@ static int sqlite3Prepare(
|
|||||||
testcase( nBytes==mxLen+1 );
|
testcase( nBytes==mxLen+1 );
|
||||||
if( nBytes>mxLen ){
|
if( nBytes>mxLen ){
|
||||||
sqlite3Error(db, SQLITE_TOOBIG, "statement too long");
|
sqlite3Error(db, SQLITE_TOOBIG, "statement too long");
|
||||||
(void)sqlite3SafetyOff(db);
|
|
||||||
rc = sqlite3ApiExit(db, SQLITE_TOOBIG);
|
rc = sqlite3ApiExit(db, SQLITE_TOOBIG);
|
||||||
goto end_prepare;
|
goto end_prepare;
|
||||||
}
|
}
|
||||||
@@ -653,10 +642,6 @@ static int sqlite3Prepare(
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if( sqlite3SafetyOff(db) ){
|
|
||||||
rc = SQLITE_MISUSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert( db->init.busy==0 || saveSqlFlag==0 );
|
assert( db->init.busy==0 || saveSqlFlag==0 );
|
||||||
if( db->init.busy==0 ){
|
if( db->init.busy==0 ){
|
||||||
Vdbe *pVdbe = pParse->pVdbe;
|
Vdbe *pVdbe = pParse->pVdbe;
|
||||||
|
@@ -2414,17 +2414,19 @@ int sqlite3WalkSelectFrom(Walker*, Select*);
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** The SQLITE_CORRUPT_BKPT macro can be either a constant (for production
|
** The SQLITE_*_BKPT macros are substitutes for the error codes with
|
||||||
** builds) or a function call (for debugging). If it is a function call,
|
** the same name but without the _BKPT suffix. These macros invoke
|
||||||
** it allows the operator to set a breakpoint at the spot where database
|
** routines that report the line-number on which the error originated
|
||||||
** corruption is first detected.
|
** using sqlite3_log(). The routines also provide a convenient place
|
||||||
|
** to set a debugger breakpoint.
|
||||||
*/
|
*/
|
||||||
#ifdef SQLITE_DEBUG
|
int sqlite3CorruptError(int);
|
||||||
int sqlite3Corrupt(void);
|
int sqlite3MisuseError(int);
|
||||||
# define SQLITE_CORRUPT_BKPT sqlite3Corrupt()
|
int sqlite3CantopenError(int);
|
||||||
#else
|
#define SQLITE_CORRUPT_BKPT sqlite3CorruptError(__LINE__)
|
||||||
# define SQLITE_CORRUPT_BKPT SQLITE_CORRUPT
|
#define SQLITE_MISUSE_BKPT sqlite3MisuseError(__LINE__)
|
||||||
#endif
|
#define SQLITE_CANTOPEN_BKPT sqlite3CantopenError(__LINE__)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** FTS4 is really an extension for FTS3. It is enabled using the
|
** FTS4 is really an extension for FTS3. It is enabled using the
|
||||||
@@ -2724,13 +2726,6 @@ FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,int,u8,int);
|
|||||||
void sqlite3RegisterBuiltinFunctions(sqlite3*);
|
void sqlite3RegisterBuiltinFunctions(sqlite3*);
|
||||||
void sqlite3RegisterDateTimeFunctions(void);
|
void sqlite3RegisterDateTimeFunctions(void);
|
||||||
void sqlite3RegisterGlobalFunctions(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 sqlite3SafetyCheckOk(sqlite3*);
|
||||||
int sqlite3SafetyCheckSickOrOk(sqlite3*);
|
int sqlite3SafetyCheckSickOrOk(sqlite3*);
|
||||||
void sqlite3ChangeCookie(Parse*, int);
|
void sqlite3ChangeCookie(Parse*, int);
|
||||||
|
65
src/util.c
65
src/util.c
@@ -123,7 +123,6 @@ void sqlite3Error(sqlite3 *db, int err_code, const char *zFormat, ...){
|
|||||||
va_start(ap, zFormat);
|
va_start(ap, zFormat);
|
||||||
z = sqlite3VMPrintf(db, zFormat, ap);
|
z = sqlite3VMPrintf(db, zFormat, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
sqlite3_log(err_code, "%s", z);
|
|
||||||
sqlite3ValueSetStr(db->pErr, -1, z, SQLITE_UTF8, SQLITE_DYNAMIC);
|
sqlite3ValueSetStr(db->pErr, -1, z, SQLITE_UTF8, SQLITE_DYNAMIC);
|
||||||
}else{
|
}else{
|
||||||
sqlite3ValueSetStr(db->pErr, 0, 0, SQLITE_UTF8, SQLITE_STATIC);
|
sqlite3ValueSetStr(db->pErr, 0, 0, SQLITE_UTF8, SQLITE_STATIC);
|
||||||
@@ -1012,64 +1011,6 @@ void *sqlite3HexToBlob(sqlite3 *db, const char *z, int n){
|
|||||||
#endif /* !SQLITE_OMIT_BLOB_LITERAL || SQLITE_HAS_CODEC */
|
#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.
|
|
||||||
*/
|
|
||||||
#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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Check to make sure we have a valid db pointer. This test is not
|
** Check to make sure we have a valid db pointer. This test is not
|
||||||
** foolproof but it does provide some measure of protection against
|
** foolproof but it does provide some measure of protection against
|
||||||
@@ -1088,11 +1029,7 @@ int sqlite3SafetyCheckOk(sqlite3 *db){
|
|||||||
u32 magic;
|
u32 magic;
|
||||||
if( db==0 ) return 0;
|
if( db==0 ) return 0;
|
||||||
magic = db->magic;
|
magic = db->magic;
|
||||||
if( magic!=SQLITE_MAGIC_OPEN
|
if( magic!=SQLITE_MAGIC_OPEN ){
|
||||||
#ifdef SQLITE_DEBUG
|
|
||||||
&& magic!=SQLITE_MAGIC_BUSY
|
|
||||||
#endif
|
|
||||||
){
|
|
||||||
return 0;
|
return 0;
|
||||||
}else{
|
}else{
|
||||||
return 1;
|
return 1;
|
||||||
|
34
src/vdbe.c
34
src/vdbe.c
@@ -563,7 +563,6 @@ int sqlite3VdbeExec(
|
|||||||
/*** INSERT STACK UNION HERE ***/
|
/*** INSERT STACK UNION HERE ***/
|
||||||
|
|
||||||
assert( p->magic==VDBE_MAGIC_RUN ); /* sqlite3_step() verifies this */
|
assert( p->magic==VDBE_MAGIC_RUN ); /* sqlite3_step() verifies this */
|
||||||
assert( db->magic==SQLITE_MAGIC_BUSY );
|
|
||||||
sqlite3VdbeMutexArrayEnter(p);
|
sqlite3VdbeMutexArrayEnter(p);
|
||||||
if( p->rc==SQLITE_NOMEM ){
|
if( p->rc==SQLITE_NOMEM ){
|
||||||
/* This happens if a malloc() inside a call to sqlite3_column_text() or
|
/* This happens if a malloc() inside a call to sqlite3_column_text() or
|
||||||
@@ -648,9 +647,7 @@ int sqlite3VdbeExec(
|
|||||||
if( checkProgress ){
|
if( checkProgress ){
|
||||||
if( db->nProgressOps==nProgressOps ){
|
if( db->nProgressOps==nProgressOps ){
|
||||||
int prc;
|
int prc;
|
||||||
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
|
prc = db->xProgress(db->pProgressArg);
|
||||||
prc =db->xProgress(db->pProgressArg);
|
|
||||||
if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
|
|
||||||
if( prc!=0 ){
|
if( prc!=0 ){
|
||||||
rc = SQLITE_INTERRUPT;
|
rc = SQLITE_INTERRUPT;
|
||||||
goto vdbe_error_halt;
|
goto vdbe_error_halt;
|
||||||
@@ -1400,21 +1397,12 @@ case OP_Function: {
|
|||||||
assert( pOp[-1].opcode==OP_CollSeq );
|
assert( pOp[-1].opcode==OP_CollSeq );
|
||||||
ctx.pColl = pOp[-1].p4.pColl;
|
ctx.pColl = pOp[-1].p4.pColl;
|
||||||
}
|
}
|
||||||
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
|
|
||||||
(*ctx.pFunc->xFunc)(&ctx, n, apVal);
|
(*ctx.pFunc->xFunc)(&ctx, n, apVal);
|
||||||
if( sqlite3SafetyOn(db) ){
|
|
||||||
sqlite3VdbeMemRelease(&ctx.s);
|
|
||||||
goto abort_due_to_misuse;
|
|
||||||
}
|
|
||||||
if( db->mallocFailed ){
|
if( db->mallocFailed ){
|
||||||
/* Even though a malloc() has failed, the implementation of the
|
/* Even though a malloc() has failed, the implementation of the
|
||||||
** user function may have called an sqlite3_result_XXX() function
|
** user function may have called an sqlite3_result_XXX() function
|
||||||
** to return a value. The following call releases any resources
|
** to return a value. The following call releases any resources
|
||||||
** associated with such a value.
|
** 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);
|
sqlite3VdbeMemRelease(&ctx.s);
|
||||||
goto no_mem;
|
goto no_mem;
|
||||||
@@ -4049,12 +4037,10 @@ case OP_Rowid: { /* out2-prerelease */
|
|||||||
pVtab = pC->pVtabCursor->pVtab;
|
pVtab = pC->pVtabCursor->pVtab;
|
||||||
pModule = pVtab->pModule;
|
pModule = pVtab->pModule;
|
||||||
assert( pModule->xRowid );
|
assert( pModule->xRowid );
|
||||||
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
|
|
||||||
rc = pModule->xRowid(pC->pVtabCursor, &v);
|
rc = pModule->xRowid(pC->pVtabCursor, &v);
|
||||||
sqlite3DbFree(db, p->zErrMsg);
|
sqlite3DbFree(db, p->zErrMsg);
|
||||||
p->zErrMsg = pVtab->zErrMsg;
|
p->zErrMsg = pVtab->zErrMsg;
|
||||||
pVtab->zErrMsg = 0;
|
pVtab->zErrMsg = 0;
|
||||||
if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
|
|
||||||
#endif /* SQLITE_OMIT_VIRTUALTABLE */
|
#endif /* SQLITE_OMIT_VIRTUALTABLE */
|
||||||
}else{
|
}else{
|
||||||
assert( pC->pCursor!=0 );
|
assert( pC->pCursor!=0 );
|
||||||
@@ -4590,7 +4576,6 @@ case OP_ParseSchema: {
|
|||||||
if( zSql==0 ){
|
if( zSql==0 ){
|
||||||
rc = SQLITE_NOMEM;
|
rc = SQLITE_NOMEM;
|
||||||
}else{
|
}else{
|
||||||
(void)sqlite3SafetyOff(db);
|
|
||||||
assert( db->init.busy==0 );
|
assert( db->init.busy==0 );
|
||||||
db->init.busy = 1;
|
db->init.busy = 1;
|
||||||
initData.rc = SQLITE_OK;
|
initData.rc = SQLITE_OK;
|
||||||
@@ -4599,7 +4584,6 @@ case OP_ParseSchema: {
|
|||||||
if( rc==SQLITE_OK ) rc = initData.rc;
|
if( rc==SQLITE_OK ) rc = initData.rc;
|
||||||
sqlite3DbFree(db, zSql);
|
sqlite3DbFree(db, zSql);
|
||||||
db->init.busy = 0;
|
db->init.busy = 0;
|
||||||
(void)sqlite3SafetyOn(db);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sqlite3BtreeLeaveAll(db);
|
sqlite3BtreeLeaveAll(db);
|
||||||
@@ -5169,9 +5153,7 @@ case OP_AggFinal: {
|
|||||||
** a transaction.
|
** a transaction.
|
||||||
*/
|
*/
|
||||||
case OP_Vacuum: {
|
case OP_Vacuum: {
|
||||||
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
|
|
||||||
rc = sqlite3RunVacuum(&p->zErrMsg, db);
|
rc = sqlite3RunVacuum(&p->zErrMsg, db);
|
||||||
if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -5315,12 +5297,10 @@ case OP_VOpen: {
|
|||||||
pVtab = pOp->p4.pVtab->pVtab;
|
pVtab = pOp->p4.pVtab->pVtab;
|
||||||
pModule = (sqlite3_module *)pVtab->pModule;
|
pModule = (sqlite3_module *)pVtab->pModule;
|
||||||
assert(pVtab && pModule);
|
assert(pVtab && pModule);
|
||||||
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
|
|
||||||
rc = pModule->xOpen(pVtab, &pVtabCursor);
|
rc = pModule->xOpen(pVtab, &pVtabCursor);
|
||||||
sqlite3DbFree(db, p->zErrMsg);
|
sqlite3DbFree(db, p->zErrMsg);
|
||||||
p->zErrMsg = pVtab->zErrMsg;
|
p->zErrMsg = pVtab->zErrMsg;
|
||||||
pVtab->zErrMsg = 0;
|
pVtab->zErrMsg = 0;
|
||||||
if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
|
|
||||||
if( SQLITE_OK==rc ){
|
if( SQLITE_OK==rc ){
|
||||||
/* Initialize sqlite3_vtab_cursor base class */
|
/* Initialize sqlite3_vtab_cursor base class */
|
||||||
pVtabCursor->pVtab = pVtab;
|
pVtabCursor->pVtab = pVtab;
|
||||||
@@ -5394,7 +5374,6 @@ case OP_VFilter: { /* jump */
|
|||||||
sqlite3VdbeMemStoreType(apArg[i]);
|
sqlite3VdbeMemStoreType(apArg[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
|
|
||||||
p->inVtabMethod = 1;
|
p->inVtabMethod = 1;
|
||||||
rc = pModule->xFilter(pVtabCursor, iQuery, pOp->p4.z, nArg, apArg);
|
rc = pModule->xFilter(pVtabCursor, iQuery, pOp->p4.z, nArg, apArg);
|
||||||
p->inVtabMethod = 0;
|
p->inVtabMethod = 0;
|
||||||
@@ -5404,7 +5383,6 @@ case OP_VFilter: { /* jump */
|
|||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
res = pModule->xEof(pVtabCursor);
|
res = pModule->xEof(pVtabCursor);
|
||||||
}
|
}
|
||||||
if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
|
|
||||||
|
|
||||||
if( res ){
|
if( res ){
|
||||||
pc = pOp->p2 - 1;
|
pc = pOp->p2 - 1;
|
||||||
@@ -5450,7 +5428,6 @@ case OP_VColumn: {
|
|||||||
sqlite3VdbeMemMove(&sContext.s, pDest);
|
sqlite3VdbeMemMove(&sContext.s, pDest);
|
||||||
MemSetTypeFlag(&sContext.s, MEM_Null);
|
MemSetTypeFlag(&sContext.s, MEM_Null);
|
||||||
|
|
||||||
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
|
|
||||||
rc = pModule->xColumn(pCur->pVtabCursor, &sContext, pOp->p2);
|
rc = pModule->xColumn(pCur->pVtabCursor, &sContext, pOp->p2);
|
||||||
sqlite3DbFree(db, p->zErrMsg);
|
sqlite3DbFree(db, p->zErrMsg);
|
||||||
p->zErrMsg = pVtab->zErrMsg;
|
p->zErrMsg = pVtab->zErrMsg;
|
||||||
@@ -5468,9 +5445,6 @@ case OP_VColumn: {
|
|||||||
REGISTER_TRACE(pOp->p3, pDest);
|
REGISTER_TRACE(pOp->p3, pDest);
|
||||||
UPDATE_MAX_BLOBSIZE(pDest);
|
UPDATE_MAX_BLOBSIZE(pDest);
|
||||||
|
|
||||||
if( sqlite3SafetyOn(db) ){
|
|
||||||
goto abort_due_to_misuse;
|
|
||||||
}
|
|
||||||
if( sqlite3VdbeMemTooBig(pDest) ){
|
if( sqlite3VdbeMemTooBig(pDest) ){
|
||||||
goto too_big;
|
goto too_big;
|
||||||
}
|
}
|
||||||
@@ -5507,7 +5481,6 @@ case OP_VNext: { /* jump */
|
|||||||
** data is available) and the error code returned when xColumn or
|
** data is available) and the error code returned when xColumn or
|
||||||
** some other method is next invoked on the save virtual table cursor.
|
** some other method is next invoked on the save virtual table cursor.
|
||||||
*/
|
*/
|
||||||
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
|
|
||||||
p->inVtabMethod = 1;
|
p->inVtabMethod = 1;
|
||||||
rc = pModule->xNext(pCur->pVtabCursor);
|
rc = pModule->xNext(pCur->pVtabCursor);
|
||||||
p->inVtabMethod = 0;
|
p->inVtabMethod = 0;
|
||||||
@@ -5517,7 +5490,6 @@ case OP_VNext: { /* jump */
|
|||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
res = pModule->xEof(pCur->pVtabCursor);
|
res = pModule->xEof(pCur->pVtabCursor);
|
||||||
}
|
}
|
||||||
if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
|
|
||||||
|
|
||||||
if( !res ){
|
if( !res ){
|
||||||
/* If there is data, jump to P2 */
|
/* If there is data, jump to P2 */
|
||||||
@@ -5543,12 +5515,10 @@ case OP_VRename: {
|
|||||||
assert( pVtab->pModule->xRename );
|
assert( pVtab->pModule->xRename );
|
||||||
REGISTER_TRACE(pOp->p1, pName);
|
REGISTER_TRACE(pOp->p1, pName);
|
||||||
assert( pName->flags & MEM_Str );
|
assert( pName->flags & MEM_Str );
|
||||||
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
|
|
||||||
rc = pVtab->pModule->xRename(pVtab, pName->z);
|
rc = pVtab->pModule->xRename(pVtab, pName->z);
|
||||||
sqlite3DbFree(db, p->zErrMsg);
|
sqlite3DbFree(db, p->zErrMsg);
|
||||||
p->zErrMsg = pVtab->zErrMsg;
|
p->zErrMsg = pVtab->zErrMsg;
|
||||||
pVtab->zErrMsg = 0;
|
pVtab->zErrMsg = 0;
|
||||||
if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -5599,12 +5569,10 @@ case OP_VUpdate: {
|
|||||||
apArg[i] = pX;
|
apArg[i] = pX;
|
||||||
pX++;
|
pX++;
|
||||||
}
|
}
|
||||||
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
|
|
||||||
rc = pModule->xUpdate(pVtab, nArg, apArg, &rowid);
|
rc = pModule->xUpdate(pVtab, nArg, apArg, &rowid);
|
||||||
sqlite3DbFree(db, p->zErrMsg);
|
sqlite3DbFree(db, p->zErrMsg);
|
||||||
p->zErrMsg = pVtab->zErrMsg;
|
p->zErrMsg = pVtab->zErrMsg;
|
||||||
pVtab->zErrMsg = 0;
|
pVtab->zErrMsg = 0;
|
||||||
if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
|
|
||||||
if( rc==SQLITE_OK && pOp->p1 ){
|
if( rc==SQLITE_OK && pOp->p1 ){
|
||||||
assert( nArg>1 && apArg[0] && (apArg[0]->flags&MEM_Null) );
|
assert( nArg>1 && apArg[0] && (apArg[0]->flags&MEM_Null) );
|
||||||
db->lastRowid = rowid;
|
db->lastRowid = rowid;
|
||||||
|
@@ -316,10 +316,6 @@ static int sqlite3Step(Vdbe *p){
|
|||||||
rc = SQLITE_ERROR;
|
rc = SQLITE_ERROR;
|
||||||
goto end_of_step;
|
goto end_of_step;
|
||||||
}
|
}
|
||||||
if( sqlite3SafetyOn(db) ){
|
|
||||||
p->rc = SQLITE_MISUSE;
|
|
||||||
return SQLITE_MISUSE;
|
|
||||||
}
|
|
||||||
if( p->pc<0 ){
|
if( p->pc<0 ){
|
||||||
/* If there are no other statements currently running, then
|
/* If there are no other statements currently running, then
|
||||||
** reset the interrupt flag. This prevents a call to sqlite3_interrupt
|
** reset the interrupt flag. This prevents a call to sqlite3_interrupt
|
||||||
@@ -352,10 +348,6 @@ static int sqlite3Step(Vdbe *p){
|
|||||||
rc = sqlite3VdbeExec(p);
|
rc = sqlite3VdbeExec(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( sqlite3SafetyOff(db) ){
|
|
||||||
rc = SQLITE_MISUSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef SQLITE_OMIT_TRACE
|
#ifndef SQLITE_OMIT_TRACE
|
||||||
/* Invoke the profile callback if there is one
|
/* Invoke the profile callback if there is one
|
||||||
*/
|
*/
|
||||||
|
@@ -1059,7 +1059,6 @@ int sqlite3VdbeList(
|
|||||||
|
|
||||||
assert( p->explain );
|
assert( p->explain );
|
||||||
assert( p->magic==VDBE_MAGIC_RUN );
|
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 );
|
assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY || p->rc==SQLITE_NOMEM );
|
||||||
|
|
||||||
/* Even though this opcode does not use dynamic strings for
|
/* 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;
|
sqlite3_vtab_cursor *pVtabCursor = pCx->pVtabCursor;
|
||||||
const sqlite3_module *pModule = pCx->pModule;
|
const sqlite3_module *pModule = pCx->pModule;
|
||||||
p->inVtabMethod = 1;
|
p->inVtabMethod = 1;
|
||||||
(void)sqlite3SafetyOff(p->db);
|
|
||||||
pModule->xClose(pVtabCursor);
|
pModule->xClose(pVtabCursor);
|
||||||
(void)sqlite3SafetyOn(p->db);
|
|
||||||
p->inVtabMethod = 0;
|
p->inVtabMethod = 0;
|
||||||
}
|
}
|
||||||
#endif
|
#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 there are any write-transactions at all, invoke the commit hook */
|
||||||
if( needXcommit && db->xCommitCallback ){
|
if( needXcommit && db->xCommitCallback ){
|
||||||
(void)sqlite3SafetyOff(db);
|
|
||||||
rc = db->xCommitCallback(db->pCommitArg);
|
rc = db->xCommitCallback(db->pCommitArg);
|
||||||
(void)sqlite3SafetyOn(db);
|
|
||||||
if( rc ){
|
if( rc ){
|
||||||
return SQLITE_CONSTRAINT;
|
return SQLITE_CONSTRAINT;
|
||||||
}
|
}
|
||||||
@@ -2213,9 +2208,7 @@ int sqlite3VdbeReset(Vdbe *p){
|
|||||||
** error, then it might not have been halted properly. So halt
|
** error, then it might not have been halted properly. So halt
|
||||||
** it now.
|
** it now.
|
||||||
*/
|
*/
|
||||||
(void)sqlite3SafetyOn(db);
|
|
||||||
sqlite3VdbeHalt(p);
|
sqlite3VdbeHalt(p);
|
||||||
(void)sqlite3SafetyOff(db);
|
|
||||||
|
|
||||||
/* If the VDBE has be run even partially, then transfer the error code
|
/* 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
|
** and error message from the VDBE into the main database structure. But
|
||||||
@@ -3017,7 +3010,7 @@ int sqlite3VdbeIdxKeyCompare(
|
|||||||
** that btreeParseCellPtr() and sqlite3GetVarint32() are implemented */
|
** that btreeParseCellPtr() and sqlite3GetVarint32() are implemented */
|
||||||
if( nCellKey<=0 || nCellKey>0x7fffffff ){
|
if( nCellKey<=0 || nCellKey>0x7fffffff ){
|
||||||
*res = 0;
|
*res = 0;
|
||||||
return SQLITE_CORRUPT;
|
return SQLITE_CORRUPT_BKPT;
|
||||||
}
|
}
|
||||||
memset(&m, 0, sizeof(m));
|
memset(&m, 0, sizeof(m));
|
||||||
rc = sqlite3VdbeMemFromBtree(pC->pCursor, 0, (int)nCellKey, 1, &m);
|
rc = sqlite3VdbeMemFromBtree(pC->pCursor, 0, (int)nCellKey, 1, &m);
|
||||||
|
@@ -95,13 +95,6 @@ int sqlite3_blob_open(
|
|||||||
memset(pParse, 0, sizeof(Parse));
|
memset(pParse, 0, sizeof(Parse));
|
||||||
pParse->db = db;
|
pParse->db = db;
|
||||||
|
|
||||||
if( sqlite3SafetyOn(db) ){
|
|
||||||
sqlite3DbFree(db, zErr);
|
|
||||||
sqlite3StackFree(db, pParse);
|
|
||||||
sqlite3_mutex_leave(db->mutex);
|
|
||||||
return SQLITE_MISUSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
sqlite3BtreeEnterAll(db);
|
sqlite3BtreeEnterAll(db);
|
||||||
pTab = sqlite3LocateTable(pParse, 0, zTable, zDb);
|
pTab = sqlite3LocateTable(pParse, 0, zTable, zDb);
|
||||||
if( pTab && IsVirtual(pTab) ){
|
if( pTab && IsVirtual(pTab) ){
|
||||||
@@ -121,7 +114,6 @@ int sqlite3_blob_open(
|
|||||||
pParse->zErrMsg = 0;
|
pParse->zErrMsg = 0;
|
||||||
}
|
}
|
||||||
rc = SQLITE_ERROR;
|
rc = SQLITE_ERROR;
|
||||||
(void)sqlite3SafetyOff(db);
|
|
||||||
sqlite3BtreeLeaveAll(db);
|
sqlite3BtreeLeaveAll(db);
|
||||||
goto blob_open_out;
|
goto blob_open_out;
|
||||||
}
|
}
|
||||||
@@ -136,7 +128,6 @@ int sqlite3_blob_open(
|
|||||||
sqlite3DbFree(db, zErr);
|
sqlite3DbFree(db, zErr);
|
||||||
zErr = sqlite3MPrintf(db, "no such column: \"%s\"", zColumn);
|
zErr = sqlite3MPrintf(db, "no such column: \"%s\"", zColumn);
|
||||||
rc = SQLITE_ERROR;
|
rc = SQLITE_ERROR;
|
||||||
(void)sqlite3SafetyOff(db);
|
|
||||||
sqlite3BtreeLeaveAll(db);
|
sqlite3BtreeLeaveAll(db);
|
||||||
goto blob_open_out;
|
goto blob_open_out;
|
||||||
}
|
}
|
||||||
@@ -177,7 +168,6 @@ int sqlite3_blob_open(
|
|||||||
sqlite3DbFree(db, zErr);
|
sqlite3DbFree(db, zErr);
|
||||||
zErr = sqlite3MPrintf(db, "cannot open %s column for writing", zFault);
|
zErr = sqlite3MPrintf(db, "cannot open %s column for writing", zFault);
|
||||||
rc = SQLITE_ERROR;
|
rc = SQLITE_ERROR;
|
||||||
(void)sqlite3SafetyOff(db);
|
|
||||||
sqlite3BtreeLeaveAll(db);
|
sqlite3BtreeLeaveAll(db);
|
||||||
goto blob_open_out;
|
goto blob_open_out;
|
||||||
}
|
}
|
||||||
@@ -227,8 +217,7 @@ int sqlite3_blob_open(
|
|||||||
}
|
}
|
||||||
|
|
||||||
sqlite3BtreeLeaveAll(db);
|
sqlite3BtreeLeaveAll(db);
|
||||||
rc = sqlite3SafetyOff(db);
|
if( db->mallocFailed ){
|
||||||
if( NEVER(rc!=SQLITE_OK) || db->mallocFailed ){
|
|
||||||
goto blob_open_out;
|
goto blob_open_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
22
src/vtab.c
22
src/vtab.c
@@ -123,16 +123,7 @@ void sqlite3VtabUnlock(VTable *pVTab){
|
|||||||
if( pVTab->nRef==0 ){
|
if( pVTab->nRef==0 ){
|
||||||
sqlite3_vtab *p = pVTab->pVtab;
|
sqlite3_vtab *p = pVTab->pVtab;
|
||||||
if( p ){
|
if( p ){
|
||||||
#ifdef SQLITE_DEBUG
|
p->pModule->xDisconnect(p);
|
||||||
if( pVTab->db->magic==SQLITE_MAGIC_BUSY ){
|
|
||||||
(void)sqlite3SafetyOff(db);
|
|
||||||
p->pModule->xDisconnect(p);
|
|
||||||
(void)sqlite3SafetyOn(db);
|
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
p->pModule->xDisconnect(p);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
sqlite3DbFree(db, pVTab);
|
sqlite3DbFree(db, pVTab);
|
||||||
}
|
}
|
||||||
@@ -468,9 +459,7 @@ static int vtabCallConstructor(
|
|||||||
db->pVTab = pTab;
|
db->pVTab = pTab;
|
||||||
|
|
||||||
/* Invoke the virtual table constructor */
|
/* Invoke the virtual table constructor */
|
||||||
(void)sqlite3SafetyOff(db);
|
|
||||||
rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr);
|
rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr);
|
||||||
(void)sqlite3SafetyOn(db);
|
|
||||||
if( rc==SQLITE_NOMEM ) db->mallocFailed = 1;
|
if( rc==SQLITE_NOMEM ) db->mallocFailed = 1;
|
||||||
|
|
||||||
if( SQLITE_OK!=rc ){
|
if( SQLITE_OK!=rc ){
|
||||||
@@ -717,10 +706,8 @@ int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab){
|
|||||||
if( ALWAYS(pTab!=0 && pTab->pVTable!=0) ){
|
if( ALWAYS(pTab!=0 && pTab->pVTable!=0) ){
|
||||||
VTable *p = vtabDisconnectAll(db, pTab);
|
VTable *p = vtabDisconnectAll(db, pTab);
|
||||||
|
|
||||||
rc = sqlite3SafetyOff(db);
|
|
||||||
assert( rc==SQLITE_OK );
|
assert( rc==SQLITE_OK );
|
||||||
rc = p->pMod->pModule->xDestroy(p->pVtab);
|
rc = p->pMod->pModule->xDestroy(p->pVtab);
|
||||||
(void)sqlite3SafetyOn(db);
|
|
||||||
|
|
||||||
/* Remove the sqlite3_vtab* from the aVTrans[] array, if applicable */
|
/* Remove the sqlite3_vtab* from the aVTrans[] array, if applicable */
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
@@ -772,10 +759,8 @@ static void callFinaliser(sqlite3 *db, int offset){
|
|||||||
int sqlite3VtabSync(sqlite3 *db, char **pzErrmsg){
|
int sqlite3VtabSync(sqlite3 *db, char **pzErrmsg){
|
||||||
int i;
|
int i;
|
||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
int rcsafety;
|
|
||||||
VTable **aVTrans = db->aVTrans;
|
VTable **aVTrans = db->aVTrans;
|
||||||
|
|
||||||
rc = sqlite3SafetyOff(db);
|
|
||||||
db->aVTrans = 0;
|
db->aVTrans = 0;
|
||||||
for(i=0; rc==SQLITE_OK && i<db->nVTrans; i++){
|
for(i=0; rc==SQLITE_OK && i<db->nVTrans; i++){
|
||||||
int (*x)(sqlite3_vtab *);
|
int (*x)(sqlite3_vtab *);
|
||||||
@@ -788,11 +773,6 @@ int sqlite3VtabSync(sqlite3 *db, char **pzErrmsg){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
db->aVTrans = aVTrans;
|
db->aVTrans = aVTrans;
|
||||||
rcsafety = sqlite3SafetyOn(db);
|
|
||||||
|
|
||||||
if( rc==SQLITE_OK ){
|
|
||||||
rc = rcsafety;
|
|
||||||
}
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1758,12 +1758,10 @@ static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){
|
|||||||
int i;
|
int i;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
(void)sqlite3SafetyOff(pParse->db);
|
|
||||||
WHERETRACE(("xBestIndex for %s\n", pTab->zName));
|
WHERETRACE(("xBestIndex for %s\n", pTab->zName));
|
||||||
TRACE_IDX_INPUTS(p);
|
TRACE_IDX_INPUTS(p);
|
||||||
rc = pVtab->pModule->xBestIndex(pVtab, p);
|
rc = pVtab->pModule->xBestIndex(pVtab, p);
|
||||||
TRACE_IDX_OUTPUTS(p);
|
TRACE_IDX_OUTPUTS(p);
|
||||||
(void)sqlite3SafetyOn(pParse->db);
|
|
||||||
|
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
if( rc==SQLITE_NOMEM ){
|
if( rc==SQLITE_NOMEM ){
|
||||||
|
@@ -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
|
|
Reference in New Issue
Block a user