diff --git a/manifest b/manifest index fb791e4527..80c82b8ffb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhancements\sto\sthe\squery\splanner\sto\sexploit\stransitive\srelationships\sin\sthe\nWHERE\sclause,\sand\sother\sminor\schanges\sto\sbring\sthe\ssessions\sbranch\sinto\nalignment\swith\sthe\strunk. -D 2013-01-25T02:10:06.424 +C Enhancements\sto\sthe\squery\splanner\sto\smake\suse\sof\sindices\sfor\sORDER\sBY\seven\nwhen\sIN\sconstraints\sare\sin\sthe\sWHERE\sclause.\s\sAdd\sextended\serror\scodes\sfor\nall\sSQLITE_CONSTRAINT\serrors. +D 2013-02-13T13:42:50.179 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a48faa9e7dd7d556d84f5456eabe5825dd8a6282 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -136,21 +136,21 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btree.c 7a80e4a67f32a2494c383a28a495bf3bd71cc230 F src/btree.h 3ad7964d6c5b1c7bff569aab6adfa075f8bf06cd F src/btreeInt.h 4e5c2bd0f9b36b2a815a6d84f771a61a65830621 -F src/build.c f4f86c07002c6f3ee96c1e34e0e993a962ef2c73 +F src/build.c 73ca65f32938e4e0d94e831b61b5749b211b79be F src/callback.c d7e46f40c3cf53c43550b7da7a1d0479910b62cc F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 72a70dcfda75d3a1f81041ce4573e7afddcd8e4e F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4 F src/delete.c 9bc9463952bdc9fc43111b1f9c83a0af9b8e2239 -F src/expr.c 4dff0b04eaaf133789279c6b8cd69175dfbb1691 +F src/expr.c f6c20285bd36e87ec47f4d840e90a32755e2a90c F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb -F src/fkey.c 5b7a12e2f8620e855b0478a9a6798df9967bb277 +F src/fkey.c e16942bd5c8a868ac53287886464a5ed0e72b179 F src/func.c 8147799b048065a1590805be464d05b4913e652c F src/global.c e59ecd2c553ad0d4bfbc84ca71231336f8993a7a F src/hash.c ac3470bbf1ca4ae4e306a8ecb0fdf1731810ffe4 F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c 36c17b9b97a9287aa8561f138d893ddf2b25d0b2 +F src/insert.c 02f8a1867088cb654eb756f98389f10441a65216 F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b @@ -173,37 +173,37 @@ F src/os.c e1acdc09ff3ac2412945cca9766e2dcf4675f31c F src/os.h 027491c77d2404c0a678bb3fb06286f331eb9b57 F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_unix.c dfdc04b126f7b05dcb2e2cc5c1262f98acbb49d9 -F src/os_win.c ce1f5db8a7bb4d6f2092b1b2cb9631bec54a6320 +F src/os_win.c e988c2de4266fbb3b8c58e4b5550a2e17f541327 F src/pager.c 4092c907222cfd451c74fe6bd2fd64b342f7190f F src/pager.h 1109a06578ec5574dc2c74cf8d9f69daf36fe3e0 F src/parse.y 5d5e12772845805fdfeb889163516b84fbb9ae95 F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 F src/pcache.h 1b5dcc3dc8103d03e625b177023ee67764fa6b7c F src/pcache1.c 9fd22671c270b35131ef480bbc00392b8b5f8ab9 -F src/pragma.c b7ef175454106000fae966b3948b19e807bffc89 +F src/pragma.c eb9d39e30f00e3ba51892749ddf9d7b86541c43e F src/prepare.c 931ad0d852a0df48f79adcba6ce79ca5f475625c F src/printf.c 4a9f882f1c1787a8b494a2987765acf9d97ac21f F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 -F src/resolve.c 0bca3bf694f14f96a13873d87f62d6a6f38f913f +F src/resolve.c 652ae6dc0f185b01b4536bb2fa7d878f13f0f1df F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c 395e458a6dc611cbe1179f424753f0c344957607 -F src/shell.c af0309c2491a0d82ded1c2af3f64fcdb29d26ad5 -F src/sqlite.h.in 6a7a592aacc98674f39cb520cb7a7af87c2c2438 +F src/select.c 7818b5c9b497499d8bd8c6d0e347a3cf67724867 +F src/shell.c 266791241d7add796ccce2317977ae6c3c67d77f +F src/sqlite.h.in ebb2e60b1d92290597f8520dc55a5885c88aefc0 F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 -F src/sqliteInt.h aa9282588b320654c0efa4379737a05e8f6616e4 +F src/sqliteInt.h 61a59586451072ec2b3aaa209e5df87fa6e1bf75 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c bedc37ec1a6bb9399944024d63f4c769971955a9 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e F src/tclsqlite.c bc021495cad081c13ccdcebd524857aedd831e11 -F src/test1.c f62769c989146149590662ab02de4a813813a9c5 +F src/test1.c 50003e3beccad5569f757598fc7ce81b4f21aa7e F src/test2.c 4178056dd1e7d70f954ad8a1e3edb71a2a784daf F src/test3.c 3c3c2407fa6ec7a19e24ae23f7cb439d0275a60d F src/test4.c bf9fa9bece01de08e6f5e02314e4af5c13590dfa F src/test5.c a6d1ac55ac054d0b2b8f37b5e655b6c92645a013 F src/test6.c 938794c970ed6810036c8d28450ca28166524bf7 F src/test7.c 2e0781754905c8adc3268d8f0967e7633af58843 -F src/test8.c 8bcce65e5ee027fbfd7da41d28371aabbfd369ff +F src/test8.c 58ea1d9698f3947e4662107ef98f429e84ae20e0 F src/test9.c bea1e8cf52aa93695487badedd6e1886c321ea60 F src/test_async.c 0612a752896fad42d55c3999a5122af10dcf22ad F src/test_autoext.c 30e7bd98ab6d70a62bb9ba572e4c7df347fe645e @@ -234,7 +234,7 @@ F src/test_regexp.c 58e0349f155bc307dfa209df4b03add0a7749866 F src/test_rtree.c aba603c949766c4193f1068b91c787f57274e0d9 F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0 F src/test_server.c 2f99eb2837dfa06a4aacf24af24c6affdf66a84f -F src/test_spellfix.c 76dd8d3111d2f5354c374f71fa23b752bd0b029c +F src/test_spellfix.c 860eb723100d4e3cff846ba5d25e02815b2a5cac F src/test_sqllog.c 8acb843ddb9928dea8962e31bb09f421a72ffccb F src/test_stat.c d1569c7a4839f13e80187e2c26b2ab4da2d03935 F src/test_superlock.c 2b97936ca127d13962c3605dbc9a4ef269c424cd @@ -251,11 +251,11 @@ F src/update.c abb0fcabe551dae0a133fd2a4370b5a8c23b1831 F src/utf.c 8d819e2e5104a430fc2005f018db14347c95a38f F src/util.c 0af2e515dc0dabacec931bca39525f6c3f1c5455 F src/vacuum.c 2727bdd08847fcb6b2d2da6d14f018910e8645d3 -F src/vdbe.c 4cf34269ba3a2f405eb4eb966c793baa07d863c0 +F src/vdbe.c 9e4164ac85aa01e1a563e6c7f565b106ff0bf67b F src/vdbe.h 1223e2548e0970cf96f573ff6b99f804a36ad683 -F src/vdbeInt.h 2de43968dc47f1961d5bc76aa3cb68eacf433a7c +F src/vdbeInt.h 0112cab1c820a599005c6bcc9504bdb17f5dbcdb F src/vdbeapi.c 58fdcd56109c05876f69c25d47a138ef370d3647 -F src/vdbeaux.c 570714c7e2440da1b04689171124d84ef3015cd4 +F src/vdbeaux.c 684c159170453c8a118786b9c174627ece825f3a F src/vdbeblob.c 11248c6362389569764682eb0f59ce910f3cc381 F src/vdbemem.c cb55e84b8e2c15704968ee05f0fae25883299b74 F src/vdbesort.c c61ca318681c0e7267da8be3abfca8469652a7e9 @@ -264,7 +264,7 @@ F src/vtab.c b05e5f1f4902461ba9f5fc49bb7eb7c3a0741a83 F src/wal.c f5c7b5027d0ed0e9bc9afeb4a3a8dfea762ec7d2 F src/wal.h 29c197540b19044e6cd73487017e5e47a1d3dac6 F src/walker.c 3d75ba73de15e0f8cd0737643badbeb0e002f07b -F src/where.c 374a6c8190f863b3c69780b441d799e8a6b9e21b +F src/where.c 43e05406f0e05960a62d4719ed77f551f8204d3f F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6 @@ -328,7 +328,7 @@ F test/boundary4.tcl 0bb4b1a94f4fc5ae59b79b9a2b7a140c405e2983 F test/boundary4.test 89e02fa66397b8a325d5eb102b5806f961f8ec4b F test/busy.test 76b4887f8b9160ba903c1ac22e8ff406ad6ae2f0 F test/cache.test f64136b0893c293d0b910ed057b3b711249099a7 -F test/capi2.test 835d4cee9f542ea50fa8d01f3fe6de80b0627360 +F test/capi2.test e8b18cc61090b6e5e388f54d6b125d711d1b265a F test/capi3.test 56ab450125ead38846cbae7e5b6a216686c3cffa F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4 F test/capi3c.test 93d24621c9ff84da9da060f30431e0453db1cdb0 @@ -349,7 +349,7 @@ F test/collate9.test 3adcc799229545940df2f25308dd1ad65869145a F test/collateA.test b8218ab90d1fa5c59dcf156efabb1b2599c580d6 F test/colmeta.test 087c42997754b8c648819832241daf724f813322 F test/colname.test 08948a4809d22817e0e5de89c7c0a8bd90cb551b -F test/conflict.test cabc41f7616675df71b4fddabca3bd5d9221915a +F test/conflict.test 0b3922d2304a14a47e3ccd61bbd6824327af659b F test/corrupt.test 4aabd06cff3fe759e3e658bcc17b71789710665e F test/corrupt2.test 9c0ab4becd50e9050bc1ebb8675456a4e5587bf0 F test/corrupt3.test 889d7cdb811800303aa722d7813fe8a4299cf726 @@ -412,7 +412,7 @@ F test/enc2.test 796c59832e2b9a52842f382ffda8f3e989db03ad F test/enc3.test 90683ad0e6ea587b9d5542ca93568af9a9858c40 F test/enc4.test c8f1ce3618508fd0909945beb8b8831feef2c020 F test/eqp.test 46aa946dd55c90635327898275d3e533d23a9845 -F test/errmsg.test 3bb606db9d040cc6854459f8f5e5a2bcd9b7fd2a +F test/errmsg.test 050717f1c6a5685de9c79f5f9f6b83d7c592f73a F test/eval.test bc269c365ba877554948441e91ad5373f9f91be3 F test/exclusive.test a1b324cb21834a490cd052d409d34789cfef57cb F test/exclusive2.test 372be98f6de44dd78734e364b7b626ea211761a6 @@ -423,9 +423,9 @@ F test/fallocate.test b5d34437bd7ab01d41b1464b8117aefd4d32160e F test/filectrl.test 14fa712e42c4cb791e09dfd58a6a03efb47ef13a F test/filefmt.test dbee33e57818249cdffbbb7b13464635217beff1 F test/fkey1.test 01c7de578e11747e720c2d9aeef27f239853c4da -F test/fkey2.test 5aa44e7153928a1f002803f94aaab4c76a7ceac2 +F test/fkey2.test 06e0b4cc9e1b3271ae2ae6feeb19755468432111 F test/fkey3.test 5ec899d12b13bcf1e9ef40eff7fb692fdb91392e -F test/fkey4.test c6c8f9f9be885f95c85c7bceb26f243ad906fd49 +F test/fkey4.test 86446017011273aad8f9a99c1a65019e7bd9ca9d F test/fkey5.test 0bf64f2d19ad80433ca0b24edbf604a18b353d5f F test/fkey_malloc.test bb74c9cb8f8fceed03b58f8a7ef2df98520bbd51 F test/format4.test 1f0cac8ff3895e9359ed87e41aaabee982a812eb @@ -518,7 +518,7 @@ F test/fts4langid.test 24a6e41063b416bbdf371ff6b4476fa41c194aa7 F test/fts4merge.test c424309743fdd203f8e56a1f1cd7872cd66cc0ee F test/fts4merge2.test 5faa558d1b672f82b847d2a337465fa745e46891 F test/fts4merge3.test aab02a09f50fe6baaddc2e159c3eabc116d45fc7 -F test/fts4unicode.test aad033abdcfa0f87ce5f56468f59fdf2a0acbcef +F test/fts4unicode.test 25ccad45896f8e50f6a694cff738a35f798cdb40 F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d F test/func.test 0d89043dab9a8853358d14c68e028ee0093bf066 F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f @@ -531,7 +531,7 @@ F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26 F test/fuzzer1.test a2e93bb1e19513dd6bf9c63d3d7c4673c983ca19 F test/fuzzerfault.test ff2282c81797b6a355f0748d8b54c7287c5d2b25 -F test/hook.test 94b927b15883f5c1477ab09eecd16275addb08f4 +F test/hook.test 777b2541f6dd4f4ca5e8d6b66c1df1b3717aeab6 F test/icu.test 70df4faca133254c042d02ae342c0a141f2663f4 F test/in.test 5941096407d8c133b9eff15bd3e666624b6cbde3 F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75 @@ -588,7 +588,7 @@ F test/lastinsert.test 474d519c68cb79d07ecae56a763aa7f322c72f51 F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200 F test/like.test 0e5412f4dac4a849f613e1ef8b529d56a6e31d08 F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da -F test/limit.test 2db7b3b34fb925b8e847d583d2eb67531d0ce67e +F test/limit.test cc0ab63385239b63c72452b0e93700bf5e8f0b99 F test/loadext.test 2b5e249c51c986a5aff1f0950cf7ba30976c8f22 F test/loadext2.test 0bcaeb4d81cd5b6e883fdfea3c1bdbe1f173cbca F test/lock.test 87af515b0c4cf928576d0f89946d67d7c265dfb4 @@ -650,7 +650,7 @@ F test/nan.test e9648b9d007c7045242af35e11a984d4b169443a F test/notify1.test 669b2b743618efdc18ca4b02f45423d5d2304abf F test/notify2.test 9503e51b9a272a5405c205ad61b7623d5a9ca489 F test/notify3.test a86259abbfb923aa27d30f0fc038c88e5251488a -F test/notnull.test cc7c78340328e6112a13c3e311a9ab3127114347 +F test/notnull.test 2afad748d18fd66d01f66463de73b3e2501fb226 F test/null.test a8b09b8ed87852742343b33441a9240022108993 F test/openv2.test 0d3040974bf402e19b7df4b783e447289d7ab394 F test/orderby1.test f33968647da5c546528fe4d2bf86c6a6a2e5a7ae @@ -728,7 +728,7 @@ F test/shared8.test b27befbefbe7f4517f1d6b7ff8f64a41ec74165d F test/shared9.test 5f2a8f79b4d6c7d107a01ffa1ed05ae7e6333e21 F test/shared_err.test 0079c05c97d88cfa03989b7c20a8b266983087aa F test/sharedlock.test ffa0a3c4ac192145b310f1254f8afca4d553eabf -F test/shell1.test 392a265895e63cff2de1c78554e3b5b1cbbe9b8a +F test/shell1.test 4a2f57952719972c6f862134463f8712e953c038 F test/shell2.test 037d6ad16e873354195d30bb2dc4b5321788154a F test/shell3.test 9196c42772d575685e722c92b4b39053c6ebba59 F test/shell4.test aa4eef8118b412d1a01477a53426ece169ea86a9 @@ -765,7 +765,7 @@ F test/tclsqlite.test a7308276aad2e6c0bfb5b0414424dd0d9cc0cad7 F test/tempdb.test 19d0f66e2e3eeffd68661a11c83ba5e6ace9128c F test/temptable.test 51edd31c65ed1560dd600b1796e8325df96318e2 F test/temptrigger.test 26670ed7a39cf2296a7f0a9e0a1d7bdb7abe936d -F test/tester.tcl ac81733138d2b159f0b7f0379b6509e301f47cd4 +F test/tester.tcl 92c630363217d4e2af8464d1acd387fadd710ab7 F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5 F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58 F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7 @@ -910,9 +910,9 @@ F test/trans.test 6e1b4c6a42dba31bd65f8fa5e61a2708e08ddde6 F test/trans2.test d5337e61de45e66b1fcbf9db833fa8c82e624b22 F test/trans3.test 373ac5183cc56be69f48ae44090e7f672939f732 F test/transitive1.test d04aa9023e425d6f2d4aa61dd81ee9e102f89062 -F test/trigger1.test 30f343f91586765874a28ad539c06f5a5f049931 +F test/trigger1.test dc47573ac79ffe0ee3eecaa517d70d8dacbccd03 F test/trigger2.test 834187beafd1db383af0c659cfa49b0576832816 -F test/trigger3.test d2c60d8be271c355d61727411e753181e877230a +F test/trigger3.test aa640bb2bbb03edd5ff69c055117ea088f121945 F test/trigger4.test 74700b76ebf3947b2f7a92405141eb2cf2a5d359 F test/trigger5.test 619391a3e9fc194081d22cefd830d811e7badf83 F test/trigger6.test 0e411654f122552da6590f0b4e6f781048a4a9b9 @@ -927,7 +927,7 @@ F test/tt3_checkpoint.c 415eccce672d681b297485fc20f44cdf0eac93af F test/types.test bf816ce73c7dfcfe26b700c19f97ef4050d194ff F test/types2.test 3555aacf8ed8dc883356e59efc314707e6247a84 F test/types3.test 99e009491a54f4dc02c06bdbc0c5eea56ae3e25a -F test/unique.test 083c7fff74695bcc27a71d75699deba3595bc9c2 +F test/unique.test cadb172bbd5a2e83cd644d186ccd602085e54edc F test/unixexcl.test a9870e46cc6f8390a494513d4f2bf55b5a8b3e46 F test/unordered.test 93dce7b6c97a817a4fe26980c484605a4511f614 F test/update.test 8bc86fd7ef1a00014f76dc6a6a7c974df4aef172 @@ -939,7 +939,7 @@ F test/vacuum3.test 77ecdd54592b45a0bcb133339f99f1ae0ae94d0d F test/vacuum4.test d3f8ecff345f166911568f397d2432c16d2867d9 F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102 F test/veryquick.test 7701bb609fe8bf6535514e8b849a309e8f00573b -F test/view.test b182a67ec43f490b156b5a710827a341be83dd17 +F test/view.test 977eb3fa17b44f73fc2b636172dc9136311024ce F test/vtab1.test 4403f987860ebddef1ce2de6db7216421035339d F test/vtab2.test 7bcffc050da5c68f4f312e49e443063e2d391c0d F test/vtab3.test baad99fd27217f5d6db10660522e0b7192446de1 @@ -983,8 +983,8 @@ F test/walro.test a31deb621033442a76c3a61e44929250d06f81b1 F test/walshared.test 6dda2293880c300baf5d791c307f653094585761 F test/walslow.test e7be6d9888f83aa5d3d3c7c08aa9b5c28b93609a F test/walthread.test de8dbaf6d9e41481c460ba31ca61e163d7348f8e -F test/where.test 9714e6f292d70c22e78e1cecb3d896457186b9b7 -F test/where2.test 43d4becaf5a5df854e6c21d624a1cb84c6904554 +F test/where.test 15ac8611c9439a2c5f4a6ac10cfe4c1ec9854c24 +F test/where2.test 399b3178289925a0aa976b3d60ef139740540ecd F test/where3.test 667e75642102c97a00bf9b23d3cb267db321d006 F test/where4.test e9b9e2f2f98f00379e6031db6a6fca29bae782a2 F test/where5.test fdf66f96d29a064b63eb543e28da4dfdccd81ad2 @@ -1004,7 +1004,7 @@ F test/win32lock.test b2a539e85ae6b2d78475e016a9636b4451dc7fb9 F test/zeroblob.test caaecfb4f908f7bc086ed238668049f96774d688 F test/zerodamage.test e7f77fded01dfcdf92ac2c5400f1e35d7a21463c F tool/build-all-msvc.bat 74fb6e5cca66ebdb6c9bbafb2f8b802f08146d38 x -F tool/build-shell.sh 562df23cfdd25822b909b382afd5f99d968437fe +F tool/build-shell.sh a9c34a606e2e522ba9eeca1e07090f67dce8c912 F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2 F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b F tool/extract.c 054069d81b095fbdc189a6f5d4466e40380505e2 @@ -1029,7 +1029,7 @@ F tool/restore_jrnl.tcl 6957a34f8f1f0f8285e07536225ec3b292a9024a F tool/rollback-test.c 9fc98427d1e23e84429d7e6d07d9094fbdec65a5 F tool/showdb.c aca2644aa4de7c0cad5821e50bbd55397e0974b8 F tool/showjournal.c b62cecaab86a4053d944c276bb5232e4d17ece02 -F tool/showwal.c f09e5a80a293919290ec85a6a37c85a5ddcf37d9 +F tool/showwal.c 3f7f7da5ec0cba51b1449a75f700493377da57b5 F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe F tool/space_used.tcl f714c41a59e326b8b9042f415b628b561bafa06b F tool/spaceanal.tcl 76f583a246a0b027f423252339e711f13198932e @@ -1047,7 +1047,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 34af6fac679aeb18ab8349f74e95f3cb6e722ea4 f1127e87b90c7ba049404ec68cb4e99009c22185 -R 0f44bd61453292415328773cf0329dea +P 82d3d1ae824e1fbc7958657be79231590ec17ace 2cef8b68f0e1216cf68bb7dd45a5a9a330748070 +R e54b78fdc1653174f63d383c576bd990 U drh -Z ad09dedaf38b5f33a2fcbd082e7bc0e7 +Z ee3bd01f1e30ad2e6302010368aa9999 diff --git a/manifest.uuid b/manifest.uuid index b02a34a62e..cb2d1c59b2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -82d3d1ae824e1fbc7958657be79231590ec17ace \ No newline at end of file +7e14dc734d7d941da5c3aa6612e26d93b5b929bd \ No newline at end of file diff --git a/src/build.c b/src/build.c index c21f0172a9..4ce65a43d7 100644 --- a/src/build.c +++ b/src/build.c @@ -2447,8 +2447,8 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ sqlite3VdbeAddOp2(v, OP_Goto, 0, j2); addr2 = sqlite3VdbeCurrentAddr(v); sqlite3VdbeAddOp3(v, OP_SorterCompare, iSorter, j2, regRecord); - sqlite3HaltConstraint( - pParse, OE_Abort, "indexed columns are not unique", P4_STATIC + sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_UNIQUE, + OE_Abort, "indexed columns are not unique", P4_STATIC ); }else{ addr2 = sqlite3VdbeCurrentAddr(v); @@ -2474,8 +2474,8 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ ** since sqlite3ReleaseTempRange() was called, it is safe to do so. */ sqlite3VdbeAddOp4(v, OP_IsUnique, iIdx, j2, regRowid, pRegKey, P4_INT32); - sqlite3HaltConstraint( - pParse, OE_Abort, "indexed columns are not unique", P4_STATIC); + sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_UNIQUE, + "indexed columns are not unique", P4_STATIC); } sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 0); sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); @@ -3692,12 +3692,19 @@ void sqlite3MayAbort(Parse *pParse){ ** error. The onError parameter determines which (if any) of the statement ** and/or current transaction is rolled back. */ -void sqlite3HaltConstraint(Parse *pParse, int onError, char *p4, int p4type){ +void sqlite3HaltConstraint( + Parse *pParse, /* Parsing context */ + int errCode, /* extended error code */ + int onError, /* Constraint type */ + char *p4, /* Error message */ + int p4type /* P4_STATIC or P4_TRANSIENT */ +){ Vdbe *v = sqlite3GetVdbe(pParse); + assert( (errCode&0xff)==SQLITE_CONSTRAINT ); if( onError==OE_Abort ){ sqlite3MayAbort(pParse); } - sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, onError, 0, p4, p4type); + sqlite3VdbeAddOp4(v, OP_Halt, errCode, onError, 0, p4, p4type); } /* diff --git a/src/expr.c b/src/expr.c index 5ba2616919..5de468e211 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2935,7 +2935,8 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ sqlite3VdbeAddOp4( v, OP_Halt, SQLITE_OK, OE_Ignore, 0, pExpr->u.zToken,0); }else{ - sqlite3HaltConstraint(pParse, pExpr->affinity, pExpr->u.zToken, 0); + sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_TRIGGER, + pExpr->affinity, pExpr->u.zToken, 0); } break; diff --git a/src/fkey.c b/src/fkey.c index 421311dc35..ac35bc194c 100644 --- a/src/fkey.c +++ b/src/fkey.c @@ -21,8 +21,9 @@ ** -------------------------- ** ** Foreign keys in SQLite come in two flavours: deferred and immediate. -** If an immediate foreign key constraint is violated, SQLITE_CONSTRAINT -** is returned and the current statement transaction rolled back. If a +** If an immediate foreign key constraint is violated, +** SQLITE_CONSTRAINT_FOREIGNKEY is returned and the current +** statement transaction rolled back. If a ** deferred foreign key constraint is violated, no action is taken ** immediately. However if the application attempts to commit the ** transaction before fixing the constraint violation, the attempt fails. @@ -86,7 +87,8 @@ ** Immediate constraints are usually handled similarly. The only difference ** is that the counter used is stored as part of each individual statement ** object (struct Vdbe). If, after the statement has run, its immediate -** constraint counter is greater than zero, it returns SQLITE_CONSTRAINT +** constraint counter is greater than zero, +** it returns SQLITE_CONSTRAINT_FOREIGNKEY ** and the statement transaction is rolled back. An exception is an INSERT ** statement that inserts a single row only (no triggers). In this case, ** instead of using a counter, an exception is thrown immediately if the @@ -426,8 +428,8 @@ static void fkLookupParent( ** incrementing a counter. This is necessary as the VM code is being ** generated for will not open a statement transaction. */ assert( nIncr==1 ); - sqlite3HaltConstraint( - pParse, OE_Abort, "foreign key constraint failed", P4_STATIC + sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_FOREIGNKEY, + OE_Abort, "foreign key constraint failed", P4_STATIC ); }else{ if( nIncr>0 && pFKey->isDeferred==0 ){ @@ -667,8 +669,8 @@ void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTab){ ** any modifications to the schema are made. This is because statement ** transactions are not able to rollback schema changes. */ sqlite3VdbeAddOp2(v, OP_FkIfZero, 0, sqlite3VdbeCurrentAddr(v)+2); - sqlite3HaltConstraint( - pParse, OE_Abort, "foreign key constraint failed", P4_STATIC + sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_FOREIGNKEY, + OE_Abort, "foreign key constraint failed", P4_STATIC ); if( iSkip ){ diff --git a/src/insert.c b/src/insert.c index 806792aef4..140b43600f 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1245,7 +1245,7 @@ void sqlite3GenerateConstraintChecks( case OE_Fail: { char *zMsg; sqlite3VdbeAddOp3(v, OP_HaltIfNull, - SQLITE_CONSTRAINT, onError, regData+i); + SQLITE_CONSTRAINT_NOTNULL, onError, regData+i); zMsg = sqlite3MPrintf(db, "%s.%s may not be NULL", pTab->zName, pTab->aCol[i].zName); sqlite3VdbeChangeP4(v, -1, zMsg, P4_DYNAMIC); @@ -1285,7 +1285,8 @@ void sqlite3GenerateConstraintChecks( }else{ zConsName = 0; } - sqlite3HaltConstraint(pParse, onError, zConsName, P4_DYNAMIC); + sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_CHECK, + onError, zConsName, P4_DYNAMIC); } sqlite3VdbeResolveLabel(v, allOk); } @@ -1316,8 +1317,8 @@ void sqlite3GenerateConstraintChecks( case OE_Rollback: case OE_Abort: case OE_Fail: { - sqlite3HaltConstraint( - pParse, onError, "PRIMARY KEY must be unique", P4_STATIC); + sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_PRIMARYKEY, + onError, "PRIMARY KEY must be unique", P4_STATIC); break; } case OE_Replace: { @@ -1454,7 +1455,8 @@ void sqlite3GenerateConstraintChecks( sqlite3StrAccumAppend(&errMsg, pIdx->nColumn>1 ? " are not unique" : " is not unique", -1); zErr = sqlite3StrAccumFinish(&errMsg); - sqlite3HaltConstraint(pParse, onError, zErr, 0); + sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_UNIQUE, + onError, zErr, 0); sqlite3DbFree(errMsg.db, zErr); break; } @@ -1862,8 +1864,8 @@ static int xferOptimization( if( pDest->iPKey>=0 ){ addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid); addr2 = sqlite3VdbeAddOp3(v, OP_NotExists, iDest, 0, regRowid); - sqlite3HaltConstraint( - pParse, onError, "PRIMARY KEY must be unique", P4_STATIC); + sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_PRIMARYKEY, + onError, "PRIMARY KEY must be unique", P4_STATIC); sqlite3VdbeJumpHere(v, addr2); autoIncStep(pParse, regAutoinc, regRowid); }else if( pDest->pIndex==0 ){ diff --git a/src/os_win.c b/src/os_win.c index 107370c41b..bbc9c27b7a 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -988,7 +988,7 @@ static const char *winNextSystemCall(sqlite3_vfs *p, const char *zName){ ** (if available). */ -void sqlite3_win32_write_debug(char *zBuf, int nBuf){ +void sqlite3_win32_write_debug(const char *zBuf, int nBuf){ char zDbgBuf[SQLITE_WIN32_DBG_BUF_SIZE]; int nMin = MIN(nBuf, (SQLITE_WIN32_DBG_BUF_SIZE - 1)); /* may be negative. */ if( nMin<-1 ) nMin = -1; /* all negative values become -1. */ @@ -1621,9 +1621,10 @@ static void logIoerr(int nRetry){ /************************************************************************* ** This section contains code for WinCE only. */ +#if !defined(SQLITE_MSVC_LOCALTIME_API) || !SQLITE_MSVC_LOCALTIME_API /* -** Windows CE does not have a localtime() function. So create a -** substitute. +** The MSVC CRT on Windows CE may not have a localtime() function. So +** create a substitute. */ #include struct tm *__cdecl localtime(const time_t *t) @@ -1647,6 +1648,7 @@ struct tm *__cdecl localtime(const time_t *t) y.tm_sec = pTm.wSecond; return &y; } +#endif #define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-(int)offsetof(winFile,h)] @@ -1668,15 +1670,17 @@ static void winceMutexAcquire(HANDLE h){ ** Create the mutex and shared memory used for locking in the file ** descriptor pFile */ -static BOOL winceCreateLock(const char *zFilename, winFile *pFile){ +static int winceCreateLock(const char *zFilename, winFile *pFile){ LPWSTR zTok; LPWSTR zName; + DWORD lastErrno; + BOOL bLogged = FALSE; BOOL bInit = TRUE; zName = utf8ToUnicode(zFilename); if( zName==0 ){ /* out of memory */ - return FALSE; + return SQLITE_IOERR_NOMEM; } /* Initialize the local lockdata */ @@ -1693,9 +1697,10 @@ static BOOL winceCreateLock(const char *zFilename, winFile *pFile){ pFile->hMutex = osCreateMutexW(NULL, FALSE, zName); if (!pFile->hMutex){ pFile->lastErrno = osGetLastError(); - winLogError(SQLITE_ERROR, pFile->lastErrno, "winceCreateLock1", zFilename); + winLogError(SQLITE_IOERR, pFile->lastErrno, + "winceCreateLock1", zFilename); sqlite3_free(zName); - return FALSE; + return SQLITE_IOERR; } /* Acquire the mutex before continuing */ @@ -1712,41 +1717,49 @@ static BOOL winceCreateLock(const char *zFilename, winFile *pFile){ /* Set a flag that indicates we're the first to create the memory so it ** must be zero-initialized */ - if (osGetLastError() == ERROR_ALREADY_EXISTS){ + lastErrno = osGetLastError(); + if (lastErrno == ERROR_ALREADY_EXISTS){ bInit = FALSE; } sqlite3_free(zName); /* If we succeeded in making the shared memory handle, map it. */ - if (pFile->hShared){ + if( pFile->hShared ){ pFile->shared = (winceLock*)osMapViewOfFile(pFile->hShared, FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, sizeof(winceLock)); /* If mapping failed, close the shared memory handle and erase it */ - if (!pFile->shared){ + if( !pFile->shared ){ pFile->lastErrno = osGetLastError(); - winLogError(SQLITE_ERROR, pFile->lastErrno, - "winceCreateLock2", zFilename); + winLogError(SQLITE_IOERR, pFile->lastErrno, + "winceCreateLock2", zFilename); + bLogged = TRUE; osCloseHandle(pFile->hShared); pFile->hShared = NULL; } } /* If shared memory could not be created, then close the mutex and fail */ - if (pFile->hShared == NULL){ + if( pFile->hShared==NULL ){ + if( !bLogged ){ + pFile->lastErrno = lastErrno; + winLogError(SQLITE_IOERR, pFile->lastErrno, + "winceCreateLock3", zFilename); + bLogged = TRUE; + } winceMutexRelease(pFile->hMutex); osCloseHandle(pFile->hMutex); pFile->hMutex = NULL; - return FALSE; + return SQLITE_IOERR; } /* Initialize the shared memory if we're supposed to */ - if (bInit) { + if( bInit ){ memset(pFile->shared, 0, sizeof(winceLock)); } winceMutexRelease(pFile->hMutex); - return TRUE; + return SQLITE_OK; } /* @@ -2755,7 +2768,7 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){ return SQLITE_OK; } case SQLITE_FCNTL_TEMPFILENAME: { - char *zTFile = sqlite3_malloc( pFile->pVfs->mxPathname ); + char *zTFile = sqlite3MallocZero( pFile->pVfs->mxPathname ); if( zTFile ){ getTempname(pFile->pVfs->mxPathname, zTFile); *(char**)pArg = zTFile; @@ -3691,6 +3704,7 @@ static int winOpen( */ if( !zUtf8Name ){ assert(isDelete && !isOpenJournal); + memset(zTmpname, 0, MAX_PATH+2); rc = getTempname(MAX_PATH+2, zTmpname); if( rc!=SQLITE_OK ){ return rc; @@ -3842,11 +3856,11 @@ static int winOpen( #if SQLITE_OS_WINCE if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB - && !winceCreateLock(zName, pFile) + && (rc = winceCreateLock(zName, pFile))!=SQLITE_OK ){ osCloseHandle(h); sqlite3_free(zConverted); - return SQLITE_CANTOPEN_BKPT; + return rc; } if( isTemp ){ pFile->zDeleteOnClose = zConverted; diff --git a/src/pragma.c b/src/pragma.c index 7d116d5bbc..babcbec629 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -184,6 +184,9 @@ static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){ { "sql_trace", SQLITE_SqlTrace }, { "vdbe_listing", SQLITE_VdbeListing }, { "vdbe_trace", SQLITE_VdbeTrace }, + { "vdbe_addoptrace", SQLITE_VdbeAddopTrace}, + { "vdbe_debug", SQLITE_SqlTrace | SQLITE_VdbeListing + | SQLITE_VdbeTrace }, #endif #ifndef SQLITE_OMIT_CHECK { "ignore_check_constraints", SQLITE_IgnoreChecks }, diff --git a/src/resolve.c b/src/resolve.c index aeeec8837d..f8cd9e5ab2 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -263,8 +263,8 @@ static int lookupName( assert( pTab!=0 && pTab->zName!=0 ); assert( pTab->nCol>0 ); if( pItem->pSelect && (pItem->pSelect->selFlags & SF_NestedFrom)!=0 ){ - ExprList *pEList = pItem->pSelect->pEList; int hit = 0; + pEList = pItem->pSelect->pEList; for(j=0; jnExpr; j++){ if( sqlite3MatchSpanName(pEList->a[j].zSpan, zCol, zTab, zDb) ){ cnt++; diff --git a/src/select.c b/src/select.c index 3168894802..2e778a57d5 100644 --- a/src/select.c +++ b/src/select.c @@ -1707,6 +1707,8 @@ static int multiSelect( int addr = 0; int nLimit; assert( !pPrior->pLimit ); + pPrior->iLimit = p->iLimit; + pPrior->iOffset = p->iOffset; pPrior->pLimit = p->pLimit; pPrior->pOffset = p->pOffset; explainSetInteger(iSub1, pParse->iNextSelectId); @@ -2963,12 +2965,15 @@ static int flattenSubquery( Select *pNew; ExprList *pOrderBy = p->pOrderBy; Expr *pLimit = p->pLimit; + Expr *pOffset = p->pOffset; Select *pPrior = p->pPrior; p->pOrderBy = 0; p->pSrc = 0; p->pPrior = 0; p->pLimit = 0; + p->pOffset = 0; pNew = sqlite3SelectDup(db, p, 0); + p->pOffset = pOffset; p->pLimit = pLimit; p->pOrderBy = pOrderBy; p->pSrc = pSrc; @@ -3293,14 +3298,15 @@ static int selectExpander(Walker *pWalker, Select *p){ struct SrcList_item *pFrom; sqlite3 *db = pParse->db; Expr *pE, *pRight, *pExpr; + u16 selFlags = p->selFlags; + p->selFlags |= SF_Expanded; if( db->mallocFailed ){ return WRC_Abort; } - if( NEVER(p->pSrc==0) || (p->selFlags & SF_Expanded)!=0 ){ + if( NEVER(p->pSrc==0) || (selFlags & SF_Expanded)!=0 ){ return WRC_Prune; } - p->selFlags |= SF_Expanded; pTabList = p->pSrc; pEList = p->pEList; @@ -3343,6 +3349,12 @@ static int selectExpander(Walker *pWalker, Select *p){ assert( pFrom->pTab==0 ); pFrom->pTab = pTab = sqlite3LocateTableItem(pParse, 0, pFrom); if( pTab==0 ) return WRC_Abort; + if( pTab->nRef==0xffff ){ + sqlite3ErrorMsg(pParse, "too many references to \"%s\": max 65535", + pTab->zName); + pFrom->pTab = 0; + return WRC_Abort; + } pTab->nRef++; #if !defined(SQLITE_OMIT_VIEW) || !defined (SQLITE_OMIT_VIRTUALTABLE) if( pTab->pSelect || IsVirtual(pTab) ){ @@ -3655,6 +3667,7 @@ void sqlite3SelectPrep( sqlite3 *db; if( NEVER(p==0) ) return; db = pParse->db; + if( db->mallocFailed ) return; if( p->selFlags & SF_HasTypeInfo ) return; sqlite3SelectExpand(pParse, p); if( pParse->nErr || db->mallocFailed ) return; @@ -4740,7 +4753,10 @@ void sqlite3ExplainSelect(Vdbe *pVdbe, Select *p){ sqlite3ExplainPrintf(pVdbe, "(null-select)"); return; } - while( p->pPrior ) p = p->pPrior; + while( p->pPrior ){ + p->pPrior->pNext = p; + p = p->pPrior; + } sqlite3ExplainPush(pVdbe); while( p ){ explainOneSelect(pVdbe, p); diff --git a/src/shell.c b/src/shell.c index b333502e13..1428a45f0c 100644 --- a/src/shell.c +++ b/src/shell.c @@ -1485,6 +1485,12 @@ static void open_db(struct callback_data *p){ extern int sqlite3_add_regexp_func(sqlite3*); sqlite3_add_regexp_func(db); } +#endif +#ifdef SQLITE_ENABLE_SPELLFIX + { + extern int sqlite3_spellfix1_register(sqlite3*); + sqlite3_spellfix1_register(db); + } #endif } } @@ -1531,17 +1537,18 @@ static void resolve_backslashes(char *z){ ** Interpret zArg as a boolean value. Return either 0 or 1. */ static int booleanValue(char *zArg){ - int val = atoi(zArg); - int j; - for(j=0; zArg[j]; j++){ - zArg[j] = ToLower(zArg[j]); + int i; + for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){} + if( i>0 && zArg[i]==0 ) return atoi(zArg); + if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){ + return 1; } - if( strcmp(zArg,"on")==0 ){ - val = 1; - }else if( strcmp(zArg,"yes")==0 ){ - val = 1; + if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){ + return 0; } - return val; + fprintf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n", + zArg); + return 0; } /* @@ -1774,7 +1781,8 @@ static int do_meta_command(char *zLine, struct callback_data *p){ p->echoOn = booleanValue(azArg[1]); }else - if( c=='e' && strncmp(azArg[0], "exit", n)==0 && nArg==1 ){ + if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){ + if( nArg>1 && (rc = atoi(azArg[1]))!=0 ) exit(rc); rc = 2; }else diff --git a/src/sqlite.h.in b/src/sqlite.h.in index c41e62c47d..cdbbad9a41 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -479,6 +479,15 @@ int sqlite3_exec( #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) #define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8)) +#define SQLITE_CONSTRAINT_CHECK (SQLITE_CONSTRAINT | (1<<8)) +#define SQLITE_CONSTRAINT_COMMITHOOK (SQLITE_CONSTRAINT | (2<<8)) +#define SQLITE_CONSTRAINT_FOREIGNKEY (SQLITE_CONSTRAINT | (3<<8)) +#define SQLITE_CONSTRAINT_FUNCTION (SQLITE_CONSTRAINT | (4<<8)) +#define SQLITE_CONSTRAINT_NOTNULL (SQLITE_CONSTRAINT | (5<<8)) +#define SQLITE_CONSTRAINT_PRIMARYKEY (SQLITE_CONSTRAINT | (6<<8)) +#define SQLITE_CONSTRAINT_TRIGGER (SQLITE_CONSTRAINT | (7<<8)) +#define SQLITE_CONSTRAINT_UNIQUE (SQLITE_CONSTRAINT | (8<<8)) +#define SQLITE_CONSTRAINT_VTAB (SQLITE_CONSTRAINT | (9<<8)) /* ** CAPI3REF: Flags For File Open Operations diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 01e68ace67..ae4b69d8c2 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -957,7 +957,7 @@ struct sqlite3 { #define SQLITE_SqlTrace 0x00000040 /* Debug print SQL as it executes */ #define SQLITE_VdbeListing 0x00000080 /* Debug listings of VDBE programs */ #define SQLITE_WriteSchema 0x00000100 /* OK to update SQLITE_MASTER */ - /* 0x00000200 Unused */ +#define SQLITE_VdbeAddopTrace 0x00000200 /* Trace sqlite3VdbeAddOp() calls */ #define SQLITE_IgnoreChecks 0x00000400 /* Do not enforce check constraints */ #define SQLITE_ReadUncommitted 0x0000800 /* For shared-cache mode */ #define SQLITE_LegacyFileFmt 0x00001000 /* Create new databases in format 1 */ @@ -1973,6 +1973,7 @@ struct WhereLevel { struct InLoop { int iCur; /* The VDBE cursor used by this IN operator */ int addrInTop; /* Top of the IN loop */ + u8 eEndLoopOp; /* IN Loop terminator. OP_Next or OP_Prev */ } *aInLoop; /* Information about each nested IN operator */ } in; /* Used when plan.wsFlags&WHERE_IN_ABLE */ Index *pCovidx; /* Possible covering index for WHERE_MULTI_OR */ @@ -2916,7 +2917,7 @@ int sqlite3OpenTableAndIndices(Parse*, Table*, int, int); void sqlite3BeginWriteOperation(Parse*, int, int); void sqlite3MultiWrite(Parse*); void sqlite3MayAbort(Parse*); -void sqlite3HaltConstraint(Parse*, int, char*, int); +void sqlite3HaltConstraint(Parse*, int, int, char*, int); Expr *sqlite3ExprDup(sqlite3*,Expr*,int); ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int); SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int); diff --git a/src/test1.c b/src/test1.c index bb8d186c12..247fc872fa 100644 --- a/src/test1.c +++ b/src/test1.c @@ -138,6 +138,18 @@ const char *sqlite3TestErrorName(int rc){ case SQLITE_SCHEMA: zName = "SQLITE_SCHEMA"; break; case SQLITE_TOOBIG: zName = "SQLITE_TOOBIG"; break; case SQLITE_CONSTRAINT: zName = "SQLITE_CONSTRAINT"; break; + case SQLITE_CONSTRAINT_UNIQUE: zName = "SQLITE_CONSTRAINT_UNIQUE"; break; + case SQLITE_CONSTRAINT_TRIGGER: zName = "SQLITE_CONSTRAINT_TRIGGER";break; + case SQLITE_CONSTRAINT_FOREIGNKEY: + zName = "SQLITE_CONSTRAINT_FOREIGNKEY"; break; + case SQLITE_CONSTRAINT_CHECK: zName = "SQLITE_CONSTRAINT_CHECK"; break; + case SQLITE_CONSTRAINT_PRIMARYKEY: + zName = "SQLITE_CONSTRAINT_PRIMARYKEY"; break; + case SQLITE_CONSTRAINT_NOTNULL: zName = "SQLITE_CONSTRAINT_NOTNULL";break; + case SQLITE_CONSTRAINT_COMMITHOOK: + zName = "SQLITE_CONSTRAINT_COMMITHOOK"; break; + case SQLITE_CONSTRAINT_VTAB: zName = "SQLITE_CONSTRAINT_VTAB"; break; + case SQLITE_CONSTRAINT_FUNCTION: zName = "SQLITE_CONSTRAINT_FUNCTION";break; case SQLITE_MISMATCH: zName = "SQLITE_MISMATCH"; break; case SQLITE_MISUSE: zName = "SQLITE_MISUSE"; break; case SQLITE_NOLFS: zName = "SQLITE_NOLFS"; break; @@ -6236,7 +6248,6 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ #ifdef SQLITE_DEBUG extern int sqlite3WhereTrace; extern int sqlite3OSTrace; - extern int sqlite3VdbeAddopTrace; extern int sqlite3WalTrace; #endif #ifdef SQLITE_TEST @@ -6299,8 +6310,6 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ (char*)&query_plan, TCL_LINK_STRING|TCL_LINK_READ_ONLY); #endif #ifdef SQLITE_DEBUG - Tcl_LinkVar(interp, "sqlite_addop_trace", - (char*)&sqlite3VdbeAddopTrace, TCL_LINK_INT); Tcl_LinkVar(interp, "sqlite_where_trace", (char*)&sqlite3WhereTrace, TCL_LINK_INT); Tcl_LinkVar(interp, "sqlite_os_trace", diff --git a/src/test8.c b/src/test8.c index 53cb149a04..6bd4e396b8 100644 --- a/src/test8.c +++ b/src/test8.c @@ -1389,7 +1389,7 @@ static int register_spellfix_module( } if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; - sqlite3Spellfix1Register(db); + sqlite3_spellfix1_register(db); return TCL_OK; } diff --git a/src/test_spellfix.c b/src/test_spellfix.c index 3f21d732b6..543dccbf66 100644 --- a/src/test_spellfix.c +++ b/src/test_spellfix.c @@ -21,6 +21,11 @@ # include # include # include "sqlite3ext.h" +# include +# define ALWAYS(X) 1 +# define NEVER(X) 0 + typedef unsigned char u8; + typedef unsigned short u16; SQLITE_EXTENSION_INIT1 #endif /* !SQLITE_CORE */ #include @@ -2668,7 +2673,7 @@ static int spellfix1Update( if( zCmd==0 ){ pVTab->zErrMsg = sqlite3_mprintf("%s.word may not be NULL", p->zTableName); - return SQLITE_CONSTRAINT; + return SQLITE_CONSTRAINT_NOTNULL; } if( strcmp(zCmd,"reset")==0 ){ /* Reset the edit cost table (if there is one). */ @@ -2809,7 +2814,7 @@ static int spellfix1Register(sqlite3 *db){ /* ** Register the spellfix1 virtual table and its associated functions. */ -int sqlite3Spellfix1Register(sqlite3 *db){ +int sqlite3_spellfix1_register(sqlite3 *db){ return spellfix1Register(db); } #endif @@ -2819,7 +2824,7 @@ int sqlite3Spellfix1Register(sqlite3 *db){ /* ** Extension load function. */ -int sqlite3_extension_init( +int sqlite3_spellfix1_init( sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi diff --git a/src/vdbe.c b/src/vdbe.c index 255fb6338e..bd365801d5 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -879,7 +879,7 @@ case OP_Halt: { if( rc==SQLITE_BUSY ){ p->rc = rc = SQLITE_BUSY; }else{ - assert( rc==SQLITE_OK || p->rc==SQLITE_CONSTRAINT ); + assert( rc==SQLITE_OK || (p->rc&0xff)==SQLITE_CONSTRAINT ); assert( rc==SQLITE_OK || db->nDeferredCons>0 ); rc = p->rc ? SQLITE_ERROR : SQLITE_DONE; } @@ -6115,7 +6115,7 @@ case OP_VUpdate: { assert( nArg>1 && apArg[0] && (apArg[0]->flags&MEM_Null) ); db->lastRowid = lastRowid = rowid; } - if( rc==SQLITE_CONSTRAINT && pOp->p4.pVtab->bConstraint ){ + if( (rc&0xff)==SQLITE_CONSTRAINT && pOp->p4.pVtab->bConstraint ){ if( pOp->p5==OE_Ignore ){ rc = SQLITE_OK; }else{ diff --git a/src/vdbeInt.h b/src/vdbeInt.h index bdae034fc0..676ac8d07a 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -123,7 +123,7 @@ struct VdbeFrame { VdbeCursor **apCsr; /* Array of Vdbe cursors for parent frame */ void *token; /* Copy of SubProgram.token */ i64 lastRowid; /* Last insert rowid (sqlite3.lastRowid) */ - u16 nCursor; /* Number of entries in apCsr */ + int nCursor; /* Number of entries in apCsr */ int pc; /* Program Counter in parent (calling) frame */ int nOp; /* Size of aOp array */ int nMem; /* Number of entries in aMem */ @@ -309,7 +309,7 @@ struct Vdbe { int nLabel; /* Number of labels used */ int *aLabel; /* Space to hold the labels */ u16 nResColumn; /* Number of columns in one row of the result set */ - u16 nCursor; /* Number of slots in apCsr[] */ + int nCursor; /* Number of slots in apCsr[] */ u32 magic; /* Magic number for sanity checking */ char *zErrMsg; /* Error message written here */ Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */ diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 2ddb045330..7a676a2e39 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -17,18 +17,6 @@ #include "sqliteInt.h" #include "vdbeInt.h" - - -/* -** When debugging the code generator in a symbolic debugger, one can -** set the sqlite3VdbeAddopTrace to 1 and all opcodes will be printed -** as they are added to the instruction stream. -*/ -#ifdef SQLITE_DEBUG -int sqlite3VdbeAddopTrace = 0; -#endif - - /* ** Create a new virtual database engine. */ @@ -159,7 +147,9 @@ int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){ pOp->p4type = P4_NOTUSED; #ifdef SQLITE_DEBUG pOp->zComment = 0; - if( sqlite3VdbeAddopTrace ) sqlite3VdbePrintOp(0, i, &p->aOp[i]); + if( p->db->flags & SQLITE_VdbeAddopTrace ){ + sqlite3VdbePrintOp(0, i, &p->aOp[i]); + } #endif #ifdef VDBE_PROFILE pOp->cycles = 0; @@ -378,7 +368,7 @@ int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){ || (opcode==OP_FkCounter && pOp->p1==0 && pOp->p2==1) #endif || ((opcode==OP_Halt || opcode==OP_HaltIfNull) - && (pOp->p1==SQLITE_CONSTRAINT && pOp->p2==OE_Abort)) + && ((pOp->p1&0xff)==SQLITE_CONSTRAINT && pOp->p2==OE_Abort)) ){ hasAbort = 1; break; @@ -513,7 +503,7 @@ int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp){ pOut->p5 = 0; #ifdef SQLITE_DEBUG pOut->zComment = 0; - if( sqlite3VdbeAddopTrace ){ + if( p->db->flags & SQLITE_VdbeAddopTrace ){ sqlite3VdbePrintOp(0, i+addr, &p->aOp[i+addr]); } #endif @@ -1539,7 +1529,7 @@ void sqlite3VdbeMakeReady( zEnd = &zCsr[nByte]; }while( nByte && !db->mallocFailed ); - p->nCursor = (u16)nCursor; + p->nCursor = nCursor; p->nOnceFlag = nOnce; if( p->aVar ){ p->nVar = (ynVar)nVar; @@ -1781,7 +1771,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){ if( needXcommit && db->xCommitCallback ){ rc = db->xCommitCallback(db->pCommitArg); if( rc ){ - return SQLITE_CONSTRAINT; + return SQLITE_CONSTRAINT_COMMITHOOK; } } @@ -2073,14 +2063,14 @@ int sqlite3VdbeCloseStatement(Vdbe *p, int eOp){ ** violations, return SQLITE_ERROR. Otherwise, SQLITE_OK. ** ** If there are outstanding FK violations and this function returns -** SQLITE_ERROR, set the result of the VM to SQLITE_CONSTRAINT and write -** an error message to it. Then return SQLITE_ERROR. +** SQLITE_ERROR, set the result of the VM to SQLITE_CONSTRAINT_FOREIGNKEY +** and write an error message to it. Then return SQLITE_ERROR. */ #ifndef SQLITE_OMIT_FOREIGN_KEY int sqlite3VdbeCheckFk(Vdbe *p, int deferred){ sqlite3 *db = p->db; if( (deferred && db->nDeferredCons>0) || (!deferred && p->nFkConstraint>0) ){ - p->rc = SQLITE_CONSTRAINT; + p->rc = SQLITE_CONSTRAINT_FOREIGNKEY; p->errorAction = OE_Abort; sqlite3SetString(&p->zErrMsg, db, "foreign key constraint failed"); return SQLITE_ERROR; @@ -2195,7 +2185,7 @@ int sqlite3VdbeHalt(Vdbe *p){ sqlite3VdbeLeave(p); return SQLITE_ERROR; } - rc = SQLITE_CONSTRAINT; + rc = SQLITE_CONSTRAINT_FOREIGNKEY; }else{ /* The auto-commit flag is true, the vdbe program was successful ** or hit an 'OR FAIL' constraint and there are no deferred foreign @@ -2238,7 +2228,7 @@ int sqlite3VdbeHalt(Vdbe *p){ if( eStatementOp ){ rc = sqlite3VdbeCloseStatement(p, eStatementOp); if( rc ){ - if( p->rc==SQLITE_OK || p->rc==SQLITE_CONSTRAINT ){ + if( p->rc==SQLITE_OK || (p->rc&0xff)==SQLITE_CONSTRAINT ){ p->rc = rc; sqlite3DbFree(db, p->zErrMsg); p->zErrMsg = 0; diff --git a/src/where.c b/src/where.c index f97bf019c9..3db76b5339 100644 --- a/src/where.c +++ b/src/where.c @@ -140,7 +140,6 @@ struct WhereTerm { struct WhereClause { Parse *pParse; /* The parser context */ WhereMaskSet *pMaskSet; /* Mapping of table cursor numbers to bitmasks */ - Bitmask vmask; /* Bitmask identifying virtual table cursors */ WhereClause *pOuter; /* Outer conjunction */ u8 op; /* Split operator. TK_AND or TK_OR */ u16 wctrlFlags; /* Might include WHERE_AND_ONLY */ @@ -317,7 +316,6 @@ static void whereClauseInit( pWC->nTerm = 0; pWC->nSlot = ArraySize(pWC->aStatic); pWC->a = pWC->aStatic; - pWC->vmask = 0; pWC->wctrlFlags = wctrlFlags; } @@ -917,7 +915,7 @@ static void transferJoinMarkings(Expr *pDerived, Expr *pBase){ ** ** CASE 1: ** -** If all subterms are of the form T.C=expr for some single column of C +** If all subterms are of the form T.C=expr for some single column of C and ** a single table T (as shown in example B above) then create a new virtual ** term that is an equivalent IN expression. In other words, if the term ** being analyzed is: @@ -1005,7 +1003,7 @@ static void exprAnalyzeOrTerm( ** Compute the set of tables that might satisfy cases 1 or 2. */ indexable = ~(Bitmask)0; - chngToIN = ~(pWC->vmask); + chngToIN = ~(Bitmask)0; for(i=pOrWc->nTerm-1, pOrTerm=pOrWc->a; i>=0 && indexable; i--, pOrTerm++){ if( (pOrTerm->eOperator & WO_SINGLE)==0 ){ WhereAndInfo *pAndInfo; @@ -2272,8 +2270,9 @@ static void bestVirtualIndex(WhereBestIdx *p){ struct sqlite3_index_constraint *pIdxCons; struct sqlite3_index_constraint_usage *pUsage; WhereTerm *pTerm; - int i, j; + int i, j, k; int nOrderBy; + int sortOrder; /* Sort order for IN clauses */ int bAllowIN; /* Allow IN optimizations */ double rCost; @@ -2372,18 +2371,27 @@ static void bestVirtualIndex(WhereBestIdx *p){ return; } + sortOrder = SQLITE_SO_ASC; pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint; for(i=0; inConstraint; i++, pIdxCons++){ if( pUsage[i].argvIndex>0 ){ j = pIdxCons->iTermOffset; pTerm = &pWC->a[j]; p->cost.used |= pTerm->prereqRight; - if( (pTerm->eOperator & WO_IN)!=0 && pUsage[i].omit==0 ){ - /* Do not attempt to use an IN constraint if the virtual table - ** says that the equivalent EQ constraint cannot be safely omitted. - ** If we do attempt to use such a constraint, some rows might be - ** repeated in the output. */ - break; + if( (pTerm->eOperator & WO_IN)!=0 ){ + if( pUsage[i].omit==0 ){ + /* Do not attempt to use an IN constraint if the virtual table + ** says that the equivalent EQ constraint cannot be safely omitted. + ** If we do attempt to use such a constraint, some rows might be + ** repeated in the output. */ + break; + } + for(k=0; knOrderBy; k++){ + if( pIdxInfo->aOrderBy[k].iColumn==pIdxCons->iColumn ){ + sortOrder = pIdxInfo->aOrderBy[k].desc; + break; + } + } } } } @@ -2413,7 +2421,8 @@ static void bestVirtualIndex(WhereBestIdx *p){ } p->cost.plan.u.pVtabIdx = pIdxInfo; if( pIdxInfo->orderByConsumed ){ - p->cost.plan.wsFlags |= WHERE_ORDERED; + assert( sortOrder==0 || sortOrder==1 ); + p->cost.plan.wsFlags |= WHERE_ORDERED + sortOrder*WHERE_REVERSE; p->cost.plan.nOBSat = nOrderBy; }else{ p->cost.plan.nOBSat = p->i ? p->aLevel[p->i-1].plan.nOBSat : 0; @@ -3010,10 +3019,7 @@ static int isSortingIndex( if( pConstraint==0 ){ isEq = 0; }else if( (pConstraint->eOperator & WO_IN)!=0 ){ - /* Constraints of the form: "X IN ..." cannot be used with an ORDER BY - ** because we do not know in what order the values on the RHS of the IN - ** operator will occur. */ - break; + isEq = 0; }else if( (pConstraint->eOperator & WO_ISNULL)!=0 ){ uniqueNotNull = 0; isEq = 1; /* "X IS NULL" means X has only a single value */ @@ -3317,8 +3323,8 @@ static void bestBtreeIndex(WhereBestIdx *p){ ** indicate this to the caller. ** ** Otherwise, if the search may find more than one row, test to see if - ** there is a range constraint on indexed column (pc.plan.nEq+1) that can be - ** optimized using the index. + ** there is a range constraint on indexed column (pc.plan.nEq+1) that + ** can be optimized using the index. */ if( pc.plan.nEq==pProbe->nColumn && pProbe->onError!=OE_None ){ testcase( pc.plan.wsFlags & WHERE_COLUMN_IN ); @@ -3659,7 +3665,8 @@ static void bestIndex(WhereBestIdx *p){ sqlite3_index_info *pIdxInfo = 0; p->ppIdxInfo = &pIdxInfo; bestVirtualIndex(p); - if( pIdxInfo->needToFreeIdxStr ){ + assert( pIdxInfo!=0 || p->pParse->db->mallocFailed ); + if( pIdxInfo && pIdxInfo->needToFreeIdxStr ){ sqlite3_free(pIdxInfo->idxStr); } sqlite3DbFree(p->pParse->db, pIdxInfo); @@ -3783,12 +3790,13 @@ static int codeEqualityTerm( int eType; int iTab; struct InLoop *pIn; + u8 bRev = (pLevel->plan.wsFlags & WHERE_REVERSE)!=0; assert( pX->op==TK_IN ); iReg = iTarget; eType = sqlite3FindInIndex(pParse, pX, 0); iTab = pX->iTable; - sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0); + sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iTab, 0); assert( pLevel->plan.wsFlags & WHERE_IN_ABLE ); if( pLevel->u.in.nIn==0 ){ pLevel->addrNxt = sqlite3VdbeMakeLabel(v); @@ -3806,6 +3814,7 @@ static int codeEqualityTerm( }else{ pIn->addrInTop = sqlite3VdbeAddOp3(v, OP_Column, iTab, 0, iReg); } + pIn->eEndLoopOp = bRev ? OP_Prev : OP_Next; sqlite3VdbeAddOp1(v, OP_IsNull, iReg); }else{ pLevel->u.in.nIn = 0; @@ -4174,8 +4183,8 @@ static Bitmask codeOneLoopStart( for(j=1; j<=nConstraint; j++){ for(k=0; ka[aConstraint[k].iTermOffset]; int iTarget = iReg+j+1; + pTerm = &pWC->a[aConstraint[k].iTermOffset]; if( pTerm->eOperator & WO_IN ){ codeEqualityTerm(pParse, pTerm, pLevel, iTarget); addrNotFound = pLevel->addrNxt; @@ -5057,24 +5066,13 @@ WhereInfo *sqlite3WhereBegin( ** bitmask for all tables to the left of the join. Knowing the bitmask ** for all tables to the left of a left join is important. Ticket #3015. ** - ** Configure the WhereClause.vmask variable so that bits that correspond - ** to virtual table cursors are set. This is used to selectively disable - ** the OR-to-IN transformation in exprAnalyzeOrTerm(). It is not helpful - ** with virtual tables. - ** ** Note that bitmasks are created for all pTabList->nSrc tables in ** pTabList, not just the first nTabList tables. nTabList is normally ** equal to pTabList->nSrc but might be shortened to 1 if the ** WHERE_ONETABLE_ONLY flag is set. */ - assert( sWBI.pWC->vmask==0 && pMaskSet->n==0 ); for(ii=0; iinSrc; ii++){ createMask(pMaskSet, pTabList->a[ii].iCursor); -#ifndef SQLITE_OMIT_VIRTUALTABLE - if( ALWAYS(pTabList->a[ii].pTab) && IsVirtual(pTabList->a[ii].pTab) ){ - sWBI.pWC->vmask |= ((Bitmask)1 << ii); - } -#endif } #ifndef NDEBUG { @@ -5558,7 +5556,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ sqlite3VdbeResolveLabel(v, pLevel->addrNxt); for(j=pLevel->u.in.nIn, pIn=&pLevel->u.in.aInLoop[j-1]; j>0; j--, pIn--){ sqlite3VdbeJumpHere(v, pIn->addrInTop+1); - sqlite3VdbeAddOp2(v, OP_Next, pIn->iCur, pIn->addrInTop); + sqlite3VdbeAddOp2(v, pIn->eEndLoopOp, pIn->iCur, pIn->addrInTop); sqlite3VdbeJumpHere(v, pIn->addrInTop-1); } sqlite3DbFree(db, pLevel->u.in.aInLoop); diff --git a/test/capi2.test b/test/capi2.test index 8b36ac6925..20ee3401bf 100644 --- a/test/capi2.test +++ b/test/capi2.test @@ -235,8 +235,9 @@ do_test capi2-3.13 { do_test capi2-3.13b {db changes} {0} do_test capi2-3.14 { - list [sqlite3_finalize $VM] [sqlite3_errmsg $DB] -} {SQLITE_CONSTRAINT {column a is not unique}} + list [sqlite3_finalize $VM] [sqlite3_errmsg $DB] \ + [sqlite3_extended_errcode $DB] +} {SQLITE_CONSTRAINT {column a is not unique} SQLITE_CONSTRAINT_UNIQUE} do_test capi2-3.15 { set VM [sqlite3_prepare $DB {CREATE TABLE t2(a NOT NULL, b)} -1 TAIL] set TAIL @@ -258,8 +259,9 @@ do_test capi2-3.18 { [get_column_names $VM] } {SQLITE_ERROR 0 {} {}} do_test capi2-3.19 { - list [sqlite3_finalize $VM] [sqlite3_errmsg $DB] -} {SQLITE_CONSTRAINT {t2.a may not be NULL}} + list [sqlite3_finalize $VM] [sqlite3_errmsg $DB] \ + [sqlite3_extended_errcode $DB] +} {SQLITE_CONSTRAINT {t2.a may not be NULL} SQLITE_CONSTRAINT_NOTNULL} do_test capi2-3.20 { execsql { @@ -278,8 +280,8 @@ do_test capi2-3.23 { sqlite3_finalize $VM } {SQLITE_CONSTRAINT} do_test capi2-3.24 { - sqlite3_errcode $DB -} {SQLITE_CONSTRAINT} + list [sqlite3_errcode $DB] [sqlite3_extended_errcode $DB] +} {SQLITE_CONSTRAINT SQLITE_CONSTRAINT_UNIQUE} # Two or more virtual machines exists at the same time. # diff --git a/test/conflict.test b/test/conflict.test index 17c7263f1e..6576959607 100644 --- a/test/conflict.test +++ b/test/conflict.test @@ -580,6 +580,7 @@ do_test conflict-9.19 { SELECT * FROM t2; } } {1 {column e is not unique}} +verify_ex_errcode conflict-9.21b SQLITE_CONSTRAINT_UNIQUE do_test conflict-9.20 { catch {execsql {COMMIT}} execsql {SELECT * FROM t3} @@ -592,6 +593,7 @@ do_test conflict-9.21 { SELECT * FROM t2; } } {1 {column e is not unique}} +verify_ex_errcode conflict-9.21b SQLITE_CONSTRAINT_UNIQUE do_test conflict-9.22 { catch {execsql {COMMIT}} execsql {SELECT * FROM t3} @@ -781,6 +783,7 @@ do_test conflict-12.3 { UPDATE t5 SET a=a+1 WHERE a=1; } } {1 {PRIMARY KEY must be unique}} +verify_ex_errcode conflict-12.3b SQLITE_CONSTRAINT_PRIMARYKEY do_test conflict-12.4 { execsql { UPDATE OR REPLACE t5 SET a=a+1 WHERE a=1; @@ -802,6 +805,7 @@ do_test conflict-13.1 { REPLACE INTO t13 VALUES(2); } } {1 {constraint failed}} +verify_ex_errcode conflict-13.1b SQLITE_CONSTRAINT_CHECK do_test conflict-13.2 { execsql { REPLACE INTO t13 VALUES(3); diff --git a/test/errmsg.test b/test/errmsg.test index 9f8409b147..6b3f3b7db6 100644 --- a/test/errmsg.test +++ b/test/errmsg.test @@ -80,12 +80,14 @@ do_test 2.2 { SQLITE_ERROR {SQL logic error or missing database} SQLITE_CONSTRAINT {column b is not unique} }] +verify_ex_errcode 2.2b SQLITE_CONSTRAINT_UNIQUE do_test 2.3 { error_messages_v2 "INSERT INTO t1 VALUES('ghi', 'def')" } [list {*}{ SQLITE_CONSTRAINT {column b is not unique} SQLITE_CONSTRAINT {column b is not unique} }] +verify_ex_errcode 2.3b SQLITE_CONSTRAINT_UNIQUE #------------------------------------------------------------------------- # Test SQLITE_SCHEMA errors. And, for _v2(), test that if the schema diff --git a/test/fkey2.test b/test/fkey2.test index a723598788..3e5b27c1e6 100644 --- a/test/fkey2.test +++ b/test/fkey2.test @@ -1433,10 +1433,12 @@ do_test fkey2-17.1.2 { set STMT [sqlite3_prepare_v2 db "INSERT INTO two VALUES(4, 5, 6)" -1 dummy] sqlite3_step $STMT } {SQLITE_CONSTRAINT} +verify_ex_errcode fkey2-17.1.2b SQLITE_CONSTRAINT_FOREIGNKEY ifcapable autoreset { do_test fkey2-17.1.3 { sqlite3_step $STMT } {SQLITE_CONSTRAINT} + verify_ex_errcode fkey2-17.1.3b SQLITE_CONSTRAINT_FOREIGNKEY } else { do_test fkey2-17.1.3 { sqlite3_step $STMT @@ -1445,6 +1447,7 @@ ifcapable autoreset { do_test fkey2-17.1.4 { sqlite3_finalize $STMT } {SQLITE_CONSTRAINT} +verify_ex_errcode fkey2-17.1.4b SQLITE_CONSTRAINT_FOREIGNKEY do_test fkey2-17.1.5 { execsql { INSERT INTO one VALUES(2, 3, 4); @@ -1488,9 +1491,11 @@ do_test fkey2-17.1.12 { do_test fkey2-17.1.13 { sqlite3_step $STMT } {SQLITE_CONSTRAINT} +verify_ex_errcode fkey2-17.1.13b SQLITE_CONSTRAINT_FOREIGNKEY do_test fkey2-17.1.14 { sqlite3_finalize $STMT } {SQLITE_CONSTRAINT} +verify_ex_errcode fkey2-17.1.14b SQLITE_CONSTRAINT_FOREIGNKEY drop_all_tables do_test fkey2-17.2.1 { @@ -1644,9 +1649,11 @@ do_test fkey2-19.2 { sqlite3_bind_int $S 1 2 sqlite3_step $S } {SQLITE_CONSTRAINT} +verify_ex_errcode fkey2-19.2b SQLITE_CONSTRAINT_FOREIGNKEY do_test fkey2-19.3 { sqlite3_reset $S } {SQLITE_CONSTRAINT} +verify_ex_errcode fkey2-19.3b SQLITE_CONSTRAINT_FOREIGNKEY do_test fkey2-19.4 { sqlite3_bind_int $S 1 1 sqlite3_step $S diff --git a/test/fkey4.test b/test/fkey4.test index d6dd2fc8ff..79cf663478 100644 --- a/test/fkey4.test +++ b/test/fkey4.test @@ -42,10 +42,12 @@ do_test fkey4-1.2 { set ::STMT1 [sqlite3_prepare_v2 $::DB $::SQL -1 TAIL] sqlite3_step $::STMT1 } {SQLITE_CONSTRAINT} +verify_ex_errcode fkey4-1.2b SQLITE_CONSTRAINT_FOREIGNKEY do_test fkey4-1.3 { set ::STMT2 [sqlite3_prepare_v2 $::DB $::SQL -1 TAIL] sqlite3_step $::STMT2 } {SQLITE_CONSTRAINT} +verify_ex_errcode fkey4-1.3b SQLITE_CONSTRAINT_FOREIGNKEY do_test fkey4-1.4 { db eval {SELECT * FROM t2} } {1 3} diff --git a/test/fts4unicode.test b/test/fts4unicode.test index 0ac60a6f01..8bd83f6d9e 100644 --- a/test/fts4unicode.test +++ b/test/fts4unicode.test @@ -44,12 +44,12 @@ proc do_unicode_token_test3 {tn args} { } do_unicode_token_test 1.0 {a B c D} {0 a a 1 b B 2 c c 3 d D} -do_unicode_token_test 1.1 {Ä Ö Ü} {0 ä Ä 1 ö Ö 2 ü Ü} -do_unicode_token_test 1.2 {xÄx xÖx xÜx} {0 xäx xÄx 1 xöx xÖx 2 xüx xÜx} +do_unicode_token_test 1.1 {Ä Ö Ü} {0 ä Ä 1 ö Ö 2 ü Ü} +do_unicode_token_test 1.2 {xÄx xÖx xÜx} {0 xäx xÄx 1 xöx xÖx 2 xüx xÜx} # 0x00DF is a small "sharp s". 0x1E9E is a capital sharp s. do_unicode_token_test 1.3 "\uDF" "0 \uDF \uDF" -do_unicode_token_test 1.4 "\u1E9E" "0 ß \u1E9E" +do_unicode_token_test 1.4 "\u1E9E" "0 ß \u1E9E" do_unicode_token_test 1.5 "\u1E9E" "0 \uDF \u1E9E" do_unicode_token_test 1.6 "The quick brown fox" { @@ -60,12 +60,15 @@ do_unicode_token_test 1.7 "The\u00bfquick\u224ebrown\u2263fox" { } do_unicode_token_test2 1.8 {a B c D} {0 a a 1 b B 2 c c 3 d D} -do_unicode_token_test2 1.9 {Ä Ö Ü} {0 a Ä 1 o Ö 2 u Ü} -do_unicode_token_test2 1.10 {xÄx xÖx xÜx} {0 xax xÄx 1 xox xÖx 2 xux xÜx} +do_unicode_token_test2 1.9 {Ä Ö Ü} {0 a Ä 1 o Ö 2 u Ü} +do_unicode_token_test2 1.10 {xÄx xÖx xÜx} {0 xax xÄx 1 xox xÖx 2 xux xÜx} # Check that diacritics are removed if remove_diacritics=1 is specified. # And that they do not break tokens. -do_unicode_token_test2 1.10 "xx\u0301xx" "0 xxxx xx\u301xx" +do_unicode_token_test2 1.11 "xx\u0301xx" "0 xxxx xx\u301xx" + +# Title-case mappings work +do_unicode_token_test 1.12 "\u01c5" "0 \u01c6 \u01c5" #------------------------------------------------------------------------- # @@ -383,5 +386,3 @@ foreach T $tokenizers { finish_test - - diff --git a/test/hook.test b/test/hook.test index aaee2301e4..09fc9e8678 100644 --- a/test/hook.test +++ b/test/hook.test @@ -75,6 +75,7 @@ do_test hook-3.6 { INSERT INTO t2 VALUES(6,7); } } {1 {constraint failed}} +verify_ex_errcode hook-3.6b SQLITE_CONSTRAINT_COMMITHOOK do_test hook-3.7 { set ::commit_cnt } {1 2 2 3 3 4 4 5 5 6 6 7} diff --git a/test/limit.test b/test/limit.test index e5aac70da4..c5b75c2b69 100644 --- a/test/limit.test +++ b/test/limit.test @@ -468,5 +468,152 @@ do_test limit-12.4 { } } {1 {no such column: x}} +# Ticket [db4d96798da8b] +# LIMIT does not work with nested views containing UNION ALL +# +do_test limit-13.1 { + db eval { + CREATE TABLE t13(x); + INSERT INTO t13 VALUES(1),(2); + CREATE VIEW v13a AS SELECT x AS y FROM t13; + CREATE VIEW v13b AS SELECT y AS z FROM v13a UNION ALL SELECT y+10 FROM v13a; + CREATE VIEW v13c AS SELECT z FROM v13b UNION ALL SELECT z+20 FROM v13b; + } +} {} +do_test limit-13.2 { + db eval {SELECT z FROM v13c LIMIT 1} +} {1} +do_test limit-13.3 { + db eval {SELECT z FROM v13c LIMIT 2} +} {1 2} +do_test limit-13.4 { + db eval {SELECT z FROM v13c LIMIT 3} +} {1 2 11} +do_test limit-13.5 { + db eval {SELECT z FROM v13c LIMIT 4} +} {1 2 11 12} +do_test limit-13.6 { + db eval {SELECT z FROM v13c LIMIT 5} +} {1 2 11 12 21} +do_test limit-13.7 { + db eval {SELECT z FROM v13c LIMIT 6} +} {1 2 11 12 21 22} +do_test limit-13.8 { + db eval {SELECT z FROM v13c LIMIT 7} +} {1 2 11 12 21 22 31} +do_test limit-13.9 { + db eval {SELECT z FROM v13c LIMIT 8} +} {1 2 11 12 21 22 31 32} +do_test limit-13.10 { + db eval {SELECT z FROM v13c LIMIT 9} +} {1 2 11 12 21 22 31 32} +do_test limit-13.11 { + db eval {SELECT z FROM v13c LIMIT 1 OFFSET 1} +} {2} +do_test limit-13.12 { + db eval {SELECT z FROM v13c LIMIT 2 OFFSET 1} +} {2 11} +do_test limit-13.13 { + db eval {SELECT z FROM v13c LIMIT 3 OFFSET 1} +} {2 11 12} +do_test limit-13.14 { + db eval {SELECT z FROM v13c LIMIT 4 OFFSET 1} +} {2 11 12 21} +do_test limit-13.15 { + db eval {SELECT z FROM v13c LIMIT 5 OFFSET 1} +} {2 11 12 21 22} +do_test limit-13.16 { + db eval {SELECT z FROM v13c LIMIT 6 OFFSET 1} +} {2 11 12 21 22 31} +do_test limit-13.17 { + db eval {SELECT z FROM v13c LIMIT 7 OFFSET 1} +} {2 11 12 21 22 31 32} +do_test limit-13.18 { + db eval {SELECT z FROM v13c LIMIT 8 OFFSET 1} +} {2 11 12 21 22 31 32} +do_test limit-13.21 { + db eval {SELECT z FROM v13c LIMIT 1 OFFSET 2} +} {11} +do_test limit-13.22 { + db eval {SELECT z FROM v13c LIMIT 2 OFFSET 2} +} {11 12} +do_test limit-13.23 { + db eval {SELECT z FROM v13c LIMIT 3 OFFSET 2} +} {11 12 21} +do_test limit-13.24 { + db eval {SELECT z FROM v13c LIMIT 4 OFFSET 2} +} {11 12 21 22} +do_test limit-13.25 { + db eval {SELECT z FROM v13c LIMIT 5 OFFSET 2} +} {11 12 21 22 31} +do_test limit-13.26 { + db eval {SELECT z FROM v13c LIMIT 6 OFFSET 2} +} {11 12 21 22 31 32} +do_test limit-13.27 { + db eval {SELECT z FROM v13c LIMIT 7 OFFSET 2} +} {11 12 21 22 31 32} +do_test limit-13.31 { + db eval {SELECT z FROM v13c LIMIT 1 OFFSET 3} +} {12} +do_test limit-13.32 { + db eval {SELECT z FROM v13c LIMIT 2 OFFSET 3} +} {12 21} +do_test limit-13.33 { + db eval {SELECT z FROM v13c LIMIT 3 OFFSET 3} +} {12 21 22} +do_test limit-13.34 { + db eval {SELECT z FROM v13c LIMIT 4 OFFSET 3} +} {12 21 22 31} +do_test limit-13.35 { + db eval {SELECT z FROM v13c LIMIT 5 OFFSET 3} +} {12 21 22 31 32} +do_test limit-13.36 { + db eval {SELECT z FROM v13c LIMIT 6 OFFSET 3} +} {12 21 22 31 32} +do_test limit-13.41 { + db eval {SELECT z FROM v13c LIMIT 1 OFFSET 4} +} {21} +do_test limit-13.42 { + db eval {SELECT z FROM v13c LIMIT 2 OFFSET 4} +} {21 22} +do_test limit-13.43 { + db eval {SELECT z FROM v13c LIMIT 3 OFFSET 4} +} {21 22 31} +do_test limit-13.44 { + db eval {SELECT z FROM v13c LIMIT 4 OFFSET 4} +} {21 22 31 32} +do_test limit-13.45 { + db eval {SELECT z FROM v13c LIMIT 5 OFFSET 4} +} {21 22 31 32} +do_test limit-13.51 { + db eval {SELECT z FROM v13c LIMIT 1 OFFSET 5} +} {22} +do_test limit-13.52 { + db eval {SELECT z FROM v13c LIMIT 2 OFFSET 5} +} {22 31} +do_test limit-13.53 { + db eval {SELECT z FROM v13c LIMIT 3 OFFSET 5} +} {22 31 32} +do_test limit-13.54 { + db eval {SELECT z FROM v13c LIMIT 4 OFFSET 5} +} {22 31 32} +do_test limit-13.61 { + db eval {SELECT z FROM v13c LIMIT 1 OFFSET 6} +} {31} +do_test limit-13.62 { + db eval {SELECT z FROM v13c LIMIT 2 OFFSET 6} +} {31 32} +do_test limit-13.63 { + db eval {SELECT z FROM v13c LIMIT 3 OFFSET 6} +} {31 32} +do_test limit-13.71 { + db eval {SELECT z FROM v13c LIMIT 1 OFFSET 7} +} {32} +do_test limit-13.72 { + db eval {SELECT z FROM v13c LIMIT 2 OFFSET 7} +} {32} +do_test limit-13.81 { + db eval {SELECT z FROM v13c LIMIT 1 OFFSET 8} +} {} finish_test diff --git a/test/notnull.test b/test/notnull.test index 240aaba9d7..01738a4551 100644 --- a/test/notnull.test +++ b/test/notnull.test @@ -48,6 +48,7 @@ do_test notnull-1.2 { SELECT * FROM t1 order by a; } } {1 {t1.a may not be NULL}} +verify_ex_errcode notnull-1.2b SQLITE_CONSTRAINT_NOTNULL do_test notnull-1.3 { catchsql { DELETE FROM t1; @@ -62,6 +63,7 @@ do_test notnull-1.4 { SELECT * FROM t1 order by a; } } {1 {t1.a may not be NULL}} +verify_ex_errcode notnull-1.4b SQLITE_CONSTRAINT_NOTNULL do_test notnull-1.5 { catchsql { DELETE FROM t1; @@ -69,6 +71,7 @@ do_test notnull-1.5 { SELECT * FROM t1 order by a; } } {1 {t1.a may not be NULL}} +verify_ex_errcode notnull-1.5b SQLITE_CONSTRAINT_NOTNULL do_test notnull-1.6 { catchsql { DELETE FROM t1; @@ -104,6 +107,7 @@ do_test notnull-1.10 { SELECT * FROM t1 order by a; } } {1 {t1.b may not be NULL}} +verify_ex_errcode notnull-1.10b SQLITE_CONSTRAINT_NOTNULL do_test notnull-1.11 { catchsql { DELETE FROM t1; @@ -146,6 +150,7 @@ do_test notnull-1.16 { SELECT * FROM t1 order by a; } } {1 {t1.c may not be NULL}} +verify_ex_errcode notnull-1.16b SQLITE_CONSTRAINT_NOTNULL do_test notnull-1.17 { catchsql { DELETE FROM t1; @@ -153,6 +158,7 @@ do_test notnull-1.17 { SELECT * FROM t1 order by a; } } {1 {t1.d may not be NULL}} +verify_ex_errcode notnull-1.17b SQLITE_CONSTRAINT_NOTNULL do_test notnull-1.18 { catchsql { DELETE FROM t1; @@ -174,6 +180,7 @@ do_test notnull-1.20 { SELECT * FROM t1 order by a; } } {1 {t1.e may not be NULL}} +verify_ex_errcode notnull-1.20b SQLITE_CONSTRAINT_NOTNULL do_test notnull-1.21 { catchsql { DELETE FROM t1; @@ -190,6 +197,7 @@ do_test notnull-2.1 { SELECT * FROM t1 ORDER BY a; } } {1 {t1.a may not be NULL}} +verify_ex_errcode notnull-2.1b SQLITE_CONSTRAINT_NOTNULL do_test notnull-2.2 { catchsql { DELETE FROM t1; @@ -198,6 +206,7 @@ do_test notnull-2.2 { SELECT * FROM t1 ORDER BY a; } } {1 {t1.a may not be NULL}} +verify_ex_errcode notnull-2.2b SQLITE_CONSTRAINT_NOTNULL do_test notnull-2.3 { catchsql { DELETE FROM t1; @@ -214,6 +223,7 @@ do_test notnull-2.4 { SELECT * FROM t1 ORDER BY a; } } {1 {t1.a may not be NULL}} +verify_ex_errcode notnull-2.4b SQLITE_CONSTRAINT_NOTNULL do_test notnull-2.5 { catchsql { DELETE FROM t1; @@ -222,6 +232,7 @@ do_test notnull-2.5 { SELECT * FROM t1 ORDER BY a; } } {1 {t1.b may not be NULL}} +verify_ex_errcode notnull-2.6b SQLITE_CONSTRAINT_NOTNULL do_test notnull-2.6 { catchsql { DELETE FROM t1; @@ -262,6 +273,7 @@ do_test notnull-2.10 { SELECT * FROM t1 ORDER BY a; } } {1 {t1.e may not be NULL}} +verify_ex_errcode notnull-2.10b SQLITE_CONSTRAINT_NOTNULL do_test notnull-3.0 { execsql { @@ -287,6 +299,7 @@ do_test notnull-3.2 { SELECT * FROM t1 order by a; } } {1 {t1.a may not be NULL}} +verify_ex_errcode notnull-3.2b SQLITE_CONSTRAINT_NOTNULL do_test notnull-3.3 { catchsql { DELETE FROM t1; @@ -301,6 +314,7 @@ do_test notnull-3.4 { SELECT * FROM t1 order by a; } } {1 {t1.a may not be NULL}} +verify_ex_errcode notnull-3.4b SQLITE_CONSTRAINT_NOTNULL do_test notnull-3.5 { catchsql { DELETE FROM t1; @@ -308,6 +322,7 @@ do_test notnull-3.5 { SELECT * FROM t1 order by a; } } {1 {t1.a may not be NULL}} +verify_ex_errcode notnull-3.5b SQLITE_CONSTRAINT_NOTNULL do_test notnull-3.6 { catchsql { DELETE FROM t1; @@ -343,6 +358,7 @@ do_test notnull-3.10 { SELECT * FROM t1 order by a; } } {1 {t1.b may not be NULL}} +verify_ex_errcode notnull-3.10b SQLITE_CONSTRAINT_NOTNULL do_test notnull-3.11 { catchsql { DELETE FROM t1; @@ -385,6 +401,7 @@ do_test notnull-3.16 { SELECT * FROM t1 order by a; } } {1 {t1.c may not be NULL}} +verify_ex_errcode notnull-3.16b SQLITE_CONSTRAINT_NOTNULL do_test notnull-3.17 { catchsql { DELETE FROM t1; @@ -392,6 +409,7 @@ do_test notnull-3.17 { SELECT * FROM t1 order by a; } } {1 {t1.d may not be NULL}} +verify_ex_errcode notnull-3.17b SQLITE_CONSTRAINT_NOTNULL do_test notnull-3.18 { catchsql { DELETE FROM t1; @@ -413,6 +431,7 @@ do_test notnull-3.20 { SELECT * FROM t1 order by a; } } {1 {t1.e may not be NULL}} +verify_ex_errcode notnull-3.20b SQLITE_CONSTRAINT_NOTNULL do_test notnull-3.21 { catchsql { DELETE FROM t1; @@ -429,6 +448,7 @@ do_test notnull-4.1 { SELECT * FROM t1 ORDER BY a; } } {1 {t1.a may not be NULL}} +verify_ex_errcode notnull-4.1b SQLITE_CONSTRAINT_NOTNULL do_test notnull-4.2 { catchsql { DELETE FROM t1; @@ -437,6 +457,7 @@ do_test notnull-4.2 { SELECT * FROM t1 ORDER BY a; } } {1 {t1.a may not be NULL}} +verify_ex_errcode notnull-4.2b SQLITE_CONSTRAINT_NOTNULL do_test notnull-4.3 { catchsql { DELETE FROM t1; @@ -453,6 +474,7 @@ do_test notnull-4.4 { SELECT * FROM t1 ORDER BY a; } } {1 {t1.a may not be NULL}} +verify_ex_errcode notnull-4.4b SQLITE_CONSTRAINT_NOTNULL do_test notnull-4.5 { catchsql { DELETE FROM t1; @@ -461,6 +483,7 @@ do_test notnull-4.5 { SELECT * FROM t1 ORDER BY a; } } {1 {t1.b may not be NULL}} +verify_ex_errcode notnull-4.5b SQLITE_CONSTRAINT_NOTNULL do_test notnull-4.6 { catchsql { DELETE FROM t1; @@ -501,6 +524,7 @@ do_test notnull-4.10 { SELECT * FROM t1 ORDER BY a; } } {1 {t1.e may not be NULL}} +verify_ex_errcode notnull-4.10b SQLITE_CONSTRAINT_NOTNULL # Test that bug 29ab7be99f is fixed. # @@ -519,6 +543,7 @@ do_test notnull-5.2 { INSERT INTO t1 SELECT * FROM t2; } } {1 {t1.b may not be NULL}} +verify_ex_errcode notnull-5.2b SQLITE_CONSTRAINT_NOTNULL do_test notnull-5.3 { execsql { SELECT * FROM t1 } } {1 2} @@ -531,9 +556,9 @@ do_test notnull-5.4 { COMMIT; } } {1 {t1.b may not be NULL}} +verify_ex_errcode notnull-5.4b SQLITE_CONSTRAINT_NOTNULL do_test notnull-5.5 { execsql { SELECT * FROM t1 } } {1 2} finish_test - diff --git a/test/shell1.test b/test/shell1.test index a3d06ece35..c60f3af702 100644 --- a/test/shell1.test +++ b/test/shell1.test @@ -220,7 +220,7 @@ do_test shell1-2.3.2 { } {0 {}} do_test shell1-2.3.3 { catchcmd "test.db" ".explain \"1 2 3\"" -} {0 {}} +} {1 {ERROR: Not a boolean value: "1 2 3". Assuming "no".}} do_test shell1-2.3.4 { catchcmd "test.db" ".explain \"OFF\"" } {0 {}} @@ -326,10 +326,6 @@ do_test shell1-3.5.4 { do_test shell1-3.6.1 { catchcmd "test.db" ".exit" } {0 {}} -do_test shell1-3.6.2 { - # too many arguments - catchcmd "test.db" ".exit BAD" -} {1 {Error: unknown command or invalid arguments: "exit". Enter ".help" for help}} # .explain ON|OFF Turn output mode suitable for EXPLAIN on or off. do_test shell1-3.7.1 { diff --git a/test/tester.tcl b/test/tester.tcl index 8b2b4ec6a9..6386eee442 100644 --- a/test/tester.tcl +++ b/test/tester.tcl @@ -54,6 +54,7 @@ # do_ioerr_test TESTNAME ARGS... # crashsql ARGS... # integrity_check TESTNAME ?DB? +# verify_ex_errcode TESTNAME EXPECTED ?DB? # do_test TESTNAME SCRIPT EXPECTED # do_execsql_test TESTNAME SQL EXPECTED # do_catchsql_test TESTNAME SQL EXPECTED @@ -974,6 +975,12 @@ proc integrity_check {name {db db}} { } } +# Check the extended error code +# +proc verify_ex_errcode {name expected {db db}} { + do_test $name [list sqlite3_extended_errcode $db] $expected +} + # Return true if the SQL statement passed as the second argument uses a # statement transaction. diff --git a/test/trigger1.test b/test/trigger1.test index c49bc659ad..1ebe12c89b 100644 --- a/test/trigger1.test +++ b/test/trigger1.test @@ -423,6 +423,7 @@ do_test trigger1-6.2 { do_test trigger1-6.3 { catchsql {DELETE FROM t2} } {1 {deletes are not permitted}} +verify_ex_errcode trigger1-6.3b SQLITE_CONSTRAINT_TRIGGER do_test trigger1-6.4 { execsql {SELECT * FROM t2} } {3 4 7 8} diff --git a/test/trigger3.test b/test/trigger3.test index 34d19700fc..fe91b9dcf8 100644 --- a/test/trigger3.test +++ b/test/trigger3.test @@ -45,6 +45,7 @@ do_test trigger3-1.1 { INSERT INTO tbl VALUES (1, 5, 6); } } {1 {Trigger abort}} +verify_ex_errcode trigger3-1.1b SQLITE_CONSTRAINT_TRIGGER do_test trigger3-1.2 { execsql { SELECT * FROM tbl; @@ -63,6 +64,7 @@ do_test trigger3-2.1 { INSERT INTO tbl VALUES (2, 5, 6); } } {1 {Trigger fail}} +verify_ex_errcode trigger3-2.1b SQLITE_CONSTRAINT_TRIGGER do_test trigger3-2.2 { execsql { SELECT * FROM tbl; @@ -77,6 +79,7 @@ do_test trigger3-3.1 { INSERT INTO tbl VALUES (3, 5, 6); } } {1 {Trigger rollback}} +verify_ex_errcode trigger3-3.1b SQLITE_CONSTRAINT_TRIGGER do_test trigger3-3.2 { execsql { SELECT * FROM tbl; @@ -92,6 +95,7 @@ do_test trigger3-3.3 { INSERT INTO tbl VALUES (3, 9, 10); } } {1 {Trigger rollback}} +verify_ex_errcode trigger3-3.3b SQLITE_CONSTRAINT_TRIGGER do_test trigger3-3.4 { execsql {SELECT * FROM tbl} } {} @@ -172,6 +176,7 @@ do_test trigger3-7.1 { INSERT INTO tbl_view VALUES(1, 2, 3); } } {1 {View rollback}} +verify_ex_errcode trigger3-7.1b SQLITE_CONSTRAINT_TRIGGER do_test trigger3-7.2 { catchsql { INSERT INTO tbl_view VALUES(2, 2, 3); @@ -182,6 +187,7 @@ do_test trigger3-7.3 { INSERT INTO tbl_view VALUES(3, 2, 3); } } {1 {View abort}} +verify_ex_errcode trigger3-7.3b SQLITE_CONSTRAINT_TRIGGER } ;# ifcapable view diff --git a/test/unique.test b/test/unique.test index 56c49eed45..eac19b59e0 100644 --- a/test/unique.test +++ b/test/unique.test @@ -48,6 +48,7 @@ do_test unique-1.3 { INSERT INTO t1(a,b,c) VALUES(1,3,4) } } {1 {column a is not unique}} +verify_ex_errcode unique-1.3b SQLITE_CONSTRAINT_UNIQUE do_test unique-1.4 { execsql { SELECT * FROM t1 ORDER BY a; @@ -58,6 +59,7 @@ do_test unique-1.5 { INSERT INTO t1(a,b,c) VALUES(3,2,4) } } {1 {column b is not unique}} +verify_ex_errcode unique-1.5b SQLITE_CONSTRAINT_UNIQUE do_test unique-1.6 { execsql { SELECT * FROM t1 ORDER BY a; @@ -99,6 +101,7 @@ do_test unique-2.3 { INSERT INTO t2 VALUES(1,5); } } {1 {column a is not unique}} +verify_ex_errcode unique-2.3b SQLITE_CONSTRAINT_UNIQUE do_test unique-2.4 { catchsql { SELECT * FROM t2 ORDER BY a @@ -125,6 +128,7 @@ do_test unique-2.8 { CREATE UNIQUE INDEX i2 ON t2(a); } } {1 {indexed columns are not unique}} +verify_ex_errcode unique-2.8b SQLITE_CONSTRAINT_UNIQUE do_test unique-2.9 { catchsql { CREATE INDEX i2 ON t2(a); @@ -163,6 +167,7 @@ do_test unique-3.4 { SELECT * FROM t3 ORDER BY a,b,c,d; } } {1 {columns a, c, d are not unique}} +verify_ex_errcode unique-3.4b SQLITE_CONSTRAINT_UNIQUE integrity_check unique-3.5 # Make sure NULLs are distinct as far as the UNIQUE tests are @@ -217,6 +222,7 @@ do_test unique-4.9 { do_test unique-4.10 { catchsql {CREATE UNIQUE INDEX i4c ON t4(b)} } {1 {indexed columns are not unique}} +verify_ex_errcode unique-4.10b SQLITE_CONSTRAINT_UNIQUE integrity_check unique-4.99 # Test the error message generation logic. In particular, make sure we @@ -249,5 +255,7 @@ do_test unique-5.2 { INSERT INTO t5 VALUES(1,2,3,4,5,6); } } {1 {columns first_column_with_long_name, second_column_with_long_name, third_column_with_long_name, fourth_column_with_long_name, fifth_column_with_long_name, sixth_column_with_long_name are not unique}} +verify_ex_errcode unique-5.2b SQLITE_CONSTRAINT_UNIQUE + finish_test diff --git a/test/view.test b/test/view.test index b4440905f9..4abd3cf70b 100644 --- a/test/view.test +++ b/test/view.test @@ -576,4 +576,37 @@ do_test view-20.1 { } } {} +# Ticket [d58ccbb3f1b]: Prevent Table.nRef overflow. +db close +sqlite3 db :memory: +do_test view-21.1 { + catchsql { + CREATE TABLE t1(x); + INSERT INTO t1 VALUES(5); + CREATE VIEW v1 AS SELECT x*2 FROM t1; + CREATE VIEW v2 AS SELECT * FROM v1 UNION SELECT * FROM v1; + CREATE VIEW v4 AS SELECT * FROM v2 UNION SELECT * FROM v2; + CREATE VIEW v8 AS SELECT * FROM v4 UNION SELECT * FROM v4; + CREATE VIEW v16 AS SELECT * FROM v8 UNION SELECT * FROM v8; + CREATE VIEW v32 AS SELECT * FROM v16 UNION SELECT * FROM v16; + CREATE VIEW v64 AS SELECT * FROM v32 UNION SELECT * FROM v32; + CREATE VIEW v128 AS SELECT * FROM v64 UNION SELECT * FROM v64; + CREATE VIEW v256 AS SELECT * FROM v128 UNION SELECT * FROM v128; + CREATE VIEW v512 AS SELECT * FROM v256 UNION SELECT * FROM v256; + CREATE VIEW v1024 AS SELECT * FROM v512 UNION SELECT * FROM v512; + CREATE VIEW v2048 AS SELECT * FROM v1024 UNION SELECT * FROM v1024; + CREATE VIEW v4096 AS SELECT * FROM v2048 UNION SELECT * FROM v2048; + CREATE VIEW v8192 AS SELECT * FROM v4096 UNION SELECT * FROM v4096; + CREATE VIEW v16384 AS SELECT * FROM v8192 UNION SELECT * FROM v8192; + CREATE VIEW v32768 AS SELECT * FROM v16384 UNION SELECT * FROM v16384; + CREATE VIEW vx AS SELECT * FROM v32768 UNION SELECT * FROM v32768; + } +} {1 {too many references to "v1": max 65535}} +do_test view-21.2 { + db progress 1000 {expr 1} + catchsql { + SELECT * FROM v32768; + } +} {1 interrupted} + finish_test diff --git a/test/where.test b/test/where.test index 05c7b2f04f..2dbc283417 100644 --- a/test/where.test +++ b/test/where.test @@ -379,11 +379,26 @@ ifcapable subquery { SELECT * FROM t1 WHERE rowid+0 IN (1,2,3,1234) order by 1; } } {1 0 4 2 1 9 3 1 16 102} - do_test where-5.3 { + do_test where-5.3a { count { SELECT * FROM t1 WHERE w IN (-1,1,2,3) order by 1; } - } {1 0 4 2 1 9 3 1 16 14} + } {1 0 4 2 1 9 3 1 16 13} + do_test where-5.3b { + count { + SELECT * FROM t1 WHERE w IN (3,-1,1,2) order by 1; + } + } {1 0 4 2 1 9 3 1 16 13} + do_test where-5.3c { + count { + SELECT * FROM t1 WHERE w IN (3,2,-1,1,2) order by 1; + } + } {1 0 4 2 1 9 3 1 16 13} + do_test where-5.3d { + count { + SELECT * FROM t1 WHERE w IN (-1,1,2,3) order by 1 DESC; + } + } {3 1 16 2 1 9 1 0 4 12} do_test where-5.4 { count { SELECT * FROM t1 WHERE w+0 IN (-1,1,2,3) order by 1; @@ -452,6 +467,30 @@ ifcapable subquery { SELECT * FROM t1 WHERE x IN (1,7) AND y IN (9,16) ORDER BY 1; } } {2 1 9 3 1 16 11} + do_test where-5.100 { + db eval { + SELECT w, x, y FROM t1 WHERE x IN (1,5) AND y IN (9,8,3025,1000,3969) + ORDER BY x, y + } + } {2 1 9 54 5 3025 62 5 3969} + do_test where-5.101 { + db eval { + SELECT w, x, y FROM t1 WHERE x IN (1,5) AND y IN (9,8,3025,1000,3969) + ORDER BY x DESC, y DESC + } + } {62 5 3969 54 5 3025 2 1 9} + do_test where-5.102 { + db eval { + SELECT w, x, y FROM t1 WHERE x IN (1,5) AND y IN (9,8,3025,1000,3969) + ORDER BY x DESC, y + } + } {54 5 3025 62 5 3969 2 1 9} + do_test where-5.103 { + db eval { + SELECT w, x, y FROM t1 WHERE x IN (1,5) AND y IN (9,8,3025,1000,3969) + ORDER BY x, y DESC + } + } {2 1 9 62 5 3969 54 5 3025} } # This procedure executes the SQL. Then it checks to see if the OP_Sort @@ -511,11 +550,16 @@ do_test where-6.7 { } } {1 100 4 2 99 9 3 98 16 nosort} ifcapable subquery { - do_test where-6.8 { + do_test where-6.8a { cksort { SELECT * FROM t3 WHERE a IN (3,5,7,1,9,4,2) ORDER BY a LIMIT 3 } - } {1 100 4 2 99 9 3 98 16 sort} + } {1 100 4 2 99 9 3 98 16 nosort} + do_test where-6.8b { + cksort { + SELECT * FROM t3 WHERE a IN (3,5,7,1,9,4,2) ORDER BY a DESC LIMIT 3 + } + } {9 92 100 7 94 64 5 96 36 nosort} } do_test where-6.9.1 { cksort { diff --git a/test/where2.test b/test/where2.test index d61c0897e8..e8c2f3613f 100644 --- a/test/where2.test +++ b/test/where2.test @@ -167,24 +167,54 @@ ifcapable subquery { } } {99 6 10000 10006 100 6 10201 10207 sort t1 i1zyx} } - do_test where2-4.6 { + do_test where2-4.6a { queryplan { SELECT * FROM t1 WHERE x IN (1,2,3,4,5,6,7,8) AND y IN (10000,10001,10002,10003,10004,10005) - ORDER BY 2 + ORDER BY x + } + } {99 6 10000 10006 nosort t1 i1xy} + do_test where2-4.6b { + queryplan { + SELECT * FROM t1 + WHERE x IN (1,2,3,4,5,6,7,8) + AND y IN (10000,10001,10002,10003,10004,10005) + ORDER BY x DESC + } + } {99 6 10000 10006 nosort t1 i1xy} + do_test where2-4.6c { + queryplan { + SELECT * FROM t1 + WHERE x IN (1,2,3,4,5,6,7,8) + AND y IN (10000,10001,10002,10003,10004,10005) + ORDER BY x, y + } + } {99 6 10000 10006 nosort t1 i1xy} + do_test where2-4.6d { + queryplan { + SELECT * FROM t1 + WHERE x IN (1,2,3,4,5,6,7,8) + AND y IN (10000,10001,10002,10003,10004,10005) + ORDER BY x, y DESC } } {99 6 10000 10006 sort t1 i1xy} # Duplicate entires on the RHS of an IN operator do not cause duplicate # output rows. # - do_test where2-4.6 { + do_test where2-4.6x { queryplan { SELECT * FROM t1 WHERE z IN (10207,10006,10006,10207) ORDER BY w } } {99 6 10000 10006 100 6 10201 10207 sort t1 i1zyx} + do_test where2-4.6y { + queryplan { + SELECT * FROM t1 WHERE z IN (10207,10006,10006,10207) + ORDER BY w DESC + } + } {100 6 10201 10207 99 6 10000 10006 sort t1 i1zyx} ifcapable compound { do_test where2-4.7 { queryplan { @@ -207,11 +237,16 @@ do_test where2-5.1 { } {99 6 10000 10006 nosort t1 i1w} ifcapable subquery { - do_test where2-5.2 { + do_test where2-5.2a { queryplan { SELECT * FROM t1 WHERE w IN (99) ORDER BY w } - } {99 6 10000 10006 sort t1 i1w} + } {99 6 10000 10006 nosort t1 i1w} + do_test where2-5.2b { + queryplan { + SELECT * FROM t1 WHERE w IN (99) ORDER BY w DESC + } + } {99 6 10000 10006 nosort t1 i1w} } # Verify that OR clauses get translated into IN operators. diff --git a/tool/build-shell.sh b/tool/build-shell.sh index 665480540c..cd2838ebd6 100644 --- a/tool/build-shell.sh +++ b/tool/build-shell.sh @@ -16,8 +16,11 @@ gcc -o sqlite3 -g -Os -I. \ -DSQLITE_ENABLE_FTS4 \ -DSQLITE_ENABLE_RTREE \ -DSQLITE_ENABLE_REGEXP \ + -DSQLITE_ENABLE_SPELLFIX -DSQLITE_CORE=1 \ -DHAVE_READLINE \ -DHAVE_USLEEP=1 \ - ../sqlite/src/shell.c ../sqlite/src/test_vfstrace.c \ + ../sqlite/src/shell.c \ ../sqlite/src/test_regexp.c \ + ../sqlite/src/test_spellfix.c \ + ../sqlite/src/test_vfstrace.c \ sqlite3.c -ldl -lreadline -lncurses diff --git a/tool/showwal.c b/tool/showwal.c index ae25a59f9a..2888c10aa5 100644 --- a/tool/showwal.c +++ b/tool/showwal.c @@ -18,6 +18,65 @@ static int perLine = 16; /* HEX elements to print per line */ typedef long long int i64; /* Datatype for 64-bit integers */ +/* Information for computing the checksum */ +typedef struct Cksum Cksum; +struct Cksum { + int bSwap; /* True to do byte swapping on 32-bit words */ + unsigned s0, s1; /* Current checksum value */ +}; + +/* +** extract a 32-bit big-endian integer +*/ +static unsigned int getInt32(const unsigned char *a){ + unsigned int x = (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3]; + return x; +} + +/* +** Swap bytes on a 32-bit unsigned integer +*/ +static unsigned int swab32(unsigned int x){ + return (((x)&0x000000FF)<<24) + (((x)&0x0000FF00)<<8) + + (((x)&0x00FF0000)>>8) + (((x)&0xFF000000)>>24); +} + +/* Extend the checksum. Reinitialize the checksum if bInit is true. +*/ +static void extendCksum( + Cksum *pCksum, + unsigned char *aData, + unsigned int nByte, + int bInit +){ + unsigned int *a32; + if( bInit ){ + int a = 0; + *((char*)&a) = 1; + if( a==1 ){ + /* Host is little-endian */ + pCksum->bSwap = getInt32(aData)!=0x377f0682; + }else{ + /* Host is big-endian */ + pCksum->bSwap = getInt32(aData)!=0x377f0683; + } + pCksum->s0 = 0; + pCksum->s1 = 0; + } + a32 = (unsigned int*)aData; + while( nByte>0 ){ + unsigned int x0 = a32[0]; + unsigned int x1 = a32[1]; + if( pCksum->bSwap ){ + x0 = swab32(x0); + x1 = swab32(x1); + } + pCksum->s0 += x0 + pCksum->s1; + pCksum->s1 += x1 + pCksum->s0; + nByte -= 8; + a32 += 2; + } +} /* ** Convert the var-int format into i64. Return the number of bytes @@ -152,39 +211,46 @@ static void print_frame(int iFrame){ } /* -** extract a 32-bit big-endian integer +** Summarize a single frame on a single line. */ -static unsigned int getInt32(const unsigned char *a){ - unsigned int x = (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3]; - return x; -} - -/* -** Print an entire page of content as hex -*/ -static void print_oneline_frame(int iFrame){ +static void print_oneline_frame(int iFrame, Cksum *pCksum){ int iStart; unsigned char *aData; + unsigned int s0, s1; iStart = 32 + (iFrame-1)*(pagesize+24); aData = getContent(iStart, 24); - fprintf(stdout, "Frame %4d: %6d %6d 0x%08x 0x%08x 0x%08x 0x%08x\n", + extendCksum(pCksum, aData, 8, 0); + extendCksum(pCksum, getContent(iStart+24, pagesize), pagesize, 0); + s0 = getInt32(aData+16); + s1 = getInt32(aData+20); + fprintf(stdout, "Frame %4d: %6d %6d 0x%08x,%08x 0x%08x,%08x %s\n", iFrame, getInt32(aData), getInt32(aData+4), getInt32(aData+8), getInt32(aData+12), - getInt32(aData+16), - getInt32(aData+20) + s0, + s1, + (s0==pCksum->s0 && s1==pCksum->s1) ? "" : "cksum-fail" ); + + /* Reset the checksum so that a single frame checksum failure will not + ** cause all subsequent frames to also show a failure. */ + pCksum->s0 = s0; + pCksum->s1 = s1; free(aData); } /* ** Decode the WAL header. */ -static void print_wal_header(void){ +static void print_wal_header(Cksum *pCksum){ unsigned char *aData; aData = getContent(0, 32); + if( pCksum ){ + extendCksum(pCksum, aData, 24, 1); + printf("Checksum byte order: %s\n", pCksum->bSwap ? "swapped" : "native"); + } printf("WAL Header:\n"); print_decode_line(aData, 0, 4,1,"Magic. 0x377f0682 (le) or 0x377f0683 (be)"); print_decode_line(aData, 4, 4, 0, "File format"); @@ -194,60 +260,199 @@ static void print_wal_header(void){ print_decode_line(aData, 20,4, 1, "Salt-2"); print_decode_line(aData, 24,4, 1, "Checksum-1"); print_decode_line(aData, 28,4, 1, "Checksum-2"); + if( pCksum ){ + if( pCksum->s0!=getInt32(aData+24) ){ + printf("**** cksum-1 mismatch: 0x%08x\n", pCksum->s0); + } + if( pCksum->s1!=getInt32(aData+28) ){ + printf("**** cksum-2 mismatch: 0x%08x\n", pCksum->s1); + } + } free(aData); } +/* +** Describe cell content. +*/ +static int describeContent( + unsigned char *a, /* Cell content */ + int nLocal, /* Bytes in a[] */ + char *zDesc /* Write description here */ +){ + int nDesc = 0; + int n, i, j; + i64 x, v; + const unsigned char *pData; + const unsigned char *pLimit; + char sep = ' '; + + pLimit = &a[nLocal]; + n = decodeVarint(a, &x); + pData = &a[x]; + a += n; + i = x - n; + while( i>0 && pData<=pLimit ){ + n = decodeVarint(a, &x); + a += n; + i -= n; + nLocal -= n; + zDesc[0] = sep; + sep = ','; + nDesc++; + zDesc++; + if( x==0 ){ + sprintf(zDesc, "*"); /* NULL is a "*" */ + }else if( x>=1 && x<=6 ){ + v = (signed char)pData[0]; + pData++; + switch( x ){ + case 6: v = (v<<16) + (pData[0]<<8) + pData[1]; pData += 2; + case 5: v = (v<<16) + (pData[0]<<8) + pData[1]; pData += 2; + case 4: v = (v<<8) + pData[0]; pData++; + case 3: v = (v<<8) + pData[0]; pData++; + case 2: v = (v<<8) + pData[0]; pData++; + } + sprintf(zDesc, "%lld", v); + }else if( x==7 ){ + sprintf(zDesc, "real"); + pData += 8; + }else if( x==8 ){ + sprintf(zDesc, "0"); + }else if( x==9 ){ + sprintf(zDesc, "1"); + }else if( x>=12 ){ + int size = (x-12)/2; + if( (x&1)==0 ){ + sprintf(zDesc, "blob(%d)", size); + }else{ + sprintf(zDesc, "txt(%d)", size); + } + pData += size; + } + j = strlen(zDesc); + zDesc += j; + nDesc += j; + } + return nDesc; +} + +/* +** Compute the local payload size given the total payload size and +** the page size. +*/ +static int localPayload(i64 nPayload, char cType){ + int maxLocal; + int minLocal; + int surplus; + int nLocal; + if( cType==13 ){ + /* Table leaf */ + maxLocal = pagesize-35; + minLocal = (pagesize-12)*32/255-23; + }else{ + maxLocal = (pagesize-12)*64/255-23; + minLocal = (pagesize-12)*32/255-23; + } + if( nPayload>maxLocal ){ + surplus = minLocal + (nPayload-minLocal)%(pagesize-4); + if( surplus<=maxLocal ){ + nLocal = surplus; + }else{ + nLocal = minLocal; + } + }else{ + nLocal = nPayload; + } + return nLocal; +} /* ** Create a description for a single cell. +** +** The return value is the local cell size. */ -static int describeCell(unsigned char cType, unsigned char *a, char **pzDesc){ +static int describeCell( + unsigned char cType, /* Page type */ + unsigned char *a, /* Cell content */ + int showCellContent, /* Show cell content if true */ + char **pzDesc /* Store description here */ +){ int i; int nDesc = 0; int n = 0; int leftChild; i64 nPayload; i64 rowid; - static char zDesc[100]; + int nLocal; + static char zDesc[1000]; i = 0; if( cType<=5 ){ leftChild = ((a[0]*256 + a[1])*256 + a[2])*256 + a[3]; a += 4; n += 4; - sprintf(zDesc, "left-child: %d ", leftChild); + sprintf(zDesc, "lx: %d ", leftChild); nDesc = strlen(zDesc); } if( cType!=5 ){ i = decodeVarint(a, &nPayload); a += i; n += i; - sprintf(&zDesc[nDesc], "sz: %lld ", nPayload); + sprintf(&zDesc[nDesc], "n: %lld ", nPayload); nDesc += strlen(&zDesc[nDesc]); + nLocal = localPayload(nPayload, cType); + }else{ + nPayload = nLocal = 0; } if( cType==5 || cType==13 ){ i = decodeVarint(a, &rowid); a += i; n += i; - sprintf(&zDesc[nDesc], "rowid: %lld ", rowid); + sprintf(&zDesc[nDesc], "r: %lld ", rowid); nDesc += strlen(&zDesc[nDesc]); } + if( nLocal0 ){ + printf(" key: lx=left-child n=payload-size r=rowid\n"); + } + if( showMap ){ + zMap = malloc(pagesize); + memset(zMap, '.', pagesize); + memset(zMap, '1', hdrSize); + memset(&zMap[hdrSize], 'H', iCellPtr); + memset(&zMap[hdrSize+iCellPtr], 'P', 2*nCell); + } for(i=0; i