mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-30 19:03:16 +03:00
Merge in the latest changes from trunk.
FossilOrigin-Name: 69d5bed017bda3e184857febcc8b6f6bed6ad228
This commit is contained in:
@ -429,6 +429,7 @@ static void vtshimAuxDestructor(void *pXAux){
|
|||||||
assert( pAux->pAllVtab==0 );
|
assert( pAux->pAllVtab==0 );
|
||||||
if( !pAux->bDisposed && pAux->xChildDestroy ){
|
if( !pAux->bDisposed && pAux->xChildDestroy ){
|
||||||
pAux->xChildDestroy(pAux->pChildAux);
|
pAux->xChildDestroy(pAux->pChildAux);
|
||||||
|
pAux->xChildDestroy = 0;
|
||||||
}
|
}
|
||||||
sqlite3_free(pAux->zName);
|
sqlite3_free(pAux->zName);
|
||||||
sqlite3_free(pAux->pMod);
|
sqlite3_free(pAux->pMod);
|
||||||
@ -527,7 +528,10 @@ void sqlite3_dispose_module(void *pX){
|
|||||||
pAux->pMod->xDisconnect(pVtab->pChild);
|
pAux->pMod->xDisconnect(pVtab->pChild);
|
||||||
}
|
}
|
||||||
pAux->bDisposed = 1;
|
pAux->bDisposed = 1;
|
||||||
if( pAux->xChildDestroy ) pAux->xChildDestroy(pAux->pChildAux);
|
if( pAux->xChildDestroy ){
|
||||||
|
pAux->xChildDestroy(pAux->pChildAux);
|
||||||
|
pAux->xChildDestroy = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
62
manifest
62
manifest
@ -1,5 +1,5 @@
|
|||||||
C Merge\sin\sthe\slatest\strunk\schanges,\sincluding\spartial\sindexes,\sthe\sMAX_PATH\nfix\sin\sos_win.c,\sand\sthe\ssqlite3_cancel_auto_extension()\sAPI.
|
C Merge\sin\sthe\slatest\schanges\sfrom\strunk.
|
||||||
D 2013-08-02T20:44:48.965
|
D 2013-08-06T14:52:27.425
|
||||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||||
F Makefile.in aff38bc64c582dd147f18739532198372587b0f0
|
F Makefile.in aff38bc64c582dd147f18739532198372587b0f0
|
||||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||||
@ -115,7 +115,7 @@ F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63
|
|||||||
F ext/misc/regexp.c af92cdaa5058fcec1451e49becc7ba44dba023dc
|
F ext/misc/regexp.c af92cdaa5058fcec1451e49becc7ba44dba023dc
|
||||||
F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a
|
F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a
|
||||||
F ext/misc/spellfix.c 5e1d547e9a2aed13897fa91bac924333f62fd2d9
|
F ext/misc/spellfix.c 5e1d547e9a2aed13897fa91bac924333f62fd2d9
|
||||||
F ext/misc/vtshim.c 5fb6be7fe37659a8cbd1e16982d74cceacbc4543
|
F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e
|
||||||
F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212
|
F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212
|
||||||
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
|
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
|
||||||
F ext/rtree/rtree.c db516d7e59a14c92df10b552789509f2b632df3a
|
F ext/rtree/rtree.c db516d7e59a14c92df10b552789509f2b632df3a
|
||||||
@ -157,7 +157,7 @@ F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a
|
|||||||
F mkextu.sh 416f9b7089d80e5590a29692c9d9280a10dbad9f
|
F mkextu.sh 416f9b7089d80e5590a29692c9d9280a10dbad9f
|
||||||
F mkextw.sh d2a981497b404d6498f5ff3e3b1f3816bdfcb338
|
F mkextw.sh d2a981497b404d6498f5ff3e3b1f3816bdfcb338
|
||||||
F mkopcodec.awk f6fccee29e68493bfd90a2e0466ede5fa94dd2fc
|
F mkopcodec.awk f6fccee29e68493bfd90a2e0466ede5fa94dd2fc
|
||||||
F mkopcodeh.awk 29b84656502eee5f444c3147f331ee686956ab0e
|
F mkopcodeh.awk e7334b45c023b5ee2efc6e8f479560c2026fa34a
|
||||||
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
|
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
|
||||||
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
|
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
|
||||||
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
|
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
|
||||||
@ -179,13 +179,13 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
|
|||||||
F src/btree.c 3f7bbfd72efb1cbf6a49515c376a031767ec930a
|
F src/btree.c 3f7bbfd72efb1cbf6a49515c376a031767ec930a
|
||||||
F src/btree.h 6fa8a3ff2483d0bb64a9f0105a8cedeac9e00cca
|
F src/btree.h 6fa8a3ff2483d0bb64a9f0105a8cedeac9e00cca
|
||||||
F src/btreeInt.h eecc84f02375b2bb7a44abbcbbe3747dde73edb2
|
F src/btreeInt.h eecc84f02375b2bb7a44abbcbbe3747dde73edb2
|
||||||
F src/build.c fc76e1cd014840781e175f57f6de38917986943b
|
F src/build.c cee4724668ebc09bb482c1be30f96e0ae2474f9b
|
||||||
F src/callback.c d7e46f40c3cf53c43550b7da7a1d0479910b62cc
|
F src/callback.c d7e46f40c3cf53c43550b7da7a1d0479910b62cc
|
||||||
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
|
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
|
||||||
F src/ctime.c 4262c227bc91cecc61ae37ed3a40f08069cfa267
|
F src/ctime.c 4262c227bc91cecc61ae37ed3a40f08069cfa267
|
||||||
F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4
|
F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4
|
||||||
F src/delete.c 30ed4bc76a1a32c55bf17ac1528c5867aa5502c0
|
F src/delete.c 30ed4bc76a1a32c55bf17ac1528c5867aa5502c0
|
||||||
F src/expr.c 2068a7c17e45f8bee6e44205b059aa30acbc71c5
|
F src/expr.c 7e55edefb8bd0b35b382ce9226c58472cd63a443
|
||||||
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
||||||
F src/fkey.c 914a6bbd987d857c41ac9d244efa6641f36faadb
|
F src/fkey.c 914a6bbd987d857c41ac9d244efa6641f36faadb
|
||||||
F src/func.c 5c50c1ea31fd864b0fe921fe1a8d4c55acd609ef
|
F src/func.c 5c50c1ea31fd864b0fe921fe1a8d4c55acd609ef
|
||||||
@ -219,7 +219,7 @@ F src/os_unix.c 9eafa5458cf2ff684ddccff82c9bb113c7cad847
|
|||||||
F src/os_win.c 1d84f2079d9b91f91a4b5dbfa5e08f1b1a0ed0ff
|
F src/os_win.c 1d84f2079d9b91f91a4b5dbfa5e08f1b1a0ed0ff
|
||||||
F src/pager.c 5d2f7475260a8588f9c441bb309d2b7eaa7ded3b
|
F src/pager.c 5d2f7475260a8588f9c441bb309d2b7eaa7ded3b
|
||||||
F src/pager.h 5cb78b8e1adfd5451e600be7719f5a99d87ac3b1
|
F src/pager.h 5cb78b8e1adfd5451e600be7719f5a99d87ac3b1
|
||||||
F src/parse.y 599bc6338f3a6a7e1d656669a5667b9d77aea86b
|
F src/parse.y 27c6b4138497d6f8360ba7847da6ed48033f957f
|
||||||
F src/pcache.c f8043b433a57aba85384a531e3937a804432a346
|
F src/pcache.c f8043b433a57aba85384a531e3937a804432a346
|
||||||
F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222
|
F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222
|
||||||
F src/pcache1.c d23d07716de96c7c0c2503ec5051a4384c3fb938
|
F src/pcache1.c d23d07716de96c7c0c2503ec5051a4384c3fb938
|
||||||
@ -229,12 +229,12 @@ F src/printf.c 41c49dac366a3a411190001a8ab495fa8887974e
|
|||||||
F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
|
F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
|
||||||
F src/resolve.c 17e670996729ac41aadf6a31f57b4e6f29b3d819
|
F src/resolve.c 17e670996729ac41aadf6a31f57b4e6f29b3d819
|
||||||
F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0
|
F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0
|
||||||
F src/select.c 20369c82dc38eb4a77b458c8f6e353ef550580c9
|
F src/select.c 8b148eb851f384412aea57091659d14b369918ca
|
||||||
F src/shell.c 52f975eae87c8338c4dfbf4c2842d2a0971f01fd
|
F src/shell.c 927e17b37b63b24461e372d982138fb22c4df321
|
||||||
F src/sqlite.h.in 9dbc04c103f297d2bd26c7e323f0bdb9aaf0dc8a
|
F src/sqlite.h.in 9dbc04c103f297d2bd26c7e323f0bdb9aaf0dc8a
|
||||||
F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0
|
F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0
|
||||||
F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
|
F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
|
||||||
F src/sqliteInt.h 717511de3ce0129f9e02f98427b6a5991bbe64e4
|
F src/sqliteInt.h 1f9abddff71bbce4f51d275d3dc5262ceae7aa61
|
||||||
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
|
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
|
||||||
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
|
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
|
||||||
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
|
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
|
||||||
@ -272,7 +272,7 @@ F src/test_osinst.c 90a845c8183013d80eccb1f29e8805608516edba
|
|||||||
F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00
|
F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00
|
||||||
F src/test_quota.c 30c64f0ef84734f2231a686df41ed882b0c59bc0
|
F src/test_quota.c 30c64f0ef84734f2231a686df41ed882b0c59bc0
|
||||||
F src/test_quota.h 8761e463b25e75ebc078bd67d70e39b9c817a0cb
|
F src/test_quota.h 8761e463b25e75ebc078bd67d70e39b9c817a0cb
|
||||||
F src/test_rtree.c 1d764c352b5348bb2869ff5f54aff8eadcb96041
|
F src/test_rtree.c f3d1d12538dccb75fd916e3fa58f250edbdd3b47
|
||||||
F src/test_schema.c cd12a2223c3a394f4d07bb93bdf6d344c5c121b6
|
F src/test_schema.c cd12a2223c3a394f4d07bb93bdf6d344c5c121b6
|
||||||
F src/test_server.c 2f99eb2837dfa06a4aacf24af24c6affdf66a84f
|
F src/test_server.c 2f99eb2837dfa06a4aacf24af24c6affdf66a84f
|
||||||
F src/test_sqllog.c c1c1bbedbcaf82b93d83e4f9dd990e62476a680e
|
F src/test_sqllog.c c1c1bbedbcaf82b93d83e4f9dd990e62476a680e
|
||||||
@ -284,17 +284,17 @@ F src/test_thread.c 1e133a40b50e9c035b00174035b846e7eef481cb
|
|||||||
F src/test_vfs.c e72f555ef7a59080f898fcf1a233deb9eb704ea9
|
F src/test_vfs.c e72f555ef7a59080f898fcf1a233deb9eb704ea9
|
||||||
F src/test_vfstrace.c 34b544e80ba7fb77be15395a609c669df2e660a2
|
F src/test_vfstrace.c 34b544e80ba7fb77be15395a609c669df2e660a2
|
||||||
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
|
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
|
||||||
F src/tokenize.c e0e8fd3cb90a88451f6b6425726c84747b6b20d7
|
F src/tokenize.c 70061085a51f2f4fc15ece94f32c03bcb78e63b2
|
||||||
F src/trigger.c 5c0ea9b8755e7c5e1a700f3e27ac4f8d92dd221e
|
F src/trigger.c 5c0ea9b8755e7c5e1a700f3e27ac4f8d92dd221e
|
||||||
F src/update.c e3668141dd9701023681239265e001388f182236
|
F src/update.c e3668141dd9701023681239265e001388f182236
|
||||||
F src/utf.c 8d819e2e5104a430fc2005f018db14347c95a38f
|
F src/utf.c 8d819e2e5104a430fc2005f018db14347c95a38f
|
||||||
F src/util.c f566b5138099a2df8533b190d0dcc74b7dfbe0c9
|
F src/util.c f566b5138099a2df8533b190d0dcc74b7dfbe0c9
|
||||||
F src/vacuum.c d9c5759f4c5a438bb43c2086f72c5d2edabc36c8
|
F src/vacuum.c d9c5759f4c5a438bb43c2086f72c5d2edabc36c8
|
||||||
F src/vdbe.c 619306bc26158896392c84eb3c593e9bff35c49a
|
F src/vdbe.c 1d95ab3d4aae198744c1c14170b2466b58eb8970
|
||||||
F src/vdbe.h 7aa3ab6210a68471c8490dedfc9aa4ef5684b9a0
|
F src/vdbe.h 7aa3ab6210a68471c8490dedfc9aa4ef5684b9a0
|
||||||
F src/vdbeInt.h cc1974b94efa98ecaec6fa14a2584d7c1e82eadf
|
F src/vdbeInt.h cc1974b94efa98ecaec6fa14a2584d7c1e82eadf
|
||||||
F src/vdbeapi.c c8c433043d14b5e00e2ed6f7e44543bcc92d1594
|
F src/vdbeapi.c c8c433043d14b5e00e2ed6f7e44543bcc92d1594
|
||||||
F src/vdbeaux.c ef37cae69147a3680f6b1927b99f79a89c8ff53c
|
F src/vdbeaux.c 6549864e5fffa3d04941551610e4800de72e1be9
|
||||||
F src/vdbeblob.c 1268e0bcb8e21fa32520b0fc376e1bcdfaa0c642
|
F src/vdbeblob.c 1268e0bcb8e21fa32520b0fc376e1bcdfaa0c642
|
||||||
F src/vdbemem.c 833005f1cbbf447289f1973dba2a0c2228c7b8ab
|
F src/vdbemem.c 833005f1cbbf447289f1973dba2a0c2228c7b8ab
|
||||||
F src/vdbesort.c 3937e06b2a0e354500e17dc206ef4c35770a5017
|
F src/vdbesort.c 3937e06b2a0e354500e17dc206ef4c35770a5017
|
||||||
@ -303,7 +303,7 @@ F src/vtab.c 2e8b489db47e20ae36cd247932dc671c9ded0624
|
|||||||
F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4
|
F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4
|
||||||
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
|
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
|
||||||
F src/walker.c 4fa43583d0a84b48f93b1e88f11adf2065be4e73
|
F src/walker.c 4fa43583d0a84b48f93b1e88f11adf2065be4e73
|
||||||
F src/where.c 30a9f5e4acd74e727b69a7f53a76863f9316b43b
|
F src/where.c 67245bb73fd9cc04ee7796a0f358d4910c45cfe9
|
||||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||||
F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6
|
F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6
|
||||||
@ -436,26 +436,26 @@ F test/descidx3.test 09ddbe3f5295f482d2f8b687cf6db8bad7acd9a2
|
|||||||
F test/diskfull.test 106391384780753ea6896b7b4f005d10e9866b6e
|
F test/diskfull.test 106391384780753ea6896b7b4f005d10e9866b6e
|
||||||
F test/distinct.test 44028aaf161a5e80a2f229622b3a174d3b352810
|
F test/distinct.test 44028aaf161a5e80a2f229622b3a174d3b352810
|
||||||
F test/distinctagg.test 1a6ef9c87a58669438fc771450d7a72577417376
|
F test/distinctagg.test 1a6ef9c87a58669438fc771450d7a72577417376
|
||||||
F test/e_createtable.test ddf3b2e4506e0813f46b69ccf55757c5570cc181
|
F test/e_createtable.test ee9b70a38369ae44360febb411976aa3c8cf2689
|
||||||
F test/e_delete.test 89aa84d3d1bd284a0689ede04bce10226a5aeaa5
|
F test/e_delete.test d5186e2f5478b659f16a2c8b66c09892823e542a
|
||||||
F test/e_droptrigger.test afd5c4d27dec607f5997a66bf7e2498a082cb235
|
F test/e_droptrigger.test 3cd080807622c13e5bbb61fc9a57bd7754da2412
|
||||||
F test/e_dropview.test 583411e470458c5d76148542cfb5a5fa84c8f93e
|
F test/e_dropview.test 0c9f7f60989164a70a67a9d9c26d1083bc808306
|
||||||
F test/e_expr.test 2a599f40f37ee9e853c4396c28ff13c2c50f6628
|
F test/e_expr.test d5cdda0e4ffb17760858ed4c7c4ece07efc40f71
|
||||||
F test/e_fkey.test 17cfb40002d165299681f39aac0cb5890c359935
|
F test/e_fkey.test 17cfb40002d165299681f39aac0cb5890c359935
|
||||||
F test/e_fts3.test 5c02288842e4f941896fd44afdef564dd5fc1459
|
F test/e_fts3.test 5c02288842e4f941896fd44afdef564dd5fc1459
|
||||||
F test/e_insert.test d5331cc95e101af2508159fc98b6801631659ffe
|
F test/e_insert.test ea84688f3b27a6a3728e4ae7a7d9ad342579d7a4
|
||||||
F test/e_reindex.test 5e6dff3a060b5234d496f6e84c3e59a94b4dce4d
|
F test/e_reindex.test e175794fc41f8e8aef34772e87a7d7b7a9251dd3
|
||||||
F test/e_resolve.test dcce9308fb13b934ce29591105d031d3e14fbba6
|
F test/e_resolve.test dcce9308fb13b934ce29591105d031d3e14fbba6
|
||||||
F test/e_select.test d5af998a402740d8f0488158d22075df2b6f88fa
|
F test/e_select.test f2358d074bd82240bc79a8348f284a2a8909dc1f
|
||||||
F test/e_select2.test 5c3d3da19c7b3e90ae444579db2b70098599ab92
|
F test/e_select2.test 22c660a7becf0712c95e1ca1b2d9e716a1261460
|
||||||
F test/e_update.test 161d5dc6a3ed9dd08f5264d13e20735d7a89f00c
|
F test/e_update.test bea00499e43ee1da77b03cdb0b20c7c864c1ec5a
|
||||||
F test/e_uri.test 8f2f56b29456a3f846276fa4e0993d4ef8a15b79
|
F test/e_uri.test a2c92d80093a7efdcfbb11093651cbea87097b6b
|
||||||
F test/e_vacuum.test 331da289ae186656cf5f2eb27f577a89c0c221af
|
F test/e_vacuum.test 5bfbdc21b65c0abf24398d0ba31dc88d93ca77a9
|
||||||
F test/enc.test e54531cd6bf941ee6760be041dff19a104c7acea
|
F test/enc.test e54531cd6bf941ee6760be041dff19a104c7acea
|
||||||
F test/enc2.test 83437a79ba1545a55fb549309175c683fb334473
|
F test/enc2.test 83437a79ba1545a55fb549309175c683fb334473
|
||||||
F test/enc3.test 90683ad0e6ea587b9d5542ca93568af9a9858c40
|
F test/enc3.test 90683ad0e6ea587b9d5542ca93568af9a9858c40
|
||||||
F test/enc4.test c8f1ce3618508fd0909945beb8b8831feef2c020
|
F test/enc4.test c8f1ce3618508fd0909945beb8b8831feef2c020
|
||||||
F test/eqp.test 8ef4d89dc44d8988b3ea6e60902905d739508db0
|
F test/eqp.test d9e7ad4e7bd36d976f1b631f76e6e6ea090c41a0
|
||||||
F test/errmsg.test 050717f1c6a5685de9c79f5f9f6b83d7c592f73a
|
F test/errmsg.test 050717f1c6a5685de9c79f5f9f6b83d7c592f73a
|
||||||
F test/eval.test bc269c365ba877554948441e91ad5373f9f91be3
|
F test/eval.test bc269c365ba877554948441e91ad5373f9f91be3
|
||||||
F test/exclusive.test c7ebbc756eacf544c108b15eed64d7d4e5f86b75
|
F test/exclusive.test c7ebbc756eacf544c108b15eed64d7d4e5f86b75
|
||||||
@ -1119,7 +1119,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
|||||||
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
|
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
|
||||||
F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae
|
F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae
|
||||||
F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
|
F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
|
||||||
P 8dfc0b78c38e519b64a796243ff7c0aff688ff36 c5c0a8ab6c222185d5f9d4321e64d9f93cd36b7d
|
P 7e1acb390770d1bd189fac7a3a7f96106f96e3a4 5dcc2d91bd343cd0fac79d3c8f079a5ce534cdf7
|
||||||
R 6bd6d033a187336743a83e4c58485278
|
R 16c019af84c40424fdcd3228006de852
|
||||||
U drh
|
U drh
|
||||||
Z 807175c2ca92264cb8fa0f2650b5caad
|
Z 236e21ad4140ab8f1ddcd5409f261d54
|
||||||
|
@ -1 +1 @@
|
|||||||
7e1acb390770d1bd189fac7a3a7f96106f96e3a4
|
69d5bed017bda3e184857febcc8b6f6bed6ad228
|
@ -35,7 +35,7 @@
|
|||||||
|
|
||||||
# Remember the TK_ values from the parse.h file
|
# Remember the TK_ values from the parse.h file
|
||||||
/^#define TK_/ {
|
/^#define TK_/ {
|
||||||
tk[$2] = 0+$3
|
tk[$2] = 0+$3 # tk[x] holds the numeric value for TK symbol X
|
||||||
}
|
}
|
||||||
|
|
||||||
# Scan for "case OP_aaaa:" lines in the vdbe.c file
|
# Scan for "case OP_aaaa:" lines in the vdbe.c file
|
||||||
@ -43,7 +43,7 @@
|
|||||||
name = $2
|
name = $2
|
||||||
sub(/:/,"",name)
|
sub(/:/,"",name)
|
||||||
sub("\r","",name)
|
sub("\r","",name)
|
||||||
op[name] = -1
|
op[name] = -1 # op[x] holds the numeric value for OP symbol x
|
||||||
jump[name] = 0
|
jump[name] = 0
|
||||||
out2_prerelease[name] = 0
|
out2_prerelease[name] = 0
|
||||||
in1[name] = 0
|
in1[name] = 0
|
||||||
@ -55,9 +55,11 @@
|
|||||||
if($i=="same" && $(i+1)=="as"){
|
if($i=="same" && $(i+1)=="as"){
|
||||||
sym = $(i+2)
|
sym = $(i+2)
|
||||||
sub(/,/,"",sym)
|
sub(/,/,"",sym)
|
||||||
op[name] = tk[sym]
|
val = tk[sym]
|
||||||
used[op[name]] = 1
|
op[name] = val
|
||||||
sameas[op[name]] = sym
|
used[val] = 1
|
||||||
|
sameas[val] = sym
|
||||||
|
def[val] = name
|
||||||
}
|
}
|
||||||
x = $i
|
x = $i
|
||||||
sub(",","",x)
|
sub(",","",x)
|
||||||
@ -90,31 +92,55 @@ END {
|
|||||||
order[n_op++] = "OP_Noop";
|
order[n_op++] = "OP_Noop";
|
||||||
op["OP_Explain"] = -1;
|
op["OP_Explain"] = -1;
|
||||||
order[n_op++] = "OP_Explain";
|
order[n_op++] = "OP_Explain";
|
||||||
|
|
||||||
|
# Assign small values to opcodes that are processed by resolveP2Values()
|
||||||
|
# to make code generation for the switch() statement smaller and faster.
|
||||||
|
for(i=0; i<n_op; i++){
|
||||||
|
name = order[i];
|
||||||
|
if( op[name]>=0 ) continue;
|
||||||
|
if( name=="OP_Function" \
|
||||||
|
|| name=="OP_AggStep" \
|
||||||
|
|| name=="OP_Transaction" \
|
||||||
|
|| name=="OP_AutoCommit" \
|
||||||
|
|| name=="OP_Savepoint" \
|
||||||
|
|| name=="OP_Checkpoint" \
|
||||||
|
|| name=="OP_Vacuum" \
|
||||||
|
|| name=="OP_JournalMode" \
|
||||||
|
|| name=="OP_VUpdate" \
|
||||||
|
|| name=="OP_VFilter" \
|
||||||
|
|| name=="OP_Next" \
|
||||||
|
|| name=="OP_SorterNext" \
|
||||||
|
|| name=="OP_Prev" \
|
||||||
|
){
|
||||||
|
cnt++
|
||||||
|
while( used[cnt] ) cnt++
|
||||||
|
op[name] = cnt
|
||||||
|
used[cnt] = 1
|
||||||
|
def[cnt] = name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Generate the numeric values for opcodes
|
||||||
for(i=0; i<n_op; i++){
|
for(i=0; i<n_op; i++){
|
||||||
name = order[i];
|
name = order[i];
|
||||||
if( op[name]<0 ){
|
if( op[name]<0 ){
|
||||||
cnt++
|
cnt++
|
||||||
while( used[cnt] ) cnt++
|
while( used[cnt] ) cnt++
|
||||||
op[name] = cnt
|
op[name] = cnt
|
||||||
|
used[cnt] = 1
|
||||||
|
def[cnt] = name
|
||||||
}
|
}
|
||||||
used[op[name]] = 1;
|
}
|
||||||
if( op[name]>max ) max = op[name]
|
max = cnt
|
||||||
printf "#define %-25s %15d", name, op[name]
|
for(i=1; i<=max; i++){
|
||||||
if( sameas[op[name]] ) {
|
if( !used[i] ){
|
||||||
printf " /* same as %-12s*/", sameas[op[name]]
|
def[i] = "OP_NotUsed_" i
|
||||||
|
}
|
||||||
|
printf "#define %-25s %15d", def[i], i
|
||||||
|
if( sameas[i] ){
|
||||||
|
printf " /* same as %-12s*/", sameas[i]
|
||||||
}
|
}
|
||||||
printf "\n"
|
printf "\n"
|
||||||
|
|
||||||
}
|
|
||||||
seenUnused = 0;
|
|
||||||
for(i=1; i<max; i++){
|
|
||||||
if( !used[i] ){
|
|
||||||
if( !seenUnused ){
|
|
||||||
printf "\n/* The following opcode values are never used */\n"
|
|
||||||
seenUnused = 1
|
|
||||||
}
|
|
||||||
printf "#define %-25s %15d\n", sprintf( "OP_NotUsed_%-3d", i ), i
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Generate the bitvectors:
|
# Generate the bitvectors:
|
||||||
@ -123,12 +149,9 @@ END {
|
|||||||
# bit 1: pushes a result onto stack
|
# bit 1: pushes a result onto stack
|
||||||
# bit 2: output to p1. release p1 before opcode runs
|
# bit 2: output to p1. release p1 before opcode runs
|
||||||
#
|
#
|
||||||
for(i=0; i<=max; i++) bv[i] = 0;
|
for(i=0; i<=max; i++){
|
||||||
for(i=0; i<n_op; i++){
|
name = def[i]
|
||||||
name = order[i];
|
|
||||||
x = op[name]
|
|
||||||
a0 = a1 = a2 = a3 = a4 = a5 = a6 = a7 = 0
|
a0 = a1 = a2 = a3 = a4 = a5 = a6 = a7 = 0
|
||||||
# a7 = a9 = a10 = a11 = a12 = a13 = a14 = a15 = 0
|
|
||||||
if( jump[name] ) a0 = 1;
|
if( jump[name] ) a0 = 1;
|
||||||
if( out2_prerelease[name] ) a1 = 2;
|
if( out2_prerelease[name] ) a1 = 2;
|
||||||
if( in1[name] ) a2 = 4;
|
if( in1[name] ) a2 = 4;
|
||||||
@ -136,8 +159,7 @@ END {
|
|||||||
if( in3[name] ) a4 = 16;
|
if( in3[name] ) a4 = 16;
|
||||||
if( out2[name] ) a5 = 32;
|
if( out2[name] ) a5 = 32;
|
||||||
if( out3[name] ) a6 = 64;
|
if( out3[name] ) a6 = 64;
|
||||||
# bv[x] = a0+a1+a2+a3+a4+a5+a6+a7+a8+a9+a10+a11+a12+a13+a14+a15;
|
bv[i] = a0+a1+a2+a3+a4+a5+a6+a7;
|
||||||
bv[x] = a0+a1+a2+a3+a4+a5+a6+a7;
|
|
||||||
}
|
}
|
||||||
print "\n"
|
print "\n"
|
||||||
print "/* Properties such as \"out2\" or \"jump\" that are specified in"
|
print "/* Properties such as \"out2\" or \"jump\" that are specified in"
|
||||||
|
11
src/build.c
11
src/build.c
@ -3805,25 +3805,20 @@ void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){
|
|||||||
KeyInfo *sqlite3IndexKeyinfo(Parse *pParse, Index *pIdx){
|
KeyInfo *sqlite3IndexKeyinfo(Parse *pParse, Index *pIdx){
|
||||||
int i;
|
int i;
|
||||||
int nCol = pIdx->nColumn;
|
int nCol = pIdx->nColumn;
|
||||||
int nBytes = sizeof(KeyInfo) + (nCol-1)*sizeof(CollSeq*) + nCol;
|
KeyInfo *pKey;
|
||||||
sqlite3 *db = pParse->db;
|
|
||||||
KeyInfo *pKey = (KeyInfo *)sqlite3DbMallocZero(db, nBytes);
|
|
||||||
|
|
||||||
|
pKey = sqlite3KeyInfoAlloc(pParse->db, nCol);
|
||||||
if( pKey ){
|
if( pKey ){
|
||||||
pKey->db = pParse->db;
|
|
||||||
pKey->aSortOrder = (u8 *)&(pKey->aColl[nCol]);
|
|
||||||
assert( &pKey->aSortOrder[nCol]==&(((u8 *)pKey)[nBytes]) );
|
|
||||||
for(i=0; i<nCol; i++){
|
for(i=0; i<nCol; i++){
|
||||||
char *zColl = pIdx->azColl[i];
|
char *zColl = pIdx->azColl[i];
|
||||||
assert( zColl );
|
assert( zColl );
|
||||||
pKey->aColl[i] = sqlite3LocateCollSeq(pParse, zColl);
|
pKey->aColl[i] = sqlite3LocateCollSeq(pParse, zColl);
|
||||||
pKey->aSortOrder[i] = pIdx->aSortOrder[i];
|
pKey->aSortOrder[i] = pIdx->aSortOrder[i];
|
||||||
}
|
}
|
||||||
pKey->nField = (u16)nCol;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( pParse->nErr ){
|
if( pParse->nErr ){
|
||||||
sqlite3DbFree(db, pKey);
|
sqlite3DbFree(pParse->db, pKey);
|
||||||
pKey = 0;
|
pKey = 0;
|
||||||
}
|
}
|
||||||
return pKey;
|
return pKey;
|
||||||
|
21
src/expr.c
21
src/expr.c
@ -1692,10 +1692,9 @@ int sqlite3CodeSubselect(
|
|||||||
switch( pExpr->op ){
|
switch( pExpr->op ){
|
||||||
case TK_IN: {
|
case TK_IN: {
|
||||||
char affinity; /* Affinity of the LHS of the IN */
|
char affinity; /* Affinity of the LHS of the IN */
|
||||||
KeyInfo keyInfo; /* Keyinfo for the generated table */
|
|
||||||
static u8 sortOrder = 0; /* Fake aSortOrder for keyInfo */
|
|
||||||
int addr; /* Address of OP_OpenEphemeral instruction */
|
int addr; /* Address of OP_OpenEphemeral instruction */
|
||||||
Expr *pLeft = pExpr->pLeft; /* the LHS of the IN operator */
|
Expr *pLeft = pExpr->pLeft; /* the LHS of the IN operator */
|
||||||
|
KeyInfo *pKeyInfo = 0; /* Key information */
|
||||||
|
|
||||||
if( rMayHaveNull ){
|
if( rMayHaveNull ){
|
||||||
sqlite3VdbeAddOp2(v, OP_Null, 0, rMayHaveNull);
|
sqlite3VdbeAddOp2(v, OP_Null, 0, rMayHaveNull);
|
||||||
@ -1719,9 +1718,7 @@ int sqlite3CodeSubselect(
|
|||||||
pExpr->iTable = pParse->nTab++;
|
pExpr->iTable = pParse->nTab++;
|
||||||
addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pExpr->iTable, !isRowid);
|
addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pExpr->iTable, !isRowid);
|
||||||
if( rMayHaveNull==0 ) sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
|
if( rMayHaveNull==0 ) sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
|
||||||
memset(&keyInfo, 0, sizeof(keyInfo));
|
pKeyInfo = isRowid ? 0 : sqlite3KeyInfoAlloc(pParse->db, 1);
|
||||||
keyInfo.nField = 1;
|
|
||||||
keyInfo.aSortOrder = &sortOrder;
|
|
||||||
|
|
||||||
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
|
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
|
||||||
/* Case 1: expr IN (SELECT ...)
|
/* Case 1: expr IN (SELECT ...)
|
||||||
@ -1738,11 +1735,12 @@ int sqlite3CodeSubselect(
|
|||||||
assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable );
|
assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable );
|
||||||
pExpr->x.pSelect->iLimit = 0;
|
pExpr->x.pSelect->iLimit = 0;
|
||||||
if( sqlite3Select(pParse, pExpr->x.pSelect, &dest) ){
|
if( sqlite3Select(pParse, pExpr->x.pSelect, &dest) ){
|
||||||
|
sqlite3DbFree(pParse->db, pKeyInfo);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
pEList = pExpr->x.pSelect->pEList;
|
pEList = pExpr->x.pSelect->pEList;
|
||||||
if( ALWAYS(pEList!=0 && pEList->nExpr>0) ){
|
if( pKeyInfo && ALWAYS(pEList!=0 && pEList->nExpr>0) ){
|
||||||
keyInfo.aColl[0] = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft,
|
pKeyInfo->aColl[0] = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft,
|
||||||
pEList->a[0].pExpr);
|
pEList->a[0].pExpr);
|
||||||
}
|
}
|
||||||
}else if( ALWAYS(pExpr->x.pList!=0) ){
|
}else if( ALWAYS(pExpr->x.pList!=0) ){
|
||||||
@ -1761,8 +1759,9 @@ int sqlite3CodeSubselect(
|
|||||||
if( !affinity ){
|
if( !affinity ){
|
||||||
affinity = SQLITE_AFF_NONE;
|
affinity = SQLITE_AFF_NONE;
|
||||||
}
|
}
|
||||||
keyInfo.aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
|
if( pKeyInfo ){
|
||||||
keyInfo.aSortOrder = &sortOrder;
|
pKeyInfo->aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
|
||||||
|
}
|
||||||
|
|
||||||
/* Loop through each expression in <exprlist>. */
|
/* Loop through each expression in <exprlist>. */
|
||||||
r1 = sqlite3GetTempReg(pParse);
|
r1 = sqlite3GetTempReg(pParse);
|
||||||
@ -1801,8 +1800,8 @@ int sqlite3CodeSubselect(
|
|||||||
sqlite3ReleaseTempReg(pParse, r1);
|
sqlite3ReleaseTempReg(pParse, r1);
|
||||||
sqlite3ReleaseTempReg(pParse, r2);
|
sqlite3ReleaseTempReg(pParse, r2);
|
||||||
}
|
}
|
||||||
if( !isRowid ){
|
if( pKeyInfo ){
|
||||||
sqlite3VdbeChangeP4(v, addr, (void *)&keyInfo, P4_KEYINFO);
|
sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO_HANDOFF);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -417,6 +417,7 @@ select(A) ::= select(X) multiselect_op(Y) oneselect(Z). {
|
|||||||
if( Z ){
|
if( Z ){
|
||||||
Z->op = (u8)Y;
|
Z->op = (u8)Y;
|
||||||
Z->pPrior = X;
|
Z->pPrior = X;
|
||||||
|
if( Y!=TK_ALL ) pParse->hasCompound = 1;
|
||||||
}else{
|
}else{
|
||||||
sqlite3SelectDelete(pParse->db, X);
|
sqlite3SelectDelete(pParse->db, X);
|
||||||
}
|
}
|
||||||
|
57
src/select.c
57
src/select.c
@ -802,6 +802,25 @@ static void selectInnerLoop(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Allocate a KeyInfo object sufficient for an index of N columns.
|
||||||
|
**
|
||||||
|
** Actually, always allocate one extra column for the rowid at the end
|
||||||
|
** of the index. So the KeyInfo returned will have space sufficient for
|
||||||
|
** N+1 columns.
|
||||||
|
*/
|
||||||
|
KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N){
|
||||||
|
KeyInfo *p = sqlite3DbMallocZero(db,
|
||||||
|
sizeof(KeyInfo) + (N+1)*(sizeof(CollSeq*)+1));
|
||||||
|
if( p ){
|
||||||
|
p->aSortOrder = (u8*)&p->aColl[N+1];
|
||||||
|
p->nField = (u16)N;
|
||||||
|
p->enc = ENC(db);
|
||||||
|
p->db = db;
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Given an expression list, generate a KeyInfo structure that records
|
** Given an expression list, generate a KeyInfo structure that records
|
||||||
** the collating sequence for each expression in that expression list.
|
** the collating sequence for each expression in that expression list.
|
||||||
@ -818,25 +837,19 @@ static void selectInnerLoop(
|
|||||||
** P4_KEYINFO_HANDOFF is the usual way of dealing with this.
|
** P4_KEYINFO_HANDOFF is the usual way of dealing with this.
|
||||||
*/
|
*/
|
||||||
static KeyInfo *keyInfoFromExprList(Parse *pParse, ExprList *pList){
|
static KeyInfo *keyInfoFromExprList(Parse *pParse, ExprList *pList){
|
||||||
sqlite3 *db = pParse->db;
|
|
||||||
int nExpr;
|
int nExpr;
|
||||||
KeyInfo *pInfo;
|
KeyInfo *pInfo;
|
||||||
struct ExprList_item *pItem;
|
struct ExprList_item *pItem;
|
||||||
|
sqlite3 *db = pParse->db;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
nExpr = pList->nExpr;
|
nExpr = pList->nExpr;
|
||||||
pInfo = sqlite3DbMallocZero(db, sizeof(*pInfo) + nExpr*(sizeof(CollSeq*)+1) );
|
pInfo = sqlite3KeyInfoAlloc(db, nExpr);
|
||||||
if( pInfo ){
|
if( pInfo ){
|
||||||
pInfo->aSortOrder = (u8*)&pInfo->aColl[nExpr];
|
|
||||||
pInfo->nField = (u16)nExpr;
|
|
||||||
pInfo->enc = ENC(db);
|
|
||||||
pInfo->db = db;
|
|
||||||
for(i=0, pItem=pList->a; i<nExpr; i++, pItem++){
|
for(i=0, pItem=pList->a; i<nExpr; i++, pItem++){
|
||||||
CollSeq *pColl;
|
CollSeq *pColl;
|
||||||
pColl = sqlite3ExprCollSeq(pParse, pItem->pExpr);
|
pColl = sqlite3ExprCollSeq(pParse, pItem->pExpr);
|
||||||
if( !pColl ){
|
if( !pColl ) pColl = db->pDfltColl;
|
||||||
pColl = db->pDfltColl;
|
|
||||||
}
|
|
||||||
pInfo->aColl[i] = pColl;
|
pInfo->aColl[i] = pColl;
|
||||||
pInfo->aSortOrder[i] = pItem->sortOrder;
|
pInfo->aSortOrder[i] = pItem->sortOrder;
|
||||||
}
|
}
|
||||||
@ -1942,23 +1955,17 @@ static int multiSelect(
|
|||||||
|
|
||||||
assert( p->pRightmost==p );
|
assert( p->pRightmost==p );
|
||||||
nCol = p->pEList->nExpr;
|
nCol = p->pEList->nExpr;
|
||||||
pKeyInfo = sqlite3DbMallocZero(db,
|
pKeyInfo = sqlite3KeyInfoAlloc(db, nCol);
|
||||||
sizeof(*pKeyInfo)+nCol*(sizeof(CollSeq*) + 1));
|
|
||||||
if( !pKeyInfo ){
|
if( !pKeyInfo ){
|
||||||
rc = SQLITE_NOMEM;
|
rc = SQLITE_NOMEM;
|
||||||
goto multi_select_end;
|
goto multi_select_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
pKeyInfo->enc = ENC(db);
|
|
||||||
pKeyInfo->nField = (u16)nCol;
|
|
||||||
|
|
||||||
for(i=0, apColl=pKeyInfo->aColl; i<nCol; i++, apColl++){
|
for(i=0, apColl=pKeyInfo->aColl; i<nCol; i++, apColl++){
|
||||||
*apColl = multiSelectCollSeq(pParse, p, i);
|
*apColl = multiSelectCollSeq(pParse, p, i);
|
||||||
if( 0==*apColl ){
|
if( 0==*apColl ){
|
||||||
*apColl = db->pDfltColl;
|
*apColl = db->pDfltColl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pKeyInfo->aSortOrder = (u8*)apColl;
|
|
||||||
|
|
||||||
for(pLoop=p; pLoop; pLoop=pLoop->pPrior){
|
for(pLoop=p; pLoop; pLoop=pLoop->pPrior){
|
||||||
for(i=0; i<2; i++){
|
for(i=0; i<2; i++){
|
||||||
@ -2327,12 +2334,8 @@ static int multiSelectOrderBy(
|
|||||||
assert( pItem->iOrderByCol>0 && pItem->iOrderByCol<=p->pEList->nExpr );
|
assert( pItem->iOrderByCol>0 && pItem->iOrderByCol<=p->pEList->nExpr );
|
||||||
aPermute[i] = pItem->iOrderByCol - 1;
|
aPermute[i] = pItem->iOrderByCol - 1;
|
||||||
}
|
}
|
||||||
pKeyMerge =
|
pKeyMerge = sqlite3KeyInfoAlloc(db, nOrderBy);
|
||||||
sqlite3DbMallocRaw(db, sizeof(*pKeyMerge)+nOrderBy*(sizeof(CollSeq*)+1));
|
|
||||||
if( pKeyMerge ){
|
if( pKeyMerge ){
|
||||||
pKeyMerge->aSortOrder = (u8*)&pKeyMerge->aColl[nOrderBy];
|
|
||||||
pKeyMerge->nField = (u16)nOrderBy;
|
|
||||||
pKeyMerge->enc = ENC(db);
|
|
||||||
for(i=0; i<nOrderBy; i++){
|
for(i=0; i<nOrderBy; i++){
|
||||||
CollSeq *pColl;
|
CollSeq *pColl;
|
||||||
Expr *pTerm = pOrderBy->a[i].pExpr;
|
Expr *pTerm = pOrderBy->a[i].pExpr;
|
||||||
@ -2369,12 +2372,8 @@ static int multiSelectOrderBy(
|
|||||||
regPrev = pParse->nMem+1;
|
regPrev = pParse->nMem+1;
|
||||||
pParse->nMem += nExpr+1;
|
pParse->nMem += nExpr+1;
|
||||||
sqlite3VdbeAddOp2(v, OP_Integer, 0, regPrev);
|
sqlite3VdbeAddOp2(v, OP_Integer, 0, regPrev);
|
||||||
pKeyDup = sqlite3DbMallocZero(db,
|
pKeyDup = sqlite3KeyInfoAlloc(db, nExpr);
|
||||||
sizeof(*pKeyDup) + nExpr*(sizeof(CollSeq*)+1) );
|
|
||||||
if( pKeyDup ){
|
if( pKeyDup ){
|
||||||
pKeyDup->aSortOrder = (u8*)&pKeyDup->aColl[nExpr];
|
|
||||||
pKeyDup->nField = (u16)nExpr;
|
|
||||||
pKeyDup->enc = ENC(db);
|
|
||||||
for(i=0; i<nExpr; i++){
|
for(i=0; i<nExpr; i++){
|
||||||
pKeyDup->aColl[i] = multiSelectCollSeq(pParse, p, i);
|
pKeyDup->aColl[i] = multiSelectCollSeq(pParse, p, i);
|
||||||
pKeyDup->aSortOrder[i] = 0;
|
pKeyDup->aSortOrder[i] = 0;
|
||||||
@ -3640,10 +3639,12 @@ static int exprWalkNoop(Walker *NotUsed, Expr *NotUsed2){
|
|||||||
static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){
|
static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){
|
||||||
Walker w;
|
Walker w;
|
||||||
memset(&w, 0, sizeof(w));
|
memset(&w, 0, sizeof(w));
|
||||||
w.xSelectCallback = convertCompoundSelectToSubquery;
|
|
||||||
w.xExprCallback = exprWalkNoop;
|
w.xExprCallback = exprWalkNoop;
|
||||||
w.pParse = pParse;
|
w.pParse = pParse;
|
||||||
sqlite3WalkSelect(&w, pSelect);
|
if( pParse->hasCompound ){
|
||||||
|
w.xSelectCallback = convertCompoundSelectToSubquery;
|
||||||
|
sqlite3WalkSelect(&w, pSelect);
|
||||||
|
}
|
||||||
w.xSelectCallback = selectExpander;
|
w.xSelectCallback = selectExpander;
|
||||||
sqlite3WalkSelect(&w, pSelect);
|
sqlite3WalkSelect(&w, pSelect);
|
||||||
}
|
}
|
||||||
|
147
src/shell.c
147
src/shell.c
@ -53,7 +53,6 @@
|
|||||||
# include <readline/history.h>
|
# include <readline/history.h>
|
||||||
#endif
|
#endif
|
||||||
#if !defined(HAVE_EDITLINE) && (!defined(HAVE_READLINE) || HAVE_READLINE!=1)
|
#if !defined(HAVE_EDITLINE) && (!defined(HAVE_READLINE) || HAVE_READLINE!=1)
|
||||||
# define readline(p) local_getline(p,stdin,0)
|
|
||||||
# define add_history(X)
|
# define add_history(X)
|
||||||
# define read_history(X)
|
# define read_history(X)
|
||||||
# define write_history(X)
|
# define write_history(X)
|
||||||
@ -337,23 +336,13 @@ static void shellstaticFunc(
|
|||||||
** to the text. NULL is returned at end of file, or if malloc()
|
** to the text. NULL is returned at end of file, or if malloc()
|
||||||
** fails.
|
** fails.
|
||||||
**
|
**
|
||||||
** The interface is like "readline" but no command-line editing
|
** If zLine is not NULL then it is a malloced buffer returned from
|
||||||
** is done.
|
** a previous call to this routine that may be reused.
|
||||||
*/
|
*/
|
||||||
static char *local_getline(char *zPrompt, FILE *in, int csvFlag){
|
static char *local_getline(char *zLine, FILE *in){
|
||||||
char *zLine;
|
int nLine = zLine==0 ? 0 : 100;
|
||||||
int nLine;
|
int n = 0;
|
||||||
int n;
|
|
||||||
int inQuote = 0;
|
|
||||||
|
|
||||||
if( zPrompt && *zPrompt ){
|
|
||||||
printf("%s",zPrompt);
|
|
||||||
fflush(stdout);
|
|
||||||
}
|
|
||||||
nLine = 100;
|
|
||||||
zLine = malloc( nLine );
|
|
||||||
if( zLine==0 ) return 0;
|
|
||||||
n = 0;
|
|
||||||
while( 1 ){
|
while( 1 ){
|
||||||
if( n+100>nLine ){
|
if( n+100>nLine ){
|
||||||
nLine = nLine*2 + 100;
|
nLine = nLine*2 + 100;
|
||||||
@ -368,42 +357,48 @@ static char *local_getline(char *zPrompt, FILE *in, int csvFlag){
|
|||||||
zLine[n] = 0;
|
zLine[n] = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
while( zLine[n] ){
|
while( zLine[n] ) n++;
|
||||||
if( zLine[n]=='"' ) inQuote = !inQuote;
|
if( n>0 && zLine[n-1]=='\n' ){
|
||||||
n++;
|
|
||||||
}
|
|
||||||
if( n>0 && zLine[n-1]=='\n' && (!inQuote || !csvFlag) ){
|
|
||||||
n--;
|
n--;
|
||||||
if( n>0 && zLine[n-1]=='\r' ) n--;
|
if( n>0 && zLine[n-1]=='\r' ) n--;
|
||||||
zLine[n] = 0;
|
zLine[n] = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
zLine = realloc( zLine, n+1 );
|
|
||||||
return zLine;
|
return zLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Retrieve a single line of input text.
|
** Retrieve a single line of input text.
|
||||||
**
|
**
|
||||||
** zPrior is a string of prior text retrieved. If not the empty
|
** If in==0 then read from standard input and prompt before each line.
|
||||||
** string, then issue a continuation prompt.
|
** If isContinuation is true, then a continuation prompt is appropriate.
|
||||||
|
** If isContinuation is zero, then the main prompt should be used.
|
||||||
|
**
|
||||||
|
** If zPrior is not NULL then it is a buffer from a prior call to this
|
||||||
|
** routine that can be reused.
|
||||||
|
**
|
||||||
|
** The result is stored in space obtained from malloc() and must either
|
||||||
|
** be freed by the caller or else passed back into this routine via the
|
||||||
|
** zPrior argument for reuse.
|
||||||
*/
|
*/
|
||||||
static char *one_input_line(const char *zPrior, FILE *in){
|
static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
|
||||||
char *zPrompt;
|
char *zPrompt;
|
||||||
char *zResult;
|
char *zResult;
|
||||||
if( in!=0 ){
|
if( in!=0 ){
|
||||||
return local_getline(0, in, 0);
|
zResult = local_getline(zPrior, in);
|
||||||
}
|
|
||||||
if( zPrior && zPrior[0] ){
|
|
||||||
zPrompt = continuePrompt;
|
|
||||||
}else{
|
}else{
|
||||||
zPrompt = mainPrompt;
|
zPrompt = isContinuation ? continuePrompt : mainPrompt;
|
||||||
}
|
|
||||||
zResult = readline(zPrompt);
|
|
||||||
#if defined(HAVE_READLINE) && HAVE_READLINE==1
|
#if defined(HAVE_READLINE) && HAVE_READLINE==1
|
||||||
if( zResult && *zResult ) add_history(zResult);
|
free(zPrior);
|
||||||
|
zResult = readline(zPrompt);
|
||||||
|
if( zResult && *zResult ) add_history(zResult);
|
||||||
|
#else
|
||||||
|
printf("%s", zPrompt);
|
||||||
|
fflush(stdout);
|
||||||
|
zResult = local_getline(zPrior, stdin);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
return zResult;
|
return zResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1995,6 +1990,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
|
|||||||
int nCol; /* Number of columns in the table */
|
int nCol; /* Number of columns in the table */
|
||||||
int nByte; /* Number of bytes in an SQL string */
|
int nByte; /* Number of bytes in an SQL string */
|
||||||
int i, j; /* Loop counters */
|
int i, j; /* Loop counters */
|
||||||
|
int needCommit; /* True to COMMIT or ROLLBACK at end */
|
||||||
int nSep; /* Number of bytes in p->separator[] */
|
int nSep; /* Number of bytes in p->separator[] */
|
||||||
char *zSql; /* An SQL statement */
|
char *zSql; /* An SQL statement */
|
||||||
CSVReader sCsv; /* Reader context */
|
CSVReader sCsv; /* Reader context */
|
||||||
@ -2096,6 +2092,8 @@ static int do_meta_command(char *zLine, struct callback_data *p){
|
|||||||
xCloser(sCsv.in);
|
xCloser(sCsv.in);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
needCommit = sqlite3_get_autocommit(db);
|
||||||
|
if( needCommit ) sqlite3_exec(db, "BEGIN", 0, 0, 0);
|
||||||
do{
|
do{
|
||||||
int startLine = sCsv.nLine;
|
int startLine = sCsv.nLine;
|
||||||
for(i=0; i<nCol; i++){
|
for(i=0; i<nCol; i++){
|
||||||
@ -2132,7 +2130,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
|
|||||||
xCloser(sCsv.in);
|
xCloser(sCsv.in);
|
||||||
sqlite3_free(sCsv.z);
|
sqlite3_free(sCsv.z);
|
||||||
sqlite3_finalize(pStmt);
|
sqlite3_finalize(pStmt);
|
||||||
sqlite3_exec(p->db, "COMMIT", 0, 0, 0);
|
if( needCommit ) sqlite3_exec(db, "COMMIT", 0, 0, 0);
|
||||||
}else
|
}else
|
||||||
|
|
||||||
if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg<3 ){
|
if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg<3 ){
|
||||||
@ -2781,7 +2779,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
|
|||||||
** Return TRUE if a semicolon occurs anywhere in the first N characters
|
** Return TRUE if a semicolon occurs anywhere in the first N characters
|
||||||
** of string z[].
|
** of string z[].
|
||||||
*/
|
*/
|
||||||
static int _contains_semicolon(const char *z, int N){
|
static int line_contains_semicolon(const char *z, int N){
|
||||||
int i;
|
int i;
|
||||||
for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
|
for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
|
||||||
return 0;
|
return 0;
|
||||||
@ -2816,7 +2814,7 @@ static int _all_whitespace(const char *z){
|
|||||||
** than a semi-colon. The SQL Server style "go" command is understood
|
** than a semi-colon. The SQL Server style "go" command is understood
|
||||||
** as is the Oracle "/".
|
** as is the Oracle "/".
|
||||||
*/
|
*/
|
||||||
static int _is_command_terminator(const char *zLine){
|
static int line_is_command_terminator(const char *zLine){
|
||||||
while( IsSpace(zLine[0]) ){ zLine++; };
|
while( IsSpace(zLine[0]) ){ zLine++; };
|
||||||
if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
|
if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
|
||||||
return 1; /* Oracle */
|
return 1; /* Oracle */
|
||||||
@ -2832,7 +2830,7 @@ static int _is_command_terminator(const char *zLine){
|
|||||||
** Return true if zSql is a complete SQL statement. Return false if it
|
** Return true if zSql is a complete SQL statement. Return false if it
|
||||||
** ends in the middle of a string literal or C-style comment.
|
** ends in the middle of a string literal or C-style comment.
|
||||||
*/
|
*/
|
||||||
static int _is_complete(char *zSql, int nSql){
|
static int line_is_complete(char *zSql, int nSql){
|
||||||
int rc;
|
int rc;
|
||||||
if( zSql==0 ) return 1;
|
if( zSql==0 ) return 1;
|
||||||
zSql[nSql] = ';';
|
zSql[nSql] = ';';
|
||||||
@ -2852,20 +2850,21 @@ static int _is_complete(char *zSql, int nSql){
|
|||||||
** Return the number of errors.
|
** Return the number of errors.
|
||||||
*/
|
*/
|
||||||
static int process_input(struct callback_data *p, FILE *in){
|
static int process_input(struct callback_data *p, FILE *in){
|
||||||
char *zLine = 0;
|
char *zLine = 0; /* A single input line */
|
||||||
char *zSql = 0;
|
char *zSql = 0; /* Accumulated SQL text */
|
||||||
int nSql = 0;
|
int nLine; /* Length of current line */
|
||||||
int nSqlPrior = 0;
|
int nSql = 0; /* Bytes of zSql[] used */
|
||||||
char *zErrMsg;
|
int nAlloc = 0; /* Allocated zSql[] space */
|
||||||
int rc;
|
int nSqlPrior = 0; /* Bytes of zSql[] used by prior line */
|
||||||
int errCnt = 0;
|
char *zErrMsg; /* Error message returned */
|
||||||
int lineno = 0;
|
int rc; /* Error code */
|
||||||
int startline = 0;
|
int errCnt = 0; /* Number of errors seen */
|
||||||
|
int lineno = 0; /* Current line number */
|
||||||
|
int startline = 0; /* Line number for start of current input */
|
||||||
|
|
||||||
while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
|
while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
|
||||||
fflush(p->out);
|
fflush(p->out);
|
||||||
free(zLine);
|
zLine = one_input_line(in, zLine, nSql>0);
|
||||||
zLine = one_input_line(zSql, in);
|
|
||||||
if( zLine==0 ){
|
if( zLine==0 ){
|
||||||
/* End of input */
|
/* End of input */
|
||||||
if( stdin_is_interactive ) printf("\n");
|
if( stdin_is_interactive ) printf("\n");
|
||||||
@ -2876,7 +2875,7 @@ static int process_input(struct callback_data *p, FILE *in){
|
|||||||
seenInterrupt = 0;
|
seenInterrupt = 0;
|
||||||
}
|
}
|
||||||
lineno++;
|
lineno++;
|
||||||
if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
|
if( nSql==0 && _all_whitespace(zLine) ) continue;
|
||||||
if( zLine && zLine[0]=='.' && nSql==0 ){
|
if( zLine && zLine[0]=='.' && nSql==0 ){
|
||||||
if( p->echoOn ) printf("%s\n", zLine);
|
if( p->echoOn ) printf("%s\n", zLine);
|
||||||
rc = do_meta_command(zLine, p);
|
rc = do_meta_command(zLine, p);
|
||||||
@ -2887,35 +2886,31 @@ static int process_input(struct callback_data *p, FILE *in){
|
|||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if( _is_command_terminator(zLine) && _is_complete(zSql, nSql) ){
|
if( line_is_command_terminator(zLine) && line_is_complete(zSql, nSql) ){
|
||||||
memcpy(zLine,";",2);
|
memcpy(zLine,";",2);
|
||||||
}
|
}
|
||||||
nSqlPrior = nSql;
|
nLine = strlen30(zLine);
|
||||||
if( zSql==0 ){
|
if( nSql+nLine+2>=nAlloc ){
|
||||||
int i;
|
nAlloc = nSql+nLine+100;
|
||||||
for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
|
zSql = realloc(zSql, nAlloc);
|
||||||
if( zLine[i]!=0 ){
|
|
||||||
nSql = strlen30(zLine);
|
|
||||||
zSql = malloc( nSql+3 );
|
|
||||||
if( zSql==0 ){
|
|
||||||
fprintf(stderr, "Error: out of memory\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
memcpy(zSql, zLine, nSql+1);
|
|
||||||
startline = lineno;
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
int len = strlen30(zLine);
|
|
||||||
zSql = realloc( zSql, nSql + len + 4 );
|
|
||||||
if( zSql==0 ){
|
if( zSql==0 ){
|
||||||
fprintf(stderr,"Error: out of memory\n");
|
fprintf(stderr, "Error: out of memory\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
zSql[nSql++] = '\n';
|
|
||||||
memcpy(&zSql[nSql], zLine, len+1);
|
|
||||||
nSql += len;
|
|
||||||
}
|
}
|
||||||
if( zSql && _contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
|
nSqlPrior = nSql;
|
||||||
|
if( nSql==0 ){
|
||||||
|
int i;
|
||||||
|
for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
|
||||||
|
memcpy(zSql, zLine+i, nLine+1-i);
|
||||||
|
startline = lineno;
|
||||||
|
nSql = nLine-i;
|
||||||
|
}else{
|
||||||
|
zSql[nSql++] = '\n';
|
||||||
|
memcpy(zSql+nSql, zLine, nLine+1);
|
||||||
|
nSql += nLine;
|
||||||
|
}
|
||||||
|
if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
|
||||||
&& sqlite3_complete(zSql) ){
|
&& sqlite3_complete(zSql) ){
|
||||||
p->cnt = 0;
|
p->cnt = 0;
|
||||||
open_db(p);
|
open_db(p);
|
||||||
@ -2939,16 +2934,12 @@ static int process_input(struct callback_data *p, FILE *in){
|
|||||||
}
|
}
|
||||||
errCnt++;
|
errCnt++;
|
||||||
}
|
}
|
||||||
free(zSql);
|
|
||||||
zSql = 0;
|
|
||||||
nSql = 0;
|
nSql = 0;
|
||||||
}else if( zSql && _all_whitespace(zSql) ){
|
}else if( nSql && _all_whitespace(zSql) ){
|
||||||
free(zSql);
|
|
||||||
zSql = 0;
|
|
||||||
nSql = 0;
|
nSql = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( zSql ){
|
if( nSql ){
|
||||||
if( !_all_whitespace(zSql) ){
|
if( !_all_whitespace(zSql) ){
|
||||||
fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
|
fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
|
||||||
}
|
}
|
||||||
|
@ -1472,12 +1472,16 @@ struct FKey {
|
|||||||
** An instance of the following structure is passed as the first
|
** An instance of the following structure is passed as the first
|
||||||
** argument to sqlite3VdbeKeyCompare and is used to control the
|
** argument to sqlite3VdbeKeyCompare and is used to control the
|
||||||
** comparison of the two index keys.
|
** comparison of the two index keys.
|
||||||
|
**
|
||||||
|
** Note that aSortOrder[] and aColl[] have nField+1 slots. There
|
||||||
|
** are nField slots for the columns of an index then one extra slot
|
||||||
|
** for the rowid at the end.
|
||||||
*/
|
*/
|
||||||
struct KeyInfo {
|
struct KeyInfo {
|
||||||
sqlite3 *db; /* The database connection */
|
sqlite3 *db; /* The database connection */
|
||||||
u8 enc; /* Text encoding - one of the SQLITE_UTF* values */
|
u8 enc; /* Text encoding - one of the SQLITE_UTF* values */
|
||||||
u16 nField; /* Number of entries in aColl[] */
|
u16 nField; /* Maximum index for aColl[] and aSortOrder[] */
|
||||||
u8 *aSortOrder; /* Sort order for each column. May be NULL */
|
u8 *aSortOrder; /* Sort order for each column. */
|
||||||
CollSeq *aColl[1]; /* Collating sequence for each term of the key */
|
CollSeq *aColl[1]; /* Collating sequence for each term of the key */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2082,6 +2086,7 @@ struct Select {
|
|||||||
#define SF_Values 0x0080 /* Synthesized from VALUES clause */
|
#define SF_Values 0x0080 /* Synthesized from VALUES clause */
|
||||||
#define SF_Materialize 0x0100 /* Force materialization of views */
|
#define SF_Materialize 0x0100 /* Force materialization of views */
|
||||||
#define SF_NestedFrom 0x0200 /* Part of a parenthesized FROM clause */
|
#define SF_NestedFrom 0x0200 /* Part of a parenthesized FROM clause */
|
||||||
|
#define SF_MaybeConvert 0x0400 /* Need convertCompoundSelectToSubquery() */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2203,6 +2208,7 @@ struct Parse {
|
|||||||
u8 iColCache; /* Next entry in aColCache[] to replace */
|
u8 iColCache; /* Next entry in aColCache[] to replace */
|
||||||
u8 isMultiWrite; /* True if statement may modify/insert multiple rows */
|
u8 isMultiWrite; /* True if statement may modify/insert multiple rows */
|
||||||
u8 mayAbort; /* True if statement may throw an ABORT exception */
|
u8 mayAbort; /* True if statement may throw an ABORT exception */
|
||||||
|
u8 hasCompound; /* Need to invoke convertCompoundSelectToSubquery() */
|
||||||
int aTempReg[8]; /* Holding area for temporary registers */
|
int aTempReg[8]; /* Holding area for temporary registers */
|
||||||
int nRangeReg; /* Size of the temporary register block */
|
int nRangeReg; /* Size of the temporary register block */
|
||||||
int iRangeReg; /* First register in temporary register block */
|
int iRangeReg; /* First register in temporary register block */
|
||||||
@ -3098,6 +3104,7 @@ void sqlite3MinimumFileFormat(Parse*, int, int);
|
|||||||
void sqlite3SchemaClear(void *);
|
void sqlite3SchemaClear(void *);
|
||||||
Schema *sqlite3SchemaGet(sqlite3 *, Btree *);
|
Schema *sqlite3SchemaGet(sqlite3 *, Btree *);
|
||||||
int sqlite3SchemaToIndex(sqlite3 *db, Schema *);
|
int sqlite3SchemaToIndex(sqlite3 *db, Schema *);
|
||||||
|
KeyInfo *sqlite3KeyInfoAlloc(sqlite3*,int);
|
||||||
KeyInfo *sqlite3IndexKeyinfo(Parse *, Index *);
|
KeyInfo *sqlite3IndexKeyinfo(Parse *, Index *);
|
||||||
int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *,
|
int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *,
|
||||||
void (*)(sqlite3_context*,int,sqlite3_value **),
|
void (*)(sqlite3_context*,int,sqlite3_value **),
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sqlite3.h>
|
#include <sqlite3.h>
|
||||||
|
#include <tcl.h>
|
||||||
|
|
||||||
/* Solely for the UNUSED_PARAMETER() macro. */
|
/* Solely for the UNUSED_PARAMETER() macro. */
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
@ -123,7 +123,6 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){
|
|||||||
}
|
}
|
||||||
case '-': {
|
case '-': {
|
||||||
if( z[1]=='-' ){
|
if( z[1]=='-' ){
|
||||||
/* IMP: R-50417-27976 -- syntax diagram for comments */
|
|
||||||
for(i=2; (c=z[i])!=0 && c!='\n'; i++){}
|
for(i=2; (c=z[i])!=0 && c!='\n'; i++){}
|
||||||
*tokenType = TK_SPACE; /* IMP: R-22934-25134 */
|
*tokenType = TK_SPACE; /* IMP: R-22934-25134 */
|
||||||
return i;
|
return i;
|
||||||
@ -156,7 +155,6 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){
|
|||||||
*tokenType = TK_SLASH;
|
*tokenType = TK_SLASH;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/* IMP: R-50417-27976 -- syntax diagram for comments */
|
|
||||||
for(i=3, c=z[2]; (c!='*' || z[i]!='/') && (c=z[i])!=0; i++){}
|
for(i=3, c=z[2]; (c!='*' || z[i]!='/') && (c=z[i])!=0; i++){}
|
||||||
if( c ) i++;
|
if( c ) i++;
|
||||||
*tokenType = TK_SPACE; /* IMP: R-22934-25134 */
|
*tokenType = TK_SPACE; /* IMP: R-22934-25134 */
|
||||||
|
@ -565,7 +565,7 @@ int sqlite3VdbeExec(
|
|||||||
int iCompare = 0; /* Result of last OP_Compare operation */
|
int iCompare = 0; /* Result of last OP_Compare operation */
|
||||||
unsigned nVmStep = 0; /* Number of virtual machine steps */
|
unsigned nVmStep = 0; /* Number of virtual machine steps */
|
||||||
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
|
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
|
||||||
unsigned nProgressLimit; /* Invoke xProgress() when nVmStep reaches this */
|
unsigned nProgressLimit = 0;/* Invoke xProgress() when nVmStep reaches this */
|
||||||
#endif
|
#endif
|
||||||
Mem *aMem = p->aMem; /* Copy of p->aMem */
|
Mem *aMem = p->aMem; /* Copy of p->aMem */
|
||||||
Mem *pIn1 = 0; /* 1st input operand */
|
Mem *pIn1 = 0; /* 1st input operand */
|
||||||
|
116
src/vdbeaux.c
116
src/vdbeaux.c
@ -408,40 +408,60 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
|
|||||||
for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){
|
for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){
|
||||||
u8 opcode = pOp->opcode;
|
u8 opcode = pOp->opcode;
|
||||||
|
|
||||||
pOp->opflags = sqlite3OpcodeProperty[opcode];
|
/* NOTE: Be sure to update mkopcodeh.awk when adding or removing
|
||||||
if( opcode==OP_Function || opcode==OP_AggStep ){
|
** cases from this switch! */
|
||||||
if( pOp->p5>nMaxArgs ) nMaxArgs = pOp->p5;
|
switch( opcode ){
|
||||||
}else if( opcode==OP_Transaction ){
|
case OP_Function:
|
||||||
if( pOp->p2!=0 ) p->readOnly = 0;
|
case OP_AggStep: {
|
||||||
p->bIsReader = 1;
|
if( pOp->p5>nMaxArgs ) nMaxArgs = pOp->p5;
|
||||||
}else if( opcode==OP_AutoCommit || opcode==OP_Savepoint ){
|
break;
|
||||||
p->bIsReader = 1;
|
}
|
||||||
}else if( opcode==OP_Vacuum
|
case OP_Transaction: {
|
||||||
|| opcode==OP_JournalMode
|
if( pOp->p2!=0 ) p->readOnly = 0;
|
||||||
|
/* fall thru */
|
||||||
|
}
|
||||||
|
case OP_AutoCommit:
|
||||||
|
case OP_Savepoint: {
|
||||||
|
p->bIsReader = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
#ifndef SQLITE_OMIT_WAL
|
#ifndef SQLITE_OMIT_WAL
|
||||||
|| opcode==OP_Checkpoint
|
case OP_Checkpoint:
|
||||||
#endif
|
#endif
|
||||||
){
|
case OP_Vacuum:
|
||||||
p->readOnly = 0;
|
case OP_JournalMode: {
|
||||||
p->bIsReader = 1;
|
p->readOnly = 0;
|
||||||
|
p->bIsReader = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||||
}else if( opcode==OP_VUpdate ){
|
case OP_VUpdate: {
|
||||||
if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
|
if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
|
||||||
}else if( opcode==OP_VFilter ){
|
break;
|
||||||
int n;
|
}
|
||||||
assert( p->nOp - i >= 3 );
|
case OP_VFilter: {
|
||||||
assert( pOp[-1].opcode==OP_Integer );
|
int n;
|
||||||
n = pOp[-1].p1;
|
assert( p->nOp - i >= 3 );
|
||||||
if( n>nMaxArgs ) nMaxArgs = n;
|
assert( pOp[-1].opcode==OP_Integer );
|
||||||
|
n = pOp[-1].p1;
|
||||||
|
if( n>nMaxArgs ) nMaxArgs = n;
|
||||||
|
break;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}else if( opcode==OP_Next || opcode==OP_SorterNext ){
|
case OP_Next:
|
||||||
pOp->p4.xAdvance = sqlite3BtreeNext;
|
case OP_SorterNext: {
|
||||||
pOp->p4type = P4_ADVANCE;
|
pOp->p4.xAdvance = sqlite3BtreeNext;
|
||||||
}else if( opcode==OP_Prev ){
|
pOp->p4type = P4_ADVANCE;
|
||||||
pOp->p4.xAdvance = sqlite3BtreePrevious;
|
break;
|
||||||
pOp->p4type = P4_ADVANCE;
|
}
|
||||||
|
case OP_Prev: {
|
||||||
|
pOp->p4.xAdvance = sqlite3BtreePrevious;
|
||||||
|
pOp->p4type = P4_ADVANCE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pOp->opflags = sqlite3OpcodeProperty[opcode];
|
||||||
if( (pOp->opflags & OPFLG_JUMP)!=0 && pOp->p2<0 ){
|
if( (pOp->opflags & OPFLG_JUMP)!=0 && pOp->p2<0 ){
|
||||||
assert( -1-pOp->p2<p->nLabel );
|
assert( -1-pOp->p2<p->nLabel );
|
||||||
pOp->p2 = aLabel[-1-pOp->p2];
|
pOp->p2 = aLabel[-1-pOp->p2];
|
||||||
@ -730,20 +750,13 @@ void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int n){
|
|||||||
pOp->p4.p = 0;
|
pOp->p4.p = 0;
|
||||||
pOp->p4type = P4_NOTUSED;
|
pOp->p4type = P4_NOTUSED;
|
||||||
}else if( n==P4_KEYINFO ){
|
}else if( n==P4_KEYINFO ){
|
||||||
KeyInfo *pKeyInfo;
|
KeyInfo *pOrig, *pNew;
|
||||||
int nField, nByte;
|
|
||||||
|
|
||||||
nField = ((KeyInfo*)zP4)->nField;
|
pOrig = (KeyInfo*)zP4;
|
||||||
nByte = sizeof(*pKeyInfo) + (nField-1)*sizeof(pKeyInfo->aColl[0]) + nField;
|
pOp->p4.pKeyInfo = pNew = sqlite3KeyInfoAlloc(db, pOrig->nField);
|
||||||
pKeyInfo = sqlite3DbMallocRaw(0, nByte);
|
if( pNew ){
|
||||||
pOp->p4.pKeyInfo = pKeyInfo;
|
memcpy(pNew->aColl, pOrig->aColl, pOrig->nField*sizeof(pNew->aColl[0]));
|
||||||
if( pKeyInfo ){
|
memcpy(pNew->aSortOrder, pOrig->aSortOrder, pOrig->nField);
|
||||||
u8 *aSortOrder;
|
|
||||||
memcpy((char*)pKeyInfo, zP4, nByte - nField);
|
|
||||||
aSortOrder = pKeyInfo->aSortOrder;
|
|
||||||
assert( aSortOrder!=0 );
|
|
||||||
pKeyInfo->aSortOrder = (unsigned char*)&pKeyInfo->aColl[nField];
|
|
||||||
memcpy(pKeyInfo->aSortOrder, aSortOrder, nField);
|
|
||||||
pOp->p4type = P4_KEYINFO;
|
pOp->p4type = P4_KEYINFO;
|
||||||
}else{
|
}else{
|
||||||
p->db->mallocFailed = 1;
|
p->db->mallocFailed = 1;
|
||||||
@ -2995,7 +3008,6 @@ int sqlite3VdbeRecordCompare(
|
|||||||
u32 idx1; /* Offset into aKey[] of next header element */
|
u32 idx1; /* Offset into aKey[] of next header element */
|
||||||
u32 szHdr1; /* Number of bytes in header */
|
u32 szHdr1; /* Number of bytes in header */
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int nField;
|
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
const unsigned char *aKey1 = (const unsigned char *)pKey1;
|
const unsigned char *aKey1 = (const unsigned char *)pKey1;
|
||||||
KeyInfo *pKeyInfo;
|
KeyInfo *pKeyInfo;
|
||||||
@ -3018,14 +3030,25 @@ int sqlite3VdbeRecordCompare(
|
|||||||
|
|
||||||
idx1 = getVarint32(aKey1, szHdr1);
|
idx1 = getVarint32(aKey1, szHdr1);
|
||||||
d1 = szHdr1;
|
d1 = szHdr1;
|
||||||
nField = pKeyInfo->nField;
|
assert( pKeyInfo->nField+1>=pPKey2->nField );
|
||||||
assert( pKeyInfo->aSortOrder!=0 );
|
assert( pKeyInfo->aSortOrder!=0 );
|
||||||
while( idx1<szHdr1 && i<pPKey2->nField ){
|
while( idx1<szHdr1 && i<pPKey2->nField ){
|
||||||
u32 serial_type1;
|
u32 serial_type1;
|
||||||
|
|
||||||
/* Read the serial types for the next element in each key. */
|
/* Read the serial types for the next element in each key. */
|
||||||
idx1 += getVarint32( aKey1+idx1, serial_type1 );
|
idx1 += getVarint32( aKey1+idx1, serial_type1 );
|
||||||
if( d1+sqlite3VdbeSerialTypeLen(serial_type1)>(u32)nKey1 ) break;
|
|
||||||
|
/* Verify that there is enough key space remaining to avoid
|
||||||
|
** a buffer overread. The "d1+serial_type1+2" subexpression will
|
||||||
|
** always be greater than or equal to the amount of required key space.
|
||||||
|
** Use that approximation to avoid the more expensive call to
|
||||||
|
** sqlite3VdbeSerialTypeLen() in the common case.
|
||||||
|
*/
|
||||||
|
if( d1+serial_type1+2>(u32)nKey1
|
||||||
|
&& d1+sqlite3VdbeSerialTypeLen(serial_type1)>(u32)nKey1
|
||||||
|
){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* Extract the values to be compared.
|
/* Extract the values to be compared.
|
||||||
*/
|
*/
|
||||||
@ -3033,13 +3056,12 @@ int sqlite3VdbeRecordCompare(
|
|||||||
|
|
||||||
/* Do the comparison
|
/* Do the comparison
|
||||||
*/
|
*/
|
||||||
rc = sqlite3MemCompare(&mem1, &pPKey2->aMem[i],
|
rc = sqlite3MemCompare(&mem1, &pPKey2->aMem[i], pKeyInfo->aColl[i]);
|
||||||
i<nField ? pKeyInfo->aColl[i] : 0);
|
|
||||||
if( rc!=0 ){
|
if( rc!=0 ){
|
||||||
assert( mem1.zMalloc==0 ); /* See comment below */
|
assert( mem1.zMalloc==0 ); /* See comment below */
|
||||||
|
|
||||||
/* Invert the result if we are using DESC sort order. */
|
/* Invert the result if we are using DESC sort order. */
|
||||||
if( i<nField && pKeyInfo->aSortOrder[i] ){
|
if( pKeyInfo->aSortOrder[i] ){
|
||||||
rc = -rc;
|
rc = -rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
40
src/where.c
40
src/where.c
@ -658,7 +658,7 @@ static void whereClauseClear(WhereClause *pWC){
|
|||||||
static int whereClauseInsert(WhereClause *pWC, Expr *p, u8 wtFlags){
|
static int whereClauseInsert(WhereClause *pWC, Expr *p, u8 wtFlags){
|
||||||
WhereTerm *pTerm;
|
WhereTerm *pTerm;
|
||||||
int idx;
|
int idx;
|
||||||
testcase( wtFlags & TERM_VIRTUAL ); /* EV: R-00211-15100 */
|
testcase( wtFlags & TERM_VIRTUAL );
|
||||||
if( pWC->nTerm>=pWC->nSlot ){
|
if( pWC->nTerm>=pWC->nSlot ){
|
||||||
WhereTerm *pOld = pWC->a;
|
WhereTerm *pOld = pWC->a;
|
||||||
sqlite3 *db = pWC->pWInfo->pParse->db;
|
sqlite3 *db = pWC->pWInfo->pParse->db;
|
||||||
@ -803,13 +803,6 @@ static Bitmask exprSelectTableUsage(WhereMaskSet *pMaskSet, Select *pS){
|
|||||||
** Return TRUE if the given operator is one of the operators that is
|
** Return TRUE if the given operator is one of the operators that is
|
||||||
** allowed for an indexable WHERE clause term. The allowed operators are
|
** allowed for an indexable WHERE clause term. The allowed operators are
|
||||||
** "=", "<", ">", "<=", ">=", "IN", and "IS NULL"
|
** "=", "<", ">", "<=", ">=", "IN", and "IS NULL"
|
||||||
**
|
|
||||||
** IMPLEMENTATION-OF: R-59926-26393 To be usable by an index a term must be
|
|
||||||
** of one of the following forms: column = expression column > expression
|
|
||||||
** column >= expression column < expression column <= expression
|
|
||||||
** expression = column expression > column expression >= column
|
|
||||||
** expression < column expression <= column column IN
|
|
||||||
** (expression-list) column IN (subquery) column IS NULL
|
|
||||||
*/
|
*/
|
||||||
static int allowedOp(int op){
|
static int allowedOp(int op){
|
||||||
assert( TK_GT>TK_EQ && TK_GT<TK_GE );
|
assert( TK_GT>TK_EQ && TK_GT<TK_GE );
|
||||||
@ -1483,8 +1476,6 @@ static void exprAnalyzeOrTerm(
|
|||||||
/* At this point, okToChngToIN is true if original pTerm satisfies
|
/* At this point, okToChngToIN is true if original pTerm satisfies
|
||||||
** case 1. In that case, construct a new virtual term that is
|
** case 1. In that case, construct a new virtual term that is
|
||||||
** pTerm converted into an IN operator.
|
** pTerm converted into an IN operator.
|
||||||
**
|
|
||||||
** EV: R-00211-15100
|
|
||||||
*/
|
*/
|
||||||
if( okToChngToIN ){
|
if( okToChngToIN ){
|
||||||
Expr *pDup; /* A transient duplicate expression */
|
Expr *pDup; /* A transient duplicate expression */
|
||||||
@ -1726,9 +1717,7 @@ static void exprAnalyze(
|
|||||||
** inequality. To avoid this, make sure to also run the full
|
** inequality. To avoid this, make sure to also run the full
|
||||||
** LIKE on all candidate expressions by clearing the isComplete flag
|
** LIKE on all candidate expressions by clearing the isComplete flag
|
||||||
*/
|
*/
|
||||||
if( c=='A'-1 ) isComplete = 0; /* EV: R-64339-08207 */
|
if( c=='A'-1 ) isComplete = 0;
|
||||||
|
|
||||||
|
|
||||||
c = sqlite3UpperToLower[c];
|
c = sqlite3UpperToLower[c];
|
||||||
}
|
}
|
||||||
*pC = c + 1;
|
*pC = c + 1;
|
||||||
@ -2818,9 +2807,6 @@ static int whereInScanEst(
|
|||||||
** in the ON clause. The term is disabled in (3) because it is not part
|
** in the ON clause. The term is disabled in (3) because it is not part
|
||||||
** of a LEFT OUTER JOIN. In (1), the term is not disabled.
|
** of a LEFT OUTER JOIN. In (1), the term is not disabled.
|
||||||
**
|
**
|
||||||
** IMPLEMENTATION-OF: R-24597-58655 No tests are done for terms that are
|
|
||||||
** completely satisfied by indices.
|
|
||||||
**
|
|
||||||
** Disabling a term causes that term to not be tested in the inner loop
|
** Disabling a term causes that term to not be tested in the inner loop
|
||||||
** of the join. Disabling is an optimization. When terms are satisfied
|
** of the join. Disabling is an optimization. When terms are satisfied
|
||||||
** by indices, we disable them to prevent redundant tests in the inner
|
** by indices, we disable them to prevent redundant tests in the inner
|
||||||
@ -3050,7 +3036,7 @@ static int codeAllEqualityTerms(
|
|||||||
/* The following true for indices with redundant columns.
|
/* The following true for indices with redundant columns.
|
||||||
** Ex: CREATE INDEX i1 ON t1(a,b,a); SELECT * FROM t1 WHERE a=0 AND b=0; */
|
** Ex: CREATE INDEX i1 ON t1(a,b,a); SELECT * FROM t1 WHERE a=0 AND b=0; */
|
||||||
testcase( (pTerm->wtFlags & TERM_CODED)!=0 );
|
testcase( (pTerm->wtFlags & TERM_CODED)!=0 );
|
||||||
testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
|
testcase( pTerm->wtFlags & TERM_VIRTUAL );
|
||||||
r1 = codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, regBase+j);
|
r1 = codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, regBase+j);
|
||||||
if( r1!=regBase+j ){
|
if( r1!=regBase+j ){
|
||||||
if( nReg==1 ){
|
if( nReg==1 ){
|
||||||
@ -3361,7 +3347,7 @@ static Bitmask codeOneLoopStart(
|
|||||||
assert( pTerm!=0 );
|
assert( pTerm!=0 );
|
||||||
assert( pTerm->pExpr!=0 );
|
assert( pTerm->pExpr!=0 );
|
||||||
assert( omitTable==0 );
|
assert( omitTable==0 );
|
||||||
testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
|
testcase( pTerm->wtFlags & TERM_VIRTUAL );
|
||||||
iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, 0, bRev, iReleaseReg);
|
iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, 0, bRev, iReleaseReg);
|
||||||
addrNxt = pLevel->addrNxt;
|
addrNxt = pLevel->addrNxt;
|
||||||
sqlite3VdbeAddOp2(v, OP_MustBeInt, iRowidReg, addrNxt);
|
sqlite3VdbeAddOp2(v, OP_MustBeInt, iRowidReg, addrNxt);
|
||||||
@ -3409,7 +3395,7 @@ static Bitmask codeOneLoopStart(
|
|||||||
assert( TK_GE==TK_GT+3 ); /* ... is correcct. */
|
assert( TK_GE==TK_GT+3 ); /* ... is correcct. */
|
||||||
|
|
||||||
assert( (pStart->wtFlags & TERM_VNULL)==0 );
|
assert( (pStart->wtFlags & TERM_VNULL)==0 );
|
||||||
testcase( pStart->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
|
testcase( pStart->wtFlags & TERM_VIRTUAL );
|
||||||
pX = pStart->pExpr;
|
pX = pStart->pExpr;
|
||||||
assert( pX!=0 );
|
assert( pX!=0 );
|
||||||
testcase( pStart->leftCursor!=iCur ); /* transitive constraints */
|
testcase( pStart->leftCursor!=iCur ); /* transitive constraints */
|
||||||
@ -3428,7 +3414,7 @@ static Bitmask codeOneLoopStart(
|
|||||||
assert( pX!=0 );
|
assert( pX!=0 );
|
||||||
assert( (pEnd->wtFlags & TERM_VNULL)==0 );
|
assert( (pEnd->wtFlags & TERM_VNULL)==0 );
|
||||||
testcase( pEnd->leftCursor!=iCur ); /* Transitive constraints */
|
testcase( pEnd->leftCursor!=iCur ); /* Transitive constraints */
|
||||||
testcase( pEnd->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
|
testcase( pEnd->wtFlags & TERM_VIRTUAL );
|
||||||
memEndValue = ++pParse->nMem;
|
memEndValue = ++pParse->nMem;
|
||||||
sqlite3ExprCode(pParse, pX->pRight, memEndValue);
|
sqlite3ExprCode(pParse, pX->pRight, memEndValue);
|
||||||
if( pX->op==TK_LT || pX->op==TK_GT ){
|
if( pX->op==TK_LT || pX->op==TK_GT ){
|
||||||
@ -3594,7 +3580,7 @@ static Bitmask codeOneLoopStart(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
nConstraint++;
|
nConstraint++;
|
||||||
testcase( pRangeStart->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
|
testcase( pRangeStart->wtFlags & TERM_VIRTUAL );
|
||||||
}else if( isMinQuery ){
|
}else if( isMinQuery ){
|
||||||
sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
|
sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
|
||||||
nConstraint++;
|
nConstraint++;
|
||||||
@ -3636,7 +3622,7 @@ static Bitmask codeOneLoopStart(
|
|||||||
}
|
}
|
||||||
codeApplyAffinity(pParse, regBase, nEq+1, zEndAff);
|
codeApplyAffinity(pParse, regBase, nEq+1, zEndAff);
|
||||||
nConstraint++;
|
nConstraint++;
|
||||||
testcase( pRangeEnd->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
|
testcase( pRangeEnd->wtFlags & TERM_VIRTUAL );
|
||||||
}
|
}
|
||||||
sqlite3DbFree(db, zStartAff);
|
sqlite3DbFree(db, zStartAff);
|
||||||
sqlite3DbFree(db, zEndAff);
|
sqlite3DbFree(db, zEndAff);
|
||||||
@ -3923,14 +3909,10 @@ static Bitmask codeOneLoopStart(
|
|||||||
|
|
||||||
/* Insert code to test every subexpression that can be completely
|
/* Insert code to test every subexpression that can be completely
|
||||||
** computed using the current set of tables.
|
** computed using the current set of tables.
|
||||||
**
|
|
||||||
** IMPLEMENTATION-OF: R-49525-50935 Terms that cannot be satisfied through
|
|
||||||
** the use of indices become tests that are evaluated against each row of
|
|
||||||
** the relevant input tables.
|
|
||||||
*/
|
*/
|
||||||
for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
|
for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
|
||||||
Expr *pE;
|
Expr *pE;
|
||||||
testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* IMP: R-30575-11662 */
|
testcase( pTerm->wtFlags & TERM_VIRTUAL );
|
||||||
testcase( pTerm->wtFlags & TERM_CODED );
|
testcase( pTerm->wtFlags & TERM_CODED );
|
||||||
if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
|
if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
|
||||||
if( (pTerm->prereqAll & newNotReady)!=0 ){
|
if( (pTerm->prereqAll & newNotReady)!=0 ){
|
||||||
@ -3990,7 +3972,7 @@ static Bitmask codeOneLoopStart(
|
|||||||
VdbeComment((v, "record LEFT JOIN hit"));
|
VdbeComment((v, "record LEFT JOIN hit"));
|
||||||
sqlite3ExprCacheClear(pParse);
|
sqlite3ExprCacheClear(pParse);
|
||||||
for(pTerm=pWC->a, j=0; j<pWC->nTerm; j++, pTerm++){
|
for(pTerm=pWC->a, j=0; j<pWC->nTerm; j++, pTerm++){
|
||||||
testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* IMP: R-30575-11662 */
|
testcase( pTerm->wtFlags & TERM_VIRTUAL );
|
||||||
testcase( pTerm->wtFlags & TERM_CODED );
|
testcase( pTerm->wtFlags & TERM_CODED );
|
||||||
if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
|
if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
|
||||||
if( (pTerm->prereqAll & newNotReady)!=0 ){
|
if( (pTerm->prereqAll & newNotReady)!=0 ){
|
||||||
@ -5763,7 +5745,7 @@ WhereInfo *sqlite3WhereBegin(
|
|||||||
initMaskSet(pMaskSet);
|
initMaskSet(pMaskSet);
|
||||||
whereClauseInit(&pWInfo->sWC, pWInfo);
|
whereClauseInit(&pWInfo->sWC, pWInfo);
|
||||||
sqlite3ExprCodeConstants(pParse, pWhere);
|
sqlite3ExprCodeConstants(pParse, pWhere);
|
||||||
whereSplit(&pWInfo->sWC, pWhere, TK_AND); /* IMP: R-15842-53296 */
|
whereSplit(&pWInfo->sWC, pWhere, TK_AND);
|
||||||
sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */
|
sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */
|
||||||
|
|
||||||
/* Special case: a WHERE clause that is constant. Evaluate the
|
/* Special case: a WHERE clause that is constant. Evaluate the
|
||||||
|
@ -58,8 +58,6 @@ proc table_list {} {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# EVIDENCE-OF: R-47266-09114 -- syntax diagram type-name
|
|
||||||
#
|
|
||||||
do_createtable_tests 0.1.1 -repair {
|
do_createtable_tests 0.1.1 -repair {
|
||||||
drop_all_tables
|
drop_all_tables
|
||||||
} {
|
} {
|
||||||
@ -79,7 +77,7 @@ do_createtable_tests 0.1.2 -error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# EVIDENCE-OF: R-60689-48779 -- syntax diagram column-constraint
|
# syntax diagram column-constraint
|
||||||
#
|
#
|
||||||
do_createtable_tests 0.2.1 -repair {
|
do_createtable_tests 0.2.1 -repair {
|
||||||
drop_all_tables
|
drop_all_tables
|
||||||
@ -126,7 +124,7 @@ do_createtable_tests 0.2.1 -repair {
|
|||||||
} {}
|
} {}
|
||||||
}
|
}
|
||||||
|
|
||||||
# EVIDENCE-OF: R-58169-51804 -- syntax diagram table-constraint
|
# -- syntax diagram table-constraint
|
||||||
#
|
#
|
||||||
do_createtable_tests 0.3.1 -repair {
|
do_createtable_tests 0.3.1 -repair {
|
||||||
drop_all_tables
|
drop_all_tables
|
||||||
@ -145,7 +143,7 @@ do_createtable_tests 0.3.1 -repair {
|
|||||||
4.1 "CREATE TABLE t1(c1, c2, FOREIGN KEY(c1) REFERENCES t2)" {}
|
4.1 "CREATE TABLE t1(c1, c2, FOREIGN KEY(c1) REFERENCES t2)" {}
|
||||||
}
|
}
|
||||||
|
|
||||||
# EVIDENCE-OF: R-44826-22243 -- syntax diagram column-def
|
# -- syntax diagram column-def
|
||||||
#
|
#
|
||||||
do_createtable_tests 0.4.1 -repair {
|
do_createtable_tests 0.4.1 -repair {
|
||||||
drop_all_tables
|
drop_all_tables
|
||||||
@ -160,7 +158,7 @@ do_createtable_tests 0.4.1 -repair {
|
|||||||
} {}
|
} {}
|
||||||
}
|
}
|
||||||
|
|
||||||
# EVIDENCE-OF: R-45698-45677 -- syntax diagram create-table-stmt
|
# -- syntax diagram create-table-stmt
|
||||||
#
|
#
|
||||||
do_createtable_tests 0.5.1 -repair {
|
do_createtable_tests 0.5.1 -repair {
|
||||||
drop_all_tables
|
drop_all_tables
|
||||||
@ -185,7 +183,6 @@ do_createtable_tests 0.5.1 -repair {
|
|||||||
15 "CREATE TABLE t1 AS SELECT count(*), max(b), min(a) FROM t2" {}
|
15 "CREATE TABLE t1 AS SELECT count(*), max(b), min(a) FROM t2" {}
|
||||||
}
|
}
|
||||||
|
|
||||||
# EVIDENCE-OF: R-24369-11919 -- syntax diagram foreign-key-clause
|
|
||||||
#
|
#
|
||||||
# 1: Explicit parent-key columns.
|
# 1: Explicit parent-key columns.
|
||||||
# 2: Implicit child-key columns.
|
# 2: Implicit child-key columns.
|
||||||
|
@ -29,9 +29,8 @@ do_execsql_test e_delete-0.0 {
|
|||||||
CREATE INDEX i1 ON t1(a);
|
CREATE INDEX i1 ON t1(a);
|
||||||
} {}
|
} {}
|
||||||
|
|
||||||
# EVIDENCE-OF: R-62077-19799 -- syntax diagram delete-stmt
|
# -- syntax diagram delete-stmt
|
||||||
#
|
# -- syntax diagram qualified-table-name
|
||||||
# EVIDENCE-OF: R-60796-31013 -- syntax diagram qualified-table-name
|
|
||||||
#
|
#
|
||||||
do_delete_tests e_delete-0.1 {
|
do_delete_tests e_delete-0.1 {
|
||||||
1 "DELETE FROM t1" {}
|
1 "DELETE FROM t1" {}
|
||||||
@ -292,7 +291,7 @@ do_delete_tests e_delete-2.5 -error { near "%s": syntax error } {
|
|||||||
# of the DELETE statement is extended by the addition of optional ORDER
|
# of the DELETE statement is extended by the addition of optional ORDER
|
||||||
# BY and LIMIT clauses:
|
# BY and LIMIT clauses:
|
||||||
#
|
#
|
||||||
# EVIDENCE-OF: R-52694-53361 -- syntax diagram delete-stmt-limited
|
# -- syntax diagram delete-stmt-limited
|
||||||
#
|
#
|
||||||
do_delete_tests e_delete-3.1 {
|
do_delete_tests e_delete-3.1 {
|
||||||
1 "DELETE FROM t1 LIMIT 5" {}
|
1 "DELETE FROM t1 LIMIT 5" {}
|
||||||
|
@ -69,7 +69,7 @@ proc droptrigger_reopen_db {{event INSERT}} {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# EVIDENCE-OF: R-27975-10951 -- syntax diagram drop-trigger-stmt
|
# -- syntax diagram drop-trigger-stmt
|
||||||
#
|
#
|
||||||
do_droptrigger_tests 1.1 -repair {
|
do_droptrigger_tests 1.1 -repair {
|
||||||
droptrigger_reopen_db
|
droptrigger_reopen_db
|
||||||
|
@ -70,7 +70,7 @@ proc do_dropview_tests {nm args} {
|
|||||||
uplevel do_select_tests $nm $args
|
uplevel do_select_tests $nm $args
|
||||||
}
|
}
|
||||||
|
|
||||||
# EVIDENCE-OF: R-53136-36436 -- syntax diagram drop-view-stmt
|
# -- syntax diagram drop-view-stmt
|
||||||
#
|
#
|
||||||
# All paths in the syntax diagram for DROP VIEW are tested by tests 1.*.
|
# All paths in the syntax diagram for DROP VIEW are tested by tests 1.*.
|
||||||
#
|
#
|
||||||
|
@ -366,9 +366,9 @@ db collate reverse reverse_collate
|
|||||||
# EVIDENCE-OF: R-59577-33471 The COLLATE operator is a unary postfix
|
# EVIDENCE-OF: R-59577-33471 The COLLATE operator is a unary postfix
|
||||||
# operator that assigns a collating sequence to an expression.
|
# operator that assigns a collating sequence to an expression.
|
||||||
#
|
#
|
||||||
# EVIDENCE-OF: R-23441-22541 The COLLATE operator has a higher
|
# EVIDENCE-OF: R-36231-30731 The COLLATE operator has a higher
|
||||||
# precedence (binds more tightly) than any prefix unary operator or any
|
# precedence (binds more tightly) than any binary operator and any unary
|
||||||
# binary operator.
|
# prefix operator except "~".
|
||||||
#
|
#
|
||||||
do_execsql_test e_expr-9.1 { SELECT 'abcd' < 'bbbb' COLLATE reverse } 0
|
do_execsql_test e_expr-9.1 { SELECT 'abcd' < 'bbbb' COLLATE reverse } 0
|
||||||
do_execsql_test e_expr-9.2 { SELECT ('abcd' < 'bbbb') COLLATE reverse } 1
|
do_execsql_test e_expr-9.2 { SELECT ('abcd' < 'bbbb') COLLATE reverse } 1
|
||||||
@ -631,7 +631,7 @@ do_test e_expr-11.7.1 { sqlite3_finalize $stmt } SQLITE_OK
|
|||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
# "Test" the syntax diagrams in lang_expr.html.
|
# "Test" the syntax diagrams in lang_expr.html.
|
||||||
#
|
#
|
||||||
# EVIDENCE-OF: R-02989-21050 -- syntax diagram signed-number
|
# -- syntax diagram signed-number
|
||||||
#
|
#
|
||||||
do_execsql_test e_expr-12.1.1 { SELECT 0, +0, -0 } {0 0 0}
|
do_execsql_test e_expr-12.1.1 { SELECT 0, +0, -0 } {0 0 0}
|
||||||
do_execsql_test e_expr-12.1.2 { SELECT 1, +1, -1 } {1 1 -1}
|
do_execsql_test e_expr-12.1.2 { SELECT 1, +1, -1 } {1 1 -1}
|
||||||
@ -646,7 +646,7 @@ do_execsql_test e_expr-12.1.6 {
|
|||||||
SELECT 0.0001, +0.0001, -0.0001
|
SELECT 0.0001, +0.0001, -0.0001
|
||||||
} {0.0001 0.0001 -0.0001}
|
} {0.0001 0.0001 -0.0001}
|
||||||
|
|
||||||
# EVIDENCE-OF: R-43188-60852 -- syntax diagram literal-value
|
# -- syntax diagram literal-value
|
||||||
#
|
#
|
||||||
set sqlite_current_time 1
|
set sqlite_current_time 1
|
||||||
do_execsql_test e_expr-12.2.1 {SELECT 123} {123}
|
do_execsql_test e_expr-12.2.1 {SELECT 123} {123}
|
||||||
@ -659,7 +659,7 @@ do_execsql_test e_expr-12.2.7 {SELECT CURRENT_DATE} {1970-01-01}
|
|||||||
do_execsql_test e_expr-12.2.8 {SELECT CURRENT_TIMESTAMP} {{1970-01-01 00:00:01}}
|
do_execsql_test e_expr-12.2.8 {SELECT CURRENT_TIMESTAMP} {{1970-01-01 00:00:01}}
|
||||||
set sqlite_current_time 0
|
set sqlite_current_time 0
|
||||||
|
|
||||||
# EVIDENCE-OF: R-50544-32159 -- syntax diagram expr
|
# -- syntax diagram expr
|
||||||
#
|
#
|
||||||
forcedelete test.db2
|
forcedelete test.db2
|
||||||
execsql {
|
execsql {
|
||||||
@ -816,7 +816,7 @@ foreach {tn expr} {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# EVIDENCE-OF: R-39820-63916 -- syntax diagram raise-function
|
# -- syntax diagram raise-function
|
||||||
#
|
#
|
||||||
foreach {tn raiseexpr} {
|
foreach {tn raiseexpr} {
|
||||||
1 "RAISE(IGNORE)"
|
1 "RAISE(IGNORE)"
|
||||||
|
@ -50,7 +50,7 @@ proc do_insert_tests {args} {
|
|||||||
uplevel do_select_tests $args
|
uplevel do_select_tests $args
|
||||||
}
|
}
|
||||||
|
|
||||||
# EVIDENCE-OF: R-21350-31508 -- syntax diagram insert-stmt
|
# -- syntax diagram insert-stmt
|
||||||
#
|
#
|
||||||
do_insert_tests e_insert-0 {
|
do_insert_tests e_insert-0 {
|
||||||
1 "INSERT INTO a1 DEFAULT VALUES" {}
|
1 "INSERT INTO a1 DEFAULT VALUES" {}
|
||||||
|
@ -26,7 +26,7 @@ do_execsql_test e_reindex-0.0 {
|
|||||||
CREATE INDEX i2 ON t1(b, a);
|
CREATE INDEX i2 ON t1(b, a);
|
||||||
} {}
|
} {}
|
||||||
|
|
||||||
# EVIDENCE-OF: R-51477-38549 -- syntax diagram reindex-stmt
|
# -- syntax diagram reindex-stmt
|
||||||
#
|
#
|
||||||
do_reindex_tests e_reindex-0.1 {
|
do_reindex_tests e_reindex-0.1 {
|
||||||
1 "REINDEX" {}
|
1 "REINDEX" {}
|
||||||
|
@ -83,7 +83,7 @@ proc do_join_test {tn select res} {
|
|||||||
# The following tests check that all paths on the syntax diagrams on
|
# The following tests check that all paths on the syntax diagrams on
|
||||||
# the lang_select.html page may be taken.
|
# the lang_select.html page may be taken.
|
||||||
#
|
#
|
||||||
# EVIDENCE-OF: R-11353-33501 -- syntax diagram join-constraint
|
# -- syntax diagram join-constraint
|
||||||
#
|
#
|
||||||
do_join_test e_select-0.1.1 {
|
do_join_test e_select-0.1.1 {
|
||||||
SELECT count(*) FROM t1 %JOIN% t2 ON (t1.a=t2.a)
|
SELECT count(*) FROM t1 %JOIN% t2 ON (t1.a=t2.a)
|
||||||
@ -101,7 +101,7 @@ do_catchsql_test e_select-0.1.5 {
|
|||||||
SELECT count(*) FROM t1, t2 USING (a) ON (t1.a=t2.a)
|
SELECT count(*) FROM t1, t2 USING (a) ON (t1.a=t2.a)
|
||||||
} {1 {near "ON": syntax error}}
|
} {1 {near "ON": syntax error}}
|
||||||
|
|
||||||
# EVIDENCE-OF: R-40919-40941 -- syntax diagram select-core
|
# -- syntax diagram select-core
|
||||||
#
|
#
|
||||||
# 0: SELECT ...
|
# 0: SELECT ...
|
||||||
# 1: SELECT DISTINCT ...
|
# 1: SELECT DISTINCT ...
|
||||||
@ -226,7 +226,7 @@ do_select_tests e_select-0.2 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# EVIDENCE-OF: R-41378-26734 -- syntax diagram result-column
|
# -- syntax diagram result-column
|
||||||
#
|
#
|
||||||
do_select_tests e_select-0.3 {
|
do_select_tests e_select-0.3 {
|
||||||
1 "SELECT * FROM t1" {a one b two c three}
|
1 "SELECT * FROM t1" {a one b two c three}
|
||||||
@ -236,9 +236,9 @@ do_select_tests e_select-0.3 {
|
|||||||
5 "SELECT 'x'||a||'x' AS alias FROM t1" {xax xbx xcx}
|
5 "SELECT 'x'||a||'x' AS alias FROM t1" {xax xbx xcx}
|
||||||
}
|
}
|
||||||
|
|
||||||
# EVIDENCE-OF: R-43129-35648 -- syntax diagram join-source
|
# -- syntax diagram join-source
|
||||||
#
|
#
|
||||||
# EVIDENCE-OF: R-36683-37460 -- syntax diagram join-op
|
# -- syntax diagram join-op
|
||||||
#
|
#
|
||||||
do_select_tests e_select-0.4 {
|
do_select_tests e_select-0.4 {
|
||||||
1 "SELECT t1.rowid FROM t1" {1 2 3}
|
1 "SELECT t1.rowid FROM t1" {1 2 3}
|
||||||
@ -263,7 +263,7 @@ do_select_tests e_select-0.4 {
|
|||||||
16 "SELECT t1.rowid FROM t1 CROSS JOIN t3" {1 1 2 2 3 3}
|
16 "SELECT t1.rowid FROM t1 CROSS JOIN t3" {1 1 2 2 3 3}
|
||||||
}
|
}
|
||||||
|
|
||||||
# EVIDENCE-OF: R-28308-37813 -- syntax diagram compound-operator
|
# -- syntax diagram compound-operator
|
||||||
#
|
#
|
||||||
do_select_tests e_select-0.5 {
|
do_select_tests e_select-0.5 {
|
||||||
1 "SELECT rowid FROM t1 UNION ALL SELECT rowid+2 FROM t4" {1 2 3 3 4}
|
1 "SELECT rowid FROM t1 UNION ALL SELECT rowid+2 FROM t4" {1 2 3 3 4}
|
||||||
@ -272,7 +272,7 @@ do_select_tests e_select-0.5 {
|
|||||||
4 "SELECT rowid FROM t1 EXCEPT SELECT rowid+2 FROM t4" {1 2}
|
4 "SELECT rowid FROM t1 EXCEPT SELECT rowid+2 FROM t4" {1 2}
|
||||||
}
|
}
|
||||||
|
|
||||||
# EVIDENCE-OF: R-06480-34950 -- syntax diagram ordering-term
|
# -- syntax diagram ordering-term
|
||||||
#
|
#
|
||||||
do_select_tests e_select-0.6 {
|
do_select_tests e_select-0.6 {
|
||||||
1 "SELECT b||a FROM t1 ORDER BY b||a" {onea threec twob}
|
1 "SELECT b||a FROM t1 ORDER BY b||a" {onea threec twob}
|
||||||
@ -281,7 +281,7 @@ do_select_tests e_select-0.6 {
|
|||||||
4 "SELECT b||a FROM t1 ORDER BY (b||a) DESC" {twob threec onea}
|
4 "SELECT b||a FROM t1 ORDER BY (b||a) DESC" {twob threec onea}
|
||||||
}
|
}
|
||||||
|
|
||||||
# EVIDENCE-OF: R-23926-36668 -- syntax diagram select-stmt
|
# -- syntax diagram select-stmt
|
||||||
#
|
#
|
||||||
do_select_tests e_select-0.7 {
|
do_select_tests e_select-0.7 {
|
||||||
1 "SELECT * FROM t1" {a one b two c three}
|
1 "SELECT * FROM t1" {a one b two c three}
|
||||||
@ -395,8 +395,8 @@ do_select_tests e_select-1.3 {
|
|||||||
# EVIDENCE-OF: R-46256-57243 There is no difference between the "INNER
|
# EVIDENCE-OF: R-46256-57243 There is no difference between the "INNER
|
||||||
# JOIN", "JOIN" and "," join operators.
|
# JOIN", "JOIN" and "," join operators.
|
||||||
#
|
#
|
||||||
# EVIDENCE-OF: R-07544-24155 The "CROSS JOIN" join operator produces the
|
# EVIDENCE-OF: R-25071-21202 The "CROSS JOIN" join operator produces the
|
||||||
# same data as the "INNER JOIN", "JOIN" and "," operators
|
# same result as the "INNER JOIN", "JOIN" and "," operators
|
||||||
#
|
#
|
||||||
# All tests are run 4 times, with the only difference in each run being
|
# All tests are run 4 times, with the only difference in each run being
|
||||||
# which of the 4 equivalent cartesian product join operators are used.
|
# which of the 4 equivalent cartesian product join operators are used.
|
||||||
@ -1226,7 +1226,7 @@ do_select_tests e_select-5.1 {
|
|||||||
# EVIDENCE-OF: R-08861-34280 If the simple SELECT is a SELECT ALL, then
|
# EVIDENCE-OF: R-08861-34280 If the simple SELECT is a SELECT ALL, then
|
||||||
# the entire set of result rows are returned by the SELECT.
|
# the entire set of result rows are returned by the SELECT.
|
||||||
#
|
#
|
||||||
# EVIDENCE-OF: R-47911-02086 If neither ALL or DISTINCT are present,
|
# EVIDENCE-OF: R-01256-01950 If neither ALL or DISTINCT are present,
|
||||||
# then the behavior is as if ALL were specified.
|
# then the behavior is as if ALL were specified.
|
||||||
#
|
#
|
||||||
# EVIDENCE-OF: R-14442-41305 If the simple SELECT is a SELECT DISTINCT,
|
# EVIDENCE-OF: R-14442-41305 If the simple SELECT is a SELECT DISTINCT,
|
||||||
|
@ -352,8 +352,8 @@ foreach {tn indexes} {
|
|||||||
# EVIDENCE-OF: R-46256-57243 There is no difference between the "INNER
|
# EVIDENCE-OF: R-46256-57243 There is no difference between the "INNER
|
||||||
# JOIN", "JOIN" and "," join operators.
|
# JOIN", "JOIN" and "," join operators.
|
||||||
#
|
#
|
||||||
# EVIDENCE-OF: R-07544-24155 The "CROSS JOIN" join operator produces the
|
# EVIDENCE-OF: R-25071-21202 The "CROSS JOIN" join operator produces the
|
||||||
# same data as the "INNER JOIN", "JOIN" and "," operators
|
# same result as the "INNER JOIN", "JOIN" and "," operators
|
||||||
#
|
#
|
||||||
test_join $tn.1.1 "t1, t2" {t1 t2}
|
test_join $tn.1.1 "t1, t2" {t1 t2}
|
||||||
test_join $tn.1.2 "t1 INNER JOIN t2" {t1 t2}
|
test_join $tn.1.2 "t1 INNER JOIN t2" {t1 t2}
|
||||||
|
@ -49,7 +49,7 @@ proc do_update_tests {args} {
|
|||||||
uplevel do_select_tests $args
|
uplevel do_select_tests $args
|
||||||
}
|
}
|
||||||
|
|
||||||
# EVIDENCE-OF: R-62337-45828 -- syntax diagram update-stmt
|
# -- syntax diagram update-stmt
|
||||||
#
|
#
|
||||||
do_update_tests e_update-0 {
|
do_update_tests e_update-0 {
|
||||||
1 "UPDATE t1 SET a=10" {}
|
1 "UPDATE t1 SET a=10" {}
|
||||||
@ -493,7 +493,7 @@ do_update_tests e_update-2.5 -error {
|
|||||||
# of the UPDATE statement is extended with optional ORDER BY and LIMIT
|
# of the UPDATE statement is extended with optional ORDER BY and LIMIT
|
||||||
# clauses
|
# clauses
|
||||||
#
|
#
|
||||||
# EVIDENCE-OF: R-45169-39597 -- syntax diagram update-stmt-limited
|
# -- syntax diagram update-stmt-limited
|
||||||
#
|
#
|
||||||
do_update_tests e_update-3.0 {
|
do_update_tests e_update-3.0 {
|
||||||
1 "UPDATE t1 SET a=b LIMIT 5" {}
|
1 "UPDATE t1 SET a=b LIMIT 5" {}
|
||||||
|
@ -359,7 +359,7 @@ foreach {tn uri error} "
|
|||||||
# EVIDENCE-OF: R-49793-28525 Setting the cache parameter to "private" is
|
# EVIDENCE-OF: R-49793-28525 Setting the cache parameter to "private" is
|
||||||
# equivalent to setting the SQLITE_OPEN_PRIVATECACHE bit.
|
# equivalent to setting the SQLITE_OPEN_PRIVATECACHE bit.
|
||||||
#
|
#
|
||||||
# EVIDENCE-OF: R-19510-48080 If sqlite3_open_v2() is used and the
|
# EVIDENCE-OF: R-31773-41793 If sqlite3_open_v2() is used and the
|
||||||
# "cache" parameter is present in a URI filename, its value overrides
|
# "cache" parameter is present in a URI filename, its value overrides
|
||||||
# any behavior requested by setting SQLITE_OPEN_PRIVATECACHE or
|
# any behavior requested by setting SQLITE_OPEN_PRIVATECACHE or
|
||||||
# SQLITE_OPEN_SHAREDCACHE flag.
|
# SQLITE_OPEN_SHAREDCACHE flag.
|
||||||
|
@ -65,7 +65,7 @@ proc fragment_count {name} {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# EVIDENCE-OF: R-45173-45977 -- syntax diagram vacuum-stmt
|
# -- syntax diagram vacuum-stmt
|
||||||
#
|
#
|
||||||
do_execsql_test e_vacuum-0.1 { VACUUM } {}
|
do_execsql_test e_vacuum-0.1 { VACUUM } {}
|
||||||
|
|
||||||
|
@ -370,32 +370,37 @@ do_eqp_test 4.3.3 {
|
|||||||
#
|
#
|
||||||
drop_all_tables
|
drop_all_tables
|
||||||
|
|
||||||
# EVIDENCE-OF: R-64208-08323 sqlite> EXPLAIN QUERY PLAN SELECT a, b
|
# EVIDENCE-OF: R-47779-47605 sqlite> EXPLAIN QUERY PLAN SELECT a, b
|
||||||
# FROM t1 WHERE a=1; 0|0|0|SCAN TABLE t1
|
# FROM t1 WHERE a=1;
|
||||||
|
# 0|0|0|SCAN TABLE t1
|
||||||
|
#
|
||||||
do_execsql_test 5.1.0 { CREATE TABLE t1(a, b) }
|
do_execsql_test 5.1.0 { CREATE TABLE t1(a, b) }
|
||||||
det 5.1.1 "SELECT a, b FROM t1 WHERE a=1" {
|
det 5.1.1 "SELECT a, b FROM t1 WHERE a=1" {
|
||||||
0 0 0 {SCAN TABLE t1}
|
0 0 0 {SCAN TABLE t1}
|
||||||
}
|
}
|
||||||
|
|
||||||
# EVIDENCE-OF: R-09022-44606 sqlite> CREATE INDEX i1 ON t1(a);
|
# EVIDENCE-OF: R-55852-17599 sqlite> CREATE INDEX i1 ON t1(a);
|
||||||
# sqlite> EXPLAIN QUERY PLAN SELECT a, b FROM t1 WHERE a=1;
|
# sqlite> EXPLAIN QUERY PLAN SELECT a, b FROM t1 WHERE a=1;
|
||||||
# 0|0|0|SEARCH TABLE t1 USING INDEX i1 (a=?)
|
# 0|0|0|SEARCH TABLE t1 USING INDEX i1
|
||||||
|
#
|
||||||
do_execsql_test 5.2.0 { CREATE INDEX i1 ON t1(a) }
|
do_execsql_test 5.2.0 { CREATE INDEX i1 ON t1(a) }
|
||||||
det 5.2.1 "SELECT a, b FROM t1 WHERE a=1" {
|
det 5.2.1 "SELECT a, b FROM t1 WHERE a=1" {
|
||||||
0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?)}
|
0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?)}
|
||||||
}
|
}
|
||||||
|
|
||||||
# EVIDENCE-OF: R-62228-34103 sqlite> CREATE INDEX i2 ON t1(a, b);
|
# EVIDENCE-OF: R-21179-11011 sqlite> CREATE INDEX i2 ON t1(a, b);
|
||||||
# sqlite> EXPLAIN QUERY PLAN SELECT a, b FROM t1 WHERE a=1;
|
# sqlite> EXPLAIN QUERY PLAN SELECT a, b FROM t1 WHERE a=1;
|
||||||
# 0|0|0|SEARCH TABLE t1 USING COVERING INDEX i2 (a=?)
|
# 0|0|0|SEARCH TABLE t1 USING COVERING INDEX i2 (a=?)
|
||||||
|
#
|
||||||
do_execsql_test 5.3.0 { CREATE INDEX i2 ON t1(a, b) }
|
do_execsql_test 5.3.0 { CREATE INDEX i2 ON t1(a, b) }
|
||||||
det 5.3.1 "SELECT a, b FROM t1 WHERE a=1" {
|
det 5.3.1 "SELECT a, b FROM t1 WHERE a=1" {
|
||||||
0 0 0 {SEARCH TABLE t1 USING COVERING INDEX i2 (a=?)}
|
0 0 0 {SEARCH TABLE t1 USING COVERING INDEX i2 (a=?)}
|
||||||
}
|
}
|
||||||
|
|
||||||
# EVIDENCE-OF: R-22253-05302 sqlite> EXPLAIN QUERY PLAN SELECT t1.*,
|
# EVIDENCE-OF: R-09991-48941 sqlite> EXPLAIN QUERY PLAN
|
||||||
# t2.* FROM t1, t2 WHERE t1.a=1 AND t1.b>2; 0|0|0|SEARCH TABLE t1
|
# SELECT t1.*, t2.* FROM t1, t2 WHERE t1.a=1 AND t1.b>2;
|
||||||
# USING COVERING INDEX i2 (a=? AND b>?) 0|1|1|SCAN TABLE t2
|
# 0|0|0|SEARCH TABLE t1 USING COVERING INDEX i2 (a=? AND b>?)
|
||||||
|
# 0|1|1|SCAN TABLE t2
|
||||||
#
|
#
|
||||||
do_execsql_test 5.4.0 {CREATE TABLE t2(c, d)}
|
do_execsql_test 5.4.0 {CREATE TABLE t2(c, d)}
|
||||||
det 5.4.1 "SELECT t1.*, t2.* FROM t1, t2 WHERE t1.a=1 AND t1.b>2" {
|
det 5.4.1 "SELECT t1.*, t2.* FROM t1, t2 WHERE t1.a=1 AND t1.b>2" {
|
||||||
@ -403,47 +408,54 @@ det 5.4.1 "SELECT t1.*, t2.* FROM t1, t2 WHERE t1.a=1 AND t1.b>2" {
|
|||||||
0 1 1 {SCAN TABLE t2}
|
0 1 1 {SCAN TABLE t2}
|
||||||
}
|
}
|
||||||
|
|
||||||
# EVIDENCE-OF: R-21040-07025 sqlite> EXPLAIN QUERY PLAN SELECT t1.*,
|
# EVIDENCE-OF: R-33626-61085 sqlite> EXPLAIN QUERY PLAN
|
||||||
# t2.* FROM t2, t1 WHERE t1.a=1 AND t1.b>2; 0|0|1|SEARCH TABLE t1
|
# SELECT t1.*, t2.* FROM t2, t1 WHERE t1.a=1 AND t1.b>2;
|
||||||
# USING COVERING INDEX i2 (a=? AND b>?) 0|1|0|SCAN TABLE t2
|
# 0|0|1|SEARCH TABLE t1 USING COVERING INDEX i2 (a=? AND b>?)
|
||||||
|
# 0|1|0|SCAN TABLE t2
|
||||||
#
|
#
|
||||||
det 5.5 "SELECT t1.*, t2.* FROM t2, t1 WHERE t1.a=1 AND t1.b>2" {
|
det 5.5 "SELECT t1.*, t2.* FROM t2, t1 WHERE t1.a=1 AND t1.b>2" {
|
||||||
0 0 1 {SEARCH TABLE t1 USING COVERING INDEX i2 (a=? AND b>?)}
|
0 0 1 {SEARCH TABLE t1 USING COVERING INDEX i2 (a=? AND b>?)}
|
||||||
0 1 0 {SCAN TABLE t2}
|
0 1 0 {SCAN TABLE t2}
|
||||||
}
|
}
|
||||||
|
|
||||||
# EVIDENCE-OF: R-39007-61103 sqlite> CREATE INDEX i3 ON t1(b);
|
# EVIDENCE-OF: R-04002-25654 sqlite> CREATE INDEX i3 ON t1(b);
|
||||||
# sqlite> EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=1 OR b=2;
|
# sqlite> EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=1 OR b=2;
|
||||||
# 0|0|0|SEARCH TABLE t1 USING COVERING INDEX i2 (a=?)
|
# 0|0|0|SEARCH TABLE t1 USING COVERING INDEX i2 (a=?)
|
||||||
# 0|0|0|SEARCH TABLE t1 USING INDEX i3 (b=?)
|
# 0|0|0|SEARCH TABLE t1 USING INDEX i3 (b=?)
|
||||||
|
#
|
||||||
do_execsql_test 5.5.0 {CREATE INDEX i3 ON t1(b)}
|
do_execsql_test 5.5.0 {CREATE INDEX i3 ON t1(b)}
|
||||||
det 5.6.1 "SELECT * FROM t1 WHERE a=1 OR b=2" {
|
det 5.6.1 "SELECT * FROM t1 WHERE a=1 OR b=2" {
|
||||||
0 0 0 {SEARCH TABLE t1 USING COVERING INDEX i2 (a=?)}
|
0 0 0 {SEARCH TABLE t1 USING COVERING INDEX i2 (a=?)}
|
||||||
0 0 0 {SEARCH TABLE t1 USING INDEX i3 (b=?)}
|
0 0 0 {SEARCH TABLE t1 USING INDEX i3 (b=?)}
|
||||||
}
|
}
|
||||||
|
|
||||||
# EVIDENCE-OF: R-33025-54904 sqlite> EXPLAIN QUERY PLAN SELECT c, d
|
# EVIDENCE-OF: R-24577-38891 sqlite> EXPLAIN QUERY PLAN
|
||||||
# FROM t2 ORDER BY c; 0|0|0|SCAN TABLE t2 0|0|0|USE TEMP
|
# SELECT c, d FROM t2 ORDER BY c;
|
||||||
# B-TREE FOR ORDER BY
|
# 0|0|0|SCAN TABLE t2
|
||||||
|
# 0|0|0|USE TEMP B-TREE FOR ORDER BY
|
||||||
|
#
|
||||||
det 5.7 "SELECT c, d FROM t2 ORDER BY c" {
|
det 5.7 "SELECT c, d FROM t2 ORDER BY c" {
|
||||||
0 0 0 {SCAN TABLE t2}
|
0 0 0 {SCAN TABLE t2}
|
||||||
0 0 0 {USE TEMP B-TREE FOR ORDER BY}
|
0 0 0 {USE TEMP B-TREE FOR ORDER BY}
|
||||||
}
|
}
|
||||||
|
|
||||||
# EVIDENCE-OF: R-38854-22809 sqlite> CREATE INDEX i4 ON t2(c);
|
# EVIDENCE-OF: R-58157-12355 sqlite> CREATE INDEX i4 ON t2(c);
|
||||||
# sqlite> EXPLAIN QUERY PLAN SELECT c, d FROM t2 ORDER BY c;
|
# sqlite> EXPLAIN QUERY PLAN SELECT c, d FROM t2 ORDER BY c;
|
||||||
# 0|0|0|SCAN TABLE t2 USING INDEX i4
|
# 0|0|0|SCAN TABLE t2 USING INDEX i4
|
||||||
|
#
|
||||||
do_execsql_test 5.8.0 {CREATE INDEX i4 ON t2(c)}
|
do_execsql_test 5.8.0 {CREATE INDEX i4 ON t2(c)}
|
||||||
det 5.8.1 "SELECT c, d FROM t2 ORDER BY c" {
|
det 5.8.1 "SELECT c, d FROM t2 ORDER BY c" {
|
||||||
0 0 0 {SCAN TABLE t2 USING INDEX i4}
|
0 0 0 {SCAN TABLE t2 USING INDEX i4}
|
||||||
}
|
}
|
||||||
|
|
||||||
# EVIDENCE-OF: R-29884-43993 sqlite> EXPLAIN QUERY PLAN SELECT
|
# EVIDENCE-OF: R-13931-10421 sqlite> EXPLAIN QUERY PLAN SELECT
|
||||||
# (SELECT b FROM t1 WHERE a=0), (SELECT a FROM t1 WHERE b=t2.c) FROM t2;
|
# (SELECT b FROM t1 WHERE a=0), (SELECT a FROM t1 WHERE b=t2.c) FROM t2;
|
||||||
# 0|0|0|SCAN TABLE t2 0|0|0|EXECUTE SCALAR SUBQUERY 1
|
# 0|0|0|SCAN TABLE t2
|
||||||
|
# 0|0|0|EXECUTE SCALAR SUBQUERY 1
|
||||||
# 1|0|0|SEARCH TABLE t1 USING COVERING INDEX i2 (a=?)
|
# 1|0|0|SEARCH TABLE t1 USING COVERING INDEX i2 (a=?)
|
||||||
# 0|0|0|EXECUTE CORRELATED SCALAR SUBQUERY 2 2|0|0|SEARCH TABLE t1 USING
|
# 0|0|0|EXECUTE CORRELATED SCALAR SUBQUERY 2
|
||||||
# INDEX i3 (b=?)
|
# 2|0|0|SEARCH TABLE t1 USING INDEX i3 (b=?)
|
||||||
|
#
|
||||||
det 5.9 {
|
det 5.9 {
|
||||||
SELECT (SELECT b FROM t1 WHERE a=0), (SELECT a FROM t1 WHERE b=t2.c) FROM t2
|
SELECT (SELECT b FROM t1 WHERE a=0), (SELECT a FROM t1 WHERE b=t2.c) FROM t2
|
||||||
} {
|
} {
|
||||||
@ -454,10 +466,12 @@ det 5.9 {
|
|||||||
2 0 0 {SEARCH TABLE t1 USING INDEX i3 (b=?)}
|
2 0 0 {SEARCH TABLE t1 USING INDEX i3 (b=?)}
|
||||||
}
|
}
|
||||||
|
|
||||||
# EVIDENCE-OF: R-17911-16445 sqlite> EXPLAIN QUERY PLAN SELECT
|
# EVIDENCE-OF: R-50892-45943 sqlite> EXPLAIN QUERY PLAN
|
||||||
# count(*) FROM (SELECT max(b) AS x FROM t1 GROUP BY a) GROUP BY x;
|
# SELECT count(*) FROM (SELECT max(b) AS x FROM t1 GROUP BY a) GROUP BY x;
|
||||||
# 1|0|0|SCAN TABLE t1 USING COVERING INDEX i2 0|0|0|SCAN
|
# 1|0|0|SCAN TABLE t1 USING COVERING INDEX i2
|
||||||
# SUBQUERY 1 0|0|0|USE TEMP B-TREE FOR GROUP BY
|
# 0|0|0|SCAN SUBQUERY 1
|
||||||
|
# 0|0|0|USE TEMP B-TREE FOR GROUP BY
|
||||||
|
#
|
||||||
det 5.10 {
|
det 5.10 {
|
||||||
SELECT count(*) FROM (SELECT max(b) AS x FROM t1 GROUP BY a) GROUP BY x
|
SELECT count(*) FROM (SELECT max(b) AS x FROM t1 GROUP BY a) GROUP BY x
|
||||||
} {
|
} {
|
||||||
@ -466,29 +480,34 @@ det 5.10 {
|
|||||||
0 0 0 {USE TEMP B-TREE FOR GROUP BY}
|
0 0 0 {USE TEMP B-TREE FOR GROUP BY}
|
||||||
}
|
}
|
||||||
|
|
||||||
# EVIDENCE-OF: R-18544-33103 sqlite> EXPLAIN QUERY PLAN SELECT * FROM
|
# EVIDENCE-OF: R-46219-33846 sqlite> EXPLAIN QUERY PLAN
|
||||||
# (SELECT * FROM t2 WHERE c=1), t1; 0|0|0|SEARCH TABLE t2 USING INDEX i4
|
# SELECT * FROM (SELECT * FROM t2 WHERE c=1), t1;
|
||||||
# (c=?) 0|1|1|SCAN TABLE t1
|
# 0|0|0|SEARCH TABLE t2 USING INDEX i4 (c=?)
|
||||||
|
# 0|1|1|SCAN TABLE t1
|
||||||
|
#
|
||||||
det 5.11 "SELECT * FROM (SELECT * FROM t2 WHERE c=1), t1" {
|
det 5.11 "SELECT * FROM (SELECT * FROM t2 WHERE c=1), t1" {
|
||||||
0 0 0 {SEARCH TABLE t2 USING INDEX i4 (c=?)}
|
0 0 0 {SEARCH TABLE t2 USING INDEX i4 (c=?)}
|
||||||
0 1 1 {SCAN TABLE t1 USING COVERING INDEX i2}
|
0 1 1 {SCAN TABLE t1 USING COVERING INDEX i2}
|
||||||
}
|
}
|
||||||
|
|
||||||
# EVIDENCE-OF: R-40701-42164 sqlite> EXPLAIN QUERY PLAN SELECT a FROM
|
# EVIDENCE-OF: R-37879-39987 sqlite> EXPLAIN QUERY PLAN
|
||||||
# t1 UNION SELECT c FROM t2; 1|0|0|SCAN TABLE t1
|
# SELECT a FROM t1 UNION SELECT c FROM t2;
|
||||||
# 2|0|0|SCAN TABLE t2 0|0|0|COMPOUND SUBQUERIES 1 AND 2
|
# 1|0|0|SCAN TABLE t1
|
||||||
# USING TEMP B-TREE (UNION)
|
# 2|0|0|SCAN TABLE t2
|
||||||
|
# 0|0|0|COMPOUND SUBQUERIES 1 AND 2 USING TEMP B-TREE (UNION)
|
||||||
|
#
|
||||||
det 5.12 "SELECT a FROM t1 UNION SELECT c FROM t2" {
|
det 5.12 "SELECT a FROM t1 UNION SELECT c FROM t2" {
|
||||||
1 0 0 {SCAN TABLE t1 USING COVERING INDEX i2}
|
1 0 0 {SCAN TABLE t1 USING COVERING INDEX i2}
|
||||||
2 0 0 {SCAN TABLE t2 USING COVERING INDEX i4}
|
2 0 0 {SCAN TABLE t2 USING COVERING INDEX i4}
|
||||||
0 0 0 {COMPOUND SUBQUERIES 1 AND 2 USING TEMP B-TREE (UNION)}
|
0 0 0 {COMPOUND SUBQUERIES 1 AND 2 USING TEMP B-TREE (UNION)}
|
||||||
}
|
}
|
||||||
|
|
||||||
# EVIDENCE-OF: R-61538-24748 sqlite> EXPLAIN QUERY PLAN SELECT a FROM
|
# EVIDENCE-OF: R-44864-63011 sqlite> EXPLAIN QUERY PLAN
|
||||||
# t1 EXCEPT SELECT d FROM t2 ORDER BY 1; 1|0|0|SCAN TABLE t1 USING
|
# SELECT a FROM t1 EXCEPT SELECT d FROM t2 ORDER BY 1;
|
||||||
# COVERING INDEX i2 2|0|0|SCAN TABLE t2
|
# 1|0|0|SCAN TABLE t1 USING COVERING INDEX i2
|
||||||
# 2|0|0|USE TEMP B-TREE FOR ORDER BY 0|0|0|COMPOUND SUBQUERIES 1 AND 2
|
# 2|0|0|SCAN TABLE t2 2|0|0|USE TEMP B-TREE FOR ORDER BY
|
||||||
# (EXCEPT)
|
# 0|0|0|COMPOUND SUBQUERIES 1 AND 2 (EXCEPT)
|
||||||
|
#
|
||||||
det 5.13 "SELECT a FROM t1 EXCEPT SELECT d FROM t2 ORDER BY 1" {
|
det 5.13 "SELECT a FROM t1 EXCEPT SELECT d FROM t2 ORDER BY 1" {
|
||||||
1 0 0 {SCAN TABLE t1 USING COVERING INDEX i2}
|
1 0 0 {SCAN TABLE t1 USING COVERING INDEX i2}
|
||||||
2 0 0 {SCAN TABLE t2}
|
2 0 0 {SCAN TABLE t2}
|
||||||
|
Reference in New Issue
Block a user