1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-30 19:03:16 +03:00

Enhancements to the query planner to make use of indices for ORDER BY even

when IN constraints are in the WHERE clause.  Add extended error codes for
all SQLITE_CONSTRAINT errors.

FossilOrigin-Name: 7e14dc734d7d941da5c3aa6612e26d93b5b929bd
This commit is contained in:
drh
2013-02-13 13:42:50 +00:00
39 changed files with 848 additions and 224 deletions

View File

@ -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

View File

@ -1 +1 @@
82d3d1ae824e1fbc7958657be79231590ec17ace
7e14dc734d7d941da5c3aa6612e26d93b5b929bd

View File

@ -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);
}
/*

View File

@ -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;

View File

@ -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 ){

View File

@ -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 ){

View File

@ -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 <time.h>
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,
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;

View File

@ -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 },

View File

@ -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; j<pEList->nExpr; j++){
if( sqlite3MatchSpanName(pEList->a[j].zSpan, zCol, zTab, zDb) ){
cnt++;

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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",

View File

@ -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;
}

View File

@ -21,6 +21,11 @@
# include <stdio.h>
# include <stdlib.h>
# include "sqlite3ext.h"
# include <assert.h>
# define ALWAYS(X) 1
# define NEVER(X) 0
typedef unsigned char u8;
typedef unsigned short u16;
SQLITE_EXTENSION_INIT1
#endif /* !SQLITE_CORE */
#include <ctype.h>
@ -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

View File

@ -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{

View File

@ -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 */

View File

@ -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;

View File

@ -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,19 +2371,28 @@ static void bestVirtualIndex(WhereBestIdx *p){
return;
}
sortOrder = SQLITE_SO_ASC;
pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
for(i=0; i<pIdxInfo->nConstraint; 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 ){
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; k<pIdxInfo->nOrderBy; k++){
if( pIdxInfo->aOrderBy[k].iColumn==pIdxCons->iColumn ){
sortOrder = pIdxInfo->aOrderBy[k].desc;
break;
}
}
}
}
}
if( i>=pIdxInfo->nConstraint ) 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; k<nConstraint; k++){
if( aUsage[k].argvIndex==j ){
WhereTerm *pTerm = &pWC->a[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; ii<pTabList->nSrc; 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);

View File

@ -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.
#

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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}

View File

@ -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 {<EFBFBD> <20> <20>} {0 <20> <20> 1 <20> <20> 2 <20> <20>}
do_unicode_token_test 1.2 {x<EFBFBD>x x<EFBFBD>x x<EFBFBD>x} {0 x<EFBFBD>x x<EFBFBD>x 1 x<EFBFBD>x x<EFBFBD>x 2 x<EFBFBD>x x<EFBFBD>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 <EFBFBD> \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 {<EFBFBD> <20> <20>} {0 a <EFBFBD> 1 o <EFBFBD> 2 u <EFBFBD>}
do_unicode_token_test2 1.10 {x<EFBFBD>x x<EFBFBD>x x<EFBFBD>x} {0 xax x<EFBFBD>x 1 xox x<EFBFBD>x 2 xux x<EFBFBD>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

View File

@ -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}

View File

@ -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

View File

@ -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

View File

@ -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 {

View File

@ -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.

View File

@ -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}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 {

View File

@ -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.

View File

@ -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

View File

@ -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( nLocal<nPayload ){
int ovfl;
unsigned char *b = &a[nLocal];
ovfl = ((b[0]*256 + b[1])*256 + b[2])*256 + b[3];
sprintf(&zDesc[nDesc], "ov: %d ", ovfl);
nDesc += strlen(&zDesc[nDesc]);
n += 4;
}
if( showCellContent && cType!=5 ){
nDesc += describeContent(a, nLocal, &zDesc[nDesc-1]);
}
*pzDesc = zDesc;
return n;
return nLocal+n;
}
/*
** Decode a btree page
*/
static void decode_btree_page(unsigned char *a, int pgno, int hdrSize){
static void decode_btree_page(
unsigned char *a, /* Content of the btree page to be decoded */
int pgno, /* Page number */
int hdrSize, /* Size of the page1-header in bytes */
const char *zArgs /* Flags to control formatting */
){
const char *zType = "unknown";
int nCell;
int i;
int i, j;
int iCellPtr;
int showCellContent = 0;
int showMap = 0;
char *zMap = 0;
switch( a[0] ){
case 2: zType = "index interior node"; break;
case 5: zType = "table interior node"; break;
case 10: zType = "index leaf"; break;
case 13: zType = "table leaf"; break;
}
while( zArgs[0] ){
switch( zArgs[0] ){
case 'c': showCellContent = 1; break;
case 'm': showMap = 1; break;
}
zArgs++;
}
printf("Decode of btree page %d:\n", pgno);
print_decode_line(a, 0, 1, 0, zType);
print_decode_line(a, 1, 2, 0, "Offset to first freeblock");
@ -261,13 +466,40 @@ static void decode_btree_page(unsigned char *a, int pgno, int hdrSize){
}else{
iCellPtr = 8;
}
if( nCell>0 ){
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<nCell; i++){
int cofst = iCellPtr + i*2;
char *zDesc;
int n;
cofst = a[cofst]*256 + a[cofst+1];
describeCell(a[0], &a[cofst-hdrSize], &zDesc);
n = describeCell(a[0], &a[cofst-hdrSize], showCellContent, &zDesc);
if( showMap ){
char zBuf[30];
memset(&zMap[cofst], '*', n);
zMap[cofst] = '[';
zMap[cofst+n-1] = ']';
sprintf(zBuf, "%d", i);
j = strlen(zBuf);
if( j<=n-2 ) memcpy(&zMap[cofst+1], zBuf, j);
}
printf(" %03x: cell[%d] %s\n", cofst, i, zDesc);
}
if( showMap ){
for(i=0; i<pagesize; i+=64){
printf(" %03x: %.64s\n", i, &zMap[i]);
}
free(zMap);
}
}
int main(int argc, char **argv){
@ -298,15 +530,18 @@ int main(int argc, char **argv){
printf("Available pages: 1..%d\n", mxFrame);
if( argc==2 ){
int i;
print_wal_header();
for(i=1; i<=mxFrame; i++) print_oneline_frame(i);
Cksum x;
print_wal_header(&x);
for(i=1; i<=mxFrame; i++){
print_oneline_frame(i, &x);
}
}else{
int i;
for(i=2; i<argc; i++){
int iStart, iEnd;
char *zLeft;
if( strcmp(argv[i], "header")==0 ){
print_wal_header();
print_wal_header(0);
continue;
}
if( !isdigit(argv[i][0]) ){
@ -318,11 +553,11 @@ int main(int argc, char **argv){
iEnd = mxFrame;
}else if( zLeft && zLeft[0]=='.' && zLeft[1]=='.' ){
iEnd = strtol(&zLeft[2], 0, 0);
#if 0
}else if( zLeft && zLeft[0]=='b' ){
int ofst, nByte, hdrSize;
unsigned char *a;
if( iStart==1 ){
hdrSize = 100;
ofst = hdrSize = 100;
nByte = pagesize-100;
}else{
@ -330,11 +565,11 @@ int main(int argc, char **argv){
ofst = (iStart-1)*pagesize;
nByte = pagesize;
}
ofst = 32 + hdrSize + (iStart-1)*(pagesize+24) + 24;
a = getContent(ofst, nByte);
decode_btree_page(a, iStart, hdrSize);
decode_btree_page(a, iStart, hdrSize, zLeft+1);
free(a);
continue;
#endif
}else{
iEnd = iStart;
}