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:
84
manifest
84
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
|
||||
|
@ -1 +1 @@
|
||||
82d3d1ae824e1fbc7958657be79231590ec17ace
|
||||
7e14dc734d7d941da5c3aa6612e26d93b5b929bd
|
19
src/build.c
19
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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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;
|
||||
|
16
src/fkey.c
16
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 ){
|
||||
|
16
src/insert.c
16
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 ){
|
||||
|
52
src/os_win.c
52
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 <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,
|
||||
"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;
|
||||
|
@ -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 },
|
||||
|
@ -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++;
|
||||
|
22
src/select.c
22
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);
|
||||
|
28
src/shell.c
28
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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
15
src/test1.c
15
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",
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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{
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
64
src/where.c
64
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; 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 ){
|
||||
/* 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; k<pIdxInfo->nOrderBy; 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; 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);
|
||||
|
@ -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.
|
||||
#
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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}
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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}
|
||||
|
147
test/limit.test
147
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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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.
|
||||
|
@ -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}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
293
tool/showwal.c
293
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( 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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user