Bring in the latest updates from trunk.

FossilOrigin-Name: 7b5f3773867ed0e4ed17bd473ba972d500035318
This commit is contained in:
drh 2014-01-28 18:06:17 +00:00
commit 19913f4419
30 changed files with 571 additions and 199 deletions

View File

@ -96,13 +96,13 @@ void sqlite3Fts3HashClear(Fts3Hash *pH){
*/
static int fts3StrHash(const void *pKey, int nKey){
const char *z = (const char *)pKey;
int h = 0;
unsigned h = 0;
if( nKey<=0 ) nKey = (int) strlen(z);
while( nKey > 0 ){
h = (h<<3) ^ h ^ *z++;
nKey--;
}
return h & 0x7fffffff;
return (int)(h & 0x7fffffff);
}
static int fts3StrCompare(const void *pKey1, int n1, const void *pKey2, int n2){
if( n1!=n2 ) return 1;

View File

@ -1,5 +1,5 @@
C Bring\sin\sall\sthe\slatest\strunk\schanges,\sincluding\sthe\sCommon\sTable\nExpressions\simplementation.
D 2014-01-24T14:05:18.988
C Bring\sin\sthe\slatest\supdates\sfrom\strunk.
D 2014-01-28T18:06:17.362
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in e4ee6d36cdf6136aee0158675a3b24dd3bf31a5a
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@ -83,7 +83,7 @@ F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
F ext/fts3/fts3Int.h eb5f8029589f3d8f1dc7fd50c773326a640388b1
F ext/fts3/fts3_aux.c 5c211e17a64885faeb16b9ba7772f9d5445c2365
F ext/fts3/fts3_expr.c 5165c365cb5a035f5be8bb296f7aa3211d43e4ac
F ext/fts3/fts3_hash.c 8dd2d06b66c72c628c2732555a32bc0943114914
F ext/fts3/fts3_hash.c 29b986e43f4e9dd40110eafa377dc0d63c422c60
F ext/fts3/fts3_hash.h 39cf6874dc239d6b4e30479b1975fe5b22a3caaf
F ext/fts3/fts3_icu.c e319e108661147bcca8dd511cd562f33a1ba81b5
F ext/fts3/fts3_porter.c 7f8b4bf5af7c0f20f73b8e87e14fa9298f52e290
@ -188,13 +188,13 @@ F src/callback.c 174e3c8656bc29f91d710ab61550d16eea34be98
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd
F src/date.c 593c744b2623971e45affd0bde347631bdfa4625
F src/delete.c 80a3947fc234baba91842b90558db67bcd8706ea
F src/expr.c 61f9105820d6702d7153dfb6ca3d58e751a5e95a
F src/delete.c 85592961a0bef547562468c9496a56f3997b3c30
F src/expr.c 96f00a262308f3f97d2afd8519c7a284e25829f3
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c 2ab0f5384b70594468ef3ac5c7ed8ca24bfd17d5
F src/func.c 6325ac2ec10833ccf4d5c36d323709221d37ea19
F src/func.c f4499b39d66b71825514334ce67b32ff14bd19f5
F src/global.c 1d7bb7ea8254ae6a68ed9bfaf65fcb3d1690b486
F src/hash.c ac3470bbf1ca4ae4e306a8ecb0fdf1731810ffe4
F src/hash.c d139319967164f139c8d1bb8a11b14db9c4ba3cd
F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
F src/insert.c a8a987ba42e7172b144052db79e7246da6ae2ccf
@ -202,7 +202,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12
F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b
F src/loadext.c 867c7b330b740c6c917af9956b13b81d0a048303
F src/main.c deaeda63657d005ad9833f2191b7ff65c83e0ded
F src/main.c e9c6feb98d8bf8fa15b87167f6ab87fcce13602c
F src/malloc.c 0203ebce9152c6a0e5de520140b8ba65187350be
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c c0c990fcaddff810ea277b4fb5d9138603dd5d4b
@ -219,30 +219,30 @@ F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30
F src/os.c 1b147e4cf7cc39e618115c14a086aed44bc91ace
F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f
F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
F src/os_unix.c 3a4dcb554d3c915075766162f28c3fd4cdb75968
F src/os_unix.c f3ed0e406cbf9c820565b2118232d0796346130f
F src/os_win.c 1b21af72c5fa6f9e519a5fcab33e80d182b1aedb
F src/pager.c efa923693e958696eee69b205a20bfbc402c8480
F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428
F src/parse.y bd51bc17cbfe7549adb4ca3747b1c3d384645065
F src/pcache.c f8043b433a57aba85384a531e3937a804432a346
F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222
F src/pcache1.c 57fee9a9a617218f5037afbbe49b09da65bde56b
F src/pcache1.c 102e6f5a2fbc646154463eb856d1fd716867b64c
F src/pragma.c ed409ce4104cf4d9de6ead40ace70974f124853b
F src/prepare.c 677521ab7132615a8a26107a1d1c3132f44ae337
F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269
F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece
F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6
F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0
F src/select.c 93764e0d81946c070e2c7f1127f35e21efabbcc3
F src/select.c a421f3fb7f52a3c0b37f5caeabd27799e8a9ae58
F src/shell.c 24722d24d4ea8ca93db35e44db7308de786767ca
F src/sqlite.h.in a92d7fcdcb1a8003a62e916ec49025f27ccb56b8
F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e
F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
F src/sqliteInt.h e4d4b5db50e69f2ce130d40d324db5b5c5638aa8
F src/sqliteInt.h 5bec5e943c184f137e5f0895886346c82618728d
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
F src/tclsqlite.c a870d43e3c19663fce878aa4c7cac9c624aab564
F src/tclsqlite.c 97a7cb53646107433f463592ed785f6e177b93b5
F src/test1.c 2401eee14a4309a7cfe2aeb2f30ad517a1d9c299
F src/test2.c 7355101c085304b90024f2261e056cdff13c6c35
F src/test3.c 1c0e5d6f080b8e33c1ce8b3078e7013fdbcd560c
@ -250,7 +250,7 @@ F src/test4.c 9b32d22f5f150abe23c1830e2057c4037c45b3df
F src/test5.c a6d1ac55ac054d0b2b8f37b5e655b6c92645a013
F src/test6.c 41cacf3b0dd180823919bf9e1fbab287c9266723
F src/test7.c 72b732baa5642f795655ba1126ea032af46ecfd2
F src/test8.c c7aab1d9fbbf54fc33d43b73aa24aa55f9eaf534
F src/test8.c 54ccd7b1df5062f0ecbf50a8f7b618f8b1f13b20
F src/test9.c bea1e8cf52aa93695487badedd6e1886c321ea60
F src/test_async.c 21e11293a2f72080eda70e1124e9102044531cd8
F src/test_autoext.c dea8a01a7153b9adc97bd26161e4226329546e12
@ -290,17 +290,17 @@ F src/test_vfstrace.c 3a0ab304682fecbceb689e7d9b904211fde11d78
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/tokenize.c 6da2de6e12218ccb0aea5184b56727d011f4bee7
F src/trigger.c 5c1c0b899ac0ce284763dcb8fdbaa38ecf15ef98
F src/update.c 3143bbdfc8c2d78b74dba15133df04843221ce0d
F src/update.c 437c130e7d16230e182782baffa8290a349cdf7d
F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269
F src/util.c e71f19b272f05c8695cf747b4bac1732685f9e5c
F src/util.c 15ac2627f548f5481d0d7e6c4eb67be673027695
F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179
F src/vdbe.c c41493ca68c23f421b21bdb0ff1f0e8df7aaa876
F src/vdbe.c 7b5d45ba9be3cb2e27ff52e0ce452a58fd3bc282
F src/vdbe.h 06016671144c70373331e348fd7edf2b2535ac97
F src/vdbeInt.h 08d79db15519f98d6d2c2dedaebfbb7f3d69a6d8
F src/vdbeapi.c 647d65813a5595c7f667b9f43d119ecd8d70be08
F src/vdbeaux.c a980f7817ab73afb5efc5fac97097421f0ee8f66
F src/vdbeaux.c 25e8ee3c8fdb3951ee46616f09c62cce217df855
F src/vdbeblob.c 6e791541114d482074e031ef8dbc3d5e5c180e23
F src/vdbemem.c 0e69351b2c6ff7d8b638688c0ae336a26befa6b2
F src/vdbemem.c 23cdc14ed43e0aafa57bd72b9bf3d5b1641afa91
F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147
F src/vdbetrace.c 6f52bc0c51e144b7efdcfb2a8f771167a8816767
F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd
@ -386,7 +386,7 @@ F test/capi3e.test ad90088b18b0367125ff2d4b5400153fd2f99aab
F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3
F test/check.test 5831ddb6f2c687782eaf2e1a07b6e17f24c4f763
F test/close.test 340bd24cc58b16c6bc01967402755027c37eb815
F test/closure01.test dbb28f1ea9eeaf0a53ec5bc0fed352e479def8c7
F test/closure01.test b1703ba40639cfc9b295cf478d70739415eec6a4
F test/coalesce.test cee0dccb9fbd2d494b77234bccf9dc6c6786eb91
F test/collate1.test 73b91005f264b7c403e2d63a6708d150679ac99a
F test/collate2.test 9aaa410a00734e48bcb27f3872617d6f69b2a621
@ -420,7 +420,7 @@ F test/corruptD.test b3c205fac7952b1de645ce44bb02335cd9e3e040
F test/corruptE.test 193b4ca4e927e77c1d5f4f56203ddc998432a7ee
F test/corruptF.test be9fde98e4c93648f1ba52b74e5318edc8f59fe4
F test/corruptG.test c150f156dace653c00a121ad0f5772a0568c41ba
F test/corruptH.test 0a247f3dc8a8f3578db5f639d86c6bb4d520207f
F test/corruptH.test 9d8186f6f8751efdfd445d8546fd98f073499039
F test/count.test 42a251178e32f617eda33f76236a7f79825a50b5
F test/coveridxscan.test cdb47d01acc4a634a34fd25abe85189e0d0f1e62
F test/crash.test fb9dc4a02dcba30d4aa5c2c226f98b220b2b959f
@ -458,8 +458,8 @@ F test/e_fts3.test 5c02288842e4f941896fd44afdef564dd5fc1459
F test/e_insert.test 1e44f84d2abe44d66e4fbf198be4b20e3cc724a0
F test/e_reindex.test 396b7b4f0a66863b4e95116a67d93b227193e589
F test/e_resolve.test dcce9308fb13b934ce29591105d031d3e14fbba6
F test/e_select.test d3226cb94fae4af3f198e68e71f655e106d0be47
F test/e_select2.test 22c660a7becf0712c95e1ca1b2d9e716a1261460
F test/e_select.test 51c062a9bda16e0ae1bbeed50806bedbd040b282
F test/e_select2.test aceb80ab927d46fba5ce7586ebabf23e2bb0604f
F test/e_update.test 312cb8f5ccfe41515a6bb092f8ea562a9bd54d52
F test/e_uri.test a2c92d80093a7efdcfbb11093651cbea87097b6b
F test/e_vacuum.test 5bfbdc21b65c0abf24398d0ba31dc88d93ca77a9
@ -742,8 +742,8 @@ F test/oserror.test 50417780d0e0d7cd23cf12a8277bb44024765df3
F test/pager1.test 1acbdb14c5952a72dd43129cabdbf69aaa3ed1fa
F test/pager2.test 67b8f40ae98112bcdba1f2b2d03ea83266418c71
F test/pager3.test 3856d9c80839be0668efee1b74811b1b7f7fc95f
F test/pager4.test b40ecb4cc7dff957ee7916e41ab21d1ed702a642
F test/pagerfault.test 7285379906ab2f1108b8e82bbdf2d386cc8ff3ff
F test/pager4.test a122e9e6925d5b23b31e3dfef8c6a44bbf19590e
F test/pagerfault.test ae9ee0db5a30aecda9db8290ce3dd12e5f7bbaa1
F test/pagerfault2.test caf4c7facb914fd3b03a17b31ae2b180c8d6ca1f
F test/pagerfault3.test 1003fcda009bf48a8e22a516e193b6ef0dd1bbd8
F test/pageropt.test 6b8f6a123a5572c195ad4ae40f2987007923bbd6
@ -755,7 +755,7 @@ F test/permutations.test 79927c8175c4dc889f30486388490dae229b3b11
F test/pragma.test e882183ecd21d064cec5c7aaea174fbd36293429
F test/pragma2.test aea7b3d82c76034a2df2b38a13745172ddc0bc13
F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552
F test/printf2.test 414fcba6d6c10e0a5e58efd213811e5ead4635a0
F test/printf2.test bed79b4c3e5da08ba88ad637c0bf62586843cfb1
F test/progress.test a282973d1d17f08071bc58a77d6b80f2a81c354d
F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc
F test/queryonly.test 5f653159e0f552f0552d43259890c1089391dcca
@ -840,7 +840,7 @@ F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715
F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa
F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b
F test/speedtest1.c 7130d2cb6db45baa553a4ab2f715116c71c2d9f4
F test/spellfix.test 674db5da8b16d2b54939b68ccc0ac31ca53d9977
F test/spellfix.test 61309f5efbec53603b3f86457d34a504f80abafe
F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298
F test/stat.test 76fd746b85459e812a0193410fb599f0531f22de
F test/stmt.test 25d64e3dbf9a3ce89558667d7f39d966fe2a71b9
@ -859,7 +859,7 @@ F test/tclsqlite.test a7308276aad2e6c0bfb5b0414424dd0d9cc0cad7
F test/tempdb.test 19d0f66e2e3eeffd68661a11c83ba5e6ace9128c
F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30
F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1
F test/tester.tcl 1b1ba4c0f5e7f76c7c74dbb8a20ad9f72a3f46f0
F test/tester.tcl 1c7b3cef48840ad67ca82cfed4ec3a4afbc322a3
F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5
F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58
F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7
@ -1107,7 +1107,7 @@ F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c
F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c
F test/win32lock.test 7a6bd73a5dcdee39b5bb93e92395e1773a194361
F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d
F test/with1.test 9d3537372c8cf6d5e0a5e9af037a52f3375fb704
F test/with1.test ce15d69d34a2576b0e47d78c244d1ba2a31679d1
F test/with2.test 2fe78fcd8deef2a0f9cfc49bfc755911d0b3fd64
F test/withM.test e97f2a8c506ab3ea9eab94e6f6072f6cc924c991
F test/without_rowid1.test aaa26da19d543cd8d3d2d0e686dfa255556c15c8
@ -1142,7 +1142,7 @@ F tool/mksqlite3h.tcl 2d0f1b3768f8d000b7881217d5fd4c776eb27467
F tool/mksqlite3internalh.tcl 3dca7bb5374cee003379b8cbac73714f610ef795
F tool/mkvsix.tcl 6477fb9dab838b7eea1eed50658ff1cda04850b5
F tool/offsets.c fe4262fdfa378e8f5499a42136d17bf3b98f6091
F tool/omittest.tcl 4665982e95a6e5c1bd806cf7bc3dea95be422d77
F tool/omittest.tcl 34d7ac01fe4fd18e3637f64abe12c40eca0f6b97
F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c
F tool/pagesig.c ff0ca355fd3c2398e933da5e22439bbff89b803b
F tool/restore_jrnl.tcl 6957a34f8f1f0f8285e07536225ec3b292a9024a
@ -1167,7 +1167,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
P cfd110bf5db2c1993a5e2ca718648bd9c17ee22c 83b0b2916589db0184435dbd4c304387f393ed60
R 5819e16ba708c7c74e3c7382ce1686de
P 9b43e559195680e558264c4c00d34dc9cf9d9146 5e3b9ecc7b2b2e50952de819b99bafdb7b9ff59e
R 51002a148d222844524dcb7bb9208985
U drh
Z ab25b0717f386dd1619d1172c5947b1e
Z 1a524338f4286caad02c997553ac895a

View File

@ -1 +1 @@
9b43e559195680e558264c4c00d34dc9cf9d9146
7b5f3773867ed0e4ed17bd473ba972d500035318

View File

@ -643,7 +643,8 @@ void sqlite3GenerateRowDelete(
** used by any BEFORE and AFTER triggers that exist. */
sqlite3VdbeAddOp2(v, OP_Copy, iPk, iOld);
for(iCol=0; iCol<pTab->nCol; iCol++){
if( mask==0xffffffff || mask&(1<<iCol) ){
testcase( mask!=0xffffffff && iCol==31 );
if( mask==0xffffffff || (mask & MASKBIT32(iCol))!=0 ){
sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, iCol, iOld+iCol+1);
}
}

View File

@ -2685,7 +2685,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
FuncDef *pDef; /* The function definition object */
int nId; /* Length of the function name in bytes */
const char *zId; /* The function name */
int constMask = 0; /* Mask of function arguments that are constant */
u32 constMask = 0; /* Mask of function arguments that are constant */
int i; /* Loop counter */
u8 enc = ENC(db); /* The text encoding used by this database */
CollSeq *pColl = 0; /* A collating sequence */
@ -2736,7 +2736,8 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
for(i=0; i<nFarg; i++){
if( i<32 && sqlite3ExprIsConstant(pFarg->a[i].pExpr) ){
constMask |= (1<<i);
testcase( i==31 );
constMask |= MASKBIT32(i);
}
if( (pDef->funcFlags & SQLITE_FUNC_NEEDCOLL)!=0 && !pColl ){
pColl = sqlite3ExprCollSeq(pParse, pFarg->a[i].pExpr);

View File

@ -137,7 +137,7 @@ static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
case SQLITE_INTEGER: {
i64 iVal = sqlite3_value_int64(argv[0]);
if( iVal<0 ){
if( (iVal<<1)==0 ){
if( iVal==SMALLEST_INT64 ){
/* IMP: R-31676-45509 If X is the integer -9223372036854775808
** then abs(X) throws an integer overflow error since there is no
** equivalent positive 64-bit two complement value. */

View File

@ -53,7 +53,7 @@ void sqlite3HashClear(Hash *pH){
** The hashing function.
*/
static unsigned int strHash(const char *z, int nKey){
int h = 0;
unsigned int h = 0;
assert( nKey>=0 );
while( nKey > 0 ){
h = (h<<3) ^ h ^ sqlite3UpperToLower[(unsigned char)*z++];

View File

@ -3324,7 +3324,7 @@ int sqlite3_test_control(int op, ...){
** that demonstrat invariants on well-formed database files.
*/
case SQLITE_TESTCTRL_NEVER_CORRUPT: {
sqlite3Config.neverCorrupt = va_arg(ap, int);
sqlite3GlobalConfig.neverCorrupt = va_arg(ap, int);
break;
}

View File

@ -4097,7 +4097,7 @@ static int unixShmSystemLock(
#ifdef SQLITE_DEBUG
{ u16 mask;
OSTRACE(("SHM-LOCK "));
mask = ofst>31 ? 0xffffffff : (1<<(ofst+n)) - (1<<ofst);
mask = ofst>31 ? 0xffff : (1<<(ofst+n)) - (1<<ofst);
if( rc==SQLITE_OK ){
if( lockType==F_UNLCK ){
OSTRACE(("unlock %d ok", ofst));

View File

@ -720,6 +720,7 @@ static sqlite3_pcache_page *pcache1Fetch(
PGroup *pGroup;
PgHdr1 *pPage = 0;
assert( offsetof(PgHdr1,page)==0 );
assert( pCache->bPurgeable || createFlag!=1 );
assert( pCache->bPurgeable || pCache->nMin==0 );
assert( pCache->bPurgeable==0 || pCache->nMin==10 );
@ -825,7 +826,7 @@ fetch_out:
pCache->iMaxKey = iKey;
}
pcache1LeaveMutex(pGroup);
return &pPage->page;
return (sqlite3_pcache_page*)pPage;
}

View File

@ -1725,7 +1725,44 @@ static CollSeq *multiSelectCollSeq(Parse *pParse, Select *p, int iCol){
}
return pRet;
}
#endif /* SQLITE_OMIT_COMPOUND_SELECT */
/*
** The select statement passed as the second parameter is a compound SELECT
** with an ORDER BY clause. This function allocates and returns a KeyInfo
** structure suitable for implementing the ORDER BY.
**
** Space to hold the KeyInfo structure is obtained from malloc. The calling
** function is responsible for ensuring that this structure is eventually
** freed.
*/
static KeyInfo *multiSelectOrderByKeyInfo(Parse *pParse, Select *p, int nExtra){
ExprList *pOrderBy = p->pOrderBy;
int nOrderBy = p->pOrderBy->nExpr;
sqlite3 *db = pParse->db;
KeyInfo *pRet = sqlite3KeyInfoAlloc(db, nOrderBy+nExtra, 1);
if( pRet ){
int i;
for(i=0; i<nOrderBy; i++){
struct ExprList_item *pItem = &pOrderBy->a[i];
Expr *pTerm = pItem->pExpr;
CollSeq *pColl;
if( pTerm->flags & EP_Collate ){
pColl = sqlite3ExprCollSeq(pParse, pTerm);
}else{
pColl = multiSelectCollSeq(pParse, p, pItem->u.x.iOrderByCol-1);
if( pColl==0 ) pColl = db->pDfltColl;
pOrderBy->a[i].pExpr =
sqlite3ExprAddCollateString(pParse, pTerm, pColl->zName);
}
assert( sqlite3KeyInfoIsWriteable(pRet) );
pRet->aColl[i] = pColl;
pRet->aSortOrder[i] = pOrderBy->a[i].sortOrder;
}
}
return pRet;
}
#ifndef SQLITE_OMIT_CTE
/*
@ -1799,6 +1836,7 @@ static void generateWithRecursiveQuery(
regOffset = p->iOffset;
p->pLimit = p->pOffset = 0;
p->iLimit = p->iOffset = 0;
pOrderBy = p->pOrderBy;
/* Locate the cursor number of the Current table */
for(i=0; ALWAYS(i<pSrc->nSrc); i++){
@ -1808,10 +1846,6 @@ static void generateWithRecursiveQuery(
}
}
/* Detach the ORDER BY clause from the compound SELECT */
pOrderBy = p->pOrderBy;
p->pOrderBy = 0;
/* Allocate cursors numbers for Queue and Distinct. The cursor number for
** the Distinct table must be exactly one greater than Queue in order
** for the SRT_DistTable and SRT_DistQueue destinations to work. */
@ -1828,7 +1862,7 @@ static void generateWithRecursiveQuery(
regCurrent = ++pParse->nMem;
sqlite3VdbeAddOp3(v, OP_OpenPseudo, iCurrent, regCurrent, nCol);
if( pOrderBy ){
KeyInfo *pKeyInfo = keyInfoFromExprList(pParse, pOrderBy, 1);
KeyInfo *pKeyInfo = multiSelectOrderByKeyInfo(pParse, p, 1);
sqlite3VdbeAddOp4(v, OP_OpenEphemeral, iQueue, pOrderBy->nExpr+2, 0,
(char*)pKeyInfo, P4_KEYINFO);
destQueue.pOrderBy = pOrderBy;
@ -1841,6 +1875,9 @@ static void generateWithRecursiveQuery(
p->selFlags |= SF_UsesEphemeral;
}
/* Detach the ORDER BY clause from the compound SELECT */
p->pOrderBy = 0;
/* Store the results of the setup-query in Queue. */
rc = sqlite3Select(pParse, pSetup, &destQueue);
if( rc ) goto end_of_recursive_query;
@ -1883,7 +1920,7 @@ end_of_recursive_query:
p->pOffset = pOffset;
return;
}
#endif
#endif /* SQLITE_OMIT_CTE */
/* Forward references */
static int multiSelectOrderBy(
@ -1893,7 +1930,6 @@ static int multiSelectOrderBy(
);
#ifndef SQLITE_OMIT_COMPOUND_SELECT
/*
** This routine is called to process a compound query form from
** two or more separate queries using UNION, UNION ALL, EXCEPT, or
@ -2625,24 +2661,7 @@ static int multiSelectOrderBy(
&& pItem->u.x.iOrderByCol<=p->pEList->nExpr );
aPermute[i] = pItem->u.x.iOrderByCol - 1;
}
pKeyMerge = sqlite3KeyInfoAlloc(db, nOrderBy, 1);
if( pKeyMerge ){
for(i=0; i<nOrderBy; i++){
CollSeq *pColl;
Expr *pTerm = pOrderBy->a[i].pExpr;
if( pTerm->flags & EP_Collate ){
pColl = sqlite3ExprCollSeq(pParse, pTerm);
}else{
pColl = multiSelectCollSeq(pParse, p, aPermute[i]);
if( pColl==0 ) pColl = db->pDfltColl;
pOrderBy->a[i].pExpr =
sqlite3ExprAddCollateString(pParse, pTerm, pColl->zName);
}
assert( sqlite3KeyInfoIsWriteable(pKeyMerge) );
pKeyMerge->aColl[i] = pColl;
pKeyMerge->aSortOrder[i] = pOrderBy->a[i].sortOrder;
}
}
pKeyMerge = multiSelectOrderByKeyInfo(pParse, p, 1);
}else{
pKeyMerge = 0;
}

View File

@ -1990,6 +1990,7 @@ typedef u64 Bitmask;
** A bit in a Bitmask
*/
#define MASKBIT(n) (((Bitmask)1)<<(n))
#define MASKBIT32(n) (((unsigned int)1)<<(n))
/*
** The following structure describes the FROM clause of a SELECT statement.

View File

@ -917,7 +917,7 @@ static int auth_callback(
const char *zArg3,
const char *zArg4
){
char *zCode;
const char *zCode;
Tcl_DString str;
int rc;
const char *zReply;
@ -1043,7 +1043,7 @@ static int DbTransPostCmd(
Tcl_Interp *interp, /* Tcl interpreter */
int result /* Result of evaluating SCRIPT */
){
static const char *azEnd[] = {
static const char *const azEnd[] = {
"RELEASE _tcl_transaction", /* rc==TCL_ERROR, nTransaction!=0 */
"COMMIT", /* rc!=TCL_ERROR, nTransaction==0 */
"ROLLBACK TO _tcl_transaction ; RELEASE _tcl_transaction",
@ -2022,7 +2022,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
Tcl_AppendResult(interp, pDb->zCommit, 0);
}
}else{
char *zCommit;
const char *zCommit;
int len;
if( pDb->zCommit ){
Tcl_Free(pDb->zCommit);
@ -2095,14 +2095,14 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
char *zSql; /* An SQL statement */
char *zLine; /* A single line of input from the file */
char **azCol; /* zLine[] broken up into columns */
char *zCommit; /* How to commit changes */
const char *zCommit; /* How to commit changes */
FILE *in; /* The input file */
int lineno = 0; /* Line number of input file */
char zLineNum[80]; /* Line number print buffer */
Tcl_Obj *pResult; /* interp result */
char *zSep;
char *zNull;
const char *zSep;
const char *zNull;
if( objc<5 || objc>7 ){
Tcl_WrongNumArgs(interp, 2, objv,
"CONFLICT-ALGORITHM TABLE FILENAME ?SEPARATOR? ?NULLINDICATOR?");
@ -3081,7 +3081,7 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
if( objc==2 ){
zArg = Tcl_GetStringFromObj(objv[1], 0);
if( strcmp(zArg,"-version")==0 ){
Tcl_AppendResult(interp,sqlite3_version,0);
Tcl_AppendResult(interp,sqlite3_libversion(),0);
return TCL_OK;
}
if( strcmp(zArg,"-has-codec")==0 ){
@ -3163,7 +3163,7 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
zErrMsg = 0;
p = (SqliteDb*)Tcl_Alloc( sizeof(*p) );
if( p==0 ){
Tcl_SetResult(interp, "malloc failed", TCL_STATIC);
Tcl_SetResult(interp, (char *)"malloc failed", TCL_STATIC);
return TCL_ERROR;
}
memset(p, 0, sizeof(*p));

View File

@ -892,7 +892,7 @@ static int echoBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
pIdxInfo->estimatedCost = cost;
}else if( useIdx ){
/* Approximation of log2(nRow). */
for( ii=0; ii<(sizeof(int)*8); ii++ ){
for( ii=0; ii<(sizeof(int)*8)-1; ii++ ){
if( nRow & (1<<ii) ){
pIdxInfo->estimatedCost = (double)ii;
}

View File

@ -467,9 +467,10 @@ void sqlite3Update(
);
for(i=0; i<pTab->nCol; i++){
if( oldmask==0xffffffff
|| (i<32 && (oldmask & (1<<i)))
|| (i<32 && (oldmask & MASKBIT32(i))!=0)
|| (pTab->aCol[i].colFlags & COLFLAG_PRIMKEY)!=0
){
testcase( oldmask!=0xffffffff && i==31 );
sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, regOld+i);
}else{
sqlite3VdbeAddOp2(v, OP_Null, 0, regOld+i);
@ -504,7 +505,7 @@ void sqlite3Update(
j = aXRef[i];
if( j>=0 ){
sqlite3ExprCode(pParse, pChanges->a[j].pExpr, regNew+i);
}else if( 0==(tmask&TRIGGER_BEFORE) || i>31 || (newmask&(1<<i)) ){
}else if( 0==(tmask&TRIGGER_BEFORE) || i>31 || (newmask & MASKBIT32(i)) ){
/* This branch loads the value of a column that will not be changed
** into a register. This is done if there are no BEFORE triggers, or
** if there are one or more BEFORE triggers that use this value via

View File

@ -1001,7 +1001,8 @@ int sqlite3VarintLen(u64 v){
** Read or write a four-byte big-endian integer value.
*/
u32 sqlite3Get4byte(const u8 *p){
return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
testcase( p[0]&0x80 );
return ((unsigned)p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
}
void sqlite3Put4byte(unsigned char *p, u32 v){
p[0] = (u8)(v>>24);

View File

@ -6235,7 +6235,7 @@ case OP_Trace: {
if( zTrace ){
int i;
for(i=0; i<db->nDb; i++){
if( ((1<<i) & p->btreeMask)==0 ) continue;
if( MASKBIT(i) & p->btreeMask)==0 ) continue;
sqlite3_file_control(db, db->aDb[i].zName, SQLITE_FCNTL_TRACE, zTrace);
}
}

View File

@ -2616,8 +2616,9 @@ void sqlite3VdbeDeleteAuxData(Vdbe *pVdbe, int iOp, int mask){
while( *pp ){
AuxData *pAux = *pp;
if( (iOp<0)
|| (pAux->iOp==iOp && (pAux->iArg>31 || !(mask & ((u32)1<<pAux->iArg))))
|| (pAux->iOp==iOp && (pAux->iArg>31 || !(mask & MASKBIT32(pAux->iArg))))
){
testcase( pAux->iArg==31 );
if( pAux->xDelete ){
pAux->xDelete(pAux->pAux);
}
@ -2932,6 +2933,9 @@ u32 sqlite3VdbeSerialGet(
u32 serial_type, /* Serial type to deserialize */
Mem *pMem /* Memory cell to write value into */
){
u64 x;
u32 y;
int i;
switch( serial_type ){
case 10: /* Reserved for future use */
case 11: /* Reserved for future use */
@ -2945,23 +2949,26 @@ u32 sqlite3VdbeSerialGet(
return 1;
}
case 2: { /* 2-byte signed integer */
pMem->u.i = (((signed char)buf[0])<<8) | buf[1];
i = 256*(signed char)buf[0] | buf[1];
pMem->u.i = (i64)i;
pMem->flags = MEM_Int;
return 2;
}
case 3: { /* 3-byte signed integer */
pMem->u.i = (((signed char)buf[0])<<16) | (buf[1]<<8) | buf[2];
i = 65536*(signed char)buf[0] | (buf[1]<<8) | buf[2];
pMem->u.i = (i64)i;
pMem->flags = MEM_Int;
return 3;
}
case 4: { /* 4-byte signed integer */
pMem->u.i = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3];
y = ((unsigned)buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3];
pMem->u.i = (i64)*(int*)&y;
pMem->flags = MEM_Int;
return 4;
}
case 5: { /* 6-byte signed integer */
u64 x = (((signed char)buf[0])<<8) | buf[1];
u32 y = (buf[2]<<24) | (buf[3]<<16) | (buf[4]<<8) | buf[5];
x = 256*(signed char)buf[0] + buf[1];
y = ((unsigned)buf[2]<<24) | (buf[3]<<16) | (buf[4]<<8) | buf[5];
x = (x<<32) | y;
pMem->u.i = *(i64*)&x;
pMem->flags = MEM_Int;
@ -2969,8 +2976,6 @@ u32 sqlite3VdbeSerialGet(
}
case 6: /* 8-byte signed integer */
case 7: { /* IEEE floating point */
u64 x;
u32 y;
#if !defined(NDEBUG) && !defined(SQLITE_OMIT_FLOATING_POINT)
/* Verify that integers and floating point values use the same
** byte order. Or, that if SQLITE_MIXED_ENDIAN_64BIT_FLOAT is
@ -2983,9 +2988,8 @@ u32 sqlite3VdbeSerialGet(
swapMixedEndianFloat(t2);
assert( sizeof(r1)==sizeof(t2) && memcmp(&r1, &t2, sizeof(r1))==0 );
#endif
x = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3];
y = (buf[4]<<24) | (buf[5]<<16) | (buf[6]<<8) | buf[7];
x = ((unsigned)buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3];
y = ((unsigned)buf[4]<<24) | (buf[5]<<16) | (buf[6]<<8) | buf[7];
x = (x<<32) | y;
if( serial_type==6 ){
pMem->u.i = *(i64*)&x;

View File

@ -598,7 +598,7 @@ void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){
/*
** Size of struct Mem not including the Mem.zMalloc member.
*/
#define MEMCELLSIZE (size_t)(&(((Mem *)0)->zMalloc))
#define MEMCELLSIZE offsetof(Mem,zMalloc)
/*
** Make an shallow copy of pFrom into pTo. Prior contents of

View File

@ -15,51 +15,68 @@ set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix closure01
ifcapable !vtab { finish_test ; return }
ifcapable !vtab||!cte { finish_test ; return }
load_static_extension db closure
do_execsql_test 1.0 {
BEGIN;
CREATE TABLE t1(x INTEGER PRIMARY KEY, y INTEGER);
WITH RECURSIVE
cnt(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM cnt LIMIT 131072)
INSERT INTO t1(x, y) SELECT i, nullif(i,1)/2 FROM cnt;
CREATE INDEX t1y ON t1(y);
INSERT INTO t1(x) VALUES(1),(2);
INSERT INTO t1(x) SELECT x+2 FROM t1;
INSERT INTO t1(x) SELECT x+4 FROM t1;
INSERT INTO t1(x) SELECT x+8 FROM t1;
INSERT INTO t1(x) SELECT x+16 FROM t1;
INSERT INTO t1(x) SELECT x+32 FROM t1;
INSERT INTO t1(x) SELECT x+64 FROM t1;
INSERT INTO t1(x) SELECT x+128 FROM t1;
INSERT INTO t1(x) SELECT x+256 FROM t1;
INSERT INTO t1(x) SELECT x+512 FROM t1;
INSERT INTO t1(x) SELECT x+1024 FROM t1;
INSERT INTO t1(x) SELECT x+2048 FROM t1;
INSERT INTO t1(x) SELECT x+4096 FROM t1;
INSERT INTO t1(x) SELECT x+8192 FROM t1;
INSERT INTO t1(x) SELECT x+16384 FROM t1;
INSERT INTO t1(x) SELECT x+32768 FROM t1;
INSERT INTO t1(x) SELECT x+65536 FROM t1;
UPDATE t1 SET y=x/2 WHERE x>1;
COMMIT;
CREATE VIRTUAL TABLE cx
USING transitive_closure(tablename=t1, idcolumn=x, parentcolumn=y);
} {}
# The entire table
do_execsql_test 1.1 {
do_timed_execsql_test 1.1 {
SELECT count(*), depth FROM cx WHERE root=1 GROUP BY depth ORDER BY 1;
} {/1 0 1 17 2 1 4 2 8 3 16 4 .* 65536 16/}
do_timed_execsql_test 1.1-cte {
WITH RECURSIVE
below(id,depth) AS (
VALUES(1,0)
UNION ALL
SELECT t1.x, below.depth+1
FROM t1 JOIN below on t1.y=below.id
)
SELECT count(*), depth FROM below GROUP BY depth ORDER BY 1;
} {/1 0 1 17 2 1 4 2 8 3 16 4 .* 65536 16/}
# descendents of 32768
do_execsql_test 1.2 {
do_timed_execsql_test 1.2 {
SELECT * FROM cx WHERE root=32768 ORDER BY id;
} {32768 0 65536 1 65537 1 131072 2}
do_timed_execsql_test 1.2-cte {
WITH RECURSIVE
below(id,depth) AS (
VALUES(32768,0)
UNION ALL
SELECT t1.x, below.depth+1
FROM t1 JOIN below on t1.y=below.id
WHERE below.depth<2
)
SELECT id, depth FROM below ORDER BY id;
} {32768 0 65536 1 65537 1 131072 2}
# descendents of 16384
do_execsql_test 1.3 {
do_timed_execsql_test 1.3 {
SELECT * FROM cx WHERE root=16384 AND depth<=2 ORDER BY id;
} {16384 0 32768 1 32769 1 65536 2 65537 2 65538 2 65539 2}
do_timed_execsql_test 1.3-cte {
WITH RECURSIVE
below(id,depth) AS (
VALUES(16384,0)
UNION ALL
SELECT t1.x, below.depth+1
FROM t1 JOIN below on t1.y=below.id
WHERE below.depth<2
)
SELECT id, depth FROM below ORDER BY id;
} {16384 0 32768 1 32769 1 65536 2 65537 2 65538 2 65539 2}
# children of 16384
do_execsql_test 1.4 {
@ -70,19 +87,41 @@ do_execsql_test 1.4 {
} {32768 1 {} t1 x y 32769 1 {} t1 x y}
# great-grandparent of 16384
do_execsql_test 1.5 {
do_timed_execsql_test 1.5 {
SELECT id, depth, root, tablename, idcolumn, parentcolumn FROM cx
WHERE root=16384
AND depth=3
AND idcolumn='Y'
AND parentcolumn='X';
} {2048 3 {} t1 Y X}
do_timed_execsql_test 1.5-cte {
WITH RECURSIVE
above(id,depth) AS (
VALUES(16384,0)
UNION ALL
SELECT t1.y, above.depth+1
FROM t1 JOIN above ON t1.x=above.id
WHERE above.depth<3
)
SELECT id FROM above WHERE depth=3;
} {2048}
# depth<5
do_execsql_test 1.6 {
do_timed_execsql_test 1.6 {
SELECT count(*), depth FROM cx WHERE root=1 AND depth<5
GROUP BY depth ORDER BY 1;
} {1 0 2 1 4 2 8 3 16 4}
do_timed_execsql_test 1.6-cte {
WITH RECURSIVE
below(id,depth) AS (
VALUES(1,0)
UNION ALL
SELECT t1.x, below.depth+1
FROM t1 JOIN below ON t1.y=below.id
WHERE below.depth<4
)
SELECT count(*), depth FROM below GROUP BY depth ORDER BY 1;
} {1 0 2 1 4 2 8 3 16 4}
# depth<=5
do_execsql_test 1.7 {
@ -103,9 +142,20 @@ do_execsql_test 1.9 {
} {8 3 16 4 32 5}
# depth==5 with min() and max()
do_execsql_test 1.10 {
do_timed_execsql_test 1.10 {
SELECT count(*), min(id), max(id) FROM cx WHERE root=1 AND depth=5;
} {32 32 63}
do_timed_execsql_test 1.10-cte {
WITH RECURSIVE
below(id,depth) AS (
VALUES(1,0)
UNION ALL
SELECT t1.x, below.depth+1
FROM t1 JOIN below ON t1.y=below.id
WHERE below.depth<5
)
SELECT count(*), min(id), max(id) FROM below WHERE depth=5;
} {32 32 63}
# Create a much smaller table t2 with only 32 elements
db eval {

View File

@ -66,6 +66,7 @@ reset_db
# Initialize the database.
#
do_execsql_test 2.1 {
PRAGMA auto_vacuum=0;
PRAGMA page_size=1024;
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
@ -95,8 +96,31 @@ do_test 2.2 {
sqlite3 db test.db
} {}
# The corruption migration caused by the test case below does not
# cause corruption to be detected in mmap mode.
#
# The trick here is that the root page of the tree scanned by the outer
# query is also currently on the free-list. So while the first seek on
# the table (for a==1) works, by the time the second is attempted The
# "INSERT INTO t2..." statements have recycled the root page of t1 and
# used it as an index leaf. Normally, BtreeMovetoUnpacked() detects
# that the PgHdr object associated with said root page does not match
# the cursor (as it is now marked with PgHdr.intKey==0) and returns
# SQLITE_CORRUPT.
#
# However, in mmap mode, the outer query and the inner queries use
# different PgHdr objects (same data, but different PgHdr container
# objects). And so the corruption is not detected. Instead, the second
# seek fails to find anything and only a single row is returned.
#
set res23 {1 {database disk image is malformed}}
if {[permutation]=="mmap"} {
set res23 {0 one}
}
do_test 2.3 {
list [catch {
set res [list]
db eval { SELECT * FROM t1 WHERE a IN (1, 2) } {
db eval {
INSERT INTO t2 SELECT randomblob(100) FROM t2;
@ -105,9 +129,11 @@ do_test 2.3 {
INSERT INTO t2 SELECT randomblob(100) FROM t2;
INSERT INTO t2 SELECT randomblob(100) FROM t2;
}
lappend res $b
}
set res
} msg] $msg
} {1 {database disk image is malformed}}
} $res23
#-------------------------------------------------------------------------
reset_db

View File

@ -333,9 +333,9 @@ do_select_tests e_select-1.1 {
6 "SELECT count(*) WHERE 1" {1}
}
# EVIDENCE-OF: R-48114-33255 If there is only a single table in the
# join-source following the FROM clause, then the input data used by the
# SELECT statement is the contents of the named table.
# EVIDENCE-OF: R-45424-07352 If there is only a single table or subquery
# in the FROM clause, then the input data used by the SELECT statement
# is the contents of the named table.
#
# The results of the SELECT queries suggest that they are operating on the
# contents of the table 'xx'.
@ -357,10 +357,10 @@ do_select_tests e_select-1.2 {
3 "SELECT sum(x), sum(y) FROM xx" {-17.89 -16.87}
}
# EVIDENCE-OF: R-23593-12456 If there is more than one table specified
# as part of the join-source following the FROM keyword, then the
# contents of each named table are joined into a single dataset for the
# simple SELECT statement to operate on.
# EVIDENCE-OF: R-28355-09804 If there is more than one table or subquery
# in FROM clause then the contents of all tables and/or subqueries are
# joined into a single dataset for the simple SELECT statement to
# operate on.
#
# There are more detailed tests for subsequent requirements that add
# more detail to this idea. We just add a single test that shows that
@ -383,10 +383,10 @@ do_select_tests e_select-1.3 {
# of cartesian joins in the SELECT documentation is consistent with SQLite.
# In doing so, we test the following three requirements as a side-effect:
#
# EVIDENCE-OF: R-46122-14930 If the join-op is "CROSS JOIN", "INNER
# JOIN", "JOIN" or a comma (",") and there is no ON or USING clause,
# then the result of the join is simply the cartesian product of the
# left and right-hand datasets.
# EVIDENCE-OF: R-49872-03192 If the join-operator is "CROSS JOIN",
# "INNER JOIN", "JOIN" or a comma (",") and there is no ON or USING
# clause, then the result of the join is simply the cartesian product of
# the left and right-hand datasets.
#
# The tests are built on this assertion. Really, they test that the output
# of a CROSS JOIN, JOIN, INNER JOIN or "," join matches the expected result
@ -513,11 +513,10 @@ do_select_tests e_select-1.4.5 [list \
4 { SELECT * FROM t1 AS y INNER JOIN t1 AS x } $t1_cross_t1 \
]
# EVIDENCE-OF: R-22775-56496 If there is an ON clause specified, then
# the ON expression is evaluated for each row of the cartesian product
# as a boolean expression. All rows for which the expression evaluates
# to false are excluded from the dataset.
# EVIDENCE-OF: R-38465-03616 If there is an ON clause then the ON
# expression is evaluated for each row of the cartesian product as a
# boolean expression. Only rows for which the expression evaluates to
# true are included from the dataset.
#
foreach {tn select res} [list \
1 { SELECT * FROM t1 %JOIN% t2 ON (1) } $t1_cross_t2 \
@ -540,9 +539,9 @@ foreach {tn select res} [list \
do_join_test e_select-1.3.$tn $select $res
}
# EVIDENCE-OF: R-63358-54862 If there is a USING clause specified as
# part of the join-constraint, then each of the column names specified
# must exist in the datasets to both the left and right of the join-op.
# EVIDENCE-OF: R-49933-05137 If there is a USING clause then each of the
# column names specified must exist in the datasets to both the left and
# right of the join-operator.
#
do_select_tests e_select-1.4 -error {
cannot join using column %s - column not present in both tables
@ -552,10 +551,10 @@ do_select_tests e_select-1.4 -error {
3 { SELECT * FROM t3, (SELECT a AS b, b AS c FROM t1) USING (a) } "a"
}
# EVIDENCE-OF: R-55987-04584 For each pair of namesake columns, the
# EVIDENCE-OF: R-22776-52830 For each pair of named columns, the
# expression "lhs.X = rhs.X" is evaluated for each row of the cartesian
# product as a boolean expression. All rows for which one or more of the
# expressions evaluates to false are excluded from the result set.
# product as a boolean expression. Only rows for which all such
# expressions evaluates to true are included from the result set.
#
do_select_tests e_select-1.5 {
1 { SELECT * FROM t1, t3 USING (a) } {a one 1 b two 2}
@ -566,8 +565,8 @@ do_select_tests e_select-1.5 {
# USING clause, the normal rules for handling affinities, collation
# sequences and NULL values in comparisons apply.
#
# EVIDENCE-OF: R-35466-18578 The column from the dataset on the
# left-hand side of the join operator is considered to be on the
# EVIDENCE-OF: R-38422-04402 The column from the dataset on the
# left-hand side of the join-operator is considered to be on the
# left-hand side of the comparison operator (=) for the purposes of
# collation sequence and affinity precedence.
#
@ -622,10 +621,9 @@ foreach {tn select res} {
} {
do_join_test e_select-1.7.$tn $select $res
}
# EVIDENCE-OF: R-41434-12448 If the join-op is a "LEFT JOIN" or "LEFT
# OUTER JOIN", then after the ON or USING filtering clauses have been
# applied, an extra row is added to the output for each row in the
# EVIDENCE-OF: R-42531-52874 If the join-operator is a "LEFT JOIN" or
# "LEFT OUTER JOIN", then after the ON or USING filtering clauses have
# been applied, an extra row is added to the output for each row in the
# original left-hand input dataset that corresponds to no rows at all in
# the composite dataset (if any).
#
@ -660,8 +658,8 @@ do_select_tests e_select-1.9 {
2b "SELECT * FROM t7 LEFT JOIN t8 USING (a)" {x ex 24 abc 24 y why 25 {} {}}
}
# EVIDENCE-OF: R-01809-52134 If the NATURAL keyword is added to any of
# the join-ops, then an implicit USING clause is added to the
# EVIDENCE-OF: R-04932-55942 If the NATURAL keyword is in the
# join-operator then an implicit USING clause is added to the
# join-constraints. The implicit USING clause contains each of the
# column names that appear in both the left and right-hand input
# datasets.

View File

@ -344,10 +344,10 @@ foreach {tn indexes} {
catchsql { DROP INDEX i3 }
execsql $indexes
# EVIDENCE-OF: R-46122-14930 If the join-op is "CROSS JOIN", "INNER
# JOIN", "JOIN" or a comma (",") and there is no ON or USING clause,
# then the result of the join is simply the cartesian product of the
# left and right-hand datasets.
# EVIDENCE-OF: R-49872-03192 If the join-operator is "CROSS JOIN",
# "INNER JOIN", "JOIN" or a comma (",") and there is no ON or USING
# clause, then the result of the join is simply the cartesian product of
# the left and right-hand datasets.
#
# EVIDENCE-OF: R-46256-57243 There is no difference between the "INNER
# JOIN", "JOIN" and "," join operators.
@ -368,10 +368,10 @@ foreach {tn indexes} {
test_join $tn.1.11 "t2 CROSS JOIN t2 AS x" {t2 t2}
test_join $tn.1.12 "t2 JOIN t2 AS x" {t2 t2}
# EVIDENCE-OF: R-22775-56496 If there is an ON clause specified, then
# the ON expression is evaluated for each row of the cartesian product
# as a boolean expression. All rows for which the expression evaluates
# to false are excluded from the dataset.
# EVIDENCE-OF: R-38465-03616 If there is an ON clause then the ON
# expression is evaluated for each row of the cartesian product as a
# boolean expression. Only rows for which the expression evaluates to
# true are included from the dataset.
#
test_join $tn.2.1 "t1, t2 ON (t1.a=t2.a)" {t1 t2 -on {te_equals a a}}
test_join $tn.2.2 "t2, t1 ON (t1.a=t2.a)" {t2 t1 -on {te_equals a a}}
@ -504,14 +504,14 @@ do_execsql_test e_select-2.2.0 {
INSERT INTO t5 VALUES(2, 'two');
} {}
# EVIDENCE-OF: R-55824-40976 A sub-select specified in the join-source
# following the FROM clause in a simple SELECT statement is handled as
# if it was a table containing the data returned by executing the
# sub-select statement.
# EVIDENCE-OF: R-59237-46742 A subquery specified in the
# table-or-subquery following the FROM clause in a simple SELECT
# statement is handled as if it was a table containing the data returned
# by executing the subquery statement.
#
# EVIDENCE-OF: R-42612-06757 Each column of the sub-select dataset
# inherits the collation sequence and affinity of the corresponding
# expression in the sub-select statement.
# EVIDENCE-OF: R-27438-53558 Each column of the subquery has the
# collation sequence and affinity of the corresponding expression in the
# subquery statement.
#
foreach {tn subselect select spec} {
1 "SELECT * FROM t2" "SELECT * FROM t1 JOIN %ss%"

View File

@ -9,7 +9,7 @@
#
#***********************************************************************
#
# Tests for the SQLITE_IOERR_NODB error condition: the database file file
# Tests for the SQLITE_READONLY_DBMOVED error condition: the database file
# is unlinked or renamed out from under SQLite.
#
@ -18,6 +18,11 @@ if {$tcl_platform(platform)!="unix"} return
set testdir [file dirname $argv0]
source $testdir/tester.tcl
if {[permutation]=="inmemory_journal"} {
finish_test
return
}
# Create a database file for testing
#
do_execsql_test pager4-1.1 {

View File

@ -1544,5 +1544,6 @@ do_faultsim_test pagerfault-36 -prep {
sqlite3_shutdown
sqlite3_config_uri 0
sqlite3_initialize
finish_test

View File

@ -59,7 +59,7 @@ do_execsql_test printf2-1.11 {
SELECT printf('%lld%n',314159.2653,'hi');
} {314159}
# EVIDENCE-OF: R-20555-31089 The %z format is interchangable with %s.
# EVIDENCE-OF: R-17002-27534 The %z format is interchangeable with %s.
#
do_execsql_test printf2-1.12 {
SELECT printf('%.*z',5,'abcdefghijklmnop');

View File

@ -234,35 +234,37 @@ do_execsql_test 6.1.3 {
SELECT word, distance FROM t3 WHERE rowid = 10 AND word MATCH 'kiiner';
} {keener 300}
proc trace_callback {sql} {
if {[string range $sql 0 2] == "-- "} {
lappend ::trace [string range $sql 3 end]
ifcapable trace {
proc trace_callback {sql} {
if {[string range $sql 0 2] == "-- "} {
lappend ::trace [string range $sql 3 end]
}
}
proc do_tracesql_test {tn sql {res {}}} {
set ::trace [list]
uplevel [list do_test $tn [subst -nocommands {
set vals [execsql {$sql}]
concat [set vals] [set ::trace]
}] [list {*}$res]]
}
db trace trace_callback
do_tracesql_test 6.2.1 {
SELECT word FROM t3 WHERE rowid = 10;
} {keener
{SELECT word, rank, NULL, langid, id FROM "main"."t3_vocab" WHERE rowid=?}
}
do_tracesql_test 6.2.2 {
SELECT word, distance FROM t3 WHERE rowid = 10;
} {keener {}
{SELECT word, rank, NULL, langid, id FROM "main"."t3_vocab" WHERE rowid=?}
}
do_tracesql_test 6.2.3 {
SELECT word, distance FROM t3 WHERE rowid = 10 AND word MATCH 'kiiner';
} {keener 300
{SELECT id, word, rank, k1 FROM "main"."t3_vocab" WHERE langid=0 AND k2>=?1 AND k2<?2}
}
}
proc do_tracesql_test {tn sql {res {}}} {
set ::trace [list]
uplevel [list do_test $tn [subst -nocommands {
set vals [execsql {$sql}]
concat [set vals] [set ::trace]
}] [list {*}$res]]
}
db trace trace_callback
do_tracesql_test 6.2.1 {
SELECT word FROM t3 WHERE rowid = 10;
} {keener
{SELECT word, rank, NULL, langid, id FROM "main"."t3_vocab" WHERE rowid=?}
}
do_tracesql_test 6.2.2 {
SELECT word, distance FROM t3 WHERE rowid = 10;
} {keener {}
{SELECT word, rank, NULL, langid, id FROM "main"."t3_vocab" WHERE rowid=?}
}
do_tracesql_test 6.2.3 {
SELECT word, distance FROM t3 WHERE rowid = 10 AND word MATCH 'kiiner';
} {keener 300
{SELECT id, word, rank, k1 FROM "main"."t3_vocab" WHERE langid=0 AND k2>=?1 AND k2<?2}
}

View File

@ -59,6 +59,7 @@
# do_test TESTNAME SCRIPT EXPECTED
# do_execsql_test TESTNAME SQL EXPECTED
# do_catchsql_test TESTNAME SQL EXPECTED
# do_timed_execsql_test TESTNAME SQL EXPECTED
#
# Commands providing a lower level interface to the global test counters:
#
@ -723,6 +724,11 @@ proc do_catchsql_test {testname sql result} {
fix_testname testname
uplevel do_test [list $testname] [list "catchsql {$sql}"] [list $result]
}
proc do_timed_execsql_test {testname sql {result {}}} {
fix_testname testname
uplevel do_test [list $testname] [list "execsql_timed {$sql}"]\
[list [list {*}$result]]
}
proc do_eqp_test {name sql res} {
uplevel do_execsql_test $name [list "EXPLAIN QUERY PLAN $sql"] [list $res]
}
@ -1019,6 +1025,14 @@ proc execsql {sql {db db}} {
# puts "SQL = $sql"
uplevel [list $db eval $sql]
}
proc execsql_timed {sql {db db}} {
set tm [time {
set x [uplevel [list $db eval $sql]]
} 1]
set tm [lindex $tm 0]
puts -nonewline " ([expr {$tm*0.001}]ms) "
set x
}
# Execute SQL and catch exceptions.
#

View File

@ -452,11 +452,256 @@ do_execsql_test 8.2-soduko {
SELECT s FROM x WHERE ind=0;
} {534678912672195348198342567859761423426853791713924856961537284287419635345286179}
#--------------------------------------------------------------------------
# Some tests that use LIMIT and OFFSET in the definition of recursive CTEs.
#
set I [list 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20]
proc limit_test {tn iLimit iOffset} {
if {$iOffset < 0} { set iOffset 0 }
if {$iLimit < 0 } {
set result [lrange $::I $iOffset end]
} else {
set result [lrange $::I $iOffset [expr $iLimit+$iOffset-1]]
}
uplevel [list do_execsql_test $tn [subst -nocommands {
WITH ii(a) AS (
VALUES(1)
UNION ALL
SELECT a+1 FROM ii WHERE a<20
LIMIT $iLimit OFFSET $iOffset
)
SELECT * FROM ii
}] $result]
}
limit_test 9.1 20 0
limit_test 9.2 0 0
limit_test 9.3 19 1
limit_test 9.4 20 -1
limit_test 9.5 5 5
limit_test 9.6 0 -1
limit_test 9.7 40 -1
limit_test 9.8 -1 -1
limit_test 9.9 -1 -1
#--------------------------------------------------------------------------
# Test the ORDER BY clause on recursive tables.
#
do_execsql_test 10.1 {
DROP TABLE IF EXISTS tree;
CREATE TABLE tree(id INTEGER PRIMARY KEY, parentid, payload);
}
proc insert_into_tree {L} {
db eval { DELETE FROM tree }
foreach key $L {
unset -nocomplain parentid
foreach seg [split $key /] {
if {$seg==""} continue
set id [db one {
SELECT id FROM tree WHERE parentid IS $parentid AND payload=$seg
}]
if {$id==""} {
db eval { INSERT INTO tree VALUES(NULL, $parentid, $seg) }
set parentid [db last_insert_rowid]
} else {
set parentid $id
}
}
}
}
insert_into_tree {
/a/a/a
/a/b/c
/a/b/c/d
/a/b/d
}
do_execsql_test 10.2 {
WITH flat(fid, p) AS (
SELECT id, '/' || payload FROM tree WHERE parentid IS NULL
UNION ALL
SELECT id, p || '/' || payload FROM flat, tree WHERE parentid=fid
)
SELECT p FROM flat ORDER BY p;
} {
/a /a/a /a/a/a
/a/b /a/b/c /a/b/c/d
/a/b/d
}
# Scan the tree-structure currently stored in table tree. Return a list
# of nodes visited.
#
proc scan_tree {bDepthFirst bReverse} {
set order "ORDER BY "
if {$bDepthFirst==0} { append order "2 ASC," }
if {$bReverse==0} {
append order " 3 ASC"
} else {
append order " 3 DESC"
}
db eval "
WITH flat(fid, depth, p) AS (
SELECT id, 1, '/' || payload FROM tree WHERE parentid IS NULL
UNION ALL
SELECT id, depth+1, p||'/'||payload FROM flat, tree WHERE parentid=fid
$order
)
SELECT p FROM flat;
"
}
insert_into_tree {
/a/b
/a/b/c
/a/d
/a/d/e
/a/d/f
/g/h
}
# Breadth first, siblings in ascending order.
#
do_test 10.3 {
scan_tree 0 0
} [list {*}{
/a /g
/a/b /a/d /g/h
/a/b/c /a/d/e /a/d/f
}]
# Depth first, siblings in ascending order.
#
do_test 10.4 {
scan_tree 1 0
} [list {*}{
/a /a/b /a/b/c
/a/d /a/d/e
/a/d/f
/g /g/h
}]
# Breadth first, siblings in descending order.
#
do_test 10.5 {
scan_tree 0 1
} [list {*}{
/g /a
/g/h /a/d /a/b
/a/d/f /a/d/e /a/b/c
}]
# Depth first, siblings in ascending order.
#
do_test 10.6 {
scan_tree 1 1
} [list {*}{
/g /g/h
/a /a/d /a/d/f
/a/d/e
/a/b /a/b/c
}]
# Test name resolution in ORDER BY clauses.
#
do_catchsql_test 10.7.1 {
WITH t(a) AS (
SELECT 1 AS b UNION ALL SELECT a+1 AS c FROM t WHERE a<5 ORDER BY a
)
SELECT * FROM t
} {1 {1st ORDER BY term does not match any column in the result set}}
do_execsql_test 10.7.2 {
WITH t(a) AS (
SELECT 1 AS b UNION ALL SELECT a+1 AS c FROM t WHERE a<5 ORDER BY b
)
SELECT * FROM t
} {1 2 3 4 5}
do_execsql_test 10.7.3 {
WITH t(a) AS (
SELECT 1 AS b UNION ALL SELECT a+1 AS c FROM t WHERE a<5 ORDER BY c
)
SELECT * FROM t
} {1 2 3 4 5}
# Test COLLATE clauses attached to ORDER BY.
#
insert_into_tree {
/a/b
/a/C
/a/d
/B/e
/B/F
/B/g
/c/h
/c/I
/c/j
}
do_execsql_test 10.8.1 {
WITH flat(fid, depth, p) AS (
SELECT id, 1, '/' || payload FROM tree WHERE parentid IS NULL
UNION ALL
SELECT id, depth+1, p||'/'||payload FROM flat, tree WHERE parentid=fid
ORDER BY 2, 3 COLLATE nocase
)
SELECT p FROM flat;
} {
/a /B /c
/a/b /a/C /a/d /B/e /B/F /B/g /c/h /c/I /c/j
}
do_execsql_test 10.8.2 {
WITH flat(fid, depth, p) AS (
SELECT id, 1, ('/' || payload) COLLATE nocase
FROM tree WHERE parentid IS NULL
UNION ALL
SELECT id, depth+1, (p||'/'||payload)
FROM flat, tree WHERE parentid=fid
ORDER BY 2, 3
)
SELECT p FROM flat;
} {
/a /B /c
/a/b /a/C /a/d /B/e /B/F /B/g /c/h /c/I /c/j
}
do_execsql_test 10.8.3 {
WITH flat(fid, depth, p) AS (
SELECT id, 1, ('/' || payload)
FROM tree WHERE parentid IS NULL
UNION ALL
SELECT id, depth+1, (p||'/'||payload) COLLATE nocase
FROM flat, tree WHERE parentid=fid
ORDER BY 2, 3
)
SELECT p FROM flat;
} {
/a /B /c
/a/b /a/C /a/d /B/e /B/F /B/g /c/h /c/I /c/j
}
do_execsql_test 10.8.4.1 {
CREATE TABLE tst(a,b);
INSERT INTO tst VALUES('a', 'A');
INSERT INTO tst VALUES('b', 'B');
INSERT INTO tst VALUES('c', 'C');
SELECT a COLLATE nocase FROM tst UNION ALL SELECT b FROM tst ORDER BY 1;
} {a A b B c C}
do_execsql_test 10.8.4.2 {
SELECT a FROM tst UNION ALL SELECT b COLLATE nocase FROM tst ORDER BY 1;
} {A B C a b c}
do_execsql_test 10.8.4.3 {
SELECT a||'' FROM tst UNION ALL SELECT b COLLATE nocase FROM tst ORDER BY 1;
} {a A b B c C}
# Test cases to illustrate on the ORDER BY clause on a recursive query can be
# used to control depth-first versus breath-first search in a tree.
#
do_execsql_test 9.1 {
do_execsql_test 11.1 {
CREATE TABLE org(
name TEXT PRIMARY KEY,
boss TEXT REFERENCES org
@ -513,7 +758,7 @@ do_execsql_test 9.1 {
# The previous query used "ORDER BY level" to yield a breath-first search.
# Change that to "ORDER BY level DESC" for a depth-first search.
#
do_execsql_test 9.2 {
do_execsql_test 11.2 {
WITH RECURSIVE
under_alice(name,level) AS (
VALUES('Alice','0')
@ -544,7 +789,7 @@ do_execsql_test 9.2 {
# Without an ORDER BY clause, the recursive query should use a FIFO,
# resulting in a breath-first search.
#
do_execsql_test 9.3 {
do_execsql_test 11.3 {
WITH RECURSIVE
under_alice(name,level) AS (
VALUES('Alice','0')
@ -572,3 +817,4 @@ do_execsql_test 9.3 {
.........Olivia}}
finish_test

View File

@ -190,6 +190,7 @@ proc main {argv} {
SQLITE_OMIT_COMPILEOPTION_DIAGS \
SQLITE_OMIT_COMPLETE \
SQLITE_OMIT_COMPOUND_SELECT \
SQLITE_OMIT_CTE \
SQLITE_OMIT_DATETIME_FUNCS \
SQLITE_OMIT_DECLTYPE \
SQLITE_OMIT_DEPRECATED \