From a5907a86b8d7bc298e2106a03e2d89e657d0b8d2 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 19 Jun 2017 11:44:22 +0000 Subject: [PATCH 01/64] Experimental "PRAGMA secure_delete=FAST" pragma. The intent is to overwrite deleted content with zeros without increasing the amount of disk I/O. FossilOrigin-Name: f1682f0faf1a93ded066464b1ddd5f987e21ee0f6bb5e828ed31c3ad903cf2c3 --- manifest | 19 +++++++++++-------- manifest.uuid | 2 +- src/btree.c | 39 ++++++++++++++++++++++++++++----------- src/btreeInt.h | 10 ++++++---- src/pragma.c | 10 +++++++--- 5 files changed, 53 insertions(+), 27 deletions(-) diff --git a/manifest b/manifest index 7ff1732e8e..bf0d4f677a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\smissing\scomma\sin\sthe\sprevious\scheck-in. -D 2017-06-17T18:49:50.823 +C Experimental\s"PRAGMA\ssecure_delete=FAST"\spragma.\s\sThe\sintent\sis\sto\soverwrite\ndeleted\scontent\swith\szeros\swithout\sincreasing\sthe\samount\sof\sdisk\sI/O. +D 2017-06-19T11:44:22.399 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 8eeb80162074004e906b53d7340a12a14c471a83743aab975947e95ce061efcc @@ -348,9 +348,9 @@ F src/auth.c 79f96c6f33bf0e5da8d1c282cee5ebb1852bb8a6ccca3e485d7c459b035d9c3c F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca -F src/btree.c 430e34151e6ef37e42d3f956bb062907c80ff91e1380704b967b8c1a02a98f64 +F src/btree.c 127ae15b6328376fa549a2ead30a3ec20db31fe991a287c42cf394965f55fff0 F src/btree.h 3edc5329bc59534d2d15b4f069a9f54b779a7e51289e98fa481ae3c0e526a5ca -F src/btreeInt.h a392d353104b4add58b4a59cb185f5d5693dde832c565b77d8d4c343ed98f610 +F src/btreeInt.h 97700795edf8a43245720414798b7b29d8e465aef46bf301ffacd431910c0da1 F src/build.c 88a8cdc11d1c081ed565aa3e795bdf9160f4556463b4c4555e9860b59dd80340 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e @@ -398,7 +398,7 @@ F src/parse.y 0513387ce02fea97897d8caef82d45f347818593f24f1bdc48e0c530a8af122d F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870 F src/pcache.h 521bb9610d38ef17a3cc9b5ddafd4546c2ea67fa3d0e464823d73c2a28d50e11 F src/pcache1.c 1195a21fe28e223e024f900b2011e80df53793f0356a24caace4188b098540dc -F src/pragma.c 2362670a9d28b71708aecb2b9b10b3f7be71f4c950961c07e81dc400e3ce6371 +F src/pragma.c b5483eba1898652d330231164c17624a93e7a991b2f5c7e8a80f9d85528b308c F src/pragma.h 37a1311d0388db480388d7ec09054f7103045eff20d4971f8a433b77f40b9921 F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a F src/printf.c 8757834f1b54dae512fb25eb1acc8e94a0d15dd2290b58f2563f65973265adb2 @@ -1583,7 +1583,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9a443397a6b110f60cae32e1f758914d72931e16ddb423e4d4a119df526bf340 -R 48cf46cf5e03c592f1eb729aae9e27b1 +P f3db02f49073c3f08c3fd7816d85e5472d5e22df20d862fe4886eb2a97efb15f +R bfe3d3db972c98c6ca95dc686a1c98c9 +T *branch * fast-secure-delete +T *sym-fast-secure-delete * +T -sym-trunk * U drh -Z 1075564756c6da5b66b28900b7b4b32b +Z 1665a7b13a5f9ef4377c01699ae7453e diff --git a/manifest.uuid b/manifest.uuid index 64f264fc2c..d384d6edc5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f3db02f49073c3f08c3fd7816d85e5472d5e22df20d862fe4886eb2a97efb15f \ No newline at end of file +f1682f0faf1a93ded066464b1ddd5f987e21ee0f6bb5e828ed31c3ad903cf2c3 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 1f06e45031..05fea69050 100644 --- a/src/btree.c +++ b/src/btree.c @@ -1640,7 +1640,7 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){ /* Overwrite deleted information with zeros when the secure_delete ** option is enabled */ - if( pPage->pBt->btsFlags & BTS_SECURE_DELETE ){ + if( pPage->pBt->btsFlags & BTS_FAST_SECURE ){ memset(&data[iStart], 0, iSize); } @@ -1931,7 +1931,7 @@ static void zeroPage(MemPage *pPage, int flags){ assert( sqlite3PagerGetData(pPage->pDbPage) == data ); assert( sqlite3PagerIswriteable(pPage->pDbPage) ); assert( sqlite3_mutex_held(pBt->mutex) ); - if( pBt->btsFlags & BTS_SECURE_DELETE ){ + if( pBt->btsFlags & BTS_FAST_SECURE ){ memset(&data[hdr], 0, pBt->usableSize - hdr); } data[hdr] = (char)flags; @@ -2354,8 +2354,10 @@ int sqlite3BtreeOpen( pBt->pCursor = 0; pBt->pPage1 = 0; if( sqlite3PagerIsreadonly(pBt->pPager) ) pBt->btsFlags |= BTS_READ_ONLY; -#ifdef SQLITE_SECURE_DELETE +#if defined(SQLITE_SECURE_DELETE) pBt->btsFlags |= BTS_SECURE_DELETE; +#elif defined(SQLITE_FAST_SECURE_DELETE) + pBt->btsFlags |= BTS_OVERWRITE; #endif /* EVIDENCE-OF: R-51873-39618 The page size for a database file is ** determined by the 2-byte integer located at an offset of 16 bytes from @@ -2803,19 +2805,34 @@ int sqlite3BtreeMaxPageCount(Btree *p, int mxPage){ } /* -** Set the BTS_SECURE_DELETE flag if newFlag is 0 or 1. If newFlag is -1, -** then make no changes. Always return the value of the BTS_SECURE_DELETE -** setting after the change. +** Change the values for the BTS_SECURE_DELETE and BTS_OVERWRITE flags: +** +** newFlag==0 Both BTS_SECURE_DELETE and BTS_OVERWRITE are cleared +** newFlag==1 BTS_SECURE_DELETE set and BTS_OVERWRITE is cleared +** newFlag==2 BTS_SECURE_DELETE cleared and BTS_OVERWRITE is set +** newFlag==(-1) No changes +** +** This routine acts as a query if newFlag is less than zero +** +** With BTS_OVERWRITE set, deleted content is overwritten by zeros, but +** freelist leaf pages are not written back to the database. Thus in-page +** deleted content is cleared, but freelist deleted content is not. +** +** With BTS_SECURE_DELETE, operation is like BTS_OVERWRITE with the addition +** that freelist leaf pages are written back into the database, increasing +** the amount of disk I/O. */ int sqlite3BtreeSecureDelete(Btree *p, int newFlag){ int b; if( p==0 ) return 0; sqlite3BtreeEnter(p); + assert( BTS_OVERWRITE==BTS_SECURE_DELETE*2 ); + assert( BTS_FAST_SECURE==(BTS_OVERWRITE|BTS_SECURE_DELETE) ); if( newFlag>=0 ){ - p->pBt->btsFlags &= ~BTS_SECURE_DELETE; - if( newFlag ) p->pBt->btsFlags |= BTS_SECURE_DELETE; - } - b = (p->pBt->btsFlags & BTS_SECURE_DELETE)!=0; + p->pBt->btsFlags &= ~BTS_FAST_SECURE; + p->pBt->btsFlags |= BTS_SECURE_DELETE*newFlag; + } + b = (p->pBt->btsFlags & BTS_FAST_SECURE)/BTS_SECURE_DELETE; sqlite3BtreeLeave(p); return b; } @@ -7210,7 +7227,7 @@ static int balance_nonroot( ** In this case, temporarily copy the cell into the aOvflSpace[] ** buffer. It will be copied out again as soon as the aSpace[] buffer ** is allocated. */ - if( pBt->btsFlags & BTS_SECURE_DELETE ){ + if( pBt->btsFlags & BTS_FAST_SECURE ){ int iOff; iOff = SQLITE_PTR_TO_INT(apDiv[i]) - SQLITE_PTR_TO_INT(pParent->aData); diff --git a/src/btreeInt.h b/src/btreeInt.h index 47de58f509..77069783c7 100644 --- a/src/btreeInt.h +++ b/src/btreeInt.h @@ -448,10 +448,12 @@ struct BtShared { #define BTS_READ_ONLY 0x0001 /* Underlying file is readonly */ #define BTS_PAGESIZE_FIXED 0x0002 /* Page size can no longer be changed */ #define BTS_SECURE_DELETE 0x0004 /* PRAGMA secure_delete is enabled */ -#define BTS_INITIALLY_EMPTY 0x0008 /* Database was empty at trans start */ -#define BTS_NO_WAL 0x0010 /* Do not open write-ahead-log files */ -#define BTS_EXCLUSIVE 0x0020 /* pWriter has an exclusive lock */ -#define BTS_PENDING 0x0040 /* Waiting for read-locks to clear */ +#define BTS_OVERWRITE 0x0008 /* Overwrite deleted content with zeros */ +#define BTS_FAST_SECURE 0x000c /* Combination of the previous two */ +#define BTS_INITIALLY_EMPTY 0x0010 /* Database was empty at trans start */ +#define BTS_NO_WAL 0x0020 /* Do not open write-ahead-log files */ +#define BTS_EXCLUSIVE 0x0040 /* pWriter has an exclusive lock */ +#define BTS_PENDING 0x0080 /* Waiting for read-locks to clear */ /* ** An instance of the following structure is used to hold information diff --git a/src/pragma.c b/src/pragma.c index 945fd2d4a7..6ab6567010 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -515,18 +515,22 @@ void sqlite3Pragma( /* ** PRAGMA [schema.]secure_delete - ** PRAGMA [schema.]secure_delete=ON/OFF + ** PRAGMA [schema.]secure_delete=ON/OFF/FAST ** ** The first form reports the current setting for the ** secure_delete flag. The second form changes the secure_delete - ** flag setting and reports thenew value. + ** flag setting and reports the new value. */ case PragTyp_SECURE_DELETE: { Btree *pBt = pDb->pBt; int b = -1; assert( pBt!=0 ); if( zRight ){ - b = sqlite3GetBoolean(zRight, 0); + if( sqlite3_stricmp(zRight, "fast")==0 ){ + b = 2; + }else{ + b = sqlite3GetBoolean(zRight, 0); + } } if( pId2->n==0 && b>=0 ){ int ii; From ab53bb635cda0ca798d3ebdd9d7fc3a4ed8854e9 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 7 Jul 2017 15:43:22 +0000 Subject: [PATCH 02/64] Add new pragmas: "function_list" and "module_list" FossilOrigin-Name: e5f01d7fde05fdb547f35816ff15c31a92c170b31877f4c640b7bc2be3f580b3 --- manifest | 19 ++++--- manifest.uuid | 2 +- src/pragma.c | 34 +++++++++++ src/pragma.h | 133 +++++++++++++++++++++++++------------------ tool/mkpragmatab.tcl | 11 ++++ 5 files changed, 134 insertions(+), 65 deletions(-) diff --git a/manifest b/manifest index 3c5acab3f4..0faff6d8bf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Exploit\sthe\sfact\sthat\sExpr.pRight\sand\sExpr.x\sare\snever\sused\sat\sthe\ssame\stime\nfor\sa\ssmall\sperformance\sgain. -D 2017-07-07T13:59:34.309 +C Add\snew\spragmas:\s"function_list"\sand\s"module_list" +D 2017-07-07T15:43:22.754 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 4ebb1d257cac7fb1bcb4ba59278416d410ff1c4bf59447a9c37a415f3516056a @@ -441,8 +441,8 @@ F src/parse.y 71bf06b02f567232deabe258641b03e833e93c4dee61a120765ad74c13e7faec F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870 F src/pcache.h 521bb9610d38ef17a3cc9b5ddafd4546c2ea67fa3d0e464823d73c2a28d50e11 F src/pcache1.c 1195a21fe28e223e024f900b2011e80df53793f0356a24caace4188b098540dc -F src/pragma.c 2362670a9d28b71708aecb2b9b10b3f7be71f4c950961c07e81dc400e3ce6371 -F src/pragma.h 99d3df4a3d2f12c5227ad403f767334910e6356325b6d155a9a99b4037093460 +F src/pragma.c 415a98ec60bd209b69e502f07f1c7b9a84140d7e44332202367b2d60e7c30e60 +F src/pragma.h 0d5573ec6c5aa8e65a7d1b33055b868295f16d1ee6aa754754fc1fc75ececd1a F src/prepare.c 4b84ae7458febe1df3e04ae62ba56abc851f771340e460d14426e6802c5615f4 F src/printf.c 8757834f1b54dae512fb25eb1acc8e94a0d15dd2290b58f2563f65973265adb2 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 @@ -1566,7 +1566,7 @@ F tool/mkmsvcmin.tcl cbd93f1cfa3a0a9ae56fc958510aa3fc3ac65e29cb111716199e3d0e66e F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c F tool/mkopcodeh.tcl a01d2c1d8a6205b03fc635adf3735b4c523befd3 F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e -F tool/mkpragmatab.tcl aa94395a91b5bd47022b7db0c08126f047887e0d299cc19ec1c23a9e5b136961 +F tool/mkpragmatab.tcl 3707a9586c5f3fccded77ac23b9f1672785f43c9bc0c1f49845bb81dbf8118d5 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl fef88397668ae83166735c41af99d79f56afaabb F tool/mksqlite3c.tcl f6214285bec900d28441366ca31af327aade18bbc424b0480497966ec05bc43c @@ -1628,7 +1628,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 115d4b83392d346634866dd959bef30fca50db2e526df17eaeb3d94da7fc895e -R 582e201382f2bd562c6f1266d901f884 +P aacbb9a461fdb34c7f9c8ce348e44c3e96c93334f210d438d92bfac1794dc686 +R 0f36dd9733d38244f7ca6a934ae9744a +T *branch * list-pragmas +T *sym-list-pragmas * +T -sym-trunk * U drh -Z 92ef67718e1f4940d85eca215e487e0c +Z 4e2b289a760c670e9cafd6cf4ad4b9b9 diff --git a/manifest.uuid b/manifest.uuid index 9b3f91218c..f1a5df0c43 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -aacbb9a461fdb34c7f9c8ce348e44c3e96c93334f210d438d92bfac1794dc686 \ No newline at end of file +e5f01d7fde05fdb547f35816ff15c31a92c170b31877f4c640b7bc2be3f580b3 \ No newline at end of file diff --git a/src/pragma.c b/src/pragma.c index 945fd2d4a7..0c81252146 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1225,6 +1225,40 @@ void sqlite3Pragma( } } break; + + case PragTyp_FUNCTION_LIST: { + int i; + HashElem *j; + FuncDef *p; + pParse->nMem = 2; + for(i=0; iu.pHash ){ + sqlite3VdbeMultiLoad(v, 1, "si", p->zName, 1); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 2); + } + } + for(j=sqliteHashFirst(&db->aFunc); j; j=sqliteHashNext(j)){ + p = (FuncDef*)sqliteHashData(j); + sqlite3VdbeMultiLoad(v, 1, "si", p->zName, 0); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 2); + } + } + break; + +#ifndef SQLITE_OMIT_VIRTUALTABLE + case PragTyp_MODULE_LIST: { + HashElem *j; + pParse->nMem = 1; + for(j=sqliteHashFirst(&db->aModule); j; j=sqliteHashNext(j)){ + Module *pMod = (Module*)sqliteHashData(j); + sqlite3VdbeMultiLoad(v, 1, "s", pMod->zName); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); + } + } + break; +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + + #endif /* SQLITE_OMIT_SCHEMA_PRAGMAS */ #ifndef SQLITE_OMIT_FOREIGN_KEY diff --git a/src/pragma.h b/src/pragma.h index 76e59cbc6b..42ad7df3c5 100644 --- a/src/pragma.h +++ b/src/pragma.h @@ -20,35 +20,37 @@ #define PragTyp_ENCODING 12 #define PragTyp_FOREIGN_KEY_CHECK 13 #define PragTyp_FOREIGN_KEY_LIST 14 -#define PragTyp_INCREMENTAL_VACUUM 15 -#define PragTyp_INDEX_INFO 16 -#define PragTyp_INDEX_LIST 17 -#define PragTyp_INTEGRITY_CHECK 18 -#define PragTyp_JOURNAL_MODE 19 -#define PragTyp_JOURNAL_SIZE_LIMIT 20 -#define PragTyp_LOCK_PROXY_FILE 21 -#define PragTyp_LOCKING_MODE 22 -#define PragTyp_PAGE_COUNT 23 -#define PragTyp_MMAP_SIZE 24 -#define PragTyp_OPTIMIZE 25 -#define PragTyp_PAGE_SIZE 26 -#define PragTyp_SECURE_DELETE 27 -#define PragTyp_SHRINK_MEMORY 28 -#define PragTyp_SOFT_HEAP_LIMIT 29 -#define PragTyp_SYNCHRONOUS 30 -#define PragTyp_TABLE_INFO 31 -#define PragTyp_TEMP_STORE 32 -#define PragTyp_TEMP_STORE_DIRECTORY 33 -#define PragTyp_THREADS 34 -#define PragTyp_WAL_AUTOCHECKPOINT 35 -#define PragTyp_WAL_CHECKPOINT 36 -#define PragTyp_ACTIVATE_EXTENSIONS 37 -#define PragTyp_HEXKEY 38 -#define PragTyp_KEY 39 -#define PragTyp_REKEY 40 -#define PragTyp_LOCK_STATUS 41 -#define PragTyp_PARSER_TRACE 42 -#define PragTyp_STATS 43 +#define PragTyp_FUNCTION_LIST 15 +#define PragTyp_INCREMENTAL_VACUUM 16 +#define PragTyp_INDEX_INFO 17 +#define PragTyp_INDEX_LIST 18 +#define PragTyp_INTEGRITY_CHECK 19 +#define PragTyp_JOURNAL_MODE 20 +#define PragTyp_JOURNAL_SIZE_LIMIT 21 +#define PragTyp_LOCK_PROXY_FILE 22 +#define PragTyp_LOCKING_MODE 23 +#define PragTyp_PAGE_COUNT 24 +#define PragTyp_MMAP_SIZE 25 +#define PragTyp_MODULE_LIST 26 +#define PragTyp_OPTIMIZE 27 +#define PragTyp_PAGE_SIZE 28 +#define PragTyp_SECURE_DELETE 29 +#define PragTyp_SHRINK_MEMORY 30 +#define PragTyp_SOFT_HEAP_LIMIT 31 +#define PragTyp_SYNCHRONOUS 32 +#define PragTyp_TABLE_INFO 33 +#define PragTyp_TEMP_STORE 34 +#define PragTyp_TEMP_STORE_DIRECTORY 35 +#define PragTyp_THREADS 36 +#define PragTyp_WAL_AUTOCHECKPOINT 37 +#define PragTyp_WAL_CHECKPOINT 38 +#define PragTyp_ACTIVATE_EXTENSIONS 39 +#define PragTyp_HEXKEY 40 +#define PragTyp_KEY 41 +#define PragTyp_REKEY 42 +#define PragTyp_LOCK_STATUS 43 +#define PragTyp_PARSER_TRACE 44 +#define PragTyp_STATS 45 /* Property flags associated with various pragma. */ #define PragFlg_NeedSchema 0x01 /* Force schema load before running */ @@ -94,26 +96,29 @@ static const char *const pragCName[] = { /* 26 */ "seq", /* Used by: database_list */ /* 27 */ "name", /* 28 */ "file", - /* 29 */ "seq", /* Used by: collation_list */ - /* 30 */ "name", - /* 31 */ "id", /* Used by: foreign_key_list */ - /* 32 */ "seq", - /* 33 */ "table", - /* 34 */ "from", - /* 35 */ "to", - /* 36 */ "on_update", - /* 37 */ "on_delete", - /* 38 */ "match", - /* 39 */ "table", /* Used by: foreign_key_check */ - /* 40 */ "rowid", - /* 41 */ "parent", - /* 42 */ "fkid", - /* 43 */ "busy", /* Used by: wal_checkpoint */ - /* 44 */ "log", - /* 45 */ "checkpointed", - /* 46 */ "timeout", /* Used by: busy_timeout */ - /* 47 */ "database", /* Used by: lock_status */ - /* 48 */ "status", + /* 29 */ "name", /* Used by: function_list */ + /* 30 */ "builtin", + /* 31 */ "name", /* Used by: module_list */ + /* 32 */ "seq", /* Used by: collation_list */ + /* 33 */ "name", + /* 34 */ "id", /* Used by: foreign_key_list */ + /* 35 */ "seq", + /* 36 */ "table", + /* 37 */ "from", + /* 38 */ "to", + /* 39 */ "on_update", + /* 40 */ "on_delete", + /* 41 */ "match", + /* 42 */ "table", /* Used by: foreign_key_check */ + /* 43 */ "rowid", + /* 44 */ "parent", + /* 45 */ "fkid", + /* 46 */ "busy", /* Used by: wal_checkpoint */ + /* 47 */ "log", + /* 48 */ "checkpointed", + /* 49 */ "timeout", /* Used by: busy_timeout */ + /* 50 */ "database", /* Used by: lock_status */ + /* 51 */ "status", }; /* Definitions of all built-in pragmas */ @@ -159,7 +164,7 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "busy_timeout", /* ePragTyp: */ PragTyp_BUSY_TIMEOUT, /* ePragFlg: */ PragFlg_Result0, - /* ColNames: */ 46, 1, + /* ColNames: */ 49, 1, /* iArg: */ 0 }, #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) {/* zName: */ "cache_size", @@ -196,7 +201,7 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "collation_list", /* ePragTyp: */ PragTyp_COLLATION_LIST, /* ePragFlg: */ PragFlg_Result0, - /* ColNames: */ 29, 2, + /* ColNames: */ 32, 2, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS) @@ -268,14 +273,14 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "foreign_key_check", /* ePragTyp: */ PragTyp_FOREIGN_KEY_CHECK, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0, - /* ColNames: */ 39, 4, + /* ColNames: */ 42, 4, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FOREIGN_KEY) {/* zName: */ "foreign_key_list", /* ePragTyp: */ PragTyp_FOREIGN_KEY_LIST, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, - /* ColNames: */ 31, 8, + /* ColNames: */ 34, 8, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) @@ -306,6 +311,13 @@ static const PragmaName aPragmaName[] = { /* ColNames: */ 0, 0, /* iArg: */ SQLITE_FullFSync }, #endif +#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) + {/* zName: */ "function_list", + /* ePragTyp: */ PragTyp_FUNCTION_LIST, + /* ePragFlg: */ PragFlg_Result0, + /* ColNames: */ 29, 2, + /* iArg: */ 0 }, +#endif #if defined(SQLITE_HAS_CODEC) {/* zName: */ "hexkey", /* ePragTyp: */ PragTyp_HEXKEY, @@ -395,7 +407,7 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "lock_status", /* ePragTyp: */ PragTyp_LOCK_STATUS, /* ePragFlg: */ PragFlg_Result0, - /* ColNames: */ 47, 2, + /* ColNames: */ 50, 2, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) @@ -414,6 +426,15 @@ static const PragmaName aPragmaName[] = { /* ePragFlg: */ 0, /* ColNames: */ 0, 0, /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) +#if !defined(SQLITE_OMIT_VIRTUALTABLE) + {/* zName: */ "module_list", + /* ePragTyp: */ PragTyp_MODULE_LIST, + /* ePragFlg: */ PragFlg_Result0, + /* ColNames: */ 31, 1, + /* iArg: */ 0 }, +#endif #endif {/* zName: */ "optimize", /* ePragTyp: */ PragTyp_OPTIMIZE, @@ -602,7 +623,7 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "wal_checkpoint", /* ePragTyp: */ PragTyp_WAL_CHECKPOINT, /* ePragFlg: */ PragFlg_NeedSchema, - /* ColNames: */ 43, 3, + /* ColNames: */ 46, 3, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) @@ -613,4 +634,4 @@ static const PragmaName aPragmaName[] = { /* iArg: */ SQLITE_WriteSchema }, #endif }; -/* Number of pragmas: 60 on by default, 74 total. */ +/* Number of pragmas: 62 on by default, 76 total. */ diff --git a/tool/mkpragmatab.tcl b/tool/mkpragmatab.tcl index c7001dc339..34d7b0a82a 100644 --- a/tool/mkpragmatab.tcl +++ b/tool/mkpragmatab.tcl @@ -252,6 +252,17 @@ set pragma_def { COLS: seq name file IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) + NAME: function_list + FLAG: Result0 + COLS: name builtin + IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) + + NAME: module_list + FLAG: Result0 + COLS: name + IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) + IF: !defined(SQLITE_OMIT_VIRTUALTABLE) + NAME: collation_list FLAG: Result0 COLS: seq name From 40cf27cb63b566d5df19823d30222f8f30c0ed22 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 7 Jul 2017 16:00:53 +0000 Subject: [PATCH 03/64] Enhance the sqlite3VdbeMultiLoad() interface to automatically generate the OP_ResultRow opcode on PRAGMA implementations, for a small reduction in the library footprint. FossilOrigin-Name: c46f0f076c674891e20240bad56693d891aedc43004bcf980a5d199515f23413 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/pragma.c | 15 ++++----------- src/vdbeaux.c | 12 +++++++++--- 4 files changed, 21 insertions(+), 22 deletions(-) diff --git a/manifest b/manifest index 3c5acab3f4..aff2064136 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Exploit\sthe\sfact\sthat\sExpr.pRight\sand\sExpr.x\sare\snever\sused\sat\sthe\ssame\stime\nfor\sa\ssmall\sperformance\sgain. -D 2017-07-07T13:59:34.309 +C Enhance\sthe\ssqlite3VdbeMultiLoad()\sinterface\sto\sautomatically\sgenerate\sthe\nOP_ResultRow\sopcode\son\sPRAGMA\simplementations,\sfor\sa\ssmall\sreduction\sin\sthe\nlibrary\sfootprint. +D 2017-07-07T16:00:53.019 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 4ebb1d257cac7fb1bcb4ba59278416d410ff1c4bf59447a9c37a415f3516056a @@ -441,7 +441,7 @@ F src/parse.y 71bf06b02f567232deabe258641b03e833e93c4dee61a120765ad74c13e7faec F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870 F src/pcache.h 521bb9610d38ef17a3cc9b5ddafd4546c2ea67fa3d0e464823d73c2a28d50e11 F src/pcache1.c 1195a21fe28e223e024f900b2011e80df53793f0356a24caace4188b098540dc -F src/pragma.c 2362670a9d28b71708aecb2b9b10b3f7be71f4c950961c07e81dc400e3ce6371 +F src/pragma.c 3f9456edac7eaf171041d51510c5cc922c9b3bd56a713fb7ad6d5b85aa72f1f6 F src/pragma.h 99d3df4a3d2f12c5227ad403f767334910e6356325b6d155a9a99b4037093460 F src/prepare.c 4b84ae7458febe1df3e04ae62ba56abc851f771340e460d14426e6802c5615f4 F src/printf.c 8757834f1b54dae512fb25eb1acc8e94a0d15dd2290b58f2563f65973265adb2 @@ -519,7 +519,7 @@ F src/vdbe.c adc8a378710ec2376101483cc8a5f499539ee9bbebfb2a784f3370704d5d44ad F src/vdbe.h dde459b1e8a02b8445ecfd5959f38cd5ebb6b0ad392d491d8b159ac8193d231a F src/vdbeInt.h 8dd7548d86a98b77b6ed910d8014d0e9e0666356b56f3d16ab7063aad4f102f5 F src/vdbeapi.c 899d8f021c89ab348708b3a9b00b855f5ecc3c0f949a75359a61a3c621021281 -F src/vdbeaux.c 32ff5e8a7226c0bc6df0f214a5cc1a76fcc5d8863c491a800ef3d6f5236feae7 +F src/vdbeaux.c 6f01fe8a49b801cc7734ccfc61d1b782131ee3bb7ee28e336f3c73474800f8f9 F src/vdbeblob.c 359891617358deefc85bef7bcf787fa6b77facb9 F src/vdbemem.c 8d78df62becfd2dce3c317f64b32a94ecaff8346d814bc8b0b877b38a1ad3718 F src/vdbesort.c f512c68d0bf7e0105316a5594c4329358c8ee9cae3b25138df041d97516c0372 @@ -1628,7 +1628,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 115d4b83392d346634866dd959bef30fca50db2e526df17eaeb3d94da7fc895e -R 582e201382f2bd562c6f1266d901f884 +P aacbb9a461fdb34c7f9c8ce348e44c3e96c93334f210d438d92bfac1794dc686 +R 7baffcdf7a331e746202781d1effd9e4 U drh -Z 92ef67718e1f4940d85eca215e487e0c +Z f6a212b381ae2bf356b441292bd9b562 diff --git a/manifest.uuid b/manifest.uuid index 9b3f91218c..1cae0fc2bb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -aacbb9a461fdb34c7f9c8ce348e44c3e96c93334f210d438d92bfac1794dc686 \ No newline at end of file +c46f0f076c674891e20240bad56693d891aedc43004bcf980a5d199515f23413 \ No newline at end of file diff --git a/src/pragma.c b/src/pragma.c index 945fd2d4a7..7135f07553 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1108,7 +1108,6 @@ void sqlite3Pragma( pCol->notNull ? 1 : 0, pCol->pDflt ? pCol->pDflt->u.zToken : 0, k); - sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 6); } } } @@ -1128,9 +1127,8 @@ void sqlite3Pragma( pTab->szTabRow, pTab->nRowLogEst, pTab->tabFlags); - sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 5); for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ - sqlite3VdbeMultiLoad(v, 2, "siii", + sqlite3VdbeMultiLoad(v, 2, "siiiX", pIdx->zName, pIdx->szIdxRow, pIdx->aiRowLogEst[0], @@ -1163,10 +1161,10 @@ void sqlite3Pragma( assert( pParse->nMem<=pPragma->nPragCName ); for(i=0; iaiColumn[i]; - sqlite3VdbeMultiLoad(v, 1, "iis", i, cnum, + sqlite3VdbeMultiLoad(v, 1, "iisX", i, cnum, cnum<0 ? 0 : pTab->aCol[cnum].zName); if( pPragma->iArg ){ - sqlite3VdbeMultiLoad(v, 4, "isi", + sqlite3VdbeMultiLoad(v, 4, "isiX", pIdx->aSortOrder[i], pIdx->azColl[i], inKeyCol); @@ -1193,7 +1191,6 @@ void sqlite3Pragma( IsUniqueIndex(pIdx), azOrigin[pIdx->idxType], pIdx->pPartIdxWhere!=0); - sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 5); } } } @@ -1209,7 +1206,6 @@ void sqlite3Pragma( i, db->aDb[i].zDbSName, sqlite3BtreeGetFilename(db->aDb[i].pBt)); - sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3); } } break; @@ -1221,7 +1217,6 @@ void sqlite3Pragma( for(p=sqliteHashFirst(&db->aCollSeq); p; p=sqliteHashNext(p)){ CollSeq *pColl = (CollSeq *)sqliteHashData(p); sqlite3VdbeMultiLoad(v, 1, "is", i++, pColl->zName); - sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 2); } } break; @@ -1250,7 +1245,6 @@ void sqlite3Pragma( actionName(pFK->aAction[1]), /* ON UPDATE */ actionName(pFK->aAction[0]), /* ON DELETE */ "NONE"); - sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 8); } ++i; pFK = pFK->pNextFrom; @@ -1360,7 +1354,7 @@ void sqlite3Pragma( }else{ sqlite3VdbeAddOp2(v, OP_Null, 0, regResult+1); } - sqlite3VdbeMultiLoad(v, regResult+2, "si", pFK->zTo, i-1); + sqlite3VdbeMultiLoad(v, regResult+2, "siX", pFK->zTo, i-1); sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, 4); sqlite3VdbeResolveLabel(v, addrOk); sqlite3DbFree(db, aiCols); @@ -2062,7 +2056,6 @@ void sqlite3Pragma( zState = azLockName[j]; } sqlite3VdbeMultiLoad(v, 1, "ss", db->aDb[i].zDbSName, zState); - sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 2); } break; } diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 138b7cb08f..ef5420e233 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -242,6 +242,9 @@ int sqlite3VdbeLoadString(Vdbe *p, int iDest, const char *zStr){ ** "s" character in zTypes[], the register is a string if the argument is ** not NULL, or OP_Null if the value is a null pointer. For each "i" character ** in zTypes[], the register is initialized to an integer. +** +** If the input string does not end with "X" then an OP_ResultRow instruction +** is generated for the values inserted. */ void sqlite3VdbeMultiLoad(Vdbe *p, int iDest, const char *zTypes, ...){ va_list ap; @@ -251,12 +254,15 @@ void sqlite3VdbeMultiLoad(Vdbe *p, int iDest, const char *zTypes, ...){ for(i=0; (c = zTypes[i])!=0; i++){ if( c=='s' ){ const char *z = va_arg(ap, const char*); - sqlite3VdbeAddOp4(p, z==0 ? OP_Null : OP_String8, 0, iDest++, 0, z, 0); + sqlite3VdbeAddOp4(p, z==0 ? OP_Null : OP_String8, 0, iDest+i, 0, z, 0); + }else if( c=='i' ){ + sqlite3VdbeAddOp2(p, OP_Integer, va_arg(ap, int), iDest+i); }else{ - assert( c=='i' ); - sqlite3VdbeAddOp2(p, OP_Integer, va_arg(ap, int), iDest++); + goto skip_op_resultrow; } } + sqlite3VdbeAddOp2(p, OP_ResultRow, iDest, i); +skip_op_resultrow: va_end(ap); } From d429ec222c9c63617f375d8b04ea4613327620f8 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 7 Jul 2017 16:06:30 +0000 Subject: [PATCH 04/64] Memory reallocation fix for the Win32 VFS for lsm1. FossilOrigin-Name: 5a3140e4dedace6de4366a3c52e41b818b6d19f356fdab738c6605afc1b674fa --- ext/lsm1/lsm_win32.c | 12 +++++++----- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/ext/lsm1/lsm_win32.c b/ext/lsm1/lsm_win32.c index d3189e4297..c6e90760e0 100644 --- a/ext/lsm1/lsm_win32.c +++ b/ext/lsm1/lsm_win32.c @@ -253,7 +253,7 @@ static int lsmWin32OsOpen( if( pWin32File==0 ){ rc = LSM_NOMEM_BKPT; }else{ - HANDLE hFile; + HANDLE hFile = NULL; rc = win32Open(pEnv, zFile, flags, &hFile); if( rc==LSM_OK ){ @@ -678,20 +678,22 @@ static int lsmWin32OsShmMap(lsm_file *pFile, int iChunk, int sz, void **ppShm){ } } - ahNew = (LPHANDLE)lsmRealloc(pWin32File->pEnv, pWin32File->ahShm, - sizeof(LPHANDLE) * nNew); + ahNew = (LPHANDLE)lsmMallocZero(pWin32File->pEnv, sizeof(LPHANDLE) * nNew); if( !ahNew ) return LSM_NOMEM_BKPT; - apNew = (LPVOID *)lsmRealloc(pWin32File->pEnv, pWin32File->apShm, - sizeof(LPVOID) * nNew); + apNew = (LPVOID *)lsmMallocZero(pWin32File->pEnv, sizeof(LPVOID) * nNew); if( !apNew ){ lsmFree(pWin32File->pEnv, ahNew); return LSM_NOMEM_BKPT; } + memcpy(ahNew, pWin32File->ahShm, pWin32File->nShm); + memcpy(apNew, pWin32File->apShm, pWin32File->nShm); for(i=pWin32File->nShm; ipEnv, pWin32File->ahShm); pWin32File->ahShm = ahNew; + lsmFree(pWin32File->pEnv, pWin32File->apShm); pWin32File->apShm = apNew; pWin32File->nShm = nNew; } diff --git a/manifest b/manifest index aff2064136..2671c0931e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\ssqlite3VdbeMultiLoad()\sinterface\sto\sautomatically\sgenerate\sthe\nOP_ResultRow\sopcode\son\sPRAGMA\simplementations,\sfor\sa\ssmall\sreduction\sin\sthe\nlibrary\sfootprint. -D 2017-07-07T16:00:53.019 +C Memory\sreallocation\sfix\sfor\sthe\sWin32\sVFS\sfor\slsm1. +D 2017-07-07T16:06:30.430 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 4ebb1d257cac7fb1bcb4ba59278416d410ff1c4bf59447a9c37a415f3516056a @@ -250,7 +250,7 @@ F ext/lsm1/lsm_tree.c 53b657439e0fcb1117b0559ad3567ac417f81f2ed0fff9bab79948a00e F ext/lsm1/lsm_unix.c 57361bcf5b1a1a028f5d66571ee490e9064d2cfb145a2cc9e5ddade467bb551b F ext/lsm1/lsm_varint.c b19ae9bd26b5a1e8402fb8a564b25d9542338a41 F ext/lsm1/lsm_vtab.c 812b74a9a7539e8cab49761591ffddc1b3580735fac5d638826c8d2be95ff38b -F ext/lsm1/lsm_win32.c 69eb9fd25197432b084037efd69b365d8182ab1e4372a9c45a9c47e542105c5c +F ext/lsm1/lsm_win32.c e2114824b1db4aea6212e05c16ab70370de46896d1d825dc4f8702411bd269f7 F ext/misc/README.md 8e008c8d2b02e09096b31dfba033253ac27c6c06a18aa5826e299fa7601d90b2 F ext/misc/amatch.c 6db4607cb17c54b853a2d7c7c36046d004853f65b9b733e6f019d543d5dfae87 F ext/misc/anycollseq.c 5ffdfde9829eeac52219136ad6aa7cd9a4edb3b15f4f2532de52f4a22525eddb @@ -1628,7 +1628,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P aacbb9a461fdb34c7f9c8ce348e44c3e96c93334f210d438d92bfac1794dc686 -R 7baffcdf7a331e746202781d1effd9e4 -U drh -Z f6a212b381ae2bf356b441292bd9b562 +P c46f0f076c674891e20240bad56693d891aedc43004bcf980a5d199515f23413 +R 4d89fae253073c0782e85c8a3d95f158 +U mistachkin +Z 1b373bb5c83dcb5af7e9a15d3d0aec3e diff --git a/manifest.uuid b/manifest.uuid index 1cae0fc2bb..4ffaaa20cc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c46f0f076c674891e20240bad56693d891aedc43004bcf980a5d199515f23413 \ No newline at end of file +5a3140e4dedace6de4366a3c52e41b818b6d19f356fdab738c6605afc1b674fa \ No newline at end of file From 5bd9e61f0552e4be71124364c48db0f0ceff1d47 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 7 Jul 2017 16:07:53 +0000 Subject: [PATCH 05/64] Remove a block from the Win32 VFS for lsm1 that is now superfluous. FossilOrigin-Name: db4a41408eff450ee429b936847313c2c92ba1f5b1fcbadaacaff3c08bfdd589 --- ext/lsm1/lsm_win32.c | 4 ---- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/ext/lsm1/lsm_win32.c b/ext/lsm1/lsm_win32.c index c6e90760e0..4408117376 100644 --- a/ext/lsm1/lsm_win32.c +++ b/ext/lsm1/lsm_win32.c @@ -687,10 +687,6 @@ static int lsmWin32OsShmMap(lsm_file *pFile, int iChunk, int sz, void **ppShm){ } memcpy(ahNew, pWin32File->ahShm, pWin32File->nShm); memcpy(apNew, pWin32File->apShm, pWin32File->nShm); - for(i=pWin32File->nShm; ipEnv, pWin32File->ahShm); pWin32File->ahShm = ahNew; lsmFree(pWin32File->pEnv, pWin32File->apShm); diff --git a/manifest b/manifest index 2671c0931e..23925d6113 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Memory\sreallocation\sfix\sfor\sthe\sWin32\sVFS\sfor\slsm1. -D 2017-07-07T16:06:30.430 +C Remove\sa\sblock\sfrom\sthe\sWin32\sVFS\sfor\slsm1\sthat\sis\snow\ssuperfluous. +D 2017-07-07T16:07:53.846 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 4ebb1d257cac7fb1bcb4ba59278416d410ff1c4bf59447a9c37a415f3516056a @@ -250,7 +250,7 @@ F ext/lsm1/lsm_tree.c 53b657439e0fcb1117b0559ad3567ac417f81f2ed0fff9bab79948a00e F ext/lsm1/lsm_unix.c 57361bcf5b1a1a028f5d66571ee490e9064d2cfb145a2cc9e5ddade467bb551b F ext/lsm1/lsm_varint.c b19ae9bd26b5a1e8402fb8a564b25d9542338a41 F ext/lsm1/lsm_vtab.c 812b74a9a7539e8cab49761591ffddc1b3580735fac5d638826c8d2be95ff38b -F ext/lsm1/lsm_win32.c e2114824b1db4aea6212e05c16ab70370de46896d1d825dc4f8702411bd269f7 +F ext/lsm1/lsm_win32.c 9745cebaf03c6e04f0017d0dda8dc1db447a372b9ae4e32e1119ded10e1b54bc F ext/misc/README.md 8e008c8d2b02e09096b31dfba033253ac27c6c06a18aa5826e299fa7601d90b2 F ext/misc/amatch.c 6db4607cb17c54b853a2d7c7c36046d004853f65b9b733e6f019d543d5dfae87 F ext/misc/anycollseq.c 5ffdfde9829eeac52219136ad6aa7cd9a4edb3b15f4f2532de52f4a22525eddb @@ -1628,7 +1628,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c46f0f076c674891e20240bad56693d891aedc43004bcf980a5d199515f23413 -R 4d89fae253073c0782e85c8a3d95f158 +P 5a3140e4dedace6de4366a3c52e41b818b6d19f356fdab738c6605afc1b674fa +R a03373dd14b96ee1d17b02c010e8a282 U mistachkin -Z 1b373bb5c83dcb5af7e9a15d3d0aec3e +Z a482709fb19951e1c4f3858db622ab32 diff --git a/manifest.uuid b/manifest.uuid index 4ffaaa20cc..5b28fe3e66 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5a3140e4dedace6de4366a3c52e41b818b6d19f356fdab738c6605afc1b674fa \ No newline at end of file +db4a41408eff450ee429b936847313c2c92ba1f5b1fcbadaacaff3c08bfdd589 \ No newline at end of file From 3bc909b0af98c2ec2e420ea5187c91a530fdeec6 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 7 Jul 2017 16:09:24 +0000 Subject: [PATCH 06/64] In lsmtest, use an empty string instead of ":memory:" when requesting a temporary database from SQLite. This prevents other test code from trying to unlink() ":memory:", which fails on win32. FossilOrigin-Name: 281ad505d7a112c5524ea9fb195dfc46f819a58f79f42b37b12fbfe46a089ff2 --- ext/lsm1/lsm-test/lsmtest1.c | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/ext/lsm1/lsm-test/lsmtest1.c b/ext/lsm1/lsm-test/lsmtest1.c index 0185bdd6ac..665dc15e58 100644 --- a/ext/lsm1/lsm-test/lsmtest1.c +++ b/ext/lsm1/lsm-test/lsmtest1.c @@ -96,7 +96,7 @@ int testControlDb(TestDb **ppDb){ #ifdef HAVE_KYOTOCABINET return tdb_open("kyotocabinet", "tmp.db", 1, ppDb); #else - return tdb_open("sqlite3", ":memory:", 1, ppDb); + return tdb_open("sqlite3", "", 1, ppDb); #endif } diff --git a/manifest b/manifest index 2671c0931e..193df61d87 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Memory\sreallocation\sfix\sfor\sthe\sWin32\sVFS\sfor\slsm1. -D 2017-07-07T16:06:30.430 +C In\slsmtest,\suse\san\sempty\sstring\sinstead\sof\s":memory:"\swhen\srequesting\sa\ntemporary\sdatabase\sfrom\sSQLite.\sThis\sprevents\sother\stest\scode\sfrom\strying\sto\nunlink()\s":memory:",\swhich\sfails\son\swin32. +D 2017-07-07T16:09:24.292 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 4ebb1d257cac7fb1bcb4ba59278416d410ff1c4bf59447a9c37a415f3516056a @@ -213,7 +213,7 @@ F ext/lsm1/Makefile a2ea4975162be8932b5efa727080f4982715d34c32035d9eb7a015ae7840 F ext/lsm1/Makefile.msc c8140509750fb207f0e984991bc426e91a11adb2f6434f218c52103b9d33a8e1 F ext/lsm1/lsm-test/README 87ea529d2abe615e856d4714bfe8bb185e6c2771b8612aa6298588b7b43e6f86 F ext/lsm1/lsm-test/lsmtest.h 346295688c4b304689950f10e4dcd4640321f3c860112b72cb0691ca075b6a71 -F ext/lsm1/lsm-test/lsmtest1.c 2570b0e21e854d3d079dc04a535ce58abe50ed512da23117ab95b01fecdb90a0 +F ext/lsm1/lsm-test/lsmtest1.c 33158978327f800e82b6a47c09b86ace809f56a9ff10b0162273ec1186cc3153 F ext/lsm1/lsm-test/lsmtest2.c 188b09aec776516aeedcfd13b9c6faf85ba16b3671a0897a2c740ee00a5dc4f8 F ext/lsm1/lsm-test/lsmtest3.c 9ab87528a36dbf4a61d7c8ad954f5ee368c0878c127b84b942b2e2abe522de26 F ext/lsm1/lsm-test/lsmtest4.c d258d6a245db5d8eaede096e2368d23f859c5e92c80ab9122463f708514fe10c @@ -1628,7 +1628,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c46f0f076c674891e20240bad56693d891aedc43004bcf980a5d199515f23413 -R 4d89fae253073c0782e85c8a3d95f158 -U mistachkin -Z 1b373bb5c83dcb5af7e9a15d3d0aec3e +P 5a3140e4dedace6de4366a3c52e41b818b6d19f356fdab738c6605afc1b674fa +R 6462b0fbfbb0e91c958086ecb4e6ea20 +U dan +Z 01bdf41d3d2686fb6c10584ef3102e0c diff --git a/manifest.uuid b/manifest.uuid index 4ffaaa20cc..e960df07d1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5a3140e4dedace6de4366a3c52e41b818b6d19f356fdab738c6605afc1b674fa \ No newline at end of file +281ad505d7a112c5524ea9fb195dfc46f819a58f79f42b37b12fbfe46a089ff2 \ No newline at end of file From baebf3cc4b81a0da6887ef12de2088fc9cc05dda Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 7 Jul 2017 16:29:37 +0000 Subject: [PATCH 07/64] Add support for LSM_DEBUG_MEM to the MSVC makefile for lsm1. FossilOrigin-Name: 3340de83df8c4fb19f729e6ff0838a9a03a1e701cdb40cb830e76f294198024a --- ext/lsm1/Makefile.msc | 4 ++++ manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/ext/lsm1/Makefile.msc b/ext/lsm1/Makefile.msc index bd8aea1acd..61fcfa3496 100644 --- a/ext/lsm1/Makefile.msc +++ b/ext/lsm1/Makefile.msc @@ -43,6 +43,10 @@ LSMTESTSRC = $(LSMDIR)\lsm-test\lsmtest1.c $(LSMDIR)\lsm-test\lsmtest2.c \ LSMOPTS = -DLSM_MUTEX_WIN32=1 -I$(LSMDIR) +!IF $(MEMDEBUG)!=0 +LSMOPTS = $(LSMOPTS) -DLSM_DEBUG_MEM=1 +!ENDIF + lsm_ckpt.lo: $(LSMDIR)\lsm_ckpt.c $(LSMHDR) $(SQLITE3H) $(LTCOMPILE) $(LSMOPTS) -c $(LSMDIR)\lsm_ckpt.c diff --git a/manifest b/manifest index 58cd408ab3..1036341e5f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sa\sblock\sfrom\sthe\sWin32\sVFS\sfor\slsm1\sthat\sis\snow\ssuperfluous. -D 2017-07-07T16:27:43.990 +C Add\ssupport\sfor\sLSM_DEBUG_MEM\sto\sthe\sMSVC\smakefile\sfor\slsm1. +D 2017-07-07T16:29:37.591 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 4ebb1d257cac7fb1bcb4ba59278416d410ff1c4bf59447a9c37a415f3516056a @@ -210,7 +210,7 @@ F ext/icu/README.txt d9fbbad0c2f647c3fdf715fc9fd64af53aedfc43 F ext/icu/icu.c 84900472a088a3a172c6c079f58a1d3a1952c332 F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37 F ext/lsm1/Makefile a2ea4975162be8932b5efa727080f4982715d34c32035d9eb7a015ae78404981 -F ext/lsm1/Makefile.msc c8140509750fb207f0e984991bc426e91a11adb2f6434f218c52103b9d33a8e1 +F ext/lsm1/Makefile.msc e5702306af1537a0e9311cc182a89bb3a36f31c18df6416f72a13f356620068f F ext/lsm1/lsm-test/README 87ea529d2abe615e856d4714bfe8bb185e6c2771b8612aa6298588b7b43e6f86 F ext/lsm1/lsm-test/lsmtest.h 346295688c4b304689950f10e4dcd4640321f3c860112b72cb0691ca075b6a71 F ext/lsm1/lsm-test/lsmtest1.c 33158978327f800e82b6a47c09b86ace809f56a9ff10b0162273ec1186cc3153 @@ -1628,7 +1628,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 281ad505d7a112c5524ea9fb195dfc46f819a58f79f42b37b12fbfe46a089ff2 db4a41408eff450ee429b936847313c2c92ba1f5b1fcbadaacaff3c08bfdd589 -R 178147b5297cfb61b57d98e52a0b02ab -U dan -Z 48480afd6748424fc3b06dba5c31edd2 +P 5f726f2830dcf91f5e5c010b10761757f746d39b9dd2b8c9770452ce65bb1652 +R 10f4aefb9087225386886b178c9318d9 +U mistachkin +Z 30c8506981cfdd14daac87f535153316 diff --git a/manifest.uuid b/manifest.uuid index a6136d17d1..e9229aa90f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5f726f2830dcf91f5e5c010b10761757f746d39b9dd2b8c9770452ce65bb1652 \ No newline at end of file +3340de83df8c4fb19f729e6ff0838a9a03a1e701cdb40cb830e76f294198024a \ No newline at end of file From e60092b90ccf09a3f723c6120b7323bdacd54f13 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 7 Jul 2017 16:46:08 +0000 Subject: [PATCH 08/64] Improve clarity in the Win32 VFS for lsm1. FossilOrigin-Name: 9c7a9e805d95d3d4a3f7e2d608280b7ca0dda01114e32cd366b1deb14e6e6839 --- ext/lsm1/lsm_win32.c | 43 +++++++++++++++++++++---------------------- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 28 insertions(+), 29 deletions(-) diff --git a/ext/lsm1/lsm_win32.c b/ext/lsm1/lsm_win32.c index 4408117376..c261eb9eab 100644 --- a/ext/lsm1/lsm_win32.c +++ b/ext/lsm1/lsm_win32.c @@ -47,12 +47,12 @@ struct Win32File { LPVOID *apShm; /* Array of 32K shared memory segments */ }; -static char *win32ShmFile(Win32File *p){ +static char *win32ShmFile(Win32File *pWin32File){ char *zShm; - int nName = strlen(p->zName); - zShm = (char *)lsmMallocZero(p->pEnv, nName+4+1); + int nName = strlen(pWin32File->zName); + zShm = (char *)lsmMallocZero(pWin32File->pEnv, nName+4+1); if( zShm ){ - memcpy(zShm, p->zName, nName); + memcpy(zShm, pWin32File->zName, nName); memcpy(&zShm[nName], "-shm", 5); } return zShm; @@ -380,6 +380,18 @@ static int lsmWin32OsSectorSize(lsm_file *pFile){ return 512; } +static void win32Unmap(Win32File *pWin32File){ + if( pWin32File->pMap!=NULL ){ + UnmapViewOfFile(pWin32File->pMap); + pWin32File->pMap = NULL; + pWin32File->nMap = 0; + } + if( pWin32File->hMap!=NULL ){ + CloseHandle(pWin32File->hMap); + pWin32File->hMap = NULL; + } +} + static int lsmWin32OsRemap( lsm_file *pFile, lsm_i64 iMin, @@ -393,15 +405,10 @@ static int lsmWin32OsRemap( const int aIncrSz[] = {256*1024, 1024*1024}; int nIncrSz = aIncrSz[iMin>(2*1024*1024)]; - if( pWin32File->pMap!=NULL ){ - UnmapViewOfFile(pWin32File->pMap); - *ppOut = pWin32File->pMap = NULL; - *pnOut = pWin32File->nMap = 0; - } - if( pWin32File->hMap!=NULL ){ - CloseHandle(pWin32File->hMap); - pWin32File->hMap = NULL; - } + *ppOut = NULL; + *pnOut = 0; + + win32Unmap(pWin32File); if( iMin>=0 ){ LARGE_INTEGER fileSize; DWORD dwSizeHigh; @@ -759,15 +766,7 @@ static int lsmWin32OsClose(lsm_file *pFile){ int nRetry = 0; Win32File *pWin32File = (Win32File *)pFile; lsmWin32OsShmUnmap(pFile, 0); - if( pWin32File->pMap!=NULL ){ - UnmapViewOfFile(pWin32File->pMap); - pWin32File->pMap = NULL; - pWin32File->nMap = 0; - } - if( pWin32File->hMap!=NULL ){ - CloseHandle(pWin32File->hMap); - pWin32File->hMap = NULL; - } + win32Unmap(pWin32File); do{ if( pWin32File->hFile==NULL ){ rc = LSM_IOERR_BKPT; diff --git a/manifest b/manifest index 1036341e5f..23ea26fdad 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\ssupport\sfor\sLSM_DEBUG_MEM\sto\sthe\sMSVC\smakefile\sfor\slsm1. -D 2017-07-07T16:29:37.591 +C Improve\sclarity\sin\sthe\sWin32\sVFS\sfor\slsm1. +D 2017-07-07T16:46:08.188 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 4ebb1d257cac7fb1bcb4ba59278416d410ff1c4bf59447a9c37a415f3516056a @@ -250,7 +250,7 @@ F ext/lsm1/lsm_tree.c 53b657439e0fcb1117b0559ad3567ac417f81f2ed0fff9bab79948a00e F ext/lsm1/lsm_unix.c 57361bcf5b1a1a028f5d66571ee490e9064d2cfb145a2cc9e5ddade467bb551b F ext/lsm1/lsm_varint.c b19ae9bd26b5a1e8402fb8a564b25d9542338a41 F ext/lsm1/lsm_vtab.c 812b74a9a7539e8cab49761591ffddc1b3580735fac5d638826c8d2be95ff38b -F ext/lsm1/lsm_win32.c 9745cebaf03c6e04f0017d0dda8dc1db447a372b9ae4e32e1119ded10e1b54bc +F ext/lsm1/lsm_win32.c 24757d71673d20634afb681f59af8da8cbe84733be82b86b133d79bd9ff335de F ext/misc/README.md 8e008c8d2b02e09096b31dfba033253ac27c6c06a18aa5826e299fa7601d90b2 F ext/misc/amatch.c 6db4607cb17c54b853a2d7c7c36046d004853f65b9b733e6f019d543d5dfae87 F ext/misc/anycollseq.c 5ffdfde9829eeac52219136ad6aa7cd9a4edb3b15f4f2532de52f4a22525eddb @@ -1628,7 +1628,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 5f726f2830dcf91f5e5c010b10761757f746d39b9dd2b8c9770452ce65bb1652 -R 10f4aefb9087225386886b178c9318d9 +P 3340de83df8c4fb19f729e6ff0838a9a03a1e701cdb40cb830e76f294198024a +R 441b83e8fe7c6e7ee9052521ffcfa22a U mistachkin -Z 30c8506981cfdd14daac87f535153316 +Z 05a5043cc6c8a10020a4334d65b17df2 diff --git a/manifest.uuid b/manifest.uuid index e9229aa90f..eaac7490b0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3340de83df8c4fb19f729e6ff0838a9a03a1e701cdb40cb830e76f294198024a \ No newline at end of file +9c7a9e805d95d3d4a3f7e2d608280b7ca0dda01114e32cd366b1deb14e6e6839 \ No newline at end of file From 8ae11aac93cd6d3cc9c47b8ef233dea7ada22d52 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 7 Jul 2017 17:33:07 +0000 Subject: [PATCH 09/64] Add the "Pragma_list" pragma. Put all three pragmas created on this branch inside of #ifdef SQLITE_INTROSPECTION_PRAGMAS. FossilOrigin-Name: 2f3c3781ef3d66ecafef083d7144287ff23eea5a6d93b014dfeb2a8ac71f757e --- manifest | 19 +++++++---------- manifest.uuid | 2 +- src/pragma.c | 10 +++++++++ src/pragma.h | 50 +++++++++++++++++++++++++++----------------- tool/mkpragmatab.tcl | 7 +++++++ 5 files changed, 57 insertions(+), 31 deletions(-) diff --git a/manifest b/manifest index 0faff6d8bf..c3cb032b8a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\snew\spragmas:\s"function_list"\sand\s"module_list" -D 2017-07-07T15:43:22.754 +C Add\sthe\s"Pragma_list"\spragma.\s\sPut\sall\sthree\spragmas\screated\son\sthis\sbranch\ninside\sof\s#ifdef\sSQLITE_INTROSPECTION_PRAGMAS. +D 2017-07-07T17:33:07.198 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 4ebb1d257cac7fb1bcb4ba59278416d410ff1c4bf59447a9c37a415f3516056a @@ -441,8 +441,8 @@ F src/parse.y 71bf06b02f567232deabe258641b03e833e93c4dee61a120765ad74c13e7faec F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870 F src/pcache.h 521bb9610d38ef17a3cc9b5ddafd4546c2ea67fa3d0e464823d73c2a28d50e11 F src/pcache1.c 1195a21fe28e223e024f900b2011e80df53793f0356a24caace4188b098540dc -F src/pragma.c 415a98ec60bd209b69e502f07f1c7b9a84140d7e44332202367b2d60e7c30e60 -F src/pragma.h 0d5573ec6c5aa8e65a7d1b33055b868295f16d1ee6aa754754fc1fc75ececd1a +F src/pragma.c 072f2907f63ca779b08a2bb97706cf0b61663fbbebdc891b882cb7d0ed21c4e5 +F src/pragma.h bb83728944b42f6d409c77f5838a8edbdb0fe83046c5496ffc9602b40340a324 F src/prepare.c 4b84ae7458febe1df3e04ae62ba56abc851f771340e460d14426e6802c5615f4 F src/printf.c 8757834f1b54dae512fb25eb1acc8e94a0d15dd2290b58f2563f65973265adb2 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 @@ -1566,7 +1566,7 @@ F tool/mkmsvcmin.tcl cbd93f1cfa3a0a9ae56fc958510aa3fc3ac65e29cb111716199e3d0e66e F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c F tool/mkopcodeh.tcl a01d2c1d8a6205b03fc635adf3735b4c523befd3 F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e -F tool/mkpragmatab.tcl 3707a9586c5f3fccded77ac23b9f1672785f43c9bc0c1f49845bb81dbf8118d5 +F tool/mkpragmatab.tcl 2144bc8550a6471a029db262a132d2df4b9e0db61b90398bf64f5b7b3f8d92cd F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl fef88397668ae83166735c41af99d79f56afaabb F tool/mksqlite3c.tcl f6214285bec900d28441366ca31af327aade18bbc424b0480497966ec05bc43c @@ -1628,10 +1628,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P aacbb9a461fdb34c7f9c8ce348e44c3e96c93334f210d438d92bfac1794dc686 -R 0f36dd9733d38244f7ca6a934ae9744a -T *branch * list-pragmas -T *sym-list-pragmas * -T -sym-trunk * +P e5f01d7fde05fdb547f35816ff15c31a92c170b31877f4c640b7bc2be3f580b3 +R 17fc399fdbe82a9f3fca67f0dc49bd1b U drh -Z 4e2b289a760c670e9cafd6cf4ad4b9b9 +Z 8b4bd12deebcc9df8b73824fc89e2153 diff --git a/manifest.uuid b/manifest.uuid index f1a5df0c43..b276224cc2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e5f01d7fde05fdb547f35816ff15c31a92c170b31877f4c640b7bc2be3f580b3 \ No newline at end of file +2f3c3781ef3d66ecafef083d7144287ff23eea5a6d93b014dfeb2a8ac71f757e \ No newline at end of file diff --git a/src/pragma.c b/src/pragma.c index 0c81252146..a7eb8c0cc8 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1226,6 +1226,7 @@ void sqlite3Pragma( } break; +#ifdef SQLITE_INTROSPECTION_PRAGMAS case PragTyp_FUNCTION_LIST: { int i; HashElem *j; @@ -1258,6 +1259,15 @@ void sqlite3Pragma( break; #endif /* SQLITE_OMIT_VIRTUALTABLE */ + case PragTyp_PRAGMA_LIST: { + int i; + for(i=0; i Date: Fri, 7 Jul 2017 17:57:21 +0000 Subject: [PATCH 10/64] Fix the usleep() macro in the Win32 test code for lsm1. FossilOrigin-Name: 63599fa524a7c72ffa5362041f2ec394d9af9c43025d8b6d5a34e98eb423d5ff --- ext/lsm1/lsm-test/lsmtest.h | 2 +- manifest | 15 +++++++-------- manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/ext/lsm1/lsm-test/lsmtest.h b/ext/lsm1/lsm-test/lsmtest.h index 92b78c8609..ee6503a983 100644 --- a/ext/lsm1/lsm-test/lsmtest.h +++ b/ext/lsm1/lsm-test/lsmtest.h @@ -20,7 +20,7 @@ extern "C" { # define gettimeofday win32GetTimeOfDay # define F_OK (0) # define sleep(sec) Sleep(1000 * (sec)) -# define usleep(usec) Sleep((usec) / 1000) +# define usleep(usec) Sleep(((usec) + 999) / 1000) # ifdef _MSC_VER # include # define snprintf _snprintf diff --git a/manifest b/manifest index 1e68ef64ae..3c905a6485 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\snew\sPRAGMAs:\s"function_list",\s"module_list",\sand\s"pragma_list".\s\sAll\sare\nenclosed\swithin\s#ifdef\sSQLITE_INTROSPECTION_PRAGMAS.\s\sThe\scompile-time\soption\nis\snot\son\sctime.c\syet,\ssince\sthese\sare\sstill\sexperimental\sand\sone\scan\salways\ntest\s"PRAGMA\spragma_list"\sand\ssee\swhether\sor\snot\sit\sreturns\san\sempty\sset. -D 2017-07-07T17:43:30.458 +C Fix\sthe\susleep()\smacro\sin\sthe\sWin32\stest\scode\sfor\slsm1. +D 2017-07-07T17:57:21.132 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 4ebb1d257cac7fb1bcb4ba59278416d410ff1c4bf59447a9c37a415f3516056a @@ -212,7 +212,7 @@ F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37 F ext/lsm1/Makefile a2ea4975162be8932b5efa727080f4982715d34c32035d9eb7a015ae78404981 F ext/lsm1/Makefile.msc e5702306af1537a0e9311cc182a89bb3a36f31c18df6416f72a13f356620068f F ext/lsm1/lsm-test/README 87ea529d2abe615e856d4714bfe8bb185e6c2771b8612aa6298588b7b43e6f86 -F ext/lsm1/lsm-test/lsmtest.h 346295688c4b304689950f10e4dcd4640321f3c860112b72cb0691ca075b6a71 +F ext/lsm1/lsm-test/lsmtest.h 9c856fbaff90f2270b1df0ddff150925bcf7e1741035c5ddea0cc43c9f56210e F ext/lsm1/lsm-test/lsmtest1.c 33158978327f800e82b6a47c09b86ace809f56a9ff10b0162273ec1186cc3153 F ext/lsm1/lsm-test/lsmtest2.c 188b09aec776516aeedcfd13b9c6faf85ba16b3671a0897a2c740ee00a5dc4f8 F ext/lsm1/lsm-test/lsmtest3.c 9ab87528a36dbf4a61d7c8ad954f5ee368c0878c127b84b942b2e2abe522de26 @@ -1628,8 +1628,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9c7a9e805d95d3d4a3f7e2d608280b7ca0dda01114e32cd366b1deb14e6e6839 2f3c3781ef3d66ecafef083d7144287ff23eea5a6d93b014dfeb2a8ac71f757e -R 4f6a333ba3ebc48a516283775adad985 -T +closed 2f3c3781ef3d66ecafef083d7144287ff23eea5a6d93b014dfeb2a8ac71f757e -U drh -Z eedd58e83d653cf2bb50d9ab0fddda0e +P e0b6ae92adfae46f64fc2e2719e22e5467c34d49c1aeaec5cc5faf04258de0f7 +R 7da3c10a5e23d1c535fd1a007598a2d9 +U mistachkin +Z 95abb7b40357bab3b1514e8c7eebc63a diff --git a/manifest.uuid b/manifest.uuid index e7f3a8d9c5..dff19d01a0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e0b6ae92adfae46f64fc2e2719e22e5467c34d49c1aeaec5cc5faf04258de0f7 \ No newline at end of file +63599fa524a7c72ffa5362041f2ec394d9af9c43025d8b6d5a34e98eb423d5ff \ No newline at end of file From a7a0bfab9193634b06843aa633af2d3c4b5e130c Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 7 Jul 2017 18:06:49 +0000 Subject: [PATCH 11/64] In the command-line shell, when running ".schema" give a sensible error when the database file is locked. FossilOrigin-Name: cc329eb8d65171f3f4fcb39b0e55ef85c97a77f3510cf864bbc1537f993d0074 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c | 10 ++++++++-- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 3c905a6485..a0f34dec88 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\susleep()\smacro\sin\sthe\sWin32\stest\scode\sfor\slsm1. -D 2017-07-07T17:57:21.132 +C In\sthe\scommand-line\sshell,\swhen\srunning\s".schema"\sgive\sa\ssensible\serror\swhen\nthe\sdatabase\sfile\sis\slocked. +D 2017-07-07T18:06:49.936 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 4ebb1d257cac7fb1bcb4ba59278416d410ff1c4bf59447a9c37a415f3516056a @@ -449,7 +449,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 6aa1fb1212e601f65b983ee1215d69a591986c8f97a3805c425c625a53839539 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c c9f7b7196e196e93979665680d055a789938b8e025556097bf484b184c0dd576 -F src/shell.c a2b148e4ca8eb81b96e1050207c83d4a16ea6bf9182374faee4dd2a43628c291 +F src/shell.c a7067f647aef4b81569bbfd025f4fd120a4e7576a647d2aad05028eb50e50e48 F src/sqlite.h.in 651cba56f8df64ff4418aa981cdfd5bc2d65e5fef95c1671f9826f1a164a5fa3 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 58fd0676d3111d02e62e5a35992a7d3da5d3f88753acc174f2d37b774fbbdd28 @@ -1628,7 +1628,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e0b6ae92adfae46f64fc2e2719e22e5467c34d49c1aeaec5cc5faf04258de0f7 -R 7da3c10a5e23d1c535fd1a007598a2d9 -U mistachkin -Z 95abb7b40357bab3b1514e8c7eebc63a +P 63599fa524a7c72ffa5362041f2ec394d9af9c43025d8b6d5a34e98eb423d5ff +R e0e6067b4f6d8ab9e2dc371d790536e4 +U drh +Z fde9cdc76debb617e008886702633a73 diff --git a/manifest.uuid b/manifest.uuid index dff19d01a0..b86f037993 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -63599fa524a7c72ffa5362041f2ec394d9af9c43025d8b6d5a34e98eb423d5ff \ No newline at end of file +cc329eb8d65171f3f4fcb39b0e55ef85c97a77f3510cf864bbc1537f993d0074 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 9ea603bab2..bc7fd44abd 100644 --- a/src/shell.c +++ b/src/shell.c @@ -5829,8 +5829,14 @@ static int do_meta_command(char *zLine, ShellState *p){ } if( zDiv ){ sqlite3_stmt *pStmt = 0; - sqlite3_prepare_v2(p->db, "SELECT name FROM pragma_database_list", - -1, &pStmt, 0); + rc = sqlite3_prepare_v2(p->db, "SELECT name FROM pragma_database_list", + -1, &pStmt, 0); + if( rc ){ + utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db)); + sqlite3_finalize(pStmt); + rc = 1; + goto meta_command_exit; + } appendText(&sSelect, "SELECT sql FROM", 0); iSchema = 0; while( sqlite3_step(pStmt)==SQLITE_ROW ){ From 9a7a77ad36c4758e2e64157cfd5fcd480d14e1f3 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 7 Jul 2017 18:31:51 +0000 Subject: [PATCH 12/64] Add support for LSM_DEBUG to the MSVC makefile for lsm1. FossilOrigin-Name: 277a7fedafbe5b43d44086f3cb73e952873913bdc4b51041f45b6571b386d7d9 --- ext/lsm1/Makefile.msc | 4 ++++ manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/ext/lsm1/Makefile.msc b/ext/lsm1/Makefile.msc index 61fcfa3496..23b4dd9ade 100644 --- a/ext/lsm1/Makefile.msc +++ b/ext/lsm1/Makefile.msc @@ -43,6 +43,10 @@ LSMTESTSRC = $(LSMDIR)\lsm-test\lsmtest1.c $(LSMDIR)\lsm-test\lsmtest2.c \ LSMOPTS = -DLSM_MUTEX_WIN32=1 -I$(LSMDIR) +!IF $(DEBUG)>2 +LSMOPTS = $(LSMOPTS) -DLSM_DEBUG=1 +!ENDIF + !IF $(MEMDEBUG)!=0 LSMOPTS = $(LSMOPTS) -DLSM_DEBUG_MEM=1 !ENDIF diff --git a/manifest b/manifest index a0f34dec88..89c3e8cfc0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\scommand-line\sshell,\swhen\srunning\s".schema"\sgive\sa\ssensible\serror\swhen\nthe\sdatabase\sfile\sis\slocked. -D 2017-07-07T18:06:49.936 +C Add\ssupport\sfor\sLSM_DEBUG\sto\sthe\sMSVC\smakefile\sfor\slsm1. +D 2017-07-07T18:31:51.950 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 4ebb1d257cac7fb1bcb4ba59278416d410ff1c4bf59447a9c37a415f3516056a @@ -210,7 +210,7 @@ F ext/icu/README.txt d9fbbad0c2f647c3fdf715fc9fd64af53aedfc43 F ext/icu/icu.c 84900472a088a3a172c6c079f58a1d3a1952c332 F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37 F ext/lsm1/Makefile a2ea4975162be8932b5efa727080f4982715d34c32035d9eb7a015ae78404981 -F ext/lsm1/Makefile.msc e5702306af1537a0e9311cc182a89bb3a36f31c18df6416f72a13f356620068f +F ext/lsm1/Makefile.msc 8b195e7b1567990cf2590802f59bda48005c601addb4deb3e1b8ee74c0ed3813 F ext/lsm1/lsm-test/README 87ea529d2abe615e856d4714bfe8bb185e6c2771b8612aa6298588b7b43e6f86 F ext/lsm1/lsm-test/lsmtest.h 9c856fbaff90f2270b1df0ddff150925bcf7e1741035c5ddea0cc43c9f56210e F ext/lsm1/lsm-test/lsmtest1.c 33158978327f800e82b6a47c09b86ace809f56a9ff10b0162273ec1186cc3153 @@ -1628,7 +1628,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 63599fa524a7c72ffa5362041f2ec394d9af9c43025d8b6d5a34e98eb423d5ff -R e0e6067b4f6d8ab9e2dc371d790536e4 -U drh -Z fde9cdc76debb617e008886702633a73 +P cc329eb8d65171f3f4fcb39b0e55ef85c97a77f3510cf864bbc1537f993d0074 +R e5eced2fc3e30bf98e8a717609a80548 +U mistachkin +Z 68553be5e7e0dfa7549bf5d6dc18a4bd diff --git a/manifest.uuid b/manifest.uuid index b86f037993..ceb1e81098 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cc329eb8d65171f3f4fcb39b0e55ef85c97a77f3510cf864bbc1537f993d0074 \ No newline at end of file +277a7fedafbe5b43d44086f3cb73e952873913bdc4b51041f45b6571b386d7d9 \ No newline at end of file From a2d85cbbfa128a8137cea1b7f8cb661069855bf6 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 7 Jul 2017 19:02:51 +0000 Subject: [PATCH 13/64] Enhance the MSVC makefile 'clean' target to handle lsm1. FossilOrigin-Name: 2d6faebc319aefeab796c5f2ead4c3c3e2a9dd25c979a16bdb555a109135b13c --- Makefile.msc | 1 + manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index 9026c38dea..da15cf6dbb 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -2266,6 +2266,7 @@ clean: -rmdir /Q/S tsrc 2>NUL del /Q .target_source 2>NUL del /Q tclsqlite3.exe $(SQLITETCLH) $(SQLITETCLDECLSH) 2>NUL + del /Q lsm.dll lsmtest.exe 2>NUL del /Q testloadext.dll 2>NUL del /Q testfixture.exe test.db 2>NUL del /Q LogEst.exe fts3view.exe rollback-test.exe showdb.exe dbdump.exe 2>NUL diff --git a/manifest b/manifest index 89c3e8cfc0..060839e772 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C Add\ssupport\sfor\sLSM_DEBUG\sto\sthe\sMSVC\smakefile\sfor\slsm1. -D 2017-07-07T18:31:51.950 +C Enhance\sthe\sMSVC\smakefile\s'clean'\starget\sto\shandle\slsm1. +D 2017-07-07T19:02:51.650 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc 4ebb1d257cac7fb1bcb4ba59278416d410ff1c4bf59447a9c37a415f3516056a +F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba F README.md 2b15fae33852f2f53996774c21fb41e1d94181c4401a0e43ac93e11f2cc901b9 F VERSION 87f1498f27e398bce3da2fa8125c9879a38ed9d87e4b5fb922b351de1e25cadb F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -1628,7 +1628,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P cc329eb8d65171f3f4fcb39b0e55ef85c97a77f3510cf864bbc1537f993d0074 -R e5eced2fc3e30bf98e8a717609a80548 +P 277a7fedafbe5b43d44086f3cb73e952873913bdc4b51041f45b6571b386d7d9 +R f6458ee7a870e2551c7761f29969d435 U mistachkin -Z 68553be5e7e0dfa7549bf5d6dc18a4bd +Z cebc3cc5b9576984263d133291a87338 diff --git a/manifest.uuid b/manifest.uuid index ceb1e81098..5104c84f16 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -277a7fedafbe5b43d44086f3cb73e952873913bdc4b51041f45b6571b386d7d9 \ No newline at end of file +2d6faebc319aefeab796c5f2ead4c3c3e2a9dd25c979a16bdb555a109135b13c \ No newline at end of file From 73518c58760337b2b1ccb2550c53b3c3f60c3fc5 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 7 Jul 2017 19:12:55 +0000 Subject: [PATCH 14/64] Fix the memcpy calls in the lsmWin32OsShmMap function for lsm1. FossilOrigin-Name: aa4890b9f9e9698c61d6ca0e24c26280f5e0a87a8c02865933ad483a1fd44d84 --- ext/lsm1/lsm_win32.c | 4 ++-- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/ext/lsm1/lsm_win32.c b/ext/lsm1/lsm_win32.c index c261eb9eab..cfbf6e938c 100644 --- a/ext/lsm1/lsm_win32.c +++ b/ext/lsm1/lsm_win32.c @@ -692,8 +692,8 @@ static int lsmWin32OsShmMap(lsm_file *pFile, int iChunk, int sz, void **ppShm){ lsmFree(pWin32File->pEnv, ahNew); return LSM_NOMEM_BKPT; } - memcpy(ahNew, pWin32File->ahShm, pWin32File->nShm); - memcpy(apNew, pWin32File->apShm, pWin32File->nShm); + memcpy(ahNew, pWin32File->ahShm, sizeof(LPHANDLE) * pWin32File->nShm); + memcpy(apNew, pWin32File->apShm, sizeof(LPVOID) * pWin32File->nShm); lsmFree(pWin32File->pEnv, pWin32File->ahShm); pWin32File->ahShm = ahNew; lsmFree(pWin32File->pEnv, pWin32File->apShm); diff --git a/manifest b/manifest index 060839e772..af5fe24818 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\sMSVC\smakefile\s'clean'\starget\sto\shandle\slsm1. -D 2017-07-07T19:02:51.650 +C Fix\sthe\smemcpy\scalls\sin\sthe\slsmWin32OsShmMap\sfunction\sfor\slsm1. +D 2017-07-07T19:12:55.644 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba @@ -250,7 +250,7 @@ F ext/lsm1/lsm_tree.c 53b657439e0fcb1117b0559ad3567ac417f81f2ed0fff9bab79948a00e F ext/lsm1/lsm_unix.c 57361bcf5b1a1a028f5d66571ee490e9064d2cfb145a2cc9e5ddade467bb551b F ext/lsm1/lsm_varint.c b19ae9bd26b5a1e8402fb8a564b25d9542338a41 F ext/lsm1/lsm_vtab.c 812b74a9a7539e8cab49761591ffddc1b3580735fac5d638826c8d2be95ff38b -F ext/lsm1/lsm_win32.c 24757d71673d20634afb681f59af8da8cbe84733be82b86b133d79bd9ff335de +F ext/lsm1/lsm_win32.c 8ec3bcc7d17c26d33b9f6af32444afa2e02c9002cda0f646946598036d17dbd4 F ext/misc/README.md 8e008c8d2b02e09096b31dfba033253ac27c6c06a18aa5826e299fa7601d90b2 F ext/misc/amatch.c 6db4607cb17c54b853a2d7c7c36046d004853f65b9b733e6f019d543d5dfae87 F ext/misc/anycollseq.c 5ffdfde9829eeac52219136ad6aa7cd9a4edb3b15f4f2532de52f4a22525eddb @@ -1628,7 +1628,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 277a7fedafbe5b43d44086f3cb73e952873913bdc4b51041f45b6571b386d7d9 -R f6458ee7a870e2551c7761f29969d435 +P 2d6faebc319aefeab796c5f2ead4c3c3e2a9dd25c979a16bdb555a109135b13c +R a245078b8c325e979b84d418c47c9bd7 U mistachkin -Z cebc3cc5b9576984263d133291a87338 +Z dbc992308fb33d5413eb87d5a1383270 diff --git a/manifest.uuid b/manifest.uuid index 5104c84f16..1759ebe651 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2d6faebc319aefeab796c5f2ead4c3c3e2a9dd25c979a16bdb555a109135b13c \ No newline at end of file +aa4890b9f9e9698c61d6ca0e24c26280f5e0a87a8c02865933ad483a1fd44d84 \ No newline at end of file From b11c650c0195eef41ed7fa9dabe99c64eef465f4 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 7 Jul 2017 19:22:35 +0000 Subject: [PATCH 15/64] Fix typos in Win32 VFS for lsm1. FossilOrigin-Name: 0961ec873b78ad2da0ea9cdf2934bc8f08276375a153fe5d9fa8d4280328deef --- ext/lsm1/lsm_win32.c | 4 ++-- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/ext/lsm1/lsm_win32.c b/ext/lsm1/lsm_win32.c index cfbf6e938c..b770af51d3 100644 --- a/ext/lsm1/lsm_win32.c +++ b/ext/lsm1/lsm_win32.c @@ -685,14 +685,14 @@ static int lsmWin32OsShmMap(lsm_file *pFile, int iChunk, int sz, void **ppShm){ } } - ahNew = (LPHANDLE)lsmMallocZero(pWin32File->pEnv, sizeof(LPHANDLE) * nNew); + ahNew = (LPHANDLE)lsmMallocZero(pWin32File->pEnv, sizeof(HANDLE) * nNew); if( !ahNew ) return LSM_NOMEM_BKPT; apNew = (LPVOID *)lsmMallocZero(pWin32File->pEnv, sizeof(LPVOID) * nNew); if( !apNew ){ lsmFree(pWin32File->pEnv, ahNew); return LSM_NOMEM_BKPT; } - memcpy(ahNew, pWin32File->ahShm, sizeof(LPHANDLE) * pWin32File->nShm); + memcpy(ahNew, pWin32File->ahShm, sizeof(HANDLE) * pWin32File->nShm); memcpy(apNew, pWin32File->apShm, sizeof(LPVOID) * pWin32File->nShm); lsmFree(pWin32File->pEnv, pWin32File->ahShm); pWin32File->ahShm = ahNew; diff --git a/manifest b/manifest index af5fe24818..a1e07ad96e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\smemcpy\scalls\sin\sthe\slsmWin32OsShmMap\sfunction\sfor\slsm1. -D 2017-07-07T19:12:55.644 +C Fix\stypos\sin\sWin32\sVFS\sfor\slsm1. +D 2017-07-07T19:22:35.281 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba @@ -250,7 +250,7 @@ F ext/lsm1/lsm_tree.c 53b657439e0fcb1117b0559ad3567ac417f81f2ed0fff9bab79948a00e F ext/lsm1/lsm_unix.c 57361bcf5b1a1a028f5d66571ee490e9064d2cfb145a2cc9e5ddade467bb551b F ext/lsm1/lsm_varint.c b19ae9bd26b5a1e8402fb8a564b25d9542338a41 F ext/lsm1/lsm_vtab.c 812b74a9a7539e8cab49761591ffddc1b3580735fac5d638826c8d2be95ff38b -F ext/lsm1/lsm_win32.c 8ec3bcc7d17c26d33b9f6af32444afa2e02c9002cda0f646946598036d17dbd4 +F ext/lsm1/lsm_win32.c 6695337721cad5fbc226d6df4de5fa8537f47b52b909e0b832e190ad7e32cdb5 F ext/misc/README.md 8e008c8d2b02e09096b31dfba033253ac27c6c06a18aa5826e299fa7601d90b2 F ext/misc/amatch.c 6db4607cb17c54b853a2d7c7c36046d004853f65b9b733e6f019d543d5dfae87 F ext/misc/anycollseq.c 5ffdfde9829eeac52219136ad6aa7cd9a4edb3b15f4f2532de52f4a22525eddb @@ -1628,7 +1628,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2d6faebc319aefeab796c5f2ead4c3c3e2a9dd25c979a16bdb555a109135b13c -R a245078b8c325e979b84d418c47c9bd7 +P aa4890b9f9e9698c61d6ca0e24c26280f5e0a87a8c02865933ad483a1fd44d84 +R 96fb79a3cbe62f69ba1f97462f1b918d U mistachkin -Z dbc992308fb33d5413eb87d5a1383270 +Z eb908a759d0763367678fc7d0ee2727b diff --git a/manifest.uuid b/manifest.uuid index 1759ebe651..17da356b1e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -aa4890b9f9e9698c61d6ca0e24c26280f5e0a87a8c02865933ad483a1fd44d84 \ No newline at end of file +0961ec873b78ad2da0ea9cdf2934bc8f08276375a153fe5d9fa8d4280328deef \ No newline at end of file From a690ff360b182ba01408740852e7e454f9b8d8e4 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 7 Jul 2017 19:43:23 +0000 Subject: [PATCH 16/64] Change the error message text for SQLITE_ERROR to omit the part about "missing database" as that meaning is now obsolete (since approx SQLite 2.0). FossilOrigin-Name: 732f90d6327c5c6368fc8b4cc207bd644ef08e3ae6d2e7295258ab099deaba63 --- ext/fts5/test/fts5aa.test | 4 +- ext/fts5/test/fts5ab.test | 1 - ext/fts5/test/fts5ac.test | 1 - ext/fts5/test/fts5ad.test | 1 - ext/fts5/test/fts5ae.test | 1 - ext/fts5/test/fts5af.test | 1 - ext/fts5/test/fts5ag.test | 1 - ext/fts5/test/fts5ah.test | 1 - ext/fts5/test/fts5ai.test | 1 - ext/fts5/test/fts5aj.test | 1 - ext/fts5/test/fts5ak.test | 1 - ext/fts5/test/fts5al.test | 3 +- ext/fts5/test/fts5alter.test | 1 - ext/fts5/test/fts5auto.test | 1 - ext/fts5/test/fts5aux.test | 1 - ext/fts5/test/fts5auxdata.test | 1 - ext/fts5/test/fts5bigpl.test | 1 - ext/fts5/test/fts5bigtok.test | 2 - ext/fts5/test/fts5colset.test | 2 - ext/fts5/test/fts5config.test | 29 ++-- ext/fts5/test/fts5conflict.test | 2 - ext/fts5/test/fts5content.test | 1 - ext/fts5/test/fts5corrupt.test | 1 - ext/fts5/test/fts5corrupt2.test | 1 - ext/fts5/test/fts5corrupt3.test | 1 - ext/fts5/test/fts5delete.test | 1 - ext/fts5/test/fts5detail.test | 1 - ext/fts5/test/fts5determin.test | 2 - ext/fts5/test/fts5dlidx.test | 1 - ext/fts5/test/fts5doclist.test | 1 - ext/fts5/test/fts5eb.test | 3 - ext/fts5/test/fts5fault1.test | 1 - ext/fts5/test/fts5fault2.test | 1 - ext/fts5/test/fts5fault3.test | 1 - ext/fts5/test/fts5fault4.test | 1 - ext/fts5/test/fts5fault5.test | 1 - ext/fts5/test/fts5fault6.test | 1 - ext/fts5/test/fts5fault7.test | 1 - ext/fts5/test/fts5fault8.test | 1 - ext/fts5/test/fts5fault9.test | 1 - ext/fts5/test/fts5faultA.test | 1 - ext/fts5/test/fts5faultB.test | 1 - ext/fts5/test/fts5full.test | 1 - ext/fts5/test/fts5fuzz1.test | 1 - ext/fts5/test/fts5hash.test | 1 - ext/fts5/test/fts5integrity.test | 1 - ext/fts5/test/fts5lastrowid.test | 1 - ext/fts5/test/fts5leftjoin.test | 2 - ext/fts5/test/fts5matchinfo.test | 1 - ext/fts5/test/fts5merge.test | 1 - ext/fts5/test/fts5merge2.test | 1 - ext/fts5/test/fts5multiclient.test | 1 - ext/fts5/test/fts5near.test | 1 - ext/fts5/test/fts5onepass.test | 1 - ext/fts5/test/fts5optimize.test | 1 - ext/fts5/test/fts5phrase.test | 1 - ext/fts5/test/fts5plan.test | 1 - ext/fts5/test/fts5porter.test | 1 - ext/fts5/test/fts5porter2.test | 1 - ext/fts5/test/fts5prefix.test | 2 - ext/fts5/test/fts5query.test | 2 - ext/fts5/test/fts5rank.test | 1 - ext/fts5/test/fts5rebuild.test | 1 - ext/fts5/test/fts5restart.test | 1 - ext/fts5/test/fts5rowid.test | 1 - ext/fts5/test/fts5simple2.test | 1 - ext/fts5/test/fts5simple3.test | 1 - ext/fts5/test/fts5synonym.test | 1 - ext/fts5/test/fts5synonym2.test | 1 - ext/fts5/test/fts5tok1.test | 2 +- ext/fts5/test/fts5tokenizer.test | 1 - ext/fts5/test/fts5unicode.test | 1 - ext/fts5/test/fts5unicode3.test | 1 - ext/fts5/test/fts5unindexed.test | 1 - ext/fts5/test/fts5update.test | 2 - ext/fts5/test/fts5version.test | 1 - ext/rtree/rtree1.test | 4 +- ext/rtree/rtree8.test | 2 +- ext/rtree/rtree9.test | 6 +- ext/rtree/rtreeD.test | 2 - manifest | 236 ++++++++++++++--------------- manifest.uuid | 2 +- src/main.c | 2 +- src/sqlite.h.in | 2 +- test/capi3.test | 2 +- test/capi3c.test | 2 +- test/e_blobwrite.test | 6 +- test/e_fts3.test | 2 +- test/e_walhook.test | 2 +- test/errmsg.test | 6 +- test/fts1o.test | 4 +- test/fts2g.test | 2 +- test/fts2o.test | 4 +- test/fts3ao.test | 4 +- test/fts3aux1.test | 6 +- test/fts3b.test | 2 +- test/fts3cov.test | 10 +- test/fts3fault.test | 4 +- test/fts3fault2.test | 2 - test/fts3tok1.test | 2 +- test/fts4content.test | 8 +- test/fts4langid.test | 2 +- test/fts4lastrowid.test | 1 - test/fts4merge.test | 2 +- test/having.test | 1 - test/indexexpr2.test | 1 - test/pagerfault.test | 2 +- test/pragma.test | 2 +- test/shell7.test | 2 - test/subjournal.test | 1 - test/triggerF.test | 1 - test/update2.test | 1 - test/vtab1.test | 2 +- test/vtab_alter.test | 2 +- 114 files changed, 183 insertions(+), 281 deletions(-) diff --git a/ext/fts5/test/fts5aa.test b/ext/fts5/test/fts5aa.test index 64c5331c64..a3ea0afc28 100644 --- a/ext/fts5/test/fts5aa.test +++ b/ext/fts5/test/fts5aa.test @@ -441,7 +441,7 @@ db func funk funk do_catchsql_test 16.2 { SELECT funk(), bm25(n1), funk() FROM n1 WHERE n1 MATCH 'a+b+c+d' } {0 {{} -1e-06 {}}} -# {1 {SQL logic error or missing database}} +# {1 {SQL logic error}} #------------------------------------------------------------------------- # @@ -595,5 +595,3 @@ do_execsql_test 22.1 { finish_test - - diff --git a/ext/fts5/test/fts5ab.test b/ext/fts5/test/fts5ab.test index 95da2cd2eb..3979dd44be 100644 --- a/ext/fts5/test/fts5ab.test +++ b/ext/fts5/test/fts5ab.test @@ -294,4 +294,3 @@ do_execsql_test 7.0 { finish_test - diff --git a/ext/fts5/test/fts5ac.test b/ext/fts5/test/fts5ac.test index 61b3230772..f3a914653f 100644 --- a/ext/fts5/test/fts5ac.test +++ b/ext/fts5/test/fts5ac.test @@ -276,4 +276,3 @@ foreach {tn expr tclexpr} { } finish_test - diff --git a/ext/fts5/test/fts5ad.test b/ext/fts5/test/fts5ad.test index 974aa781aa..65c7d4c74f 100644 --- a/ext/fts5/test/fts5ad.test +++ b/ext/fts5/test/fts5ad.test @@ -242,4 +242,3 @@ foreach {T create} { } finish_test - diff --git a/ext/fts5/test/fts5ae.test b/ext/fts5/test/fts5ae.test index 5153306d19..d9f132ca97 100644 --- a/ext/fts5/test/fts5ae.test +++ b/ext/fts5/test/fts5ae.test @@ -309,4 +309,3 @@ foreach {tn q cnt} { } finish_test - diff --git a/ext/fts5/test/fts5af.test b/ext/fts5/test/fts5af.test index 6aab55a557..fa4ebd2955 100644 --- a/ext/fts5/test/fts5af.test +++ b/ext/fts5/test/fts5af.test @@ -178,4 +178,3 @@ do_execsql_test 5.1 { } ;# foreach_detail_mode finish_test - diff --git a/ext/fts5/test/fts5ag.test b/ext/fts5/test/fts5ag.test index de126a25f0..9ead957c9d 100644 --- a/ext/fts5/test/fts5ag.test +++ b/ext/fts5/test/fts5ag.test @@ -142,4 +142,3 @@ if {[detail_is_full]} { finish_test - diff --git a/ext/fts5/test/fts5ah.test b/ext/fts5/test/fts5ah.test index b7beb5655b..24613f5c41 100644 --- a/ext/fts5/test/fts5ah.test +++ b/ext/fts5/test/fts5ah.test @@ -167,4 +167,3 @@ do_execsql_test 1.8.2 { #db eval {SELECT rowid, fts5_decode(rowid, block) aS r FROM t1_data} {puts $r} finish_test - diff --git a/ext/fts5/test/fts5ai.test b/ext/fts5/test/fts5ai.test index e32c806c46..24e780a7dd 100644 --- a/ext/fts5/test/fts5ai.test +++ b/ext/fts5/test/fts5ai.test @@ -55,4 +55,3 @@ do_execsql_test 1.2 { finish_test - diff --git a/ext/fts5/test/fts5aj.test b/ext/fts5/test/fts5aj.test index 6b9dddd8b0..50dae20162 100644 --- a/ext/fts5/test/fts5aj.test +++ b/ext/fts5/test/fts5aj.test @@ -66,4 +66,3 @@ do_execsql_test 2.0 { INSERT INTO t1(t1) VALUES('integrity-check') } finish_test - diff --git a/ext/fts5/test/fts5ak.test b/ext/fts5/test/fts5ak.test index 0f699a601f..cab0ae2d3e 100644 --- a/ext/fts5/test/fts5ak.test +++ b/ext/fts5/test/fts5ak.test @@ -147,4 +147,3 @@ do_execsql_test 3.1 { } finish_test - diff --git a/ext/fts5/test/fts5al.test b/ext/fts5/test/fts5al.test index c0dd2117dd..842d991a37 100644 --- a/ext/fts5/test/fts5al.test +++ b/ext/fts5/test/fts5al.test @@ -77,7 +77,7 @@ foreach {tn defn} { } { do_test 2.2.$tn { catchsql { INSERT INTO ft1(ft1, rank) VALUES('rank', $defn) } - } {1 {SQL logic error or missing database}} + } {1 {SQL logic error}} } #------------------------------------------------------------------------- @@ -297,4 +297,3 @@ do_catchsql_test 4.4.4 { finish_test - diff --git a/ext/fts5/test/fts5alter.test b/ext/fts5/test/fts5alter.test index eae01b7386..8b80a85e99 100644 --- a/ext/fts5/test/fts5alter.test +++ b/ext/fts5/test/fts5alter.test @@ -100,4 +100,3 @@ do_execsql_test 3.3 { } {1 2} finish_test - diff --git a/ext/fts5/test/fts5auto.test b/ext/fts5/test/fts5auto.test index 218b3f4862..79d432b812 100644 --- a/ext/fts5/test/fts5auto.test +++ b/ext/fts5/test/fts5auto.test @@ -342,4 +342,3 @@ foreach {tn expr} { finish_test - diff --git a/ext/fts5/test/fts5aux.test b/ext/fts5/test/fts5aux.test index fa3167a4d1..ad2ea82ea0 100644 --- a/ext/fts5/test/fts5aux.test +++ b/ext/fts5/test/fts5aux.test @@ -279,4 +279,3 @@ do_execsql_test 9.3 { finish_test - diff --git a/ext/fts5/test/fts5auxdata.test b/ext/fts5/test/fts5auxdata.test index dbbb1dba78..a2a41704c5 100644 --- a/ext/fts5/test/fts5auxdata.test +++ b/ext/fts5/test/fts5auxdata.test @@ -112,4 +112,3 @@ db eval { } finish_test - diff --git a/ext/fts5/test/fts5bigpl.test b/ext/fts5/test/fts5bigpl.test index 85f74606c6..2c9df11b1f 100644 --- a/ext/fts5/test/fts5bigpl.test +++ b/ext/fts5/test/fts5bigpl.test @@ -61,4 +61,3 @@ do_test 2.1...slow { } {} finish_test - diff --git a/ext/fts5/test/fts5bigtok.test b/ext/fts5/test/fts5bigtok.test index 9ccaf6c860..f74ec8f665 100644 --- a/ext/fts5/test/fts5bigtok.test +++ b/ext/fts5/test/fts5bigtok.test @@ -64,5 +64,3 @@ foreach_detail_mode $::testprefix { } finish_test - - diff --git a/ext/fts5/test/fts5colset.test b/ext/fts5/test/fts5colset.test index f704496b78..74f23004ac 100644 --- a/ext/fts5/test/fts5colset.test +++ b/ext/fts5/test/fts5colset.test @@ -84,5 +84,3 @@ foreach_detail_mode $::testprefix { finish_test - - diff --git a/ext/fts5/test/fts5config.test b/ext/fts5/test/fts5config.test index 386d112e7d..97b9c5edd5 100644 --- a/ext/fts5/test/fts5config.test +++ b/ext/fts5/test/fts5config.test @@ -66,7 +66,7 @@ foreach {tn val} { } { do_catchsql_test 3.$tn { INSERT INTO t1(t1, rank) VALUES('rank', $val); - } {1 {SQL logic error or missing database}} + } {1 {SQL logic error}} } #------------------------------------------------------------------------- @@ -169,33 +169,33 @@ do_execsql_test 9.0 { } {} do_catchsql_test 9.1.1 { INSERT INTO abc(abc, rank) VALUES('pgsz', -5); -} {1 {SQL logic error or missing database}} +} {1 {SQL logic error}} do_catchsql_test 9.1.2 { INSERT INTO abc(abc, rank) VALUES('pgsz', 50000000); -} {1 {SQL logic error or missing database}} +} {1 {SQL logic error}} do_catchsql_test 9.1.3 { INSERT INTO abc(abc, rank) VALUES('pgsz', 66.67); -} {1 {SQL logic error or missing database}} +} {1 {SQL logic error}} do_catchsql_test 9.2.1 { INSERT INTO abc(abc, rank) VALUES('automerge', -5); -} {1 {SQL logic error or missing database}} +} {1 {SQL logic error}} do_catchsql_test 9.2.2 { INSERT INTO abc(abc, rank) VALUES('automerge', 50000000); -} {1 {SQL logic error or missing database}} +} {1 {SQL logic error}} do_catchsql_test 9.2.3 { INSERT INTO abc(abc, rank) VALUES('automerge', 66.67); -} {1 {SQL logic error or missing database}} +} {1 {SQL logic error}} do_execsql_test 9.2.4 { INSERT INTO abc(abc, rank) VALUES('automerge', 1); } {} do_catchsql_test 9.3.1 { INSERT INTO abc(abc, rank) VALUES('crisismerge', -5); -} {1 {SQL logic error or missing database}} +} {1 {SQL logic error}} do_catchsql_test 9.3.2 { INSERT INTO abc(abc, rank) VALUES('crisismerge', 66.67); -} {1 {SQL logic error or missing database}} +} {1 {SQL logic error}} do_execsql_test 9.3.3 { INSERT INTO abc(abc, rank) VALUES('crisismerge', 1); } {} @@ -205,14 +205,14 @@ do_execsql_test 9.3.4 { do_catchsql_test 9.4.1 { INSERT INTO abc(abc, rank) VALUES('nosuchoption', 1); -} {1 {SQL logic error or missing database}} +} {1 {SQL logic error}} do_catchsql_test 9.5.1 { INSERT INTO abc(abc, rank) VALUES('hashsize', 'not an integer'); -} {1 {SQL logic error or missing database}} +} {1 {SQL logic error}} do_catchsql_test 9.5.2 { INSERT INTO abc(abc, rank) VALUES('hashsize', -500000); -} {1 {SQL logic error or missing database}} +} {1 {SQL logic error}} do_catchsql_test 9.5.3 { INSERT INTO abc(abc, rank) VALUES('hashsize', 500000); } {0 {}} @@ -245,7 +245,7 @@ foreach {tn opt} { do_catchsql_test 12.1 { INSERT INTO t1(t1, rank) VALUES('rank', NULL);; -} {1 {SQL logic error or missing database}} +} {1 {SQL logic error}} #------------------------------------------------------------------------- # errors in the 'usermerge' option @@ -260,8 +260,7 @@ foreach {tn val} { 4 1 } { set sql "INSERT INTO tt(tt, rank) VALUES('usermerge', $val)" - do_catchsql_test 13.$tn $sql {1 {SQL logic error or missing database}} + do_catchsql_test 13.$tn $sql {1 {SQL logic error}} } finish_test - diff --git a/ext/fts5/test/fts5conflict.test b/ext/fts5/test/fts5conflict.test index 5c1e593249..644db53a1e 100644 --- a/ext/fts5/test/fts5conflict.test +++ b/ext/fts5/test/fts5conflict.test @@ -66,5 +66,3 @@ do_execsql_test 2.1 { } finish_test - - diff --git a/ext/fts5/test/fts5content.test b/ext/fts5/test/fts5content.test index 69e66a54f8..a74b26dd2e 100644 --- a/ext/fts5/test/fts5content.test +++ b/ext/fts5/test/fts5content.test @@ -255,4 +255,3 @@ do_execsql_test 6.2 { finish_test - diff --git a/ext/fts5/test/fts5corrupt.test b/ext/fts5/test/fts5corrupt.test index edaafb2379..1462912c65 100644 --- a/ext/fts5/test/fts5corrupt.test +++ b/ext/fts5/test/fts5corrupt.test @@ -96,4 +96,3 @@ do_catchsql_test 3.1 { } {1 {database disk image is malformed}} finish_test - diff --git a/ext/fts5/test/fts5corrupt2.test b/ext/fts5/test/fts5corrupt2.test index c10017a266..74721e5398 100644 --- a/ext/fts5/test/fts5corrupt2.test +++ b/ext/fts5/test/fts5corrupt2.test @@ -269,4 +269,3 @@ do_catchsql_test 6.2 { sqlite3_fts5_may_be_corrupt 0 finish_test - diff --git a/ext/fts5/test/fts5corrupt3.test b/ext/fts5/test/fts5corrupt3.test index 9653bcaac2..72e9ab17c5 100644 --- a/ext/fts5/test/fts5corrupt3.test +++ b/ext/fts5/test/fts5corrupt3.test @@ -409,4 +409,3 @@ do_catchsql_test 9.2.2 { sqlite3_fts5_may_be_corrupt 0 finish_test - diff --git a/ext/fts5/test/fts5delete.test b/ext/fts5/test/fts5delete.test index 15d62c552d..488ce02f1b 100644 --- a/ext/fts5/test/fts5delete.test +++ b/ext/fts5/test/fts5delete.test @@ -51,4 +51,3 @@ do_test 1.2 { } {} finish_test - diff --git a/ext/fts5/test/fts5detail.test b/ext/fts5/test/fts5detail.test index 58fda3e995..cf4b718ba0 100644 --- a/ext/fts5/test/fts5detail.test +++ b/ext/fts5/test/fts5detail.test @@ -241,4 +241,3 @@ do_execsql_test 5.3 { finish_test - diff --git a/ext/fts5/test/fts5determin.test b/ext/fts5/test/fts5determin.test index e368c4704e..c9094edfa1 100644 --- a/ext/fts5/test/fts5determin.test +++ b/ext/fts5/test/fts5determin.test @@ -63,5 +63,3 @@ foreach_detail_mode $::testprefix { finish_test - - diff --git a/ext/fts5/test/fts5dlidx.test b/ext/fts5/test/fts5dlidx.test index 655beb984b..c8071e1f75 100644 --- a/ext/fts5/test/fts5dlidx.test +++ b/ext/fts5/test/fts5dlidx.test @@ -197,4 +197,3 @@ foreach v $vocab { finish_test - diff --git a/ext/fts5/test/fts5doclist.test b/ext/fts5/test/fts5doclist.test index 411289a523..d8308fd0fa 100644 --- a/ext/fts5/test/fts5doclist.test +++ b/ext/fts5/test/fts5doclist.test @@ -44,4 +44,3 @@ do_execsql_test 1.2 { finish_test - diff --git a/ext/fts5/test/fts5eb.test b/ext/fts5/test/fts5eb.test index 510a0d790c..dd66decb9b 100644 --- a/ext/fts5/test/fts5eb.test +++ b/ext/fts5/test/fts5eb.test @@ -81,6 +81,3 @@ do_execsql_test 3.3 { finish_test - - - diff --git a/ext/fts5/test/fts5fault1.test b/ext/fts5/test/fts5fault1.test index 9d63a1175f..96025133e4 100644 --- a/ext/fts5/test/fts5fault1.test +++ b/ext/fts5/test/fts5fault1.test @@ -351,4 +351,3 @@ do_faultsim_test 9.1 -faults oom-* -prep { finish_test - diff --git a/ext/fts5/test/fts5fault2.test b/ext/fts5/test/fts5fault2.test index 43c7c7a3dd..aa21f7b481 100644 --- a/ext/fts5/test/fts5fault2.test +++ b/ext/fts5/test/fts5fault2.test @@ -137,4 +137,3 @@ do_faultsim_test 5.0 -faults oom-* -prep { } finish_test - diff --git a/ext/fts5/test/fts5fault3.test b/ext/fts5/test/fts5fault3.test index bfeead4e23..a294692dbe 100644 --- a/ext/fts5/test/fts5fault3.test +++ b/ext/fts5/test/fts5fault3.test @@ -110,4 +110,3 @@ do_faultsim_test 3.2 -faults oom-* -prep { finish_test - diff --git a/ext/fts5/test/fts5fault4.test b/ext/fts5/test/fts5fault4.test index bfa54a5b04..877e0228ad 100644 --- a/ext/fts5/test/fts5fault4.test +++ b/ext/fts5/test/fts5fault4.test @@ -395,4 +395,3 @@ do_faultsim_test 14.1 -faults oom-t* -prep { } finish_test - diff --git a/ext/fts5/test/fts5fault5.test b/ext/fts5/test/fts5fault5.test index 75b7d9af50..3bb23ac1f9 100644 --- a/ext/fts5/test/fts5fault5.test +++ b/ext/fts5/test/fts5fault5.test @@ -130,4 +130,3 @@ do_faultsim_test 3.3 -faults oom-t* -body { finish_test - diff --git a/ext/fts5/test/fts5fault6.test b/ext/fts5/test/fts5fault6.test index 118761fab5..890905d714 100644 --- a/ext/fts5/test/fts5fault6.test +++ b/ext/fts5/test/fts5fault6.test @@ -292,4 +292,3 @@ do_faultsim_test 6 -faults oom* -prep { db close } finish_test - diff --git a/ext/fts5/test/fts5fault7.test b/ext/fts5/test/fts5fault7.test index a35b19ade2..c93e099f82 100644 --- a/ext/fts5/test/fts5fault7.test +++ b/ext/fts5/test/fts5fault7.test @@ -116,4 +116,3 @@ do_faultsim_test 2.2 -faults oom-* -body { } finish_test - diff --git a/ext/fts5/test/fts5fault8.test b/ext/fts5/test/fts5fault8.test index c613490e54..5afab77541 100644 --- a/ext/fts5/test/fts5fault8.test +++ b/ext/fts5/test/fts5fault8.test @@ -82,4 +82,3 @@ do_faultsim_test 4 -faults oom-* -prep { finish_test - diff --git a/ext/fts5/test/fts5fault9.test b/ext/fts5/test/fts5fault9.test index 908a91d22a..1daa5c1cc9 100644 --- a/ext/fts5/test/fts5fault9.test +++ b/ext/fts5/test/fts5fault9.test @@ -153,4 +153,3 @@ do_faultsim_test 6 -faults oom-* -body { } ;# foreach_detail_mode... finish_test - diff --git a/ext/fts5/test/fts5faultA.test b/ext/fts5/test/fts5faultA.test index 817ccb4ee8..212401fe58 100644 --- a/ext/fts5/test/fts5faultA.test +++ b/ext/fts5/test/fts5faultA.test @@ -61,4 +61,3 @@ do_faultsim_test 2 -faults oom* -prep { faultsim_test_result {0 {1 2}} } finish_test - diff --git a/ext/fts5/test/fts5faultB.test b/ext/fts5/test/fts5faultB.test index e30b03a13e..a4fef523f5 100644 --- a/ext/fts5/test/fts5faultB.test +++ b/ext/fts5/test/fts5faultB.test @@ -132,4 +132,3 @@ do_faultsim_test 4.2 -faults oom* -body { finish_test - diff --git a/ext/fts5/test/fts5full.test b/ext/fts5/test/fts5full.test index c640f56e06..91ded37d8f 100644 --- a/ext/fts5/test/fts5full.test +++ b/ext/fts5/test/fts5full.test @@ -40,4 +40,3 @@ do_test 1.1 { finish_test - diff --git a/ext/fts5/test/fts5fuzz1.test b/ext/fts5/test/fts5fuzz1.test index 599d7bcc89..52dc23d77c 100644 --- a/ext/fts5/test/fts5fuzz1.test +++ b/ext/fts5/test/fts5fuzz1.test @@ -90,4 +90,3 @@ do_catchsql_test 4.1 { } {1 {fts5: syntax error near "`"}} finish_test - diff --git a/ext/fts5/test/fts5hash.test b/ext/fts5/test/fts5hash.test index f3952d6157..e2a34bd1f3 100644 --- a/ext/fts5/test/fts5hash.test +++ b/ext/fts5/test/fts5hash.test @@ -130,4 +130,3 @@ breakpoint } ;# foreach_detail_mode finish_test - diff --git a/ext/fts5/test/fts5integrity.test b/ext/fts5/test/fts5integrity.test index 37ca9331dd..a38b16461c 100644 --- a/ext/fts5/test/fts5integrity.test +++ b/ext/fts5/test/fts5integrity.test @@ -210,4 +210,3 @@ foreach {tn pgsz} { } finish_test - diff --git a/ext/fts5/test/fts5lastrowid.test b/ext/fts5/test/fts5lastrowid.test index 0f7628b233..d152a8f09b 100644 --- a/ext/fts5/test/fts5lastrowid.test +++ b/ext/fts5/test/fts5lastrowid.test @@ -70,4 +70,3 @@ do_execsql_test 1.6 { finish_test - diff --git a/ext/fts5/test/fts5leftjoin.test b/ext/fts5/test/fts5leftjoin.test index f13ca5206b..4ef6a8961b 100644 --- a/ext/fts5/test/fts5leftjoin.test +++ b/ext/fts5/test/fts5leftjoin.test @@ -41,5 +41,3 @@ do_execsql_test 1.2 { } {1 abc 2 abc} finish_test - - diff --git a/ext/fts5/test/fts5matchinfo.test b/ext/fts5/test/fts5matchinfo.test index 99b07677af..13ad18fd2f 100644 --- a/ext/fts5/test/fts5matchinfo.test +++ b/ext/fts5/test/fts5matchinfo.test @@ -492,4 +492,3 @@ do_catchsql_test 14.2 { } {1 {unrecognized matchinfo flag: d}} finish_test - diff --git a/ext/fts5/test/fts5merge.test b/ext/fts5/test/fts5merge.test index 73e006a7d2..3b86167b0d 100644 --- a/ext/fts5/test/fts5merge.test +++ b/ext/fts5/test/fts5merge.test @@ -241,4 +241,3 @@ do_execsql_test 6.3 { finish_test - diff --git a/ext/fts5/test/fts5merge2.test b/ext/fts5/test/fts5merge2.test index 0d3fad8b08..e8f5bb161c 100644 --- a/ext/fts5/test/fts5merge2.test +++ b/ext/fts5/test/fts5merge2.test @@ -55,4 +55,3 @@ do_execsql_test 1.2 { } finish_test - diff --git a/ext/fts5/test/fts5multiclient.test b/ext/fts5/test/fts5multiclient.test index a1e9aa0d30..c3716fc111 100644 --- a/ext/fts5/test/fts5multiclient.test +++ b/ext/fts5/test/fts5multiclient.test @@ -45,4 +45,3 @@ do_multiclient_test tn { };# do_multiclient_test };# foreach_detail_mode finish_test - diff --git a/ext/fts5/test/fts5near.test b/ext/fts5/test/fts5near.test index b4ae205dee..bbe144a898 100644 --- a/ext/fts5/test/fts5near.test +++ b/ext/fts5/test/fts5near.test @@ -68,4 +68,3 @@ do_near_test 1.25 "a b c d e f g h i" { NEAR(i a+b+c+d b+c, 4) } 0 finish_test - diff --git a/ext/fts5/test/fts5onepass.test b/ext/fts5/test/fts5onepass.test index a614b780a2..01021ed348 100644 --- a/ext/fts5/test/fts5onepass.test +++ b/ext/fts5/test/fts5onepass.test @@ -178,4 +178,3 @@ do_execsql_test 4.3.1 { do_test 4.2.2 { fts5_level_segs ttt } {3} finish_test - diff --git a/ext/fts5/test/fts5optimize.test b/ext/fts5/test/fts5optimize.test index 3ef6d8a165..e0f0fd7242 100644 --- a/ext/fts5/test/fts5optimize.test +++ b/ext/fts5/test/fts5optimize.test @@ -106,4 +106,3 @@ foreach {tn nStep} { do_test 2.$tn.6 { fts5_segcount t1 } 1 } finish_test - diff --git a/ext/fts5/test/fts5phrase.test b/ext/fts5/test/fts5phrase.test index 6dac684e83..10598ccf43 100644 --- a/ext/fts5/test/fts5phrase.test +++ b/ext/fts5/test/fts5phrase.test @@ -116,4 +116,3 @@ do_execsql_test 2.0 { } finish_test - diff --git a/ext/fts5/test/fts5plan.test b/ext/fts5/test/fts5plan.test index 114980e85a..a7b70f5b73 100644 --- a/ext/fts5/test/fts5plan.test +++ b/ext/fts5/test/fts5plan.test @@ -64,4 +64,3 @@ do_eqp_test 1.5 { finish_test - diff --git a/ext/fts5/test/fts5porter.test b/ext/fts5/test/fts5porter.test index 2535eb75b1..c7b1ce6f3f 100644 --- a/ext/fts5/test/fts5porter.test +++ b/ext/fts5/test/fts5porter.test @@ -11803,4 +11803,3 @@ foreach {in out} $test_vocab { finish_test - diff --git a/ext/fts5/test/fts5porter2.test b/ext/fts5/test/fts5porter2.test index 5e0aeb029f..6e81b2d310 100644 --- a/ext/fts5/test/fts5porter2.test +++ b/ext/fts5/test/fts5porter2.test @@ -67,4 +67,3 @@ foreach {in out} $test_vocab { finish_test - diff --git a/ext/fts5/test/fts5prefix.test b/ext/fts5/test/fts5prefix.test index 01d0fe5d14..279f312f22 100644 --- a/ext/fts5/test/fts5prefix.test +++ b/ext/fts5/test/fts5prefix.test @@ -341,5 +341,3 @@ foreach {tn create} { } finish_test - - diff --git a/ext/fts5/test/fts5query.test b/ext/fts5/test/fts5query.test index 570abf46ba..854651ef4f 100644 --- a/ext/fts5/test/fts5query.test +++ b/ext/fts5/test/fts5query.test @@ -79,5 +79,3 @@ for {set tn 1 ; set pgsz 64} {$tn<32} {incr tn; incr pgsz 16} { finish_test - - diff --git a/ext/fts5/test/fts5rank.test b/ext/fts5/test/fts5rank.test index 2cef8718b7..1268eebe3c 100644 --- a/ext/fts5/test/fts5rank.test +++ b/ext/fts5/test/fts5rank.test @@ -152,4 +152,3 @@ do_execsql_test 4.1 { finish_test - diff --git a/ext/fts5/test/fts5rebuild.test b/ext/fts5/test/fts5rebuild.test index 1044421d5e..01918310f7 100644 --- a/ext/fts5/test/fts5rebuild.test +++ b/ext/fts5/test/fts5rebuild.test @@ -64,4 +64,3 @@ do_catchsql_test 2.2 { INSERT INTO nc(nc) VALUES('rebuild'); } {1 {'rebuild' may not be used with a contentless fts5 table}} finish_test - diff --git a/ext/fts5/test/fts5restart.test b/ext/fts5/test/fts5restart.test index 0dd7d69454..db2c62b675 100644 --- a/ext/fts5/test/fts5restart.test +++ b/ext/fts5/test/fts5restart.test @@ -149,4 +149,3 @@ do_test 4.3 { finish_test - diff --git a/ext/fts5/test/fts5rowid.test b/ext/fts5/test/fts5rowid.test index 19590cdf0d..e7fd1bc2c5 100644 --- a/ext/fts5/test/fts5rowid.test +++ b/ext/fts5/test/fts5rowid.test @@ -216,4 +216,3 @@ do_execsql_test 6.2 { finish_test - diff --git a/ext/fts5/test/fts5simple2.test b/ext/fts5/test/fts5simple2.test index a6c1789473..e57cea70fa 100644 --- a/ext/fts5/test/fts5simple2.test +++ b/ext/fts5/test/fts5simple2.test @@ -370,4 +370,3 @@ do_execsql_test 17.6 { #db eval {SELECT rowid, fts5_decode_none(rowid, block) aS r FROM t2_data} {puts $r} finish_test - diff --git a/ext/fts5/test/fts5simple3.test b/ext/fts5/test/fts5simple3.test index c755ea0567..0d4972b372 100644 --- a/ext/fts5/test/fts5simple3.test +++ b/ext/fts5/test/fts5simple3.test @@ -116,4 +116,3 @@ do_execsql_test 4.6 { finish_test - diff --git a/ext/fts5/test/fts5synonym.test b/ext/fts5/test/fts5synonym.test index 6243663123..86610ee9eb 100644 --- a/ext/fts5/test/fts5synonym.test +++ b/ext/fts5/test/fts5synonym.test @@ -421,4 +421,3 @@ do_execsql_test 7.1.2 { } ;# foreach_detail_mode finish_test - diff --git a/ext/fts5/test/fts5synonym2.test b/ext/fts5/test/fts5synonym2.test index 7e92822c33..8bbfb07566 100644 --- a/ext/fts5/test/fts5synonym2.test +++ b/ext/fts5/test/fts5synonym2.test @@ -161,4 +161,3 @@ foreach {tn expr} { } finish_test - diff --git a/ext/fts5/test/fts5tok1.test b/ext/fts5/test/fts5tok1.test index 6ba170062e..a336f1173e 100644 --- a/ext/fts5/test/fts5tok1.test +++ b/ext/fts5/test/fts5tok1.test @@ -109,7 +109,7 @@ do_catchsql_test 2.0 { do_catchsql_test 2.1 { CREATE VIRTUAL TABLE t4 USING fts5tokenize; SELECT * FROM t4; -} {1 {SQL logic error or missing database}} +} {1 {SQL logic error}} finish_test diff --git a/ext/fts5/test/fts5tokenizer.test b/ext/fts5/test/fts5tokenizer.test index f68aa19a10..e71979ecab 100644 --- a/ext/fts5/test/fts5tokenizer.test +++ b/ext/fts5/test/fts5tokenizer.test @@ -302,4 +302,3 @@ do_test 9.5.2 { set ::flags } {query} finish_test - diff --git a/ext/fts5/test/fts5unicode.test b/ext/fts5/test/fts5unicode.test index 46f4c4f1aa..aa203a2f0e 100644 --- a/ext/fts5/test/fts5unicode.test +++ b/ext/fts5/test/fts5unicode.test @@ -59,4 +59,3 @@ do_execsql_test 2.1 " finish_test - diff --git a/ext/fts5/test/fts5unicode3.test b/ext/fts5/test/fts5unicode3.test index 876ad27461..99f9c8c953 100644 --- a/ext/fts5/test/fts5unicode3.test +++ b/ext/fts5/test/fts5unicode3.test @@ -126,4 +126,3 @@ do_test 1.5 { finish_test - diff --git a/ext/fts5/test/fts5unindexed.test b/ext/fts5/test/fts5unindexed.test index 16d43f84c2..8b72c4c776 100644 --- a/ext/fts5/test/fts5unindexed.test +++ b/ext/fts5/test/fts5unindexed.test @@ -76,4 +76,3 @@ do_execsql_test 3.2 { finish_test - diff --git a/ext/fts5/test/fts5update.test b/ext/fts5/test/fts5update.test index 399c7ffb11..b558c2fb7d 100644 --- a/ext/fts5/test/fts5update.test +++ b/ext/fts5/test/fts5update.test @@ -117,5 +117,3 @@ do_execsql_test 2.2.integrity { } finish_test - - diff --git a/ext/fts5/test/fts5version.test b/ext/fts5/test/fts5version.test index 7e4d74d114..58cd3488b7 100644 --- a/ext/fts5/test/fts5version.test +++ b/ext/fts5/test/fts5version.test @@ -61,4 +61,3 @@ do_test 1.7 { finish_test - diff --git a/ext/rtree/rtree1.test b/ext/rtree/rtree1.test index a29cfb945d..8d17c456e6 100644 --- a/ext/rtree/rtree1.test +++ b/ext/rtree/rtree1.test @@ -338,7 +338,7 @@ do_test rtree-7.2.1 { CREATE TABLE t4_node(a); } catchsql { ALTER TABLE "abc 123" RENAME TO t4 } -} {1 {SQL logic error or missing database}} +} {1 {SQL logic error}} do_test rtree-7.2.2 { execsql_intout { SELECT * FROM "abc 123" } } {1 2 3 4 5 6 7} @@ -348,7 +348,7 @@ do_test rtree-7.2.3 { CREATE TABLE t4_rowid(a); } catchsql { ALTER TABLE "abc 123" RENAME TO t4 } -} {1 {SQL logic error or missing database}} +} {1 {SQL logic error}} do_test rtree-7.2.4 { db close sqlite3 db test.db diff --git a/ext/rtree/rtree8.test b/ext/rtree/rtree8.test index 578a1468b8..024d098e07 100644 --- a/ext/rtree/rtree8.test +++ b/ext/rtree/rtree8.test @@ -129,7 +129,7 @@ do_execsql_test rtree8-2.2.3 { populate_t1 10 do_catchsql_test rtree8-3.1 { SELECT * FROM t1 WHERE x1 MATCH '1234' -} {1 {SQL logic error or missing database}} +} {1 {SQL logic error}} #------------------------------------------------------------------------- # Test a couple of invalid arguments to rtreedepth(). diff --git a/ext/rtree/rtree9.test b/ext/rtree/rtree9.test index 571341b2a9..b2361b2bd0 100644 --- a/ext/rtree/rtree9.test +++ b/ext/rtree/rtree9.test @@ -69,17 +69,17 @@ do_execsql_test rtree9-3.3 { do_catchsql_test rtree9-4.1 { SELECT id FROM rt32 WHERE id MATCH cube(5.5, 5.5, 1, 1, 1) ORDER BY id; -} {1 {SQL logic error or missing database}} +} {1 {SQL logic error}} for {set x 2} {$x<200} {incr x 2} { do_catchsql_test rtree9-4.2.[expr $x/2] { SELECT id FROM rt WHERE id MATCH randomblob($x) - } {1 {SQL logic error or missing database}} + } {1 {SQL logic error}} } do_catchsql_test rtree9-4.3 { SELECT id FROM rt WHERE id MATCH CAST( (cube(5.5, 5.5, 5.5, 1, 1, 1) || X'1234567812345678') AS blob ) -} {1 {SQL logic error or missing database}} +} {1 {SQL logic error}} #------------------------------------------------------------------------- diff --git a/ext/rtree/rtreeD.test b/ext/rtree/rtreeD.test index d846fc61ff..7f92898b0a 100644 --- a/ext/rtree/rtreeD.test +++ b/ext/rtree/rtreeD.test @@ -53,5 +53,3 @@ do_multiclient_test tn { } finish_test - - diff --git a/manifest b/manifest index a1e07ad96e..0f6d0fc92b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\stypos\sin\sWin32\sVFS\sfor\slsm1. -D 2017-07-07T19:22:35.281 +C Change\sthe\serror\smessage\stext\sfor\sSQLITE_ERROR\sto\somit\sthe\spart\sabout\n"missing\sdatabase"\sas\sthat\smeaning\sis\snow\sobsolete\s(since\sapprox\sSQLite\s2.0). +D 2017-07-07T19:43:23.476 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba @@ -118,88 +118,88 @@ F ext/fts5/fts5_vocab.c e44fefa7f0c1db252998af071daf06a7147e17e7 F ext/fts5/fts5parse.y a070b538e08ae9e2177d15c337ed2a3464408f0f886e746307098f746efd94ca F ext/fts5/mkportersteps.tcl 5acf962d2e0074f701620bb5308155fa1e4a63ba F ext/fts5/test/fts5_common.tcl b01c584144b5064f30e6c648145a2dd6bc440841 -F ext/fts5/test/fts5aa.test 6dd1bfa4426a8d77e8c8d447aad02515c85118b082f24053ac89802300077ff1 -F ext/fts5/test/fts5ab.test 30325a89453280160106be411bba3acf138e6d1b -F ext/fts5/test/fts5ac.test 55cad4275a1f5acabfe14d8442a8046b47e49e5f -F ext/fts5/test/fts5ad.test 36995f0586f30f5602074e012b9224c71ec5171c -F ext/fts5/test/fts5ae.test 612dcb51f4069226791ff14c17dbfb3138c56f20 -F ext/fts5/test/fts5af.test c92825778ed2adc80014832762c056bbe968ef88 -F ext/fts5/test/fts5ag.test 27180de76c03036be75ee80b93d8c5f540014071 -F ext/fts5/test/fts5ah.test dfb7897711dbcda1dacb038aec310daca139fcf5 -F ext/fts5/test/fts5ai.test 3909d0b949b2afcaae4d5795cd79153da75381df -F ext/fts5/test/fts5aj.test 05b569f5c16ea3098fb1984eec5cf50dbdaae5d8 -F ext/fts5/test/fts5ak.test fb26389985407826f6076bb9f382c67d3db6b5d9 -F ext/fts5/test/fts5al.test 18c277f5986df0a3d9071dfd7128afeb16fe9d5d -F ext/fts5/test/fts5alter.test 6022c61467a82aa11c70822ccad22b328dcf0d04 -F ext/fts5/test/fts5auto.test 401c20e89f1114d733b94809be1e6f893e16c09e -F ext/fts5/test/fts5aux.test 5dd158a1e7869e27e9762a2a452b189c728d1be3 -F ext/fts5/test/fts5auxdata.test 141a7cbffcceb1bd2799b4b29c183ff8780d586e -F ext/fts5/test/fts5bigpl.test 04ee0d7eebbebf17c31f5a0b5c5f9494eac3a0cb -F ext/fts5/test/fts5bigtok.test 017a9397b14e7598883a6328ead4a6539b42d59a -F ext/fts5/test/fts5colset.test 97084e7fd3183a3c148ade1d4ad980b7e764cb2711ac77c3176680c3e75ea2b9 +F ext/fts5/test/fts5aa.test cba3fae6466446980caf1b9f5f26df77f95a999d35db7d932d6e82ae7ba0ede9 +F ext/fts5/test/fts5ab.test 9205c839332c908aaad2b01ab8670ece8b161e8f2ec8a9fabf18ca9385880bb7 +F ext/fts5/test/fts5ac.test a7aa7e1fefc6e1918aa4d3111d5c44a09177168e962c5fd2cca9620de8a7ed6d +F ext/fts5/test/fts5ad.test fc1dbd6307913fbf36c45c1e49e1733a8706f8343b93407f2d2d90f1f9ca3bd0 +F ext/fts5/test/fts5ae.test 1142d16d9cc193894dc13cc8f9c7a8a21411ac61b5567a878514df6f9f0d7bb7 +F ext/fts5/test/fts5af.test aa635947bda31ac87fbe99483eef4d9a8571f58ad89c75dfb63312a35688eceb +F ext/fts5/test/fts5ag.test 7816f25a0707578f08145ab539fc0ca025f8951e788b28a6a18a06b2099469dd +F ext/fts5/test/fts5ah.test 27b5a33bfd0363ca8a4dc659e6e2a5df3dea1c3c5b04bc51ca6aeb1277bd9b21 +F ext/fts5/test/fts5ai.test d837c42249c0d8ad1a2912270e22cf2f303790a611f85c0be3a58e42a3696e3d +F ext/fts5/test/fts5aj.test 745020852d85f5dd49d11cb7ad11d3cc6dafc4fe6d6d24bc0875ac8f43ee4149 +F ext/fts5/test/fts5ak.test 0d41cbf04e70249c84670e1782aa8972e4f67d91c9bc6205d0ba7c34e159481b +F ext/fts5/test/fts5al.test 00c4c1c6a1366b73aa48ce2068c634520867c3cf7f5d1676ebbb775ee1f35734 +F ext/fts5/test/fts5alter.test a15637efe5333134e0969180b15c7bba567f76c5082952f11f1d60bbdf2e0977 +F ext/fts5/test/fts5auto.test 78989e6527ce69c9eddbef7392fea5c10b0010cd2b2ae68eec7bc869c471e691 +F ext/fts5/test/fts5aux.test 10be2b1efd0d5f51a905e2eab7ad6678c2ad0be9bb78fa55029a38125401db8a +F ext/fts5/test/fts5auxdata.test eacc97ff04892f1a5f3d4df5a73f8bcbc3955ea1d12c9f24137eb1fc079e7611 +F ext/fts5/test/fts5bigpl.test 6466c89b38439f0aba26ac09e232a6b963f29b1cbe1304f6a664fe1e7a8f5fd3 +F ext/fts5/test/fts5bigtok.test 541119e616c637caea925a8c028c37c2c29e94383e00aa2f9198d530724b6e36 +F ext/fts5/test/fts5colset.test a30473451321bbf0b6218af62e96b4ae5fa99931cfdb210b5ecc804623b30f75 F ext/fts5/test/fts5columnsize.test a8cfef21ffa1c264b9f670a7d94eeaccb5341c07 -F ext/fts5/test/fts5config.test 7788b9c058074d640dfcdd81d97b6a9480000368 -F ext/fts5/test/fts5conflict.test 26f4e46c4d31e16221794832a990dc4e30e18de5 -F ext/fts5/test/fts5content.test 9a952c95518a14182dc3b59e3c8fa71cda82a4e1 -F ext/fts5/test/fts5corrupt.test c2ad090192708150d50d961278df10ae7a4b8b62 -F ext/fts5/test/fts5corrupt2.test 128eb6e2d26b09f4da339e581f424b3321e0fdaa -F ext/fts5/test/fts5corrupt3.test f77f65e386231daf62902466b40ff998b2c8ce4f -F ext/fts5/test/fts5delete.test 0585395660889090a6a04b0cac0e70b16801da44ee321534d6169da49af8167f -F ext/fts5/test/fts5detail.test ef5c690535a797413acaf5ad9b8ab5d49972df69 -F ext/fts5/test/fts5determin.test 10648edb75ef1e196b10978fd21a9be0c31e09c3 -F ext/fts5/test/fts5dlidx.test 007e9390c94638760797dbec2990c97c3fa08dfe -F ext/fts5/test/fts5doclist.test 8edb5b57e5f144030ed74ec00ef6fa4294fed79b +F ext/fts5/test/fts5config.test 068dfb917544412d7ab409822432ac989ece7684c8404bcb8da48755b5658798 +F ext/fts5/test/fts5conflict.test 655925678e630d3cdf145d18725a558971806416f453ac8410ca8c04d934238d +F ext/fts5/test/fts5content.test 688d5ac7af194ebc67495daea76a69e3cd5480122c2320e72d41241b423b4116 +F ext/fts5/test/fts5corrupt.test 8957f0f7e57e0f8a102c5b6e1a7326d6a1966b28e1d99c5883822af1e6038e9e +F ext/fts5/test/fts5corrupt2.test 6deaf9f9606b3c957529db9881622bb3a7829b19bb3cdf8f276f074d684ede56 +F ext/fts5/test/fts5corrupt3.test 1b489101212206da1f27d0d03b9667e54571cba72db7e70b195fdf39f867b48c +F ext/fts5/test/fts5delete.test cbf87e3b8867c4d5cfcaed975c7475fd3f99d072bce2075fcedf43d1f82af775 +F ext/fts5/test/fts5detail.test 31b240dbf6d44ac3507e2f8b65f29fdc12465ffd531212378c7ce1066766f54e +F ext/fts5/test/fts5determin.test 1b77879b2ae818b5b71c859e534ee334dac088b7cf3ff3bf76a2c82b1c788d11 +F ext/fts5/test/fts5dlidx.test 60a02a55c20382826fbdd3e2118dbef8b24aeb3bfe0bbf213f94063165131f8e +F ext/fts5/test/fts5doclist.test e39a6001495f1dc68e20323586ac965787986c2bf6f515b9b0285627b089d9e6 F ext/fts5/test/fts5ea.test b01e3a18cdfabbff8104a96a5242a06a68a998a0 -F ext/fts5/test/fts5eb.test 14597b5ecc9b2b7039ac5e0b0fca0311a7d22005 -F ext/fts5/test/fts5fault1.test e09040d3e17b8c0837101e8c79c8a874c4376fb7 -F ext/fts5/test/fts5fault2.test d8c6c7f916ccbdfc10b2c69530e9dd3bc8313232 -F ext/fts5/test/fts5fault3.test d6e9577d4312e331a913c72931bf131704efc8f3 -F ext/fts5/test/fts5fault4.test dcbe3043c5611edd350191ea03a8daa190f0de5a -F ext/fts5/test/fts5fault5.test 10c13a783de3f42a21e3e53e123b62ed0c3a1618 -F ext/fts5/test/fts5fault6.test 9682664d679643ac6736e90c225526cc84073cda -F ext/fts5/test/fts5fault7.test cb14ea3c1f42394f06f2284abc58eecee6ff8080 -F ext/fts5/test/fts5fault8.test 6785af34bd1760de74e2824ea9c161965af78f85 -F ext/fts5/test/fts5fault9.test e10e395428a9ea0596ebe752ff7123d16ab78e08 -F ext/fts5/test/fts5faultA.test fa5d59c0ff62b7125cd14eee38ded1c46e15a7ea -F ext/fts5/test/fts5faultB.test 8a7e4c89c663e599e88fa1b9f2b8dcf4b85a338bd250e1a94341773b1e9ebfcc +F ext/fts5/test/fts5eb.test e5fe57b4141db456f06094afca45541fb0c13b30032eccae05100b4dbec11955 +F ext/fts5/test/fts5fault1.test d28a65caee75db6897c3cf1358c5230d3bb2a3bf7fb31062c19c7e5382b3d2bd +F ext/fts5/test/fts5fault2.test 69c8fdbef830cd0d450908d4504d5bb86609e255af99c421c20a0756251fe344 +F ext/fts5/test/fts5fault3.test da2f9e3e56ff5740d68ebdd6877c97089e7ed28ddff28a0da87a6afea27e5522 +F ext/fts5/test/fts5fault4.test 1c1db5fcfe59401e7833146100f1d8de284a0a686fac31ddac9fb56c459f725b +F ext/fts5/test/fts5fault5.test 4ed4888a8274e667b5f55a57bd477f5f925b26f296c0668573e93db4f2a68913 +F ext/fts5/test/fts5fault6.test 143533e8c5601f56556ed5c7e7e7f3fc32f45ff11f54569435c5ddc8098ce65a +F ext/fts5/test/fts5fault7.test 0acbec416edb24b8881f154e99c31e9ccf73f539cfcd164090be139e9e97ed4c +F ext/fts5/test/fts5fault8.test 318238659d35f82ad215ecb57ca4c87486ea85d45dbeedaee42f148ff5105ee2 +F ext/fts5/test/fts5fault9.test 0111b229388bdf251b91cfead68580227801dd30960a19aa8fe9021a1e73cb6d +F ext/fts5/test/fts5faultA.test be4487576bff8c22cee6597d1893b312f306504a8c6ccd3c53ca85af12290c8c +F ext/fts5/test/fts5faultB.test 28810d93d37b59ebd5cf9502897f4dc9e6adb8ea6a5f64e125d3088597199d0d F ext/fts5/test/fts5faultD.test cc5d1225556e356615e719c612e845d41bff7d5a -F ext/fts5/test/fts5full.test 6f6143af0c6700501d9fd597189dfab1555bb741 -F ext/fts5/test/fts5fuzz1.test bece4695fc169b61ab236ada7931c6e4942cbef9 -F ext/fts5/test/fts5hash.test 06f9309ccb4d5050a131594e9e47d0b21456837d -F ext/fts5/test/fts5integrity.test f5e4f8d284385875068ad0f3e894ce43e9de835d -F ext/fts5/test/fts5lastrowid.test 4fac1aba696dd6c956e03b0cf91f6f1f3aaec494 -F ext/fts5/test/fts5leftjoin.test 513ad7a7c053f8a6b7968ed6c84d1fc8c7a84fd29cfde0d14cc085ae6ca682c6 -F ext/fts5/test/fts5matchinfo.test f7dde99697bcb310ea8faa8eb2714d9f4dfc0e1b -F ext/fts5/test/fts5merge.test 9f65f090d214ff865c56bef4f864aaa1182af6e3 -F ext/fts5/test/fts5merge2.test a6da3c16d694235938d1939f503cfa53f0943d75 -F ext/fts5/test/fts5multiclient.test 5bd54a6bc8ff818be233a50a8dec93da99098f2a -F ext/fts5/test/fts5near.test b214cddb1c1f1bddf45c75af768f20145f7e71cc -F ext/fts5/test/fts5onepass.test 7ed9608e258132cb8d55e7c479b08676ad68810c -F ext/fts5/test/fts5optimize.test 9d3ac53bb9cae58cb070d795db86bcb2f9fec105 -F ext/fts5/test/fts5phrase.test f6d1d464da5beb25dc56277aa4f1d6102f0d9a2f -F ext/fts5/test/fts5plan.test fb0ee60c9a092b17bb958dd742f01e3731b520d50b5d61b288c49c7acdc286cb -F ext/fts5/test/fts5porter.test 7cdc07bef301d70eebbfa75dcaf45c3680e1d0e1 -F ext/fts5/test/fts5porter2.test 2e65633d58a1c525d5af0f6c01e5a59155bb3487 -F ext/fts5/test/fts5prefix.test 6ef7e875738412907b17687d25db39a25cbdaba4 -F ext/fts5/test/fts5query.test f5ec25f5f2fbb70033424113cdffc101b1985a40 -F ext/fts5/test/fts5rank.test 485e1d7ab8b0f939172a88e279acd0894b1f64458f92d7cd5826a31335c6a093 -F ext/fts5/test/fts5rebuild.test 03935f617ace91ed23a6099c7c74d905227ff29b -F ext/fts5/test/fts5restart.test c17728fdea26e7d0f617d22ad5b4b2862b994c17 -F ext/fts5/test/fts5rowid.test 16908a99d6efc9ba21081b4f2b86b3fc699839a6 +F ext/fts5/test/fts5full.test 49b565da02918c06e58f51f0b953b0302b96f155aa68baba24782b81570685e2 +F ext/fts5/test/fts5fuzz1.test 238d8c45f3b81342aa384de3e581ff2fa330bf922a7b69e484bbc06051a1080e +F ext/fts5/test/fts5hash.test b0c8fc0abb5409db5238ffa3c0f83faea447f99ed79b471c69c4b19fb44b8f70 +F ext/fts5/test/fts5integrity.test 6c4aad7f7380ec459a0c27ebbc0cb314fa67f3a3dad0cc820f612d33aa887166 +F ext/fts5/test/fts5lastrowid.test be98fe3e03235296585b72daad7aed5717ba0062bae5e5c18dd6e04e194c6b28 +F ext/fts5/test/fts5leftjoin.test c0b4cafb9661379e576dc4405c0891d8fcc2782680740513c4d1fc114b43d4ad +F ext/fts5/test/fts5matchinfo.test f06a3f786089aef34856720e6d4c236749b306d36f513c0665fe504f0740b6e7 +F ext/fts5/test/fts5merge.test e92a8db28b45931e7a9c7b1bbd36101692759d00274df74d83fd29d25d53b3a6 +F ext/fts5/test/fts5merge2.test 3ebad1a59d6ad3fb66eff6523a09e95dc6367cbefb3cd73196801dea0425c8e2 +F ext/fts5/test/fts5multiclient.test 5ff811c028d6108045ffef737f1e9f05028af2458e456c0937c1d1b8dea56d45 +F ext/fts5/test/fts5near.test 211477940142d733ac04fad97cb24095513ab2507073a99c2765c3ddd2ef58bd +F ext/fts5/test/fts5onepass.test f9b7d9b2c334900c6542a869760290e2ab5382af8fbd618834bf1fcc3e7b84da +F ext/fts5/test/fts5optimize.test 36a752d24c818792032e4ff502936fc9cc5ef938721696396fdc79214b2717f1 +F ext/fts5/test/fts5phrase.test 13e5d8e9083077b3d9c74315b3c92ec723cc6eb37c8155e0bfe1bba00559f07b +F ext/fts5/test/fts5plan.test e30e8378441114ef6977a3dc24ecd203caa670d782124dfc9a6e9af09f7abc4d +F ext/fts5/test/fts5porter.test 8d08010c28527db66bc3feebd2b8767504aaeb9b101a986342fa7833d49d0d15 +F ext/fts5/test/fts5porter2.test 0d251a673f02fa13ca7f011654873b3add20745f7402f108600a23e52d8c7457 +F ext/fts5/test/fts5prefix.test a0fa67b06650f2deaa7bf27745899d94e0fb547ad9ecbd08bfad98c04912c056 +F ext/fts5/test/fts5query.test bdb6fd9e73268cfc07f789f1448cd71ea78acb02e481c619f286289ea18ca518 +F ext/fts5/test/fts5rank.test 6e149da77a269923a8439aaa52366e49b85be4721902662da39a5ded16ed85d9 +F ext/fts5/test/fts5rebuild.test 6d09fd54b1170a1e54fe17b808bbf17fba3154956cc2f065dd94bf1e3d254f63 +F ext/fts5/test/fts5restart.test 835ecc8f449e3919f72509ab58056d0cedca40d1fe04108ccf8ac4c2ba41f415 +F ext/fts5/test/fts5rowid.test 365997f5aebd619df3ae46c2a4bfc8edba361899bc4e52cebfba0dbcbf720522 F ext/fts5/test/fts5simple.test 5da9b15ed534eb0be9f279d8a2bb2e24d30e4e38 -F ext/fts5/test/fts5simple2.test 00839031878f52391562594fdab0503e424ee071 -F ext/fts5/test/fts5simple3.test 25faa8cb8ad470c6f01f670bcc1317c19a89f091 -F ext/fts5/test/fts5synonym.test f964f9a98580dec06c995d4638ecb36eee60ae4a -F ext/fts5/test/fts5synonym2.test aa4c43bd3b691ff80f658cb064f5ab40690e834e -F ext/fts5/test/fts5tok1.test beb894c6f3468f10a574302f69ebe4436b0287c7 +F ext/fts5/test/fts5simple2.test 258a1b0c590409bfa5271e872c79572b319d2a56554d0585f68f146a0da603f0 +F ext/fts5/test/fts5simple3.test d5c74a9d3ca71bd5dd5cacb7c55b86ea12cdddfc8b1910e3de2995206898380f +F ext/fts5/test/fts5synonym.test 1651815b8008de170e8e600dcacc17521d765482ea8f074ae82cfa870d8bb7fb +F ext/fts5/test/fts5synonym2.test b54cce5c34ec08ed616f646635538ae82e34a0e28f947ec60b6fadbc4b3fb17a +F ext/fts5/test/fts5tok1.test ce6551e41ff56f30b69963577324624733bed0d1753589f06120d664d9cd45c9 F ext/fts5/test/fts5tok2.test dcacb32d4a2a3f0dd3215d4a3987f78ae4be21a2 -F ext/fts5/test/fts5tokenizer.test f64ab5fe48fa1317ff6315264bfe26e73cbdefde -F ext/fts5/test/fts5unicode.test fbef8d8a3b4b88470536cc57604a82ca52e51841 +F ext/fts5/test/fts5tokenizer.test 6aeb5e8061ffc0ff9a5299f27beaee3b2b4b8b336d4f107262bca338bea8f8e9 +F ext/fts5/test/fts5unicode.test 54c38bd568cd2a02f5b3803e0e1f386b865fac3cb9b9ddbd40ced9176ae39d2a F ext/fts5/test/fts5unicode2.test 529ac7e8648c943bc87bfed1e427128a2f3f9e33 -F ext/fts5/test/fts5unicode3.test 35c3d02aa7acf7d43d8de3bfe32c15ba96e8928e -F ext/fts5/test/fts5unindexed.test e9539d5b78c677315e7ed8ea911d4fd25437c680 -F ext/fts5/test/fts5update.test 57c7012a7919889048947addae10e0613df45529 -F ext/fts5/test/fts5version.test 978f59541d8cef7e8591f8be2115ec5ccb863e2e +F ext/fts5/test/fts5unicode3.test c3caecbe8264629ffe653b43ca5790b9793eba4422f92203e5247558e5a534e7 +F ext/fts5/test/fts5unindexed.test 9021af86a0fb9fc616f7a69a996db0116e7936d0db63892db6bafabbec21af4d +F ext/fts5/test/fts5update.test 0737876e20e97a6a6abf45de19fc99315727bcee6a83fadcada1cc080b9aa8f0 +F ext/fts5/test/fts5version.test 99b81372630fbf359107c96580fa761e41cdfb1dafc9966e148629ca72efee71 F ext/fts5/test/fts5vocab.test 026799f8d24befc452cbddda79822f5ae8d5f4eb F ext/fts5/tool/fts5speed.tcl b0056f91a55b2d1a3684ec05729de92b042e2f85 F ext/fts5/tool/fts5txt2db.tcl 526a9979c963f1c54fd50976a05a502e533a4c59 @@ -319,19 +319,19 @@ F ext/rbu/test_rbu.c ec18cfc69a104309df23c359e3c80306c9a6bdd1d2c53c8b70ae158e983 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 F ext/rtree/rtree.c c5886d4ba7e7c66d0f9ee0b788d5532f8537ca04db19cec7f2f64dcf46e9be37 F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e -F ext/rtree/rtree1.test d5f0ba215b3bd1d05269ada86e74073b8445852aa0d33a63e10ec63a09c39473 +F ext/rtree/rtree1.test d3a0c2951207f060ddf14f8e0018bf02228b112ef49bfcb4dc5dc4003362f3bc F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba F ext/rtree/rtree3.test 2cafe8265d1ff28f206fce88d114f208349df482 F ext/rtree/rtree4.test c8fe384f60ebd49540a5fecc990041bf452eb6e0 F ext/rtree/rtree5.test 6a510494f12454bf57ef28f45bc7764ea279431e F ext/rtree/rtree6.test 773a90db2dce6a8353dd0d5b64bca69b29761196 F ext/rtree/rtree7.test 1fa710b9e6bf997a0c1a537b81be7bb6fded1971 -F ext/rtree/rtree8.test db79c812f9e4a11f9b1f3f9934007884610a713a -F ext/rtree/rtree9.test b5eb13849545dfd271a54ff16784cb00d8792aea +F ext/rtree/rtree8.test 076d9d5b783b61b7a23a5ab45fc899551dfffd821974f36ee599ff29f4de7a61 +F ext/rtree/rtree9.test 8bfa84dfaba1c897468a2448c28db0a00ad12d464225b5993c7814e907f3776f F ext/rtree/rtreeA.test e25d76c1701f8591e7a0b6de8224d5dbc1418c562654c7240e6f33f37b1e36f7 F ext/rtree/rtreeB.test c85f9ce78766c4e68b8b89fbf2979ee9cfa82b4e F ext/rtree/rtreeC.test c0a9c67f2efa98b6fae12acb8a28348d231a481d -F ext/rtree/rtreeD.test bdfaaf26df8b4eea7364039aca9150bc1e1f8825 +F ext/rtree/rtreeD.test fe46aa7f012e137bd58294409b16c0d43976c3bb92c8f710481e577c4a1100dc F ext/rtree/rtreeE.test 45a147a64a76306172819562309681d8e90f94bb F ext/rtree/rtreeF.test 66deb9fd1611c7ca2e374adba63debdc2dbb12b4 F ext/rtree/rtreeG.test 3b185719630795f38594f64cd7d1de86a33f91f1 @@ -413,7 +413,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c bb70abf32c7c926745eb550938db9132309584a667a44c2db0e5fa3207600391 F src/legacy.c 134ab3e3fae00a0f67a5187981d6935b24b337bcf0f4b3e5c9fa5763da95bf4e F src/loadext.c a72909474dadce771d3669bf84bf689424f6f87d471fee898589c3ef9b2acfd9 -F src/main.c 0ed4383f4de08ac1a808c45666743c6352dfee87adf4557e99bf2a954b31bdf6 +F src/main.c e36ab281dc7d08eacf8789459b06e34ea1272631a67489799d4303be81aa7c14 F src/malloc.c e20bb2b48abec52d3faf01cce12e8b4f95973755fafec98d45162dfdab111978 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de @@ -450,7 +450,7 @@ F src/resolve.c 6aa1fb1212e601f65b983ee1215d69a591986c8f97a3805c425c625a53839539 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c c9f7b7196e196e93979665680d055a789938b8e025556097bf484b184c0dd576 F src/shell.c a7067f647aef4b81569bbfd025f4fd120a4e7576a647d2aad05028eb50e50e48 -F src/sqlite.h.in 651cba56f8df64ff4418aa981cdfd5bc2d65e5fef95c1671f9826f1a164a5fa3 +F src/sqlite.h.in c38c31f2a874af2b7d8443aba1fba3652d8ee75f60305d2512215cbe0fa0674a F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 58fd0676d3111d02e62e5a35992a7d3da5d3f88753acc174f2d37b774fbbdd28 F src/sqliteInt.h 7a7cd6f682471cce4afe64216f71fd64c622712aeb9d947c33c38337a7cf19a9 @@ -624,9 +624,9 @@ F test/cache.test 13bc046b26210471ca6f2889aceb1ea52dc717de F test/cacheflush.test af25bb1509df04c1da10e38d8f322d66eceedf61 F test/cachespill.test 895997f84a25b323b166aecb69baab2d6380ea98f9e0bcc688c4493c535cfab9 F test/capi2.test 011c16da245fdc0106a2785035de6b242c05e738 -F test/capi3.test f0c66919e43d42e1572a69be039e4527a931b00f +F test/capi3.test c6afa851428e60b78134f26e2a7ad55204b0b1612db62f284749f6b4b775fe2a F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4 -F test/capi3c.test 0b9edb0c2156a964b9271cd5ea7ae56736cc2fcb +F test/capi3c.test 09e311d58b5d9586dde8ad87801a5dc41f52b7da273a331b5f7bdb12b3c7c92f F test/capi3d.test 485048dc5cd07bc68011e4917ad035ad6047ab82 F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3 @@ -711,7 +711,7 @@ F test/distinctagg.test 1a6ef9c87a58669438fc771450d7a72577417376 F test/e_blobbytes.test 439a945953b35cb6948a552edaec4dc31fd70a05 F test/e_blobclose.test 4b3c8c60c2171164d472059c73e9f3c1844bb66d F test/e_blobopen.test e95e1d40f995056f6f322cd5e1a1b83a27e1a145 -F test/e_blobwrite.test 650ded42ee5e0c2dbf263583ce01adf280129599 +F test/e_blobwrite.test 4e4e20e25d94f4496272cf46ba1cb68eee7b1b3b1c26127735758a7d4a542f77 F test/e_changes.test fd66105385153dbf21fdb35eb8ef6c3e1eade579 F test/e_createtable.test d4c6059d44dcd4b636de9aae322766062b471844 F test/e_delete.test ab39084f26ae1f033c940b70ebdbbd523dc4962e @@ -719,7 +719,7 @@ F test/e_droptrigger.test 3cd080807622c13e5bbb61fc9a57bd7754da2412 F test/e_dropview.test 21ce09c361227ddbc9819a5608ee2700c276bdd5 F test/e_expr.test d0dd488e0527cbc560ae2dea1939cc44cb9b9924 F test/e_fkey.test 54cc0046d2d952d6c42b0dd94414e7a8f75f79f4 -F test/e_fts3.test 5c02288842e4f941896fd44afdef564dd5fc1459 +F test/e_fts3.test 8cf40550bb088a6aa187c818c00fabe26ef82900a4cd5c66b427ccafe28bedaa F test/e_insert.test 3de217e95094d3d165992a6de1164bbc4bd92dc7 F test/e_reindex.test 2bebf7b393e519198b7c654407221cf171a439b8 F test/e_resolve.test a61751c368b109db73df0f20fc75fb47e166b1d8 @@ -732,14 +732,14 @@ F test/e_vacuum.test 1b8b4772d05374aa1b8958669138bbb4213ee26a F test/e_wal.test ae9a593207a77d711443ee69ffe081fda9243625 F test/e_walauto.test 248af31e73c98df23476a22bdb815524c9dc3ba8 F test/e_walckpt.test 28c371a6bb5e5fe7f31679c1df1763a19d19e8a0 -F test/e_walhook.test 4c0613a0c76e7a9d5c4c211e1b4cbcc1143914df +F test/e_walhook.test 01b494287ba9e60b70f6ebf3c6c62e0ffe01788e344a4846b08e5de0b344cb66 F test/emptytable.test a38110becbdfa6325cd65cb588dca658cd885f62 F test/enc.test e54531cd6bf941ee6760be041dff19a104c7acea F test/enc2.test 83437a79ba1545a55fb549309175c683fb334473 F test/enc3.test 6807f7a7740a00361ca8d0ccd66bc60c8dc5f2b6 F test/enc4.test c8f1ce3618508fd0909945beb8b8831feef2c020 F test/eqp.test 3f9ba0b2594837c7beaa3ba824e2137cfe857308f020ec5a0c7a62b444e837b0 -F test/errmsg.test f31592a594b44ee121371d25ddd5d63497bb3401 +F test/errmsg.test eae9f091eb39ce7e20305de45d8e5d115b68fa856fba4ea6757b6ca3705ff7f9 F test/eval.test a64c9105d6ff163df7cf09d6ac29cdad5922078c F test/exclusive.test 9a57bd66e39144b888ca75c309914fcdefb4e3f9 F test/exclusive2.test 984090e8e9d1b331d2e8111daf6e5d61dda0bef7 @@ -775,7 +775,7 @@ F test/fts1k.test 65d3b41487b9f738d11b0f00eca375c0ca6bd970 F test/fts1l.test 15c119ed2362b2b28d5300c0540a6a43eab66c36 F test/fts1m.test 2d9ca67b095d49f037a914087cc0a61e89da4f0c F test/fts1n.test a2317dcd27b1d087ee3878b30e0a59c593c98b7a -F test/fts1o.test fd92f82ea9090dbc2a13d4cd58aafe5afa371b6a +F test/fts1o.test d1554caede42bba2c82fe613bcc921856c196b752449ead0470fac52a20fd3b8 F test/fts1porter.test d86e9c3e0c7f8ff95add6582b4b585fb4e02b96d F test/fts2.test e3fb95f96a650411574efc136f3fb10eef479ed7 F test/fts2a.test 473a5c8b473a4e21a8e3fddaed1e59666e0c6ab7 @@ -784,7 +784,7 @@ F test/fts2c.test ffb5a35230ac72c4354535c547965ce6824537c0 F test/fts2d.test b7eaa671ca9a16997f3e5b158ee777ae21052b0b F test/fts2e.test 2da13dbc2d009105f42196845c1e1ce136c03d38 F test/fts2f.test cf84096235991709c1e61caa389632aa0a4f976d -F test/fts2g.test d49d6f6c900e6e20a0fb980ec1cd568dee12af76 +F test/fts2g.test 3d26fe171bda6133ebf5a380731d70eaa2ef2f6f73d79769cf8946e622b6d597 F test/fts2h.test 223af921323b409d4b5b18ff4e51619541b174bb F test/fts2i.test 1b22451d1f13f7c509baec620dc3a4a754885dd6 F test/fts2j.test 298fa1670aa21cd445b282d139b70c72e7ade12b @@ -792,7 +792,7 @@ F test/fts2k.test c7ebf4a4937594aa07459e3e1bca1251c1be8659 F test/fts2l.test 3333336621524cf7d60bb62d6ef6ab69647866ed F test/fts2m.test 4b30142ead6f3ed076e880a2a464064c5ad58c51 F test/fts2n.test 12b9c5352128cebd1c6b8395e43788d4b09087c2 -F test/fts2o.test 09cd920d585ebf1c2910b6be869efa286e308a84 +F test/fts2o.test 4054ac7433eb5440f1b1d200cfa449342dc4aabd991759139813e17c73e5bf9a F test/fts2p.test 4b48c35c91e6a7dbf5ac8d1e5691823cc999aafb F test/fts2q.test b2fbbe038b7a31a52a6079b215e71226d8c6a682 F test/fts2r.test b154c30b63061d8725e320fba1a39e2201cadd5e @@ -813,19 +813,19 @@ F test/fts3ak.test bd14deafe9d1586e8e9bf032411026ac4f8c925d F test/fts3al.test 07d64326e79bbdbab20ee87fc3328fbf01641c9f F test/fts3am.test 218aa6ba0dfc50c7c16b2022aac5c6be593d08d8 F test/fts3an.test a49ccadc07a2f7d646ec1b81bc09da2d85a85b18 -F test/fts3ao.test 3e4e3d5e75c076520341d0bdf4eb17c00e8cbde2 +F test/fts3ao.test c416d50c4fdb6f32a15205b3d0a49eb74fcea92feb66b531a83c904770de5ff1 F test/fts3atoken.test 4b4c16fdcfc972f2cdbba212375a060a86ccf5f1 F test/fts3auto.test b981fea19b132b4e6878f50d7c1f369b28f68eb9 -F test/fts3aux1.test ca32c138aa777b476271df2da2c5538b7a43ada1 +F test/fts3aux1.test 24b8a69e342a6684e3929408b245cdf5de0d45f8094108fa0a57cd007228963d F test/fts3aux2.test 7ae2b2c13aefdf4169279a27a5f51780ce57f6ba -F test/fts3b.test e93bbb653e52afde110ad53bbd793f14fe7a8984 +F test/fts3b.test c15c4a9d04e210d0be67e54ce6a87b927168fbf9c1e3faec8c1a732c366fd491 F test/fts3c.test fc723a9cf10b397fdfc2b32e73c53c8b1ec02958 F test/fts3comp1.test a0f5b16a2df44dd0b15751787130af2183167c0c F test/fts3conf.test 60317efd562080e198b5bdc9fcd222ce32cf01d7 F test/fts3corrupt.test 2710b77983cc7789295ddbffea52c1d3b7506dbb F test/fts3corrupt2.test 6d96efae2f8a6af3eeaf283aba437e6d0e5447ba F test/fts3corrupt3.test 56e0ee83e90b57f5f3644cb7d1b36a067b7b8b19cdf0dedce45e5e13cf752f65 -F test/fts3cov.test e0fb00d8b715ddae4a94c305992dfc3ef70353d7 +F test/fts3cov.test 9c3681325b9a850bca8dd75cc29dde73e9a87972bb75204e97d826f13c7181f9 F test/fts3d.test d3e9c8fb75135ada06bf3bab4f9666224965d708 F test/fts3defer.test 0be4440b73a2e651fc1e472066686d6ada4b9963 F test/fts3defer2.test c540f5f5c2840f70c68fd9b597df817ec7170468 @@ -837,8 +837,8 @@ F test/fts3expr2.test 18da930352e5693eaa163a3eacf96233b7290d1a F test/fts3expr3.test c4d4a7d6327418428c96e0a3a1137c251b8dfbf8 F test/fts3expr4.test c39a15d676b14fc439d9bf845aa7bddcf4a74dc3 F test/fts3expr5.test f9abfffbf5e53d48a33e12a1e8f8ba2c551c9b49 -F test/fts3fault.test 3764ecffb3d341c5b05b3abe64153f385880035e67706ca2fc719e5d3352aedb -F test/fts3fault2.test 536bbe01fe2946ec24b063a5eee813e8fd90354a6ca0b8f941d299c405edd17e +F test/fts3fault.test 9fb7d6266a38806de841f7244bac1b0fe3a1477184bbb10b172d19d2ca6ad692 +F test/fts3fault2.test 6a17a11d8034b1c4eca9f3091649273d56c49ff049e2173df8060f94341e9da0 F test/fts3first.test dbdedd20914c8d539aa3206c9b34a23775644641 F test/fts3join.test a758accc808cebaef8d622aac07994a2eae15c40eebc40888dcbbabc6f6bafb6 F test/fts3malloc.test b0e4c133b8d61d4f6d112d8110f8320e9e453ef6 @@ -853,19 +853,19 @@ F test/fts3rnd.test 1320d8826a845e38a96e769562bf83d7a92a15d0 F test/fts3shared.test 57e26a801f21027b7530da77db54286a6fe4997e F test/fts3snippet.test 01a4231816e03a0660ae53ba2404fe69012fe0db F test/fts3sort.test ed34c716a11cc2009a35210e84ad5f9c102362ca -F test/fts3tok1.test 178c050199af8c05299b1ad572514ce1c54b7827 +F test/fts3tok1.test a663f4cac22a9505400bc22aacb818d7055240409c28729669ea7d4cc2120d15 F test/fts3tok_err.test 52273cd193b9036282f7bacb43da78c6be87418d F test/fts3varint.test 752c08ed5d32c5d7dc211b056f4ed68a76b7e36e F test/fts4aa.test 10aac8e9d62c7357590acfabe3fad01e9a9ce1cb F test/fts4check.test c3056eab9524232e4c9bdcd119912947e07bcc1c -F test/fts4content.test 05716af19a899cd70d5cd916c580043c03f30db4 +F test/fts4content.test 1518195a9f92b711d94419f76409a31cc78755854fb0abb1da2b74b9e0cf843e F test/fts4docid.test e33c383cfbdff0284685604d256f347a18fdbf01 F test/fts4growth.test e5390da74619cacc389711bac9349640b32c4f9a F test/fts4growth2.test 13ad4e76451af6e6906c95cdc725d01b00044269 F test/fts4incr.test 4e353a0bd886ea984e56fce9e77724fc923b8d0d -F test/fts4langid.test 89a107d36710dc3f44dab0861a784ffab967bd1f32c8d700b031748b9d2703c6 -F test/fts4lastrowid.test fa5e157955a3121615ef3e16ff5196e96c9e1e64 -F test/fts4merge.test d2b39f6b1bd4a9738a13540e2d044cba11c43d47 +F test/fts4langid.test 2168ba330af34f8a1c8832de0aab4c4b6fa195a16419c9c0c8aad59ceb6ff714 +F test/fts4lastrowid.test 185835895948d5325c7710649824042373b2203149abe8024a9319d25234dfd7 +F test/fts4merge.test 10b55f410fade8691a455210b0b9302ef178a4f06fba0ad1941801caab82f5a9 F test/fts4merge2.test 5faa558d1b672f82b847d2a337465fa745e46891 F test/fts4merge3.test 8d9ccb4a3d41c4c617a149d6c4b13ad02de797d0 F test/fts4merge4.test d895b1057a7798b67e03455d0fa50e9ea836c47b @@ -896,7 +896,7 @@ F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14 F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536 F test/gcfault.test dd28c228a38976d6336a3fc42d7e5f1ad060cb8c F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98 -F test/having.test 30a02b8a9a47cba7bdb5281999c5cbff407c2ac296511ee64dd0b418fe38eb0f +F test/having.test b3d6b17cc9601b6b373b2d0f08c075ccf30e2d307249c3c8a236e3c36907b1a5 F test/hexlit.test 4a6a5f46e3c65c4bf1fa06f5dd5a9507a5627751 F test/hidden.test 23c1393a79e846d68fd902d72c85d5e5dcf98711 F test/hook.test dbc0b87756e1e20e7497b56889c9e9cd2f8cc2b5 @@ -931,7 +931,7 @@ F test/index8.test bc2e3db70e8e62459aaa1bd7e4a9b39664f8f9d7 F test/index9.test 0aa3e509dddf81f93380396e40e9bb386904c1054924ba8fa9bcdfe85a8e7721 F test/indexedby.test 9c4cd331224e57f79fbf411ae245e6272d415985 F test/indexexpr1.test 038b3befa74e5a75126b6e9dd2ae5df61c1c7cf7 -F test/indexexpr2.test 68ee9dbe83fcf85e50f4d0bd1f742a082496f2ee5153f4be2a1861db84462bf7 +F test/indexexpr2.test 3ddd7f23bc381b9f2b7a15f2d083b1a4078e7733dce8295602ecfa3c74a34cf9 F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7 F test/insert.test 38742b5e9601c8f8d76e9b7555f7270288c2d371 @@ -1072,7 +1072,7 @@ F test/pager1.test 841868017e9dd3cb459b8d78862091a7d9cff21d F test/pager2.test 67b8f40ae98112bcdba1f2b2d03ea83266418c71 F test/pager3.test 3856d9c80839be0668efee1b74811b1b7f7fc95f F test/pager4.test a122e9e6925d5b23b31e3dfef8c6a44bbf19590e -F test/pagerfault.test 42ff797b1e6426c141cc7ee8b7417c9f27427950 +F test/pagerfault.test 263c5442c06caf0b9b9e3fe42acdeb11f254dcebe533f69f401aaef9111eaf20 F test/pagerfault2.test caf4c7facb914fd3b03a17b31ae2b180c8d6ca1f F test/pagerfault3.test 1003fcda009bf48a8e22a516e193b6ef0dd1bbd8 F test/pageropt.test 84e4cc5cbca285357f7906e99b21be4f2bf5abc0 @@ -1082,7 +1082,7 @@ F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442 F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff F test/permutations.test 8aaa22a0f428a7e6b8446b97bc7691a273eaeff5dc290fb9129bf79fa9813a6e -F test/pragma.test 1e94755164a3a3264cd39836de4bebcb7809e5f8 +F test/pragma.test f274259d6393b6681eb433beb8dd39a26ec06a4431052a4880b43b84912a3f58 F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f F test/pragma3.test 14c12bc5352b1e100e0b6b44f371053a81ccf8ed F test/pragma4.test 6e85b6eab8e61ffc9c7db59d842276674e8e3264 @@ -1176,7 +1176,7 @@ F test/shell3.test 9b95ba643eaa228376f06a898fb410ee9b6e57c1 F test/shell4.test 89ad573879a745974ff2df20ff97c5d6ffffbd5d F test/shell5.test 0d973866d0df8501486a840f51d1502ab0d9b38ca12c9b242ee26adc788af576 F test/shell6.test ab1592ebe881371f651f18ee6a0df21cbfb5310f88cb832ab642d4038f679772 -F test/shell7.test 07751911b294698e0c5df67bcbd29e7d2f0f2907 +F test/shell7.test 115132f66d0463417f408562cc2cf534f6bbc6d83a6d50f0072a9eb171bae97f F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3 F test/show_speedtest1_rtree.tcl 32e6c5f073d7426148a6936a0408f4b5b169aba5 F test/shrink.test 1b4330b1fd9e818c04726d45cb28db73087535ce @@ -1216,7 +1216,7 @@ F test/stat.test f8f1279ffffabe6df825723af18cc6e0ae70a893 F test/statfault.test f525a7bf633e50afd027700e9a486090684b1ac1 F test/stmt.test 64844332db69cf1a735fcb3e11548557fc95392f F test/stmtvtab1.test 2a3cee496574ee9515e5e7a92fb8d9447903ccc14536a21545debeda267ff3c8 -F test/subjournal.test 2121a93ef3d3e83d52bf236c8a02aef4009fbf52884754104b2b6cad9a041095 +F test/subjournal.test 8d4e2572c0ee9a15549f0d8e40863161295107e52f07a3e8012a2e1fdd093c49 F test/subquery.test d7268d193dd33d5505df965399d3a594e76ae13f F test/subquery2.test 438f8a7da1457277b22e4176510f7659b286995f F test/subselect.test 0966aa8e720224dbd6a5e769a3ec2a723e332303 @@ -1417,7 +1417,7 @@ F test/triggerB.test 56780c031b454abac2340dbb3b71ac5c56c3d7fe F test/triggerC.test 302d8995f5ffe63bbc15053abb3ef7a39cf5a092 F test/triggerD.test 8e7f3921a92a5797d472732108109e44575fa650 F test/triggerE.test 15fa63f1097db1f83dd62d121616006978063d1f -F test/triggerF.test 55b1eb13433997faac3a4948c1d8252f6c8c636b +F test/triggerF.test 6a8c22bd058cf467f0c7d112afe87f7a8c579c0c4681b914b8f19020f48528a4 F test/triggerG.test 175cafdc6399d85231a09e82e051b0e45a2fd1f23dd08ae715bc359716149ab6 F test/tt3_checkpoint.c 9e75cf7c1c364f52e1c47fd0f14c4340a9db0fe1 F test/tt3_index.c 39eec10a35f57672225be4d182862152896dee4a @@ -1432,7 +1432,7 @@ F test/unique2.test 3674e9f2a3f1fbbfd4772ac74b7a97090d0f77d2 F test/unixexcl.test d936ba2b06794018e136418addd59a2354eeae97 F test/unordered.test ca7adce0419e4ca0c50f039885e76ed2c531eda8 F test/update.test 6c68446b8a0a33d522a7c72b320934596a2d7d32 -F test/update2.test 81772e5c9b93d1006d66d65e9a1327281bdec4e8 +F test/update2.test fffc92e72ae568fe048588762e650cd8ccbd8c8b6e4fe9099231766bfe4b51de F test/uri.test 3481026f00ade6dfe8adb7acb6e1e47b04369568 F test/uri2.test 9d3ba7a53ee167572d53a298ee4a5d38ec4a8fb7 F test/userauth01.test e740a2697a7b40d7c5003a7d7edaee16acd349a9 @@ -1446,7 +1446,7 @@ F test/vacuummem.test 7b42abb3208bd82dd23a7536588396f295a314f2 F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102 F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661 F test/view.test 765802c7a66d37fabd5ac8e2f2dbe572b43eb9ab -F test/vtab1.test ed4a576231d8a36e70fd18e2b79b621b31e7f22a +F test/vtab1.test f7d743a1d71f4a1187c79a5c26d20b764f705ea8588d969454d7c530b92e21d3 F test/vtab2.test f8cd1bb9aba7143eba97812d9617880a36d247ad F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e F test/vtab4.test 8e73ed268f3d596bc3590f45fc948fb40f28e9c3 @@ -1463,7 +1463,7 @@ F test/vtabE.test d5024aa42754962f6bb0afd261681686488e7afe F test/vtabF.test 1918844c7c902f6a16c8dacf1ec8f84886d6e78b F test/vtabH.test 26d54e8b5407f797638b787a55f9c88323850a58dd142de02d06b9a1159bd283 F test/vtabI.test 751b07636700dbdea328e4265b6077ccd6811a3f -F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5 +F test/vtab_alter.test 736e66fb5ec7b4fee58229aa3ada2f27ec58bc58c00edae4836890c3784c6783 F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8 F test/vtab_shared.test 5253bff2355a9a3f014c15337da7e177ab0ef8ad F test/wal.test 613efec03e517e1775d86b993a54877d2e29a477 @@ -1628,7 +1628,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P aa4890b9f9e9698c61d6ca0e24c26280f5e0a87a8c02865933ad483a1fd44d84 -R 96fb79a3cbe62f69ba1f97462f1b918d -U mistachkin -Z eb908a759d0763367678fc7d0ee2727b +P 0961ec873b78ad2da0ea9cdf2934bc8f08276375a153fe5d9fa8d4280328deef +R 79fe59dfa4a836939eb45a203b110400 +U drh +Z 8d02d118072fdff02038158664ac514a diff --git a/manifest.uuid b/manifest.uuid index 17da356b1e..375b8be127 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0961ec873b78ad2da0ea9cdf2934bc8f08276375a153fe5d9fa8d4280328deef \ No newline at end of file +732f90d6327c5c6368fc8b4cc207bd644ef08e3ae6d2e7295258ab099deaba63 \ No newline at end of file diff --git a/src/main.c b/src/main.c index 14f3ce9467..54d12a3806 100644 --- a/src/main.c +++ b/src/main.c @@ -1404,7 +1404,7 @@ const char *sqlite3ErrName(int rc){ const char *sqlite3ErrStr(int rc){ static const char* const aMsg[] = { /* SQLITE_OK */ "not an error", - /* SQLITE_ERROR */ "SQL logic error or missing database", + /* SQLITE_ERROR */ "SQL logic error", /* SQLITE_INTERNAL */ 0, /* SQLITE_PERM */ "access permission denied", /* SQLITE_ABORT */ "callback requested query abort", diff --git a/src/sqlite.h.in b/src/sqlite.h.in index a29ec7bc5a..bf5118b2c3 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -417,7 +417,7 @@ int sqlite3_exec( */ #define SQLITE_OK 0 /* Successful result */ /* beginning-of-error-codes */ -#define SQLITE_ERROR 1 /* SQL error or missing database */ +#define SQLITE_ERROR 1 /* Generic error */ #define SQLITE_INTERNAL 2 /* Internal logic error in SQLite */ #define SQLITE_PERM 3 /* Access permission denied */ #define SQLITE_ABORT 4 /* Callback routine requested an abort */ diff --git a/test/capi3.test b/test/capi3.test index 84889f5faf..c64640e84f 100644 --- a/test/capi3.test +++ b/test/capi3.test @@ -769,7 +769,7 @@ forcedelete test.db-journal # Test the english language string equivalents for sqlite error codes set code2english [list \ SQLITE_OK {not an error} \ -SQLITE_ERROR {SQL logic error or missing database} \ +SQLITE_ERROR {SQL logic error} \ SQLITE_PERM {access permission denied} \ SQLITE_ABORT {callback requested query abort} \ SQLITE_BUSY {database is locked} \ diff --git a/test/capi3c.test b/test/capi3c.test index 57cf146c73..b8added16b 100644 --- a/test/capi3c.test +++ b/test/capi3c.test @@ -726,7 +726,7 @@ forcedelete test.db-journal # Test the english language string equivalents for sqlite error codes set code2english [list \ SQLITE_OK {not an error} \ -SQLITE_ERROR {SQL logic error or missing database} \ +SQLITE_ERROR {SQL logic error} \ SQLITE_PERM {access permission denied} \ SQLITE_ABORT {callback requested query abort} \ SQLITE_BUSY {database is locked} \ diff --git a/test/e_blobwrite.test b/test/e_blobwrite.test index 7b2249c243..eaf9958743 100644 --- a/test/e_blobwrite.test +++ b/test/e_blobwrite.test @@ -110,7 +110,7 @@ sqlite3_blob_close $B # sqlite3_blob_open db main t2 a 44 3 B blob_write_error_test 2.2.1 $B 31 $blob 10 \ - SQLITE_ERROR {SQL logic error or missing database} + SQLITE_ERROR {SQL logic error} # Make a successful write to the blob handle. This shows that the # sqlite3_errcode() and sqlite3_errmsg() values are set even if the @@ -122,10 +122,10 @@ blob_write_error_test 2.2.1 $B 30 $blob 10 SQLITE_OK {not an error} # SQLITE_ERROR is returned and no data is written. # blob_write_error_test 2.2.2 $B 31 $blob -1 \ - SQLITE_ERROR {SQL logic error or missing database} + SQLITE_ERROR {SQL logic error} blob_write_error_test 2.2.3 $B 20 $blob 10 SQLITE_OK {not an error} blob_write_error_test 2.2.4 $B -1 $blob 10 \ - SQLITE_ERROR {SQL logic error or missing database} + SQLITE_ERROR {SQL logic error} sqlite3_blob_close $B # EVIDENCE-OF: R-20958-54138 An attempt to write to an expired BLOB diff --git a/test/e_fts3.test b/test/e_fts3.test index 2a580ca313..22c3fdb157 100644 --- a/test/e_fts3.test +++ b/test/e_fts3.test @@ -177,7 +177,7 @@ read_test 1.2.1.9 { SELECT docid, * FROM pages } {} do_error_test fts3-1.2.1.10 { INSERT INTO pages(rowid, docid, title, body) VALUES(1, 2, 'A title', 'A document body'); -} {SQL logic error or missing database} +} {SQL logic error} # Test the optimize() function example: ddl_test 1.2.2.1 { CREATE VIRTUAL TABLE docs USING fts3 } diff --git a/test/e_walhook.test b/test/e_walhook.test index c963524a97..b4a3156367 100644 --- a/test/e_walhook.test +++ b/test/e_walhook.test @@ -121,7 +121,7 @@ do_test 3.1.2 { proc my_wal_hook {args} { return 1 ;# SQLITE_ERROR } do_catchsql_test 4.1 { INSERT INTO t1 VALUES(7) -} {1 {SQL logic error or missing database}} +} {1 {SQL logic error}} proc my_wal_hook {args} { return 5 ;# SQLITE_BUSY } do_catchsql_test 4.2 { diff --git a/test/errmsg.test b/test/errmsg.test index 8df8a704f4..f32da59a39 100644 --- a/test/errmsg.test +++ b/test/errmsg.test @@ -56,7 +56,7 @@ db func sql_error sql_error do_test 1.1 { error_messages "SELECT sql_error('custom message')" } [list {*}{ - SQLITE_ERROR {SQL logic error or missing database} + SQLITE_ERROR {SQL logic error} SQLITE_ERROR {custom message} }] do_test 1.2 { @@ -77,7 +77,7 @@ do_execsql_test 2.1 { do_test 2.2 { error_messages "INSERT INTO t1 VALUES('ghi', 'def')" } [list {*}{ - SQLITE_ERROR {SQL logic error or missing database} + SQLITE_ERROR {SQL logic error} SQLITE_CONSTRAINT {UNIQUE constraint failed: t1.b} }] verify_ex_errcode 2.2b SQLITE_CONSTRAINT_UNIQUE @@ -101,7 +101,7 @@ do_execsql_test 3.1.1 { do_test 3.1.2 { error_messages "SELECT a FROM t2" "DROP TABLE t2" } [list {*}{ - SQLITE_ERROR {SQL logic error or missing database} + SQLITE_ERROR {SQL logic error} SQLITE_SCHEMA {database schema has changed} }] do_execsql_test 3.2.1 { diff --git a/test/fts1o.test b/test/fts1o.test index 61fd74ca0e..3ed095294d 100644 --- a/test/fts1o.test +++ b/test/fts1o.test @@ -52,7 +52,7 @@ do_test fts1o-2.1 { CREATE TABLE t1_term(a, b, c); ALTER TABLE fts_t1 RENAME to t1; } -} {1 {SQL logic error or missing database}} +} {1 {SQL logic error}} do_test fts1o-2.2 { execsql { SELECT rowid, snippet(fts_t1) FROM fts_t1 WHERE a MATCH 'four'; } } {1 {one three four}} @@ -72,7 +72,7 @@ do_test fts1o-3.2 { catchsql { ALTER TABLE fts_t1 RENAME to t1; } -} {1 {SQL logic error or missing database}} +} {1 {SQL logic error}} # NOTE(shess) rowid AS rowid to defeat caching. Otherwise, this # seg-faults, I suspect that there's something up with a stale # virtual-table reference, but I'm not quite sure how it happens here diff --git a/test/fts2g.test b/test/fts2g.test index 4cffb91fc7..176c619aa3 100644 --- a/test/fts2g.test +++ b/test/fts2g.test @@ -73,7 +73,7 @@ do_test fts2g-1.9 { # No support for all-except queries. do_test fts2g-1.10 { catchsql {SELECT rowid FROM t1 WHERE t1 MATCH '-this -something'} -} {1 {SQL logic error or missing database}} +} {1 {SQL logic error}} # Test that docListOrMerge() correctly handles reaching the end of one # doclist before it reaches the end of the other. diff --git a/test/fts2o.test b/test/fts2o.test index 63e71b958a..de319ea96a 100644 --- a/test/fts2o.test +++ b/test/fts2o.test @@ -69,7 +69,7 @@ do_test fts2o-2.5 { CREATE TABLE t1_segdir(a, b, c); ALTER TABLE fts_t1 RENAME to t1; } -} {1 {SQL logic error or missing database}} +} {1 {SQL logic error}} do_test fts2o-2.6 { execsql { SELECT rowid, snippet(fts_t1) FROM fts_t1 WHERE a MATCH 'four'; } } {1 {one three four}} @@ -89,7 +89,7 @@ do_test fts2o-2.9 { catchsql { ALTER TABLE fts_t1 RENAME to t1; } -} {1 {SQL logic error or missing database}} +} {1 {SQL logic error}} do_test fts2o-2.10 { execsql { SELECT rowid, snippet(fts_t1) FROM fts_t1 WHERE a MATCH 'four'; } } {1 {one three four}} diff --git a/test/fts3ao.test b/test/fts3ao.test index 60f0aa7d90..2cff1350eb 100644 --- a/test/fts3ao.test +++ b/test/fts3ao.test @@ -71,7 +71,7 @@ do_test fts3ao-2.5 { CREATE TABLE t1_segdir(a, b, c); ALTER TABLE fts_t1 RENAME to t1; } -} {1 {SQL logic error or missing database}} +} {1 {SQL logic error}} do_test fts3ao-2.6 { execsql { SELECT rowid, snippet(fts_t1) FROM fts_t1 WHERE a MATCH 'four'; } } {1 {one three four}} @@ -91,7 +91,7 @@ do_test fts3ao-2.9 { catchsql { ALTER TABLE fts_t1 RENAME to t1; } -} {1 {SQL logic error or missing database}} +} {1 {SQL logic error}} do_test fts3ao-2.10 { execsql { SELECT rowid, snippet(fts_t1) FROM fts_t1 WHERE a MATCH 'four'; } } {1 {one three four}} diff --git a/test/fts3aux1.test b/test/fts3aux1.test index b6111f8470..9bbed53c45 100644 --- a/test/fts3aux1.test +++ b/test/fts3aux1.test @@ -364,10 +364,10 @@ do_execsql_test 3.2.1 { } do_catchsql_test 3.2.2 { SELECT * FROM terms3 -} {1 {SQL logic error or missing database}} +} {1 {SQL logic error}} do_catchsql_test 3.2.3 { SELECT * FROM terms3 WHERE term = 'abc' -} {1 {SQL logic error or missing database}} +} {1 {SQL logic error}} do_catchsql_test 3.3.1 { INSERT INTO terms VALUES(1,2,3); @@ -516,6 +516,6 @@ do_test 8.1 { do_test 8.2 { execsql {DETACH att} catchsql { SELECT * FROM aux2 } -} {1 {SQL logic error or missing database}} +} {1 {SQL logic error}} finish_test diff --git a/test/fts3b.test b/test/fts3b.test index 9bde3a254c..ee0a1cea68 100644 --- a/test/fts3b.test +++ b/test/fts3b.test @@ -206,7 +206,7 @@ do_test fts3b-4.8 { INSERT INTO t4 (rowid, docid, c) VALUES (14, 15, 'bad test'); SELECT * FROM t4 WHERE docid = 14; } -} {1 {SQL logic error or missing database}} +} {1 {SQL logic error}} do_test fts3b-4.9 { execsql { SELECT docid FROM t4 WHERE t4 MATCH 'testing' } diff --git a/test/fts3cov.test b/test/fts3cov.test index c43999d2da..817679d0a4 100644 --- a/test/fts3cov.test +++ b/test/fts3cov.test @@ -96,7 +96,7 @@ do_test fts3cov-2.2 { } {} do_error_test fts3cov-2.3 { SELECT * FROM t1 WHERE t1 MATCH 'c*' -} {SQL logic error or missing database} +} {SQL logic error} # Test the "replaced with NULL" case: do_test fts3cov-2.4 { @@ -104,7 +104,7 @@ do_test fts3cov-2.4 { } {} do_error_test fts3cov-2.5 { SELECT * FROM t1 WHERE t1 MATCH 'cloud' -} {SQL logic error or missing database} +} {SQL logic error} #-------------------------------------------------------------------------- # The following tests are to test the effects of OOM errors while storing @@ -308,13 +308,13 @@ do_test fts3cov-9.1 { } {} do_error_test fts3cov-9.2 { INSERT INTO xx(xx) VALUES('optimise'); -- British spelling -} {SQL logic error or missing database} +} {SQL logic error} do_error_test fts3cov-9.3 { INSERT INTO xx(xx) VALUES('short'); -} {SQL logic error or missing database} +} {SQL logic error} do_error_test fts3cov-9.4 { INSERT INTO xx(xx) VALUES('waytoolongtobecorrect'); -} {SQL logic error or missing database} +} {SQL logic error} do_test fts3cov-9.5 { execsql { INSERT INTO xx(xx) VALUES('optimize') } } {} diff --git a/test/fts3fault.test b/test/fts3fault.test index 56835f4e0e..996a108dfd 100644 --- a/test/fts3fault.test +++ b/test/fts3fault.test @@ -145,7 +145,7 @@ do_faultsim_test 7.2 -prep { } -test { faultsim_test_result {1 {unrecognized matchinfo: fs3}} \ {1 {vtable constructor failed: t1}} \ - {1 {SQL logic error or missing database}} + {1 {SQL logic error}} } do_faultsim_test 7.3 -prep { faultsim_delete_and_reopen @@ -154,7 +154,7 @@ do_faultsim_test 7.3 -prep { } -test { faultsim_test_result {1 {unrecognized parameter: matchnfo=fts3}} \ {1 {vtable constructor failed: t1}} \ - {1 {SQL logic error or missing database}} + {1 {SQL logic error}} } diff --git a/test/fts3fault2.test b/test/fts3fault2.test index e4f292042c..5c182d73c9 100644 --- a/test/fts3fault2.test +++ b/test/fts3fault2.test @@ -245,5 +245,3 @@ eval fts3_configure_incr_load $chunkconfig finish_test - - diff --git a/test/fts3tok1.test b/test/fts3tok1.test index 09b07e9db1..139fae89d9 100644 --- a/test/fts3tok1.test +++ b/test/fts3tok1.test @@ -108,7 +108,7 @@ do_catchsql_test 2.0 { do_catchsql_test 2.1 { CREATE VIRTUAL TABLE t4 USING fts3tokenize; SELECT * FROM t4; -} {1 {SQL logic error or missing database}} +} {1 {SQL logic error}} do_catchsql_test 2.2 { CREATE VIRTUAL TABLE t USING fts4(tokenize=simple""); diff --git a/test/fts4content.test b/test/fts4content.test index 67642b6b8a..2da51d1516 100644 --- a/test/fts4content.test +++ b/test/fts4content.test @@ -424,7 +424,7 @@ do_execsql_test 6.2.1 { do_catchsql_test 6.2.2 { DROP TABLE t7; SELECT * FROM ft7; -} {1 {SQL logic error or missing database}} +} {1 {SQL logic error}} db close sqlite3 db test.db @@ -457,10 +457,10 @@ do_execsql_test 6.2.7 { } do_catchsql_test 6.2.8 { SELECT * FROM ft7 WHERE ft7 MATCH '"A A"'; -} {1 {SQL logic error or missing database}} +} {1 {SQL logic error}} do_catchsql_test 6.2.9 { SELECT * FROM ft7 WHERE ft7 MATCH '"A A"'; -} {1 {SQL logic error or missing database}} +} {1 {SQL logic error}} db close sqlite3 db test.db @@ -504,7 +504,7 @@ do_execsql_test 7.2.3 { do_catchsql_test 7.2.4 { SELECT * FROM ft9 WHERE ft9 MATCH 'N'; -} {1 {SQL logic error or missing database}} +} {1 {SQL logic error}} #------------------------------------------------------------------------- # Test cases 8.* diff --git a/test/fts4langid.test b/test/fts4langid.test index 9954acd718..9fffe95219 100644 --- a/test/fts4langid.test +++ b/test/fts4langid.test @@ -387,7 +387,7 @@ for {set i 0} {$i < 50} {incr i} { } do_catchsql_test 4.1.5 { INSERT INTO t4(content, lid) VALUES('hello world', 101) -} {1 {SQL logic error or missing database}} +} {1 {SQL logic error}} #------------------------------------------------------------------------- # Test cases 5.* diff --git a/test/fts4lastrowid.test b/test/fts4lastrowid.test index b5720a2ef3..7b35e3c53b 100644 --- a/test/fts4lastrowid.test +++ b/test/fts4lastrowid.test @@ -70,4 +70,3 @@ do_execsql_test 1.6 { finish_test - diff --git a/test/fts4merge.test b/test/fts4merge.test index eac18311d3..63272c41b9 100644 --- a/test/fts4merge.test +++ b/test/fts4merge.test @@ -89,7 +89,7 @@ foreach mod {fts3 fts4} { } { do_catchsql_test 2.$tn { INSERT INTO t2(t2) VALUES($arg); - } {1 {SQL logic error or missing database}} + } {1 {SQL logic error}} } #------------------------------------------------------------------------- diff --git a/test/having.test b/test/having.test index 6d2f9fdcc5..aea12319d7 100644 --- a/test/having.test +++ b/test/having.test @@ -151,4 +151,3 @@ do_execsql_test 4.3 { finish_test - diff --git a/test/indexexpr2.test b/test/indexexpr2.test index 47d50de3ef..c72561f347 100644 --- a/test/indexexpr2.test +++ b/test/indexexpr2.test @@ -41,4 +41,3 @@ do_execsql_test 2.1 { } {2 2 3 3 4 4} finish_test - diff --git a/test/pagerfault.test b/test/pagerfault.test index 2e70171b20..392c1a2b98 100644 --- a/test/pagerfault.test +++ b/test/pagerfault.test @@ -676,7 +676,7 @@ do_faultsim_test pagerfault-14a -prep { } -body { if {[catch {db backup test.db2} msg]} { error [regsub {.*: } $msg {}] } } -test { - faultsim_test_result {0 {}} {1 {}} {1 {SQL logic error or missing database}} + faultsim_test_result {0 {}} {1 {}} {1 {SQL logic error}} } # If TEMP_STORE is 2 or greater, then the database [db2] will be created diff --git a/test/pragma.test b/test/pragma.test index 44498d076b..27400917d8 100644 --- a/test/pragma.test +++ b/test/pragma.test @@ -1696,7 +1696,7 @@ testvfs tvfs sqlite3 db test.db -vfs tvfs do_test pragma-19.1 { catchsql {PRAGMA error} -} {1 {SQL logic error or missing database}} +} {1 {SQL logic error}} do_test pragma-19.2 { catchsql {PRAGMA error='This is the error message'} } {1 {This is the error message}} diff --git a/test/shell7.test b/test/shell7.test index a062885140..898018d775 100644 --- a/test/shell7.test +++ b/test/shell7.test @@ -50,5 +50,3 @@ foreach {tn l x} [db eval { SELECT tn, length(x) AS l, x FROM f1 }] { finish_test - - diff --git a/test/subjournal.test b/test/subjournal.test index d4ea643c6e..8d4c4499b0 100644 --- a/test/subjournal.test +++ b/test/subjournal.test @@ -67,4 +67,3 @@ do_test 2.4 { } {ok} finish_test - diff --git a/test/triggerF.test b/test/triggerF.test index d5e3565edd..e0c3b52d64 100644 --- a/test/triggerF.test +++ b/test/triggerF.test @@ -69,4 +69,3 @@ foreach {tn sql log} { } finish_test - diff --git a/test/update2.test b/test/update2.test index 6a359d11a9..af4ce96e7f 100644 --- a/test/update2.test +++ b/test/update2.test @@ -202,4 +202,3 @@ do_test 5.2 { finish_test - diff --git a/test/vtab1.test b/test/vtab1.test index 59ab959746..3354788096 100644 --- a/test/vtab1.test +++ b/test/vtab1.test @@ -954,7 +954,7 @@ do_test vtab1.10-3 { catchsql { INSERT INTO e VALUES(1, 2, 3); } -} {1 {SQL logic error or missing database}} +} {1 {SQL logic error}} do_test vtab1.10-4 { catch {execsql { EXPLAIN SELECT * FROM e WHERE rowid = 2; diff --git a/test/vtab_alter.test b/test/vtab_alter.test index eb50a28a5e..64053d1484 100644 --- a/test/vtab_alter.test +++ b/test/vtab_alter.test @@ -95,7 +95,7 @@ do_test vtab_alter-2.5 { do_test vtab_alter-3.1 { execsql { CREATE TABLE y_base(a, b, c) } catchsql { ALTER TABLE x RENAME TO y } -} {1 {SQL logic error or missing database}} +} {1 {SQL logic error}} do_test vtab_alter-3.2 { execsql { SELECT * FROM x } } {1 2 3} From 1d91e9f26a5ed62070afdec1d00773e110344ead Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 7 Jul 2017 20:35:14 +0000 Subject: [PATCH 17/64] Adjust copy_file() lsmtest function so it works properly for locked database files on Win32. FossilOrigin-Name: 54a3855583deac93c955ed77fe82be6a6b7aadd3fdb7e6b895888e2a4ff530bd --- ext/lsm1/lsm-test/lsmtest6.c | 24 +++++++++++++++--------- ext/lsm1/lsm-test/lsmtest_main.c | 5 +++++ manifest | 17 ++++++++--------- manifest.uuid | 2 +- 4 files changed, 29 insertions(+), 19 deletions(-) diff --git a/ext/lsm1/lsm-test/lsmtest6.c b/ext/lsm1/lsm-test/lsmtest6.c index d858249f3e..b0e6a39410 100644 --- a/ext/lsm1/lsm-test/lsmtest6.c +++ b/ext/lsm1/lsm-test/lsmtest6.c @@ -257,7 +257,7 @@ void testDeleteLsmdb(const char *zFile){ testFree(zShm); } -static void copy_file(const char *zFrom, const char *zTo){ +static void copy_file(const char *zFrom, const char *zTo, int isDatabase){ if( access(zFrom, F_OK) ){ unlink(zTo); @@ -278,9 +278,15 @@ static void copy_file(const char *zFrom, const char *zTo){ aBuf = testMalloc(4096); for(i=0; i #endif +#include #include #include #include @@ -1522,6 +1523,10 @@ int main(int argc, char **argv){ const char *zReport = "malloc.txt NOT generated"; #endif +#if defined(_MSC_VER) || defined(__MSVCRT__) + _set_fmode(_O_BINARY); +#endif + testMallocInstall(tdb_lsm_env()); if( argc<2 ){ diff --git a/manifest b/manifest index c2a8631797..582a0a70c7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s"PRAGMA\ssecure_delete=FAST"\soption,\swhich\soverwrites\smost\sdeleted\ncontent\swithout\sincreasing\sthe\samount\sof\sI/O.\s\sDeleted\scontent\smight\spersist\non\sthe\sfree\spage\slist,\showever.\s\sAnd\sextra\sCPU\scycles\sare\sused\sfor\szeroing,\nof\scourse. -D 2017-07-07T20:06:28.516 +C Adjust\scopy_file()\slsmtest\sfunction\sso\sit\sworks\sproperly\sfor\slocked\sdatabase\sfiles\son\sWin32. +D 2017-07-07T20:35:14.495 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba @@ -218,7 +218,7 @@ F ext/lsm1/lsm-test/lsmtest2.c 188b09aec776516aeedcfd13b9c6faf85ba16b3671a0897a2 F ext/lsm1/lsm-test/lsmtest3.c 9ab87528a36dbf4a61d7c8ad954f5ee368c0878c127b84b942b2e2abe522de26 F ext/lsm1/lsm-test/lsmtest4.c d258d6a245db5d8eaede096e2368d23f859c5e92c80ab9122463f708514fe10c F ext/lsm1/lsm-test/lsmtest5.c 8d5242a0f870d65eeada191c8945781fed9cb8ece3886573790ebd373b62dac5 -F ext/lsm1/lsm-test/lsmtest6.c 1f21509ea5d2b28b74539c2a70b8001619d0713091511067278f57871f4b753a +F ext/lsm1/lsm-test/lsmtest6.c dd27f91675c54892d34f2335e7d7f581dda56d3426177d37804a986dbc076f48 F ext/lsm1/lsm-test/lsmtest7.c 7a917455a0f956a8ed3f44f5c9387ec0ea6627714874464cc3fa5c5a9cabb2f2 F ext/lsm1/lsm-test/lsmtest8.c b87a1279b0cfbb39df1fff50074696fbf5d83822349f65706fab6d618a7a52fa F ext/lsm1/lsm-test/lsmtest9.c dd1a0ebf41134933a744d1e00e60429a2a21fc50d587ae7dd6bdb6e96d805bdc @@ -226,7 +226,7 @@ F ext/lsm1/lsm-test/lsmtest_bt.c d70d9a9be5eef9360af1251dd083948d74fd30137a08f61 F ext/lsm1/lsm-test/lsmtest_datasource.c 5d770be191d0ca51315926723009b2c25c0b4b8136840494ef710ac324aa916c F ext/lsm1/lsm-test/lsmtest_func.c 159aa401bc8032bfa3d8cf2977bd687abebab880255895a5eb45770d626fa38d F ext/lsm1/lsm-test/lsmtest_io.c ba678e052f497b4c2ff41d47672a1f2a02f495d14083845ee66e0bda678f5b80 -F ext/lsm1/lsm-test/lsmtest_main.c f1d18e3a3e9315ec4198901a11c9d2ec6cb96d1a40089fd60b6a64e0b6b8db35 +F ext/lsm1/lsm-test/lsmtest_main.c d0a7f9fe1119b0b347ec21908276bae60e0003dd0cba6634bfabcaa71b6db3e4 F ext/lsm1/lsm-test/lsmtest_mem.c c2980abdbc5024628d10910acb703354f2606b4a6f9624679da4e9a56bcee3e9 F ext/lsm1/lsm-test/lsmtest_tdb.c e46c3f44880d45fd444daf2b2a53bca7a64f9df3f6480cbb1b47a039cc95626a F ext/lsm1/lsm-test/lsmtest_tdb.h 8733eee249b12956a9df8322994b43d19bd8c02ad2e8b0bb5164db4d6ccc1735 @@ -1628,8 +1628,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 732f90d6327c5c6368fc8b4cc207bd644ef08e3ae6d2e7295258ab099deaba63 f1682f0faf1a93ded066464b1ddd5f987e21ee0f6bb5e828ed31c3ad903cf2c3 -R 1f238fbce697fb2308131c37c5985e85 -T +closed f1682f0faf1a93ded066464b1ddd5f987e21ee0f6bb5e828ed31c3ad903cf2c3 -U drh -Z c2c4f30ab3360a9e7249032b4e3580ff +P 38978ce65b280bb7cba3fc08ba91485fb1b84cd9fbba2e950ecf41c021ff452a +R 1560fcde20282350646516a96135e121 +U mistachkin +Z d23b91b5991a79a51cd11ccd5641741c diff --git a/manifest.uuid b/manifest.uuid index bc0b488c81..9c98879ddd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -38978ce65b280bb7cba3fc08ba91485fb1b84cd9fbba2e950ecf41c021ff452a \ No newline at end of file +54a3855583deac93c955ed77fe82be6a6b7aadd3fdb7e6b895888e2a4ff530bd \ No newline at end of file From 85bd1cd52bf0740a95a5ea907209e2982aba2366 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 7 Jul 2017 21:15:24 +0000 Subject: [PATCH 18/64] For lsmtest, use a more portable means of setting open() files to binary. FossilOrigin-Name: aea6e0ffd33f41482f1b53b9f21b77add2865abda4eec1d9ee197177f74f43d0 --- ext/lsm1/lsm-test/lsmtest.h | 4 ++++ ext/lsm1/lsm-test/lsmtest6.c | 4 ++-- ext/lsm1/lsm-test/lsmtest_io.c | 2 +- ext/lsm1/lsm-test/lsmtest_main.c | 6 +----- manifest | 18 +++++++++--------- manifest.uuid | 2 +- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/ext/lsm1/lsm-test/lsmtest.h b/ext/lsm1/lsm-test/lsmtest.h index ee6503a983..f5d03e8f3d 100644 --- a/ext/lsm1/lsm-test/lsmtest.h +++ b/ext/lsm1/lsm-test/lsmtest.h @@ -15,6 +15,10 @@ extern "C" { #endif +#ifndef _O_BINARY +# define _O_BINARY (0) +#endif + #ifdef _WIN32 # include "windows.h" # define gettimeofday win32GetTimeOfDay diff --git a/ext/lsm1/lsm-test/lsmtest6.c b/ext/lsm1/lsm-test/lsmtest6.c index b0e6a39410..b795465990 100644 --- a/ext/lsm1/lsm-test/lsmtest6.c +++ b/ext/lsm1/lsm-test/lsmtest6.c @@ -269,8 +269,8 @@ static void copy_file(const char *zFrom, const char *zTo, int isDatabase){ struct stat buf; u8 *aBuf; - fd1 = open(zFrom, O_RDONLY, 0644); - fd2 = open(zTo, O_RDWR | O_CREAT, 0644); + fd1 = open(zFrom, O_RDONLY | _O_BINARY, 0644); + fd2 = open(zTo, O_RDWR | O_CREAT | _O_BINARY, 0644); fstat(fd1, &buf); sz = buf.st_size; diff --git a/ext/lsm1/lsm-test/lsmtest_io.c b/ext/lsm1/lsm-test/lsmtest_io.c index 7d572ab0f7..f5599719b1 100644 --- a/ext/lsm1/lsm-test/lsmtest_io.c +++ b/ext/lsm1/lsm-test/lsmtest_io.c @@ -227,7 +227,7 @@ int do_io(int nArg, char **azArg){ aData = malloc(pgsz); memset(aData, 0x77, pgsz); - ctx.fd = open(zFile, O_RDWR|O_CREAT, 0644); + ctx.fd = open(zFile, O_RDWR|O_CREAT|_O_BINARY, 0644); if( ctx.fd<0 ){ perror("open: "); return -1; diff --git a/ext/lsm1/lsm-test/lsmtest_main.c b/ext/lsm1/lsm-test/lsmtest_main.c index ab44925b37..447f9849a2 100644 --- a/ext/lsm1/lsm-test/lsmtest_main.c +++ b/ext/lsm1/lsm-test/lsmtest_main.c @@ -1240,7 +1240,7 @@ static int do_writer_test(int nArg, char **azArg){ printf("Preparing file... "); fflush(stdout); unlink("writer.out"); - fd = open("writer.out", O_RDWR|O_CREAT, 0664); + fd = open("writer.out", O_RDWR|O_CREAT|_O_BINARY, 0664); if( fd<0 ){ testPrintError("open(): %d - %s\n", errno, strerror(errno)); return -1; @@ -1523,10 +1523,6 @@ int main(int argc, char **argv){ const char *zReport = "malloc.txt NOT generated"; #endif -#if defined(_MSC_VER) || defined(__MSVCRT__) - _set_fmode(_O_BINARY); -#endif - testMallocInstall(tdb_lsm_env()); if( argc<2 ){ diff --git a/manifest b/manifest index 582a0a70c7..96a038c340 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Adjust\scopy_file()\slsmtest\sfunction\sso\sit\sworks\sproperly\sfor\slocked\sdatabase\sfiles\son\sWin32. -D 2017-07-07T20:35:14.495 +C For\slsmtest,\suse\sa\smore\sportable\smeans\sof\ssetting\sopen()\sfiles\sto\sbinary. +D 2017-07-07T21:15:24.685 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba @@ -212,21 +212,21 @@ F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37 F ext/lsm1/Makefile a2ea4975162be8932b5efa727080f4982715d34c32035d9eb7a015ae78404981 F ext/lsm1/Makefile.msc 8b195e7b1567990cf2590802f59bda48005c601addb4deb3e1b8ee74c0ed3813 F ext/lsm1/lsm-test/README 87ea529d2abe615e856d4714bfe8bb185e6c2771b8612aa6298588b7b43e6f86 -F ext/lsm1/lsm-test/lsmtest.h 9c856fbaff90f2270b1df0ddff150925bcf7e1741035c5ddea0cc43c9f56210e +F ext/lsm1/lsm-test/lsmtest.h b608c88f4f509fb030be55692e2d6c22389f92acf6911fbad76080a5b7a67bd4 F ext/lsm1/lsm-test/lsmtest1.c 33158978327f800e82b6a47c09b86ace809f56a9ff10b0162273ec1186cc3153 F ext/lsm1/lsm-test/lsmtest2.c 188b09aec776516aeedcfd13b9c6faf85ba16b3671a0897a2c740ee00a5dc4f8 F ext/lsm1/lsm-test/lsmtest3.c 9ab87528a36dbf4a61d7c8ad954f5ee368c0878c127b84b942b2e2abe522de26 F ext/lsm1/lsm-test/lsmtest4.c d258d6a245db5d8eaede096e2368d23f859c5e92c80ab9122463f708514fe10c F ext/lsm1/lsm-test/lsmtest5.c 8d5242a0f870d65eeada191c8945781fed9cb8ece3886573790ebd373b62dac5 -F ext/lsm1/lsm-test/lsmtest6.c dd27f91675c54892d34f2335e7d7f581dda56d3426177d37804a986dbc076f48 +F ext/lsm1/lsm-test/lsmtest6.c de2932c87f4cd255de18f334aaffe999922274fc73537839bb000389d7e6aab0 F ext/lsm1/lsm-test/lsmtest7.c 7a917455a0f956a8ed3f44f5c9387ec0ea6627714874464cc3fa5c5a9cabb2f2 F ext/lsm1/lsm-test/lsmtest8.c b87a1279b0cfbb39df1fff50074696fbf5d83822349f65706fab6d618a7a52fa F ext/lsm1/lsm-test/lsmtest9.c dd1a0ebf41134933a744d1e00e60429a2a21fc50d587ae7dd6bdb6e96d805bdc F ext/lsm1/lsm-test/lsmtest_bt.c d70d9a9be5eef9360af1251dd083948d74fd30137a08f61bef995f7ac04e037f F ext/lsm1/lsm-test/lsmtest_datasource.c 5d770be191d0ca51315926723009b2c25c0b4b8136840494ef710ac324aa916c F ext/lsm1/lsm-test/lsmtest_func.c 159aa401bc8032bfa3d8cf2977bd687abebab880255895a5eb45770d626fa38d -F ext/lsm1/lsm-test/lsmtest_io.c ba678e052f497b4c2ff41d47672a1f2a02f495d14083845ee66e0bda678f5b80 -F ext/lsm1/lsm-test/lsmtest_main.c d0a7f9fe1119b0b347ec21908276bae60e0003dd0cba6634bfabcaa71b6db3e4 +F ext/lsm1/lsm-test/lsmtest_io.c 76d88fd3307977bac646766270c3c3550e35db84c30d912ce9ed5209954dbff9 +F ext/lsm1/lsm-test/lsmtest_main.c 5c09d83771684d312f05900a9baaec36de35ba944f50de18d3cd048d77ddad8e F ext/lsm1/lsm-test/lsmtest_mem.c c2980abdbc5024628d10910acb703354f2606b4a6f9624679da4e9a56bcee3e9 F ext/lsm1/lsm-test/lsmtest_tdb.c e46c3f44880d45fd444daf2b2a53bca7a64f9df3f6480cbb1b47a039cc95626a F ext/lsm1/lsm-test/lsmtest_tdb.h 8733eee249b12956a9df8322994b43d19bd8c02ad2e8b0bb5164db4d6ccc1735 @@ -1628,7 +1628,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 38978ce65b280bb7cba3fc08ba91485fb1b84cd9fbba2e950ecf41c021ff452a -R 1560fcde20282350646516a96135e121 +P 54a3855583deac93c955ed77fe82be6a6b7aadd3fdb7e6b895888e2a4ff530bd +R cffa0e246b9b1b52313665f4ee7633f9 U mistachkin -Z d23b91b5991a79a51cd11ccd5641741c +Z a1c8c4addf6f708ab7459adb3af8bef9 diff --git a/manifest.uuid b/manifest.uuid index 9c98879ddd..c017009eff 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -54a3855583deac93c955ed77fe82be6a6b7aadd3fdb7e6b895888e2a4ff530bd \ No newline at end of file +aea6e0ffd33f41482f1b53b9f21b77add2865abda4eec1d9ee197177f74f43d0 \ No newline at end of file From 50963c9da8b05fe4d64a522feda142107e64b3b8 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 7 Jul 2017 21:20:26 +0000 Subject: [PATCH 19/64] Fix comment in the Win32 VFS for lsm1. FossilOrigin-Name: 12a421bcacf72128426eeafed8663accd8f2ac7edb46f620b60b8239065e657e --- ext/lsm1/lsm_win32.c | 2 +- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ext/lsm1/lsm_win32.c b/ext/lsm1/lsm_win32.c index b770af51d3..34a1c8a0b2 100644 --- a/ext/lsm1/lsm_win32.c +++ b/ext/lsm1/lsm_win32.c @@ -951,7 +951,7 @@ static int lsmWin32OsMutexNotHeld(lsm_mutex *p){ } #endif /* -** End of pthreads mutex implementation. +** End of Win32 mutex implementation. *************************************************************************/ #else /************************************************************************* diff --git a/manifest b/manifest index 96a038c340..16e782aa03 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C For\slsmtest,\suse\sa\smore\sportable\smeans\sof\ssetting\sopen()\sfiles\sto\sbinary. -D 2017-07-07T21:15:24.685 +C Fix\scomment\sin\sthe\sWin32\sVFS\sfor\slsm1. +D 2017-07-07T21:20:26.973 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba @@ -250,7 +250,7 @@ F ext/lsm1/lsm_tree.c 53b657439e0fcb1117b0559ad3567ac417f81f2ed0fff9bab79948a00e F ext/lsm1/lsm_unix.c 57361bcf5b1a1a028f5d66571ee490e9064d2cfb145a2cc9e5ddade467bb551b F ext/lsm1/lsm_varint.c b19ae9bd26b5a1e8402fb8a564b25d9542338a41 F ext/lsm1/lsm_vtab.c 812b74a9a7539e8cab49761591ffddc1b3580735fac5d638826c8d2be95ff38b -F ext/lsm1/lsm_win32.c 6695337721cad5fbc226d6df4de5fa8537f47b52b909e0b832e190ad7e32cdb5 +F ext/lsm1/lsm_win32.c 646b20f966e834bbf91ce763050bd6cf2732095b8165e6b1f09da22493149bc5 F ext/misc/README.md 8e008c8d2b02e09096b31dfba033253ac27c6c06a18aa5826e299fa7601d90b2 F ext/misc/amatch.c 6db4607cb17c54b853a2d7c7c36046d004853f65b9b733e6f019d543d5dfae87 F ext/misc/anycollseq.c 5ffdfde9829eeac52219136ad6aa7cd9a4edb3b15f4f2532de52f4a22525eddb @@ -1628,7 +1628,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 54a3855583deac93c955ed77fe82be6a6b7aadd3fdb7e6b895888e2a4ff530bd -R cffa0e246b9b1b52313665f4ee7633f9 +P aea6e0ffd33f41482f1b53b9f21b77add2865abda4eec1d9ee197177f74f43d0 +R def83fb5cfa9576d8c12369340380816 U mistachkin -Z a1c8c4addf6f708ab7459adb3af8bef9 +Z 8beb9c524f111477daf399393f3c71eb diff --git a/manifest.uuid b/manifest.uuid index c017009eff..4bf839d015 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -aea6e0ffd33f41482f1b53b9f21b77add2865abda4eec1d9ee197177f74f43d0 \ No newline at end of file +12a421bcacf72128426eeafed8663accd8f2ac7edb46f620b60b8239065e657e \ No newline at end of file From 12ca0fc25933d4d94de6c4caffebbd3823c0b9ba Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 7 Jul 2017 22:47:32 +0000 Subject: [PATCH 20/64] Basic test cases for PRAGMA secure_delete=FAST. FossilOrigin-Name: 0c246017b45c5290f3a7932dfce649f1a6d8f9afc00c6c3edf2ef06c17dbca1d --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/securedel.test | 24 ++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 16e782aa03..b54eac96d3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\scomment\sin\sthe\sWin32\sVFS\sfor\slsm1. -D 2017-07-07T21:20:26.973 +C Basic\stest\scases\sfor\sPRAGMA\ssecure_delete=FAST. +D 2017-07-07T22:47:32.568 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba @@ -1138,7 +1138,7 @@ F test/schema2.test 906408621ea881fdb496d878b1822572a34e32c5 F test/schema3.test 1bc1008e1f8cb5654b248c55f27249366eb7ed38 F test/schema4.test 3b26c9fa916abb6dadf894137adcf41b7796f7b9 F test/schema5.test 29699b4421f183c8f0e88bd28ce7d75d13ea653e -F test/securedel.test 21749c32ccc30f1ea9e4b9f33295a6521ec20fa0 +F test/securedel.test 5f997cb6bd38727b81e0985f53ec386c99db6441b2b9e6357240649d29017239 F test/securedel2.test 2d54c28e46eb1fd6902089958b20b1b056c6f1c5 F test/select1.test be62204d2bd9a5a8a149e9974cfddce893d8f686 F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56 @@ -1628,7 +1628,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P aea6e0ffd33f41482f1b53b9f21b77add2865abda4eec1d9ee197177f74f43d0 -R def83fb5cfa9576d8c12369340380816 -U mistachkin -Z 8beb9c524f111477daf399393f3c71eb +P 12a421bcacf72128426eeafed8663accd8f2ac7edb46f620b60b8239065e657e +R e6f8feea678ffb081657c6bb012062fd +U drh +Z c614413c179295441abb82c2446a03c8 diff --git a/manifest.uuid b/manifest.uuid index 4bf839d015..855c66f415 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -12a421bcacf72128426eeafed8663accd8f2ac7edb46f620b60b8239065e657e \ No newline at end of file +0c246017b45c5290f3a7932dfce649f1a6d8f9afc00c6c3edf2ef06c17dbca1d \ No newline at end of file diff --git a/test/securedel.test b/test/securedel.test index 7111e08e71..a78f466031 100644 --- a/test/securedel.test +++ b/test/securedel.test @@ -52,6 +52,30 @@ do_test securedel-1.4 { PRAGMA db2.secure_delete; } } {1 1} +do_test securedel-1.5 { + db eval { + PRAGMA secure_delete=FAST; + PRAGMA db2.secure_delete; + } +} {2 2} +do_test securedel-1.6 { + db eval { + PRAGMA secure_delete=ON; + PRAGMA db2.secure_delete; + } +} {1 1} +do_test securedel-1.7 { + db eval { + PRAGMA main.secure_delete=FAST; + PRAGMA db2.secure_delete; + } +} {2 1} +do_test securedel-1.8 { + db eval { + PRAGMA main.secure_delete=ON; + PRAGMA db2.secure_delete; + } +} {1 1} do_test securedel-2.1 { db eval { From 2aa31333c2d4c79c0697d4dcbb90965a5df5e276 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 8 Jul 2017 22:30:30 +0000 Subject: [PATCH 21/64] Add the --icc, --gcc7, and --orm options to the speed-check.sh test script. FossilOrigin-Name: 70dae08a9a6e35416f7268b9a95f3c8562b74697918bd1e9d5b5cf4719b9d075 --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/speed-check.sh | 11 ++++++++++- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index b54eac96d3..f9301ef9cc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Basic\stest\scases\sfor\sPRAGMA\ssecure_delete=FAST. -D 2017-07-07T22:47:32.568 +C Add\sthe\s--icc,\s--gcc7,\sand\s--orm\soptions\sto\sthe\sspeed-check.sh\stest\sscript. +D 2017-07-08T22:30:30.933 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba @@ -1588,7 +1588,7 @@ F tool/showstat4.c b14159aa062f661b394ba37b6b7b94bfb8012ab9 F tool/showwal.c ad9d768f96ca6199ad3a8c9562d679680bd032dd01204ea3e5ea6fb931d81847 F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe F tool/spaceanal.tcl f40dc82b4d5e39d040a02a3ec38268e324068815e4292a15ffa30ee93208bbfd -F tool/speed-check.sh 9630ba0468b609c52f48309243d4eb6e9c34deda +F tool/speed-check.sh fd24151fd66465f01886c3f75faf8fa46d19f068c69d16514ca73887adcdafe4 F tool/speedtest.tcl 06c76698485ccf597b9e7dbb1ac70706eb873355 F tool/speedtest16.c ecb6542862151c3e6509bbc00509b234562ae81e F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff @@ -1628,7 +1628,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 12a421bcacf72128426eeafed8663accd8f2ac7edb46f620b60b8239065e657e -R e6f8feea678ffb081657c6bb012062fd +P 0c246017b45c5290f3a7932dfce649f1a6d8f9afc00c6c3edf2ef06c17dbca1d +R 790e0518c141c3e30ee1148ab425730a U drh -Z c614413c179295441abb82c2446a03c8 +Z 9e4f8a303b6a755dc44ed919de98f263 diff --git a/manifest.uuid b/manifest.uuid index 855c66f415..6a4c02ff58 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0c246017b45c5290f3a7932dfce649f1a6d8f9afc00c6c3edf2ef06c17dbca1d \ No newline at end of file +70dae08a9a6e35416f7268b9a95f3c8562b74697918bd1e9d5b5cf4719b9d075 \ No newline at end of file diff --git a/tool/speed-check.sh b/tool/speed-check.sh index 1e1389f2fd..5de218748a 100644 --- a/tool/speed-check.sh +++ b/tool/speed-check.sh @@ -84,6 +84,12 @@ while test "$1" != ""; do --clang) CC=clang ;; + --icc) + CC=/home/drh/intel/bin/icc + ;; + --gcc7) + CC=gcc-7 + ;; --heap) CC_OPTS="$CC_OPTS -DSQLITE_ENABLE_MEMSYS5" shift; @@ -107,6 +113,9 @@ while test "$1" != ""; do SPEEDTEST_OPTS="$SPEEDTEST_OPTS --testset rtree" CC_OPTS="$CC_OPTS -DSQLITE_ENABLE_RTREE" ;; + --orm) + SPEEDTEST_OPTS="$SPEEDTEST_OPTS --testset orm" + ;; *) CC_OPTS="$CC_OPTS $1" ;; @@ -143,5 +152,5 @@ if test $doExplain -eq 1; then ./speedtest1 --explain $SPEEDTEST_OPTS | ./sqlite3 >explain-$NAME.txt fi if test "$NAME" != "trunk"; then - fossil test-diff --tk cout-trunk.txt cout-$NAME.txt + fossil test-diff --tk -c 20 cout-trunk.txt cout-$NAME.txt fi From d7ca600ede9f472b39dc54714f2c74f7f56fc385 Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 9 Jul 2017 00:30:58 +0000 Subject: [PATCH 22/64] Make sure the columns of a VALUES() clause are named "column%d" even if the VALUES() clause is a subquery in the FROM clause of an outer query. FossilOrigin-Name: acf3b9cc9c3932431979995a1dceacc06c659ab400fad95ce3728ff8895a022b --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/select.c | 6 +++++- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index f9301ef9cc..4b30010431 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s--icc,\s--gcc7,\sand\s--orm\soptions\sto\sthe\sspeed-check.sh\stest\sscript. -D 2017-07-08T22:30:30.933 +C Make\ssure\sthe\scolumns\sof\sa\sVALUES()\sclause\sare\snamed\s"column%d"\seven\sif\nthe\sVALUES()\sclause\sis\sa\ssubquery\sin\sthe\sFROM\sclause\sof\san\souter\squery. +D 2017-07-09T00:30:58.430 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba @@ -448,7 +448,7 @@ F src/printf.c 8757834f1b54dae512fb25eb1acc8e94a0d15dd2290b58f2563f65973265adb2 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 6aa1fb1212e601f65b983ee1215d69a591986c8f97a3805c425c625a53839539 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac -F src/select.c c9f7b7196e196e93979665680d055a789938b8e025556097bf484b184c0dd576 +F src/select.c c1e669e01cb37c0683108a10e929615112572666053381df786806113b9a3ac4 F src/shell.c a7067f647aef4b81569bbfd025f4fd120a4e7576a647d2aad05028eb50e50e48 F src/sqlite.h.in c38c31f2a874af2b7d8443aba1fba3652d8ee75f60305d2512215cbe0fa0674a F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1628,7 +1628,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0c246017b45c5290f3a7932dfce649f1a6d8f9afc00c6c3edf2ef06c17dbca1d -R 790e0518c141c3e30ee1148ab425730a +P 70dae08a9a6e35416f7268b9a95f3c8562b74697918bd1e9d5b5cf4719b9d075 +R bd4690b24493be6c9d3f040b4f986ae1 U drh -Z 9e4f8a303b6a755dc44ed919de98f263 +Z ceb54c87f0670b76840ec1e6992b9263 diff --git a/manifest.uuid b/manifest.uuid index 6a4c02ff58..55ca94591e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -70dae08a9a6e35416f7268b9a95f3c8562b74697918bd1e9d5b5cf4719b9d075 \ No newline at end of file +acf3b9cc9c3932431979995a1dceacc06c659ab400fad95ce3728ff8895a022b \ No newline at end of file diff --git a/src/select.c b/src/select.c index c50052f2e9..1c700e35a5 100644 --- a/src/select.c +++ b/src/select.c @@ -1704,7 +1704,11 @@ int sqlite3ColumnsFromExprList( zName = pEList->a[i].zSpan; } } - zName = sqlite3MPrintf(db, "%s", zName); + if( zName ){ + zName = sqlite3DbStrDup(db, zName); + }else{ + zName = sqlite3MPrintf(db,"column%d",i); + } /* Make sure the column name is unique. If the name is not unique, ** append an integer to the name so that it becomes unique. From 155507b344e8ad8a2abf144514e13329610f34d1 Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 9 Jul 2017 18:55:29 +0000 Subject: [PATCH 23/64] Always make "column%d" column-names 1-based, never 0-based. FossilOrigin-Name: 70096c505d702a9646da24613da387cee19afcf395d0294b3797c5ab50bb3ee2 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/select.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 4b30010431..a37c3415da 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\sthe\scolumns\sof\sa\sVALUES()\sclause\sare\snamed\s"column%d"\seven\sif\nthe\sVALUES()\sclause\sis\sa\ssubquery\sin\sthe\sFROM\sclause\sof\san\souter\squery. -D 2017-07-09T00:30:58.430 +C Always\smake\s"column%d"\scolumn-names\s1-based,\snever\s0-based. +D 2017-07-09T18:55:29.015 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba @@ -448,7 +448,7 @@ F src/printf.c 8757834f1b54dae512fb25eb1acc8e94a0d15dd2290b58f2563f65973265adb2 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 6aa1fb1212e601f65b983ee1215d69a591986c8f97a3805c425c625a53839539 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac -F src/select.c c1e669e01cb37c0683108a10e929615112572666053381df786806113b9a3ac4 +F src/select.c 6aa7e8ee53dcb9d0b77b05670bb44a1076d6747bc9b2c1f12a365b553ab6c828 F src/shell.c a7067f647aef4b81569bbfd025f4fd120a4e7576a647d2aad05028eb50e50e48 F src/sqlite.h.in c38c31f2a874af2b7d8443aba1fba3652d8ee75f60305d2512215cbe0fa0674a F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1628,7 +1628,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 70dae08a9a6e35416f7268b9a95f3c8562b74697918bd1e9d5b5cf4719b9d075 -R bd4690b24493be6c9d3f040b4f986ae1 +P acf3b9cc9c3932431979995a1dceacc06c659ab400fad95ce3728ff8895a022b +R 60d8e23fc76e5f2c3762a18b534f29c2 U drh -Z ceb54c87f0670b76840ec1e6992b9263 +Z b13c2baffb7906f86d964ad698ac5682 diff --git a/manifest.uuid b/manifest.uuid index 55ca94591e..471b2ee259 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -acf3b9cc9c3932431979995a1dceacc06c659ab400fad95ce3728ff8895a022b \ No newline at end of file +70096c505d702a9646da24613da387cee19afcf395d0294b3797c5ab50bb3ee2 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 1c700e35a5..bb6f68221b 100644 --- a/src/select.c +++ b/src/select.c @@ -1707,7 +1707,7 @@ int sqlite3ColumnsFromExprList( if( zName ){ zName = sqlite3DbStrDup(db, zName); }else{ - zName = sqlite3MPrintf(db,"column%d",i); + zName = sqlite3MPrintf(db,"column%d",i+1); } /* Make sure the column name is unique. If the name is not unique, From e75be1aedb09ff85f97485877085540e812a4a6a Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 10 Jul 2017 11:17:51 +0000 Subject: [PATCH 24/64] Remove the error message text from disused error codes such as SQLITE_EMPTY and SQLITE_FORMAT. FossilOrigin-Name: 871752f2925ee14bdd3e994c00832d00860c03f6f28e63504aa6d35978b7f37c --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/main.c | 8 ++++++-- src/sqlite.h.in | 4 ++-- test/capi3.test | 3 --- 5 files changed, 17 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index a37c3415da..e4f30e7f52 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Always\smake\s"column%d"\scolumn-names\s1-based,\snever\s0-based. -D 2017-07-09T18:55:29.015 +C Remove\sthe\serror\smessage\stext\sfrom\sdisused\serror\scodes\ssuch\sas\nSQLITE_EMPTY\sand\sSQLITE_FORMAT. +D 2017-07-10T11:17:51.852 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba @@ -413,7 +413,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c bb70abf32c7c926745eb550938db9132309584a667a44c2db0e5fa3207600391 F src/legacy.c 134ab3e3fae00a0f67a5187981d6935b24b337bcf0f4b3e5c9fa5763da95bf4e F src/loadext.c a72909474dadce771d3669bf84bf689424f6f87d471fee898589c3ef9b2acfd9 -F src/main.c e36ab281dc7d08eacf8789459b06e34ea1272631a67489799d4303be81aa7c14 +F src/main.c 66bf423085fb7e4ceb2d9c569884077995d7a529feba1dd722ea290212372610 F src/malloc.c e20bb2b48abec52d3faf01cce12e8b4f95973755fafec98d45162dfdab111978 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de @@ -450,7 +450,7 @@ F src/resolve.c 6aa1fb1212e601f65b983ee1215d69a591986c8f97a3805c425c625a53839539 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 6aa7e8ee53dcb9d0b77b05670bb44a1076d6747bc9b2c1f12a365b553ab6c828 F src/shell.c a7067f647aef4b81569bbfd025f4fd120a4e7576a647d2aad05028eb50e50e48 -F src/sqlite.h.in c38c31f2a874af2b7d8443aba1fba3652d8ee75f60305d2512215cbe0fa0674a +F src/sqlite.h.in 03a422ba13da1dfef7f1aaa1ba344acf18dc867112620b1fdb2a1426cabba634 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 58fd0676d3111d02e62e5a35992a7d3da5d3f88753acc174f2d37b774fbbdd28 F src/sqliteInt.h 7a7cd6f682471cce4afe64216f71fd64c622712aeb9d947c33c38337a7cf19a9 @@ -624,7 +624,7 @@ F test/cache.test 13bc046b26210471ca6f2889aceb1ea52dc717de F test/cacheflush.test af25bb1509df04c1da10e38d8f322d66eceedf61 F test/cachespill.test 895997f84a25b323b166aecb69baab2d6380ea98f9e0bcc688c4493c535cfab9 F test/capi2.test 011c16da245fdc0106a2785035de6b242c05e738 -F test/capi3.test c6afa851428e60b78134f26e2a7ad55204b0b1612db62f284749f6b4b775fe2a +F test/capi3.test 02f4cbbd3478608278c8cf10ea558475f187c5e4944bc6215d1f970f51b98f5c F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4 F test/capi3c.test 09e311d58b5d9586dde8ad87801a5dc41f52b7da273a331b5f7bdb12b3c7c92f F test/capi3d.test 485048dc5cd07bc68011e4917ad035ad6047ab82 @@ -1628,7 +1628,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P acf3b9cc9c3932431979995a1dceacc06c659ab400fad95ce3728ff8895a022b -R 60d8e23fc76e5f2c3762a18b534f29c2 +P 70096c505d702a9646da24613da387cee19afcf395d0294b3797c5ab50bb3ee2 +R 599e40027aa06aba6639eebf73b95973 U drh -Z b13c2baffb7906f86d964ad698ac5682 +Z be8ad28c2c42a9cd93fa855fe84d686d diff --git a/manifest.uuid b/manifest.uuid index 471b2ee259..b10a1c0588 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -70096c505d702a9646da24613da387cee19afcf395d0294b3797c5ab50bb3ee2 \ No newline at end of file +871752f2925ee14bdd3e994c00832d00860c03f6f28e63504aa6d35978b7f37c \ No newline at end of file diff --git a/src/main.c b/src/main.c index 54d12a3806..a72520084b 100644 --- a/src/main.c +++ b/src/main.c @@ -1419,15 +1419,19 @@ const char *sqlite3ErrStr(int rc){ /* SQLITE_FULL */ "database or disk is full", /* SQLITE_CANTOPEN */ "unable to open database file", /* SQLITE_PROTOCOL */ "locking protocol", - /* SQLITE_EMPTY */ "table contains no data", + /* SQLITE_EMPTY */ 0, /* SQLITE_SCHEMA */ "database schema has changed", /* SQLITE_TOOBIG */ "string or blob too big", /* SQLITE_CONSTRAINT */ "constraint failed", /* SQLITE_MISMATCH */ "datatype mismatch", /* SQLITE_MISUSE */ "library routine called out of sequence", +#ifdef SQLITE_DISABLE_LFS /* SQLITE_NOLFS */ "large file support is disabled", +#else + /* SQLITE_NOLFS */ 0, +#endif /* SQLITE_AUTH */ "authorization denied", - /* SQLITE_FORMAT */ "auxiliary database format error", + /* SQLITE_FORMAT */ 0, /* SQLITE_RANGE */ "bind or column index out of range", /* SQLITE_NOTADB */ "file is encrypted or is not a database", }; diff --git a/src/sqlite.h.in b/src/sqlite.h.in index bf5118b2c3..037269973a 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -432,7 +432,7 @@ int sqlite3_exec( #define SQLITE_FULL 13 /* Insertion failed because database is full */ #define SQLITE_CANTOPEN 14 /* Unable to open the database file */ #define SQLITE_PROTOCOL 15 /* Database lock protocol error */ -#define SQLITE_EMPTY 16 /* Database is empty */ +#define SQLITE_EMPTY 16 /* Not used */ #define SQLITE_SCHEMA 17 /* The database schema changed */ #define SQLITE_TOOBIG 18 /* String or BLOB exceeds size limit */ #define SQLITE_CONSTRAINT 19 /* Abort due to constraint violation */ @@ -440,7 +440,7 @@ int sqlite3_exec( #define SQLITE_MISUSE 21 /* Library used incorrectly */ #define SQLITE_NOLFS 22 /* Uses OS features not supported on host */ #define SQLITE_AUTH 23 /* Authorization denied */ -#define SQLITE_FORMAT 24 /* Auxiliary database format error */ +#define SQLITE_FORMAT 24 /* Not used */ #define SQLITE_RANGE 25 /* 2nd parameter to sqlite3_bind out of range */ #define SQLITE_NOTADB 26 /* File opened that is not a database file */ #define SQLITE_NOTICE 27 /* Notifications from sqlite3_log() */ diff --git a/test/capi3.test b/test/capi3.test index c64640e84f..c8eea9d601 100644 --- a/test/capi3.test +++ b/test/capi3.test @@ -781,14 +781,11 @@ SQLITE_IOERR {disk I/O error} \ SQLITE_CORRUPT {database disk image is malformed} \ SQLITE_FULL {database or disk is full} \ SQLITE_CANTOPEN {unable to open database file} \ -SQLITE_EMPTY {table contains no data} \ SQLITE_SCHEMA {database schema has changed} \ SQLITE_CONSTRAINT {constraint failed} \ SQLITE_MISMATCH {datatype mismatch} \ SQLITE_MISUSE {library routine called out of sequence} \ -SQLITE_NOLFS {large file support is disabled} \ SQLITE_AUTH {authorization denied} \ -SQLITE_FORMAT {auxiliary database format error} \ SQLITE_RANGE {bind or column index out of range} \ SQLITE_NOTADB {file is encrypted or is not a database} \ unknownerror {unknown error} \ From ff4fa772f557d6986653e0cbcfc7ff5e97f8961d Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 10 Jul 2017 12:07:53 +0000 Subject: [PATCH 25/64] Update error message text for standard error codes to better describe the latest usage of those error codes. Modify sqlite3_open_v2() so that it does return a valid sqlite3 object in the event of SQLITE_MISUSE due to bad open flags, so that sqlite3_errmsg() does not report "out of memory" in that case. FossilOrigin-Name: f27b6370407842e2c175ea4aa9ce018723c57eaac0cccc1f8399bc20f33324be --- manifest | 50 +++++++++++++++++----------------- manifest.uuid | 2 +- src/main.c | 62 +++++++++++++++++++++---------------------- test/attach.test | 2 +- test/backup2.test | 6 ++--- test/bind.test | 8 +++--- test/capi3.test | 12 ++++----- test/capi3c.test | 16 +++++------ test/close.test | 2 +- test/corrupt2.test | 4 +-- test/corruptA.test | 8 +++--- test/e_blobwrite.test | 8 +++--- test/filefmt.test | 8 +++--- test/fuzz3.test | 2 +- test/incrvacuum.test | 2 +- test/misc5.test | 2 +- test/misuse.test | 6 ++--- test/pager1.test | 2 +- test/shared_err.test | 2 +- test/syscall.test | 4 +-- test/vtab1.test | 2 +- test/vtab7.test | 2 +- 22 files changed, 104 insertions(+), 108 deletions(-) diff --git a/manifest b/manifest index e4f30e7f52..533b3b378f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sthe\serror\smessage\stext\sfrom\sdisused\serror\scodes\ssuch\sas\nSQLITE_EMPTY\sand\sSQLITE_FORMAT. -D 2017-07-10T11:17:51.852 +C Update\serror\smessage\stext\sfor\sstandard\serror\scodes\sto\sbetter\sdescribe\sthe\nlatest\susage\sof\sthose\serror\scodes.\s\sModify\ssqlite3_open_v2()\sso\sthat\sit\sdoes\nreturn\sa\svalid\ssqlite3\sobject\sin\sthe\sevent\sof\sSQLITE_MISUSE\sdue\sto\sbad\nopen\sflags,\sso\sthat\ssqlite3_errmsg()\sdoes\snot\sreport\s"out\sof\smemory"\sin\sthat\ncase. +D 2017-07-10T12:07:53.037 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba @@ -413,7 +413,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c bb70abf32c7c926745eb550938db9132309584a667a44c2db0e5fa3207600391 F src/legacy.c 134ab3e3fae00a0f67a5187981d6935b24b337bcf0f4b3e5c9fa5763da95bf4e F src/loadext.c a72909474dadce771d3669bf84bf689424f6f87d471fee898589c3ef9b2acfd9 -F src/main.c 66bf423085fb7e4ceb2d9c569884077995d7a529feba1dd722ea290212372610 +F src/main.c 20574bb9a0d7911efcd659ac252f2126dc4e3308bed3c8764ea3fb5a00f70420 F src/malloc.c e20bb2b48abec52d3faf01cce12e8b4f95973755fafec98d45162dfdab111978 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de @@ -567,7 +567,7 @@ F test/async3.test d73a062002376d7edc1fe3edff493edbec1fc2f7 F test/async4.test 1787e3952128aa10238bf39945126de7ca23685a F test/async5.test 383ab533fdb9f7ad228cc99ee66e1acb34cc0dc0 F test/atof1.test ff0b0156fd705b67c506e1f2bfe9e26102bea9bd -F test/attach.test 9976867b1a6585018f0966857aa82ed44e0bd6dc +F test/attach.test b4c269f780b82acb1a17f2dddefe4da7304406cfa7cc371318ee55b7bf5ffb0c F test/attach2.test 0ec5defa340363de6cd50fd595046465e9aaba2d F test/attach3.test c59d92791070c59272e00183b7353eeb94915976 F test/attach4.test 53bf502f17647c6d6c5add46dda6bac8b6f4665c @@ -587,7 +587,7 @@ F test/autovacuum_ioerr2.test 8a367b224183ad801e0e24dcb7d1501f45f244b4 F test/avtrans.test 0252654f4295ddda3b2cce0e894812259e655a85 F test/backcompat.test 3e64cedda754c778ef6bbe417b6e7a295e662a4d F test/backup.test dd4a5ff756e3df3931dacb1791db0584d4bad989 -F test/backup2.test 34986ef926ea522911a51dfdb2f8e99b7b75ebcf +F test/backup2.test 24e84f0b2b43199f5aed49ef8a43183bfc550de5772162ed7721223dbdf56b4e F test/backup4.test 8f6fd48e0dfde77b9a3bb26dc471ede3e101df32 F test/backup5.test ee5da6d7fe5082f5b9b0bbfa31d016f52412a2e4 F test/backup_ioerr.test 4c3c7147cee85b024ecf6e150e090c32fdbb5135 @@ -604,7 +604,7 @@ F test/bigfile.test aa74f4e5db51c8e54a1d9de9fa65d01d1eb20b59 F test/bigfile2.test 1b489a3a39ae90c7f027b79110d6b4e1dbc71bfc F test/bigrow.test f0aeb7573dcb8caaafea76454be3ade29b7fc747 F test/bigsort.test 8299fa9298f4f1e02fc7d2712e8b77d6cd60e5a2 -F test/bind.test 3c7b320969000c441a70952b0b15938fbb66237c +F test/bind.test 1e136709b306f7ed3192d349c2930d89df6ab621654ad6f1a72381d3fe76f483 F test/bindxfer.test efecd12c580c14df5f4ad3b3e83c667744a4f7e0 F test/bitvec.test 75894a880520164d73b1305c1c3f96882615e142 F test/blob.test e7ac6c7d3a985cc4678c64f325292529a69ae252 @@ -624,15 +624,15 @@ F test/cache.test 13bc046b26210471ca6f2889aceb1ea52dc717de F test/cacheflush.test af25bb1509df04c1da10e38d8f322d66eceedf61 F test/cachespill.test 895997f84a25b323b166aecb69baab2d6380ea98f9e0bcc688c4493c535cfab9 F test/capi2.test 011c16da245fdc0106a2785035de6b242c05e738 -F test/capi3.test 02f4cbbd3478608278c8cf10ea558475f187c5e4944bc6215d1f970f51b98f5c +F test/capi3.test 986e57cea8ab423b3fc8c2e3b69330394252d3d2a4496122ff3749e258305695 F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4 -F test/capi3c.test 09e311d58b5d9586dde8ad87801a5dc41f52b7da273a331b5f7bdb12b3c7c92f +F test/capi3c.test 7ebed1d8fa2f3190149d556fe8cff5a006be62af437c5c4640db614470126098 F test/capi3d.test 485048dc5cd07bc68011e4917ad035ad6047ab82 F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3 F test/cffault.test 9d6b20606afe712374952eec4f8fd74b1a8097ef F test/check.test 33a698e8c63613449d85d624a38ef669bf20331daabebe3891c9405dd6df463a -F test/close.test 83947daf3b700631f90f4850ddaab455be4af73d +F test/close.test 799ea4599d2f5704b0a30f477d17c2c760d8523fa5d0c8be4a7df2a8cad787d8 F test/closure01.test b1703ba40639cfc9b295cf478d70739415eec6a4 F test/coalesce.test cee0dccb9fbd2d494b77234bccf9dc6c6786eb91 F test/collate1.test 08c18e7512a5a32c97938854263fa15362eeb846 @@ -653,7 +653,7 @@ F test/conflict2.test bb0b94cf7196c64a3cbd815c66d3ee98c2fecd9c F test/conflict3.test a83db76a6c3503b2fa057c7bfb08c318d8a422202d8bc5b86226e078e5b49ff9 F test/contrib01.test 2a1cbc0f2f48955d7d073f725765da6fbceda6b4 F test/corrupt.test 141c39ea650c1365e85a49e402fa05cb9617fb97 -F test/corrupt2.test e4964cee73dda57a90958e0087a6b388b1d9cb58 +F test/corrupt2.test b6281ceadd6114d55e89b25e01c617af930dda71567f6a0996a719c385ac142e F test/corrupt3.test e676f478fe602915d721472811f6f410b75ddc7e F test/corrupt4.test 8d1d86b850fcc43e417450454f2044e52d55778a F test/corrupt5.test 8ead52af76006f3286e9396cb41898018ccea107 @@ -661,7 +661,7 @@ F test/corrupt6.test fc6a891716139665dae0073b6945e3670bf92568 F test/corrupt7.test b036f94bda4b0b23a2919bf717046ce9ecca4543 F test/corrupt8.test 2399dfe40d2c0c63af86706e30f3e6302a8d0516 F test/corrupt9.test 730a3db08d4ab9aa43392ea30d9c2b4879cbff85 -F test/corruptA.test 53e56dafd180addcdadb402244b8cb9771d2ba26 +F test/corruptA.test 112f4b2ae0b95ebf3ea63718642fb969a93acea557ace3a307234d19c245989b F test/corruptB.test 73a8d6c0b9833697ecf16b63e3c5c05c945b5dec F test/corruptC.test 46ec43bd90a02fd7b37ad8a7a949c55aa5717f89 F test/corruptD.test b3c205fac7952b1de645ce44bb02335cd9e3e040 @@ -711,7 +711,7 @@ F test/distinctagg.test 1a6ef9c87a58669438fc771450d7a72577417376 F test/e_blobbytes.test 439a945953b35cb6948a552edaec4dc31fd70a05 F test/e_blobclose.test 4b3c8c60c2171164d472059c73e9f3c1844bb66d F test/e_blobopen.test e95e1d40f995056f6f322cd5e1a1b83a27e1a145 -F test/e_blobwrite.test 4e4e20e25d94f4496272cf46ba1cb68eee7b1b3b1c26127735758a7d4a542f77 +F test/e_blobwrite.test f87ff598b67af5b3ec002a8d83e804dc8d23808e88cf0080c176612fc9ffce14 F test/e_changes.test fd66105385153dbf21fdb35eb8ef6c3e1eade579 F test/e_createtable.test d4c6059d44dcd4b636de9aae322766062b471844 F test/e_delete.test ab39084f26ae1f033c940b70ebdbbd523dc4962e @@ -750,7 +750,7 @@ F test/extension01.test 00d13cec817f331a687a243e0e5a2d87b0e358c9 F test/extraquick.test cb254400bd42bfb777ff675356aabf3287978f79 F test/fallocate.test 3e979af17dfa7e5e9dda5eba1a696c04fa9d47f7 F test/filectrl.test 6e871c2d35dead1d9a88e176e8d2ca094fec6bb3 -F test/filefmt.test e4edbdc637ca9576ccf4337a3cce627d9df7a56c +F test/filefmt.test f393e80c4b8d493b7a7f8f3809a8425bbf4292af1f5140f01cb1427798a2bbd4 F test/fkey1.test ba64806ff9a04eecab2679caad377ae99a5e94e4 F test/fkey2.test 155809016fad6b2a1491facf2ac53a551bc57c2c F test/fkey3.test 76d475c80b84ee7a5d062e56ccb6ea68882e2b49 @@ -882,7 +882,7 @@ F test/func5.test cdd224400bc3e48d891827cc913a57051a426fa4 F test/fuzz-oss1.test e58330d01cbbd8215ee636b17a03fe220b37dbfa F test/fuzz.test 96083052bf5765e4518c1ba686ce2bab785670d1 F test/fuzz2.test 76dc35b32b6d6f965259508508abce75a6c4d7e1 -F test/fuzz3.test b47377143f0c80f91ed29d722861077ff34415d5 +F test/fuzz3.test 9c813e6613b837cb7a277b0383cd66bfa07042b4cf0317157c35852f30043c31 F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26 F test/fuzzcheck.c 2152602232c96d9c790eff3013e1369ce59de3203fa0b75bc613531448454e61 @@ -916,7 +916,7 @@ F test/incrblob4.test 21a52a6843a56cdcce968c6a86b72a7066d0e6ba F test/incrblob_err.test 69f9247fed50278d48ea710d1a8f9cdb09e4c0b8 F test/incrblobfault.test 74dd8ac108304cea0b4a0df6df63a1567e558758 F test/incrcorrupt.test 6c567fbf870aa9e91866fe52ce6f200cd548939a -F test/incrvacuum.test d2a6ddf5e429720b5fe502766af747915ccf6c32 +F test/incrvacuum.test b729aab1d4983037da57e66c20dfd7458561a85626dcf824f60175e35f4ce152 F test/incrvacuum2.test 7d26cfda66c7e55898d196de54ac4ec7d86a4e3d F test/incrvacuum3.test 75256fb1377e7c39ef2de62bfc42bbff67be295a F test/incrvacuum_ioerr.test 6ae2f783424e47a0033304808fe27789cf93e635 @@ -1027,11 +1027,11 @@ F test/misc1.test 6430dabfb4b4fa480633590118964201f94d3ccc F test/misc2.test 00d7de54eda90e237fc9a38b9e5ccc769ebf6d4d F test/misc3.test cf3dda47d5dda3e53fc5804a100d3c82be736c9d F test/misc4.test 0d8be3466adf123a7791a66ba2bc8e8d229e87f3 -F test/misc5.test fff0f75e834bc09a39f6079320dd8c37de956f4f +F test/misc5.test 60e1fc758a93cacd19eb2fafcd1d40d150a05047546c7a92389c98047d621901 F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91 F test/misc7.test edd0b63e2ee29a256900b0514f6fff27e19e9bb2 F test/misc8.test ba03aaa08f02d62fbb8d3b2f5595c1b33aa9bbc5 -F test/misuse.test 3c34719944ba045cc6c188a4852ba04680728912 +F test/misuse.test 9e7f78402005e833af71dcab32d048003869eca5abcaccc985d4f8dc1d86bcc7 F test/mmap1.test d2cfc1635171c434dcff0ece2f1c8e0a658807ce F test/mmap2.test 9d6dd9ddb4ad2379f29cc78f38ce1e63ed418022 F test/mmap3.test b3c297e78e6a8520aafcc1a8f140535594c9086e @@ -1068,7 +1068,7 @@ F test/oserror.test b32dc34f2363ef18532e3a0a7358e3e7e321974f F test/ossfuzz.c f5abed3177f719df3c3109901fcdd26b9fb7f581c8da50fc26f3a81ddfb2c2ae F test/ossshell.c 296ab63067841bd1b1e97b46a0b2af48ee7f69d50d1a723008bee12dd7122622 F test/ovfl.test 199c482696defceacee8c8e0e0ef36da62726b2f -F test/pager1.test 841868017e9dd3cb459b8d78862091a7d9cff21d +F test/pager1.test 8149b2a8986fee667ab6a8171ab310be19e77ae215bebad0e90c857b0df1935c F test/pager2.test 67b8f40ae98112bcdba1f2b2d03ea83266418c71 F test/pager3.test 3856d9c80839be0668efee1b74811b1b7f7fc95f F test/pager4.test a122e9e6925d5b23b31e3dfef8c6a44bbf19590e @@ -1168,7 +1168,7 @@ F test/shared8.test 00a07bf5e1337ecf72e94542bdefdc330d7a2538 F test/shared9.test 5f2a8f79b4d6c7d107a01ffa1ed05ae7e6333e21 F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5 F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e -F test/shared_err.test 2f2aee20db294b9924e81f6ccbe60f19e21e8506 +F test/shared_err.test 32634e404a3317eeb94abc7a099c556a346fdb8fb3858dbe222a4cbb8926a939 F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304 F test/shell1.test 76ae80ab24af6cdb994cff6df5f21f8cdbb0dc0f7229e937e8f1beb653611e26 F test/shell2.test e242a9912f44f4c23c3d1d802a83e934e84c853b @@ -1226,7 +1226,7 @@ F test/superlock.test ec94f0556b6488d97f71c79f9061ae08d9ab8f12 F test/symlink.test c9ebe7330d228249e447038276bfc8a7b22f4849 F test/sync.test 2f84bdbc2b2df1fcb0220575b4b9f8cea94b7529 F test/sync2.test 6be8ed007fa063b147773c1982b5bdba97a32badc536bdc6077eff5cf8710ece -F test/syscall.test f59ba4e25f7ba4a4c031026cc2ef8b6e4b4c639c +F test/syscall.test 7a60601770172a8014a4d222d5f3d95a5d2b5c47fbb0374e2698e89c99e37256 F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04 F test/tabfunc01.test 699251cb99651415218a891384510a685c7ab012 F test/table.test b708f3e5fa2542fa51dfab21fc07b36ea445cb2f @@ -1446,13 +1446,13 @@ F test/vacuummem.test 7b42abb3208bd82dd23a7536588396f295a314f2 F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102 F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661 F test/view.test 765802c7a66d37fabd5ac8e2f2dbe572b43eb9ab -F test/vtab1.test f7d743a1d71f4a1187c79a5c26d20b764f705ea8588d969454d7c530b92e21d3 +F test/vtab1.test 8f91b9538d1404c3932293a588c4344218a0c94792d4289bb55e41020e7b3fff F test/vtab2.test f8cd1bb9aba7143eba97812d9617880a36d247ad F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e F test/vtab4.test 8e73ed268f3d596bc3590f45fc948fb40f28e9c3 F test/vtab5.test 889f444970393c73f1e077e2bdc5d845e157a391 F test/vtab6.test 8e789f526e6594cf7ae933d1adee0caa87dc9f78 -F test/vtab7.test ae560ebea870ed04e9aa4177cc302f910faaabb5 +F test/vtab7.test 70c6f4a1d6177144a8236e4172d5fba92e683440374664ad1f04851fbb335d3c F test/vtab8.test e19fa4a538fcd1bb66c22825fa8f71618fb13583 F test/vtab9.test ea58d2b95d61955f87226381716b2d0b1d4e4f9b F test/vtabA.test 1317f06a03597eee29f40a49b6c21e1aaba4285f @@ -1628,7 +1628,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 70096c505d702a9646da24613da387cee19afcf395d0294b3797c5ab50bb3ee2 -R 599e40027aa06aba6639eebf73b95973 +P 871752f2925ee14bdd3e994c00832d00860c03f6f28e63504aa6d35978b7f37c +R a1568d9978fdfb8ac96c905e0b9664ac U drh -Z be8ad28c2c42a9cd93fa855fe84d686d +Z f2fdb5ba13e65b73c37e99cdc01125b2 diff --git a/manifest.uuid b/manifest.uuid index b10a1c0588..5370f90c3b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -871752f2925ee14bdd3e994c00832d00860c03f6f28e63504aa6d35978b7f37c \ No newline at end of file +f27b6370407842e2c175ea4aa9ce018723c57eaac0cccc1f8399bc20f33324be \ No newline at end of file diff --git a/src/main.c b/src/main.c index a72520084b..f437645192 100644 --- a/src/main.c +++ b/src/main.c @@ -1407,7 +1407,7 @@ const char *sqlite3ErrStr(int rc){ /* SQLITE_ERROR */ "SQL logic error", /* SQLITE_INTERNAL */ 0, /* SQLITE_PERM */ "access permission denied", - /* SQLITE_ABORT */ "callback requested query abort", + /* SQLITE_ABORT */ "query aborted", /* SQLITE_BUSY */ "database is locked", /* SQLITE_LOCKED */ "database table is locked", /* SQLITE_NOMEM */ "out of memory", @@ -1424,7 +1424,7 @@ const char *sqlite3ErrStr(int rc){ /* SQLITE_TOOBIG */ "string or blob too big", /* SQLITE_CONSTRAINT */ "constraint failed", /* SQLITE_MISMATCH */ "datatype mismatch", - /* SQLITE_MISUSE */ "library routine called out of sequence", + /* SQLITE_MISUSE */ "bad parameter or other API misuse", #ifdef SQLITE_DISABLE_LFS /* SQLITE_NOLFS */ "large file support is disabled", #else @@ -1432,8 +1432,8 @@ const char *sqlite3ErrStr(int rc){ #endif /* SQLITE_AUTH */ "authorization denied", /* SQLITE_FORMAT */ 0, - /* SQLITE_RANGE */ "bind or column index out of range", - /* SQLITE_NOTADB */ "file is encrypted or is not a database", + /* SQLITE_RANGE */ "column index out of range", + /* SQLITE_NOTADB */ "file is not a database", }; const char *zErr = "unknown error"; switch( rc ){ @@ -2273,12 +2273,9 @@ const void *sqlite3_errmsg16(sqlite3 *db){ 'o', 'u', 't', ' ', 'o', 'f', ' ', 'm', 'e', 'm', 'o', 'r', 'y', 0 }; static const u16 misuse[] = { - 'l', 'i', 'b', 'r', 'a', 'r', 'y', ' ', - 'r', 'o', 'u', 't', 'i', 'n', 'e', ' ', - 'c', 'a', 'l', 'l', 'e', 'd', ' ', - 'o', 'u', 't', ' ', - 'o', 'f', ' ', - 's', 'e', 'q', 'u', 'e', 'n', 'c', 'e', 0 + 'b', 'a', 'd', ' ', 'p', 'a', 'r', 'a', 'm', 'e', 't', 'e', 'r', ' ', + 'o', 'r', ' ', 'o', 't', 'h', 'e', 'r', ' ', 'A', 'P', 'I', ' ', + 'm', 'i', 's', 'u', 's', 'e', 0 }; const void *z; @@ -2813,26 +2810,6 @@ static int openDatabase( if( rc ) return rc; #endif - /* Only allow sensible combinations of bits in the flags argument. - ** Throw an error if any non-sense combination is used. If we - ** do not block illegal combinations here, it could trigger - ** assert() statements in deeper layers. Sensible combinations - ** are: - ** - ** 1: SQLITE_OPEN_READONLY - ** 2: SQLITE_OPEN_READWRITE - ** 6: SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE - */ - assert( SQLITE_OPEN_READONLY == 0x01 ); - assert( SQLITE_OPEN_READWRITE == 0x02 ); - assert( SQLITE_OPEN_CREATE == 0x04 ); - testcase( (1<<(flags&7))==0x02 ); /* READONLY */ - testcase( (1<<(flags&7))==0x04 ); /* READWRITE */ - testcase( (1<<(flags&7))==0x40 ); /* READWRITE | CREATE */ - if( ((1<<(flags&7)) & 0x46)==0 ){ - return SQLITE_MISUSE_BKPT; /* IMP: R-65497-44594 */ - } - if( sqlite3GlobalConfig.bCoreMutex==0 ){ isThreadsafe = 0; }else if( flags & SQLITE_OPEN_NOMUTEX ){ @@ -2954,9 +2931,30 @@ static int openDatabase( db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, sqlite3StrBINARY, 0); assert( db->pDfltColl!=0 ); - /* Parse the filename/URI argument. */ + /* Parse the filename/URI argument + ** + ** Only allow sensible combinations of bits in the flags argument. + ** Throw an error if any non-sense combination is used. If we + ** do not block illegal combinations here, it could trigger + ** assert() statements in deeper layers. Sensible combinations + ** are: + ** + ** 1: SQLITE_OPEN_READONLY + ** 2: SQLITE_OPEN_READWRITE + ** 6: SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE + */ db->openFlags = flags; - rc = sqlite3ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg); + assert( SQLITE_OPEN_READONLY == 0x01 ); + assert( SQLITE_OPEN_READWRITE == 0x02 ); + assert( SQLITE_OPEN_CREATE == 0x04 ); + testcase( (1<<(flags&7))==0x02 ); /* READONLY */ + testcase( (1<<(flags&7))==0x04 ); /* READWRITE */ + testcase( (1<<(flags&7))==0x40 ); /* READWRITE | CREATE */ + if( ((1<<(flags&7)) & 0x46)==0 ){ + rc = SQLITE_MISUSE_BKPT; /* IMP: R-65497-44594 */ + }else{ + rc = sqlite3ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg); + } if( rc!=SQLITE_OK ){ if( rc==SQLITE_NOMEM ) sqlite3OomFault(db); sqlite3ErrorWithMsg(db, rc, zErrMsg ? "%s" : 0, zErrMsg); diff --git a/test/attach.test b/test/attach.test index 54be6a41ac..1c3239f562 100644 --- a/test/attach.test +++ b/test/attach.test @@ -792,7 +792,7 @@ do_test attach-8.1 { catchsql { ATTACH 'test2.db' AS t2; } -} {1 {file is encrypted or is not a database}} +} {1 {file is not a database}} do_test attach-8.2 { db errorcode } {26} diff --git a/test/backup2.test b/test/backup2.test index 989319923a..ad2d9a491b 100644 --- a/test/backup2.test +++ b/test/backup2.test @@ -122,7 +122,7 @@ do_test backup2-7 { close $out set rc [catch {db backup temp bu2.db} res] lappend rc $res -} {1 {backup failed: file is encrypted or is not a database}} +} {1 {backup failed: file is not a database}} # Try to backup database that does not exist # @@ -144,7 +144,7 @@ do_test backup2-9 { if {$tcl_platform(platform)=="windows"} { set msg {cannot open source database: unable to open database file} } elseif {$tcl_platform(os)=="OpenBSD"} { - set msg {restore failed: file is encrypted or is not a database} + set msg {restore failed: file is not a database} } else { set msg {cannot open source database: disk I/O error} } @@ -160,7 +160,7 @@ do_test backup2-10 { do_test backup2-11 { set rc [catch {db restore temp bu2.db} res] lappend rc $res -} {1 {restore failed: file is encrypted or is not a database}} +} {1 {restore failed: file is not a database}} # Try to restore a database that does not exist # diff --git a/test/bind.test b/test/bind.test index 34f3155b95..8cafaab2bc 100644 --- a/test/bind.test +++ b/test/bind.test @@ -366,11 +366,11 @@ do_test bind-8.1 { } {1} do_test bind-8.2 { sqlite3_errmsg $DB -} {bind or column index out of range} +} {column index out of range} ifcapable {utf16} { do_test bind-8.3 { encoding convertfrom unicode [sqlite3_errmsg16 $DB] - } {bind or column index out of range} + } {column index out of range} } do_test bind-8.4 { sqlite3_bind_null $VM 1 @@ -381,11 +381,11 @@ do_test bind-8.5 { } {1} do_test bind-8.6 { sqlite3_errmsg $DB -} {bind or column index out of range} +} {column index out of range} ifcapable {utf16} { do_test bind-8.7 { encoding convertfrom unicode [sqlite3_errmsg16 $DB] - } {bind or column index out of range} + } {column index out of range} } do_test bind-8.8 { diff --git a/test/capi3.test b/test/capi3.test index c8eea9d601..becf1bf5db 100644 --- a/test/capi3.test +++ b/test/capi3.test @@ -187,11 +187,11 @@ if {[clang_sanitize_address]==0} { } {SQLITE_MISUSE} do_test capi3-3.6.2-misuse { sqlite3_errmsg $db2 - } {library routine called out of sequence} + } {bad parameter or other API misuse} ifcapable {utf16} { do_test capi3-3.6.3-misuse { utf8 [sqlite3_errmsg16 $db2] - } {library routine called out of sequence} + } {bad parameter or other API misuse} } } @@ -771,7 +771,7 @@ set code2english [list \ SQLITE_OK {not an error} \ SQLITE_ERROR {SQL logic error} \ SQLITE_PERM {access permission denied} \ -SQLITE_ABORT {callback requested query abort} \ +SQLITE_ABORT {query aborted} \ SQLITE_BUSY {database is locked} \ SQLITE_LOCKED {database table is locked} \ SQLITE_NOMEM {out of memory} \ @@ -784,10 +784,10 @@ SQLITE_CANTOPEN {unable to open database file} \ SQLITE_SCHEMA {database schema has changed} \ SQLITE_CONSTRAINT {constraint failed} \ SQLITE_MISMATCH {datatype mismatch} \ -SQLITE_MISUSE {library routine called out of sequence} \ +SQLITE_MISUSE {bad parameter or other API misuse} \ SQLITE_AUTH {authorization denied} \ -SQLITE_RANGE {bind or column index out of range} \ -SQLITE_NOTADB {file is encrypted or is not a database} \ +SQLITE_RANGE {column index out of range} \ +SQLITE_NOTADB {file is not a database} \ unknownerror {unknown error} \ ] diff --git a/test/capi3c.test b/test/capi3c.test index b8added16b..5d889e3249 100644 --- a/test/capi3c.test +++ b/test/capi3c.test @@ -176,11 +176,11 @@ if {[clang_sanitize_address]==0} { } {SQLITE_MISUSE} do_test capi3c-3.6.2-misuse { sqlite3_errmsg $db2 - } {library routine called out of sequence} + } {bad parameter or other API misuse} ifcapable {utf16} { do_test capi3c-3.6.3-misuse { utf8 [sqlite3_errmsg16 $db2] - } {library routine called out of sequence} + } {bad parameter or other API misuse} } } @@ -728,7 +728,7 @@ set code2english [list \ SQLITE_OK {not an error} \ SQLITE_ERROR {SQL logic error} \ SQLITE_PERM {access permission denied} \ -SQLITE_ABORT {callback requested query abort} \ +SQLITE_ABORT {query aborted} \ SQLITE_BUSY {database is locked} \ SQLITE_LOCKED {database table is locked} \ SQLITE_NOMEM {out of memory} \ @@ -738,16 +738,14 @@ SQLITE_IOERR {disk I/O error} \ SQLITE_CORRUPT {database disk image is malformed} \ SQLITE_FULL {database or disk is full} \ SQLITE_CANTOPEN {unable to open database file} \ -SQLITE_EMPTY {table contains no data} \ +SQLITE_EMPTY {unknown error} \ SQLITE_SCHEMA {database schema has changed} \ SQLITE_CONSTRAINT {constraint failed} \ SQLITE_MISMATCH {datatype mismatch} \ -SQLITE_MISUSE {library routine called out of sequence} \ -SQLITE_NOLFS {large file support is disabled} \ +SQLITE_MISUSE {bad parameter or other API misuse} \ SQLITE_AUTH {authorization denied} \ -SQLITE_FORMAT {auxiliary database format error} \ -SQLITE_RANGE {bind or column index out of range} \ -SQLITE_NOTADB {file is encrypted or is not a database} \ +SQLITE_RANGE {column index out of range} \ +SQLITE_NOTADB {file is not a database} \ unknownerror {unknown error} \ ] diff --git a/test/close.test b/test/close.test index 1b789bc776..99bc7255e2 100644 --- a/test/close.test +++ b/test/close.test @@ -73,7 +73,7 @@ do_test 1.4.3 { list [catch { sqlite3_prepare $DB "SELECT * FROM sqlite_master" -1 dummy } msg] $msg -} {1 {(21) library routine called out of sequence}} +} {1 {(21) bad parameter or other API misuse}} do_test 1.4.4 { sqlite3_finalize $STMT diff --git a/test/corrupt2.test b/test/corrupt2.test index efeb26bc8a..4b58da1cc1 100644 --- a/test/corrupt2.test +++ b/test/corrupt2.test @@ -59,7 +59,7 @@ do_test corrupt2-1.2 { $::presql SELECT * FROM sqlite_master; " db2 -} {1 {file is encrypted or is not a database}} +} {1 {file is not a database}} do_test corrupt2-1.3 { db2 close @@ -79,7 +79,7 @@ do_test corrupt2-1.3 { $::presql SELECT * FROM sqlite_master; " db2 -} {1 {file is encrypted or is not a database}} +} {1 {file is not a database}} do_test corrupt2-1.4 { db2 close diff --git a/test/corruptA.test b/test/corruptA.test index bb9912bd2b..12d918615f 100644 --- a/test/corruptA.test +++ b/test/corruptA.test @@ -53,7 +53,7 @@ do_test corruptA-2.1 { hexio_write test.db 19 $unreadable_version ;# the read format number sqlite3 db test.db catchsql {SELECT * FROM t1} -} {1 {file is encrypted or is not a database}} +} {1 {file is not a database}} do_test corruptA-2.2 { db close @@ -61,7 +61,7 @@ do_test corruptA-2.2 { hexio_write test.db 21 41 ;# max embedded payload fraction sqlite3 db test.db catchsql {SELECT * FROM t1} -} {1 {file is encrypted or is not a database}} +} {1 {file is not a database}} do_test corruptA-2.3 { db close @@ -69,7 +69,7 @@ do_test corruptA-2.3 { hexio_write test.db 22 1f ;# min embedded payload fraction sqlite3 db test.db catchsql {SELECT * FROM t1} -} {1 {file is encrypted or is not a database}} +} {1 {file is not a database}} do_test corruptA-2.4 { db close @@ -77,7 +77,7 @@ do_test corruptA-2.4 { hexio_write test.db 23 21 ;# min leaf payload fraction sqlite3 db test.db catchsql {SELECT * FROM t1} -} {1 {file is encrypted or is not a database}} +} {1 {file is not a database}} finish_test diff --git a/test/e_blobwrite.test b/test/e_blobwrite.test index eaf9958743..afcfc281a7 100644 --- a/test/e_blobwrite.test +++ b/test/e_blobwrite.test @@ -136,13 +136,13 @@ do_test 2.3 { execsql { DELETE FROM t2 WHERE b=43 } } {} blob_write_error_test 2.3.1 $B 5 $blob 5 \ - SQLITE_ABORT {callback requested query abort} + SQLITE_ABORT {query aborted} do_test 2.3.2 { execsql { SELECT 1, 2, 3 } sqlite3_errcode db } {SQLITE_OK} blob_write_error_test 2.3.3 $B 5 $blob 5 \ - SQLITE_ABORT {callback requested query abort} + SQLITE_ABORT {query aborted} sqlite3_blob_close $B # EVIDENCE-OF: R-08382-59936 Writes to the BLOB that occurred before the @@ -173,7 +173,7 @@ do_execsql_test 3.1.2 { 1 .....0123456789......................... xyz } blob_write_error_test 3.1.3 $B 15 $blob 10 \ - SQLITE_ABORT {callback requested query abort} + SQLITE_ABORT {query aborted} sqlite3_blob_close $B do_execsql_test 3.1.4 { SELECT * FROM t3 WHERE i=1; @@ -190,7 +190,7 @@ do_execsql_test 3.2.2 { 2 xyz ........................................ } blob_write_error_test 3.2.3 $B 15 $blob 10 \ - SQLITE_ABORT {callback requested query abort} + SQLITE_ABORT {query aborted} sqlite3_blob_close $B do_execsql_test 3.2.4 { SELECT * FROM t3 WHERE i=2; diff --git a/test/filefmt.test b/test/filefmt.test index 087a955c39..b44ef8e29a 100644 --- a/test/filefmt.test +++ b/test/filefmt.test @@ -45,7 +45,7 @@ do_test filefmt-1.3 { catchsql { SELECT count(*) FROM sqlite_master } -} {1 {file is encrypted or is not a database}} +} {1 {file is not a database}} do_test filefmt-1.4 { db close hexio_write test.db 0 53 @@ -85,7 +85,7 @@ do_test filefmt-1.6 { catchsql { SELECT count(*) FROM sqlite_master } -} {1 {file is encrypted or is not a database}} +} {1 {file is not a database}} # The page-size must be at least 512 bytes @@ -97,7 +97,7 @@ do_test filefmt-1.7 { catchsql { SELECT count(*) FROM sqlite_master } -} {1 {file is encrypted or is not a database}} +} {1 {file is not a database}} # Usable space per page (page-size minus unused space per page) # must be at least 480 bytes @@ -114,7 +114,7 @@ ifcapable pager_pragmas { catchsql { SELECT count(*) FROM sqlite_master } - } {1 {file is encrypted or is not a database}} + } {1 {file is not a database}} } #------------------------------------------------------------------------- diff --git a/test/fuzz3.test b/test/fuzz3.test index 6d2a01c7d3..bf778ed2bc 100644 --- a/test/fuzz3.test +++ b/test/fuzz3.test @@ -152,7 +152,7 @@ for {set ii 0} {$ii < 5000} {incr ii} { if {$rc == 0 || $msg eq "database or disk is full" || $msg eq "database disk image is malformed" - || $msg eq "file is encrypted or is not a database" + || $msg eq "file is not a database" || [string match "malformed database schema*" $msg] } { set msg ok diff --git a/test/incrvacuum.test b/test/incrvacuum.test index 91f5c8e1e0..7004bbbcf4 100644 --- a/test/incrvacuum.test +++ b/test/incrvacuum.test @@ -736,7 +736,7 @@ if {[permutation] == ""} { catchsql { PRAGMA incremental_vacuum(10); } db3 - } {1 {file is encrypted or is not a database}} + } {1 {file is not a database}} db3 close } diff --git a/test/misc5.test b/test/misc5.test index 0e7e34dd16..881aba1cd8 100644 --- a/test/misc5.test +++ b/test/misc5.test @@ -522,7 +522,7 @@ if {[permutation] == ""} { catchsql { CREATE TABLE t1(a,b,c); } - } {1 {file is encrypted or is not a database}} + } {1 {file is not a database}} } # Ticket #1371. Allow floating point numbers of the form .N or N. diff --git a/test/misuse.test b/test/misuse.test index d5d836cbfb..e15cf3357e 100644 --- a/test/misuse.test +++ b/test/misuse.test @@ -179,12 +179,12 @@ if {[clang_sanitize_address]==0} { db cache flush sqlite3_close $::DB catchsql2 {SELECT * FROM t1} - } {1 {library routine called out of sequence}} + } {1 {bad parameter or other API misuse}} do_test misuse-4.5 { catchsql { SELECT * FROM t1 } - } {1 {library routine called out of sequence}} + } {1 {bad parameter or other API misuse}} # Attempt to use a database after it has been closed. # @@ -204,7 +204,7 @@ if {[clang_sanitize_address]==0} { sqlite3_prepare $::DB {SELECT * FROM t1} -1 TAIL } msg] lappend r $msg - } {1 {(21) library routine called out of sequence}} + } {1 {(21) bad parameter or other API misuse}} } finish_test diff --git a/test/pager1.test b/test/pager1.test index c25c837b67..8451e0b3d2 100644 --- a/test/pager1.test +++ b/test/pager1.test @@ -2718,7 +2718,7 @@ do_test 38.1 { close $fd sqlite3 db test.db catchsql { CREATE TABLE t1(x) } -} {1 {file is encrypted or is not a database}} +} {1 {file is not a database}} do_test 38.2 { catch { db close } forcedelete test.db diff --git a/test/shared_err.test b/test/shared_err.test index 96e5ee4540..fdc1c13975 100644 --- a/test/shared_err.test +++ b/test/shared_err.test @@ -378,7 +378,7 @@ do_malloc_test shared_err-6 -tclbody { # sqlite3_enable_shared_cache 0 # } msg # set msg -#} {library routine called out of sequence} +#} {bad parameter or other API misuse} # Again provoke a malloc() failure when a cursor position is being saved, # this time during a ROLLBACK operation by some other handle. diff --git a/test/syscall.test b/test/syscall.test index 5716b35a6e..2532187b47 100644 --- a/test/syscall.test +++ b/test/syscall.test @@ -218,8 +218,8 @@ proc create_db_file {nByte} { foreach {nByte res} { 1 {0 {}} - 2 {1 {file is encrypted or is not a database}} - 3 {1 {file is encrypted or is not a database}} + 2 {1 {file is not a database}} + 3 {1 {file is not a database}} } { do_test 7.$nByte { create_db_file $nByte diff --git a/test/vtab1.test b/test/vtab1.test index 3354788096..3c60a8f9c9 100644 --- a/test/vtab1.test +++ b/test/vtab1.test @@ -948,7 +948,7 @@ do_test vtab1.10-2 { sqlite3_declare_vtab $ptr {CREATE TABLE abc(a, b, c)} } msg] list $rc $msg -} {1 {library routine called out of sequence}} +} {1 {bad parameter or other API misuse}} do_test vtab1.10-3 { set ::echo_module_begin_fail r catchsql { diff --git a/test/vtab7.test b/test/vtab7.test index 162bab5e87..8320993de7 100644 --- a/test/vtab7.test +++ b/test/vtab7.test @@ -162,7 +162,7 @@ ifcapable attach { # catchsql { # INSERT INTO abc2 VALUES(1, 2, 3); # } -# } {1 {library routine called out of sequence}} +# } {1 {bad parameter or other API misuse}} # These tests, vtab7-4.*, test that an SQLITE_LOCKED error is returned # if an attempt to write to a virtual module table or create a new From 9f6e14c1ef5e62a1972b042c6f252bbd2a7ecb18 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 10 Jul 2017 13:24:58 +0000 Subject: [PATCH 26/64] For sqlite3TreeView() debugging output, show the Expr.flags field on scalar subqueries. FossilOrigin-Name: dc857a96b00f13ffdf77bc222bc5acbbe14a36ca51e5368b568b3177d1be737a --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/treeview.c | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 533b3b378f..e4b8deb363 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\serror\smessage\stext\sfor\sstandard\serror\scodes\sto\sbetter\sdescribe\sthe\nlatest\susage\sof\sthose\serror\scodes.\s\sModify\ssqlite3_open_v2()\sso\sthat\sit\sdoes\nreturn\sa\svalid\ssqlite3\sobject\sin\sthe\sevent\sof\sSQLITE_MISUSE\sdue\sto\sbad\nopen\sflags,\sso\sthat\ssqlite3_errmsg()\sdoes\snot\sreport\s"out\sof\smemory"\sin\sthat\ncase. -D 2017-07-10T12:07:53.037 +C For\ssqlite3TreeView()\sdebugging\soutput,\sshow\sthe\sExpr.flags\sfield\son\nscalar\ssubqueries. +D 2017-07-10T13:24:58.019 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba @@ -509,7 +509,7 @@ F src/test_windirent.h 5d67483a55442e31e1bde0f4a230e6e932ad5906 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c 1003d6d90c6783206c711f0a9397656fa5b055209f4d092caa43bb3bf5215db5 -F src/treeview.c 6cf8d7fe9e63fae57dad1bb57f6615e14eac0c527e43d868e805042cae8ed1f7 +F src/treeview.c 2ee4a5dada213d5ab08a742af5c876cee6f1aaae65f10a61923f3fb63846afef F src/trigger.c d1cae560bfacc8bfb3a072d73658245c1714c0389097da69b4cb23877a082d7e F src/update.c c443935c652af9365e033f756550b5032d02e1b06eb2cb890ed7511ae0c051dc F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c @@ -1628,7 +1628,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 871752f2925ee14bdd3e994c00832d00860c03f6f28e63504aa6d35978b7f37c -R a1568d9978fdfb8ac96c905e0b9664ac +P f27b6370407842e2c175ea4aa9ce018723c57eaac0cccc1f8399bc20f33324be +R fcaff20edc67c3421a07c8a2f98bc875 U drh -Z f2fdb5ba13e65b73c37e99cdc01125b2 +Z 4c32d3cf2874c5b6c91c344882e30f5e diff --git a/manifest.uuid b/manifest.uuid index 5370f90c3b..2957a08a1c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f27b6370407842e2c175ea4aa9ce018723c57eaac0cccc1f8399bc20f33324be \ No newline at end of file +dc857a96b00f13ffdf77bc222bc5acbbe14a36ca51e5368b568b3177d1be737a \ No newline at end of file diff --git a/src/treeview.c b/src/treeview.c index fc188256f9..ba9fa7b2f0 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -382,17 +382,17 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){ } #ifndef SQLITE_OMIT_SUBQUERY case TK_EXISTS: { - sqlite3TreeViewLine(pView, "EXISTS-expr"); + sqlite3TreeViewLine(pView, "EXISTS-expr flags=0x%x", pExpr->flags); sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0); break; } case TK_SELECT: { - sqlite3TreeViewLine(pView, "SELECT-expr"); + sqlite3TreeViewLine(pView, "SELECT-expr flags=0x%x", pExpr->flags); sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0); break; } case TK_IN: { - sqlite3TreeViewLine(pView, "IN"); + sqlite3TreeViewLine(pView, "IN flags=0x%x", pExpr->flags); sqlite3TreeViewExpr(pView, pExpr->pLeft, 1); if( ExprHasProperty(pExpr, EP_xIsSelect) ){ sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0); From ebc63013b786094937bcb9714a8421caba869937 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 10 Jul 2017 14:33:00 +0000 Subject: [PATCH 27/64] When testing non-indexed WHERE constraints, test those that involve correlated sub-queries last of all. This increases the chances of not having to run the sub-query at all. FossilOrigin-Name: 1f9c1f359e4693954ba7e2bc7b172ef34eb046e4ca2796df8336975b9d6aa92b --- manifest | 19 +++++++++++-------- manifest.uuid | 2 +- src/sqliteInt.h | 2 +- src/wherecode.c | 33 +++++++++++++++++++++++---------- 4 files changed, 36 insertions(+), 20 deletions(-) diff --git a/manifest b/manifest index e4b8deb363..687a233e79 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C For\ssqlite3TreeView()\sdebugging\soutput,\sshow\sthe\sExpr.flags\sfield\son\nscalar\ssubqueries. -D 2017-07-10T13:24:58.019 +C When\stesting\snon-indexed\sWHERE\sconstraints,\stest\sthose\sthat\sinvolve\ncorrelated\ssub-queries\slast\sof\sall.\sThis\sincreases\sthe\schances\sof\snot\shaving\nto\srun\sthe\ssub-query\sat\sall. +D 2017-07-10T14:33:00.503 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba @@ -453,7 +453,7 @@ F src/shell.c a7067f647aef4b81569bbfd025f4fd120a4e7576a647d2aad05028eb50e50e48 F src/sqlite.h.in 03a422ba13da1dfef7f1aaa1ba344acf18dc867112620b1fdb2a1426cabba634 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 58fd0676d3111d02e62e5a35992a7d3da5d3f88753acc174f2d37b774fbbdd28 -F src/sqliteInt.h 7a7cd6f682471cce4afe64216f71fd64c622712aeb9d947c33c38337a7cf19a9 +F src/sqliteInt.h 44398832c9eea319c618fd046678dd929127010a0923a0af97c6b2bc1a18fb81 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -531,7 +531,7 @@ F src/wal.h 06b2a0b599cc0f53ea97f497cf8c6b758c999f71 F src/walker.c a7ca64ce08a83a20d32186fbe06bca9234e348cfcf07959ee322fdc3e8a6173a F src/where.c e7cc80943459ade4ccaeb5c7c10f8a0db8b797e0b0f2509de7efc557b76bf7b6 F src/whereInt.h 2a4b634d63ce488b46d4b0da8f2eaa8f9aeab202bc25ef76f007de5e3fba1f20 -F src/wherecode.c f17f5d51e372168db51af637e265aa5e80f99fcc81bfead96b66e71a7732bc62 +F src/wherecode.c 3eb2130872cb2c570b519dcb7fe34d2bfd1d515292c5131874e797044f8ef832 F src/whereexpr.c fa51927cc6830b9d3155cafa4e589452ec023fe313a56550d2079dca6c52fbd8 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1628,7 +1628,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f27b6370407842e2c175ea4aa9ce018723c57eaac0cccc1f8399bc20f33324be -R fcaff20edc67c3421a07c8a2f98bc875 -U drh -Z 4c32d3cf2874c5b6c91c344882e30f5e +P dc857a96b00f13ffdf77bc222bc5acbbe14a36ca51e5368b568b3177d1be737a +R 2c3079a102d9ba8d31221f8f910d8428 +T *branch * defer-where-subqueries +T *sym-defer-where-subqueries * +T -sym-trunk * +U dan +Z 903fd4acf5ba1f2541b4e3fb6b879043 diff --git a/manifest.uuid b/manifest.uuid index 2957a08a1c..d520ade2d9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dc857a96b00f13ffdf77bc222bc5acbbe14a36ca51e5368b568b3177d1be737a \ No newline at end of file +1f9c1f359e4693954ba7e2bc7b172ef34eb046e4ca2796df8336975b9d6aa92b \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 4acd100be2..e48ff05441 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2398,7 +2398,7 @@ struct Expr { /* ** Combinations of two or more EP_* flags */ -#define EP_Propagate (EP_Collate|EP_Subquery) /* Propagate these bits up tree */ +#define EP_Propagate (EP_Collate|EP_Subquery|EP_VarSelect) /* Prop. up tree */ /* ** These macros can be used to test, set, or clear bits in the diff --git a/src/wherecode.c b/src/wherecode.c index dc982938ac..beeb1924d6 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -1130,7 +1130,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( int iRowidReg = 0; /* Rowid is stored in this register, if not zero */ int iReleaseReg = 0; /* Temp register to free before returning */ Index *pIdx = 0; /* Index used by loop (if any) */ - int loopAgain; /* True if constraint generator loop should repeat */ + int iLoop; /* Iteration of constraint generator loop */ pParse = pWInfo->pParse; v = pParse->pVdbe; @@ -2025,13 +2025,20 @@ Bitmask sqlite3WhereCodeOneLoopStart( /* Insert code to test every subexpression that can be completely ** computed using the current set of tables. ** - ** This loop may run either once (pIdx==0) or twice (pIdx!=0). If - ** it is run twice, then the first iteration codes those sub-expressions - ** that can be computed using columns from pIdx only (without seeking - ** the main table cursor). + ** This loop may run between one and three times, depending on the + ** constraints to be generated. The value of stack variable iLoop + ** determines the constraints coded by each iteration, as follows: + ** + ** iLoop==1: Code only expressions that are entirely covered by pIdx. + ** iLoop==2: Code remaining expressions that do not contain correlated + ** sub-queries. + ** iLoop==3: Code all remaining expressions. + ** + ** An effort is made to skip unnecessary iterations of the loop. */ + iLoop = (pIdx ? 1 : 2); do{ - loopAgain = 0; + int iNext = 0; /* Next value for iLoop */ for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){ Expr *pE; int skipLikeAddr = 0; @@ -2049,10 +2056,16 @@ Bitmask sqlite3WhereCodeOneLoopStart( if( pLevel->iLeftJoin && !ExprHasProperty(pE, EP_FromJoin) ){ continue; } - if( pIdx && !sqlite3ExprCoveredByIndex(pE, pLevel->iTabCur, pIdx) ){ - loopAgain = 1; + + if( iNext==1 && !sqlite3ExprCoveredByIndex(pE, pLevel->iTabCur, pIdx) ){ + iNext = 2; continue; } + if( iLoop<3 && (pE->flags & EP_VarSelect) ){ + if( iNext==0 ) iNext = 3; + continue; + } + if( pTerm->wtFlags & TERM_LIKECOND ){ /* If the TERM_LIKECOND flag is set, that means that the range search ** is sufficient to guarantee that the LIKE operator is true, so we @@ -2072,8 +2085,8 @@ Bitmask sqlite3WhereCodeOneLoopStart( if( skipLikeAddr ) sqlite3VdbeJumpHere(v, skipLikeAddr); pTerm->wtFlags |= TERM_CODED; } - pIdx = 0; - }while( loopAgain ); + iLoop = iNext; + }while( iLoop>0 ); /* Insert code to test for implied constraints based on transitivity ** of the "==" operator. From 8674ec5a7f5125375c35fa47a24922e081702339 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 10 Jul 2017 14:39:42 +0000 Subject: [PATCH 28/64] Fix a problem causing non-covered WHERE terms to be evaluated before covered WHERE terms. FossilOrigin-Name: 7d3cb39f60951dcec1ff87da2c4ec998f993de5edf49ee5e5f480c6fe4e5a052 --- manifest | 15 ++++++--------- manifest.uuid | 2 +- src/wherecode.c | 2 +- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 687a233e79..07340e2948 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\stesting\snon-indexed\sWHERE\sconstraints,\stest\sthose\sthat\sinvolve\ncorrelated\ssub-queries\slast\sof\sall.\sThis\sincreases\sthe\schances\sof\snot\shaving\nto\srun\sthe\ssub-query\sat\sall. -D 2017-07-10T14:33:00.503 +C Fix\sa\sproblem\scausing\snon-covered\sWHERE\sterms\sto\sbe\sevaluated\sbefore\scovered\nWHERE\sterms. +D 2017-07-10T14:39:42.059 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba @@ -531,7 +531,7 @@ F src/wal.h 06b2a0b599cc0f53ea97f497cf8c6b758c999f71 F src/walker.c a7ca64ce08a83a20d32186fbe06bca9234e348cfcf07959ee322fdc3e8a6173a F src/where.c e7cc80943459ade4ccaeb5c7c10f8a0db8b797e0b0f2509de7efc557b76bf7b6 F src/whereInt.h 2a4b634d63ce488b46d4b0da8f2eaa8f9aeab202bc25ef76f007de5e3fba1f20 -F src/wherecode.c 3eb2130872cb2c570b519dcb7fe34d2bfd1d515292c5131874e797044f8ef832 +F src/wherecode.c 39bddb38a402acf4c191f4a6e69b37d0deb18bbfd01b28ab433653b7a91d7ef4 F src/whereexpr.c fa51927cc6830b9d3155cafa4e589452ec023fe313a56550d2079dca6c52fbd8 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1628,10 +1628,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P dc857a96b00f13ffdf77bc222bc5acbbe14a36ca51e5368b568b3177d1be737a -R 2c3079a102d9ba8d31221f8f910d8428 -T *branch * defer-where-subqueries -T *sym-defer-where-subqueries * -T -sym-trunk * +P 1f9c1f359e4693954ba7e2bc7b172ef34eb046e4ca2796df8336975b9d6aa92b +R 053f7bb60ad55030babe7702fd1ffbbc U dan -Z 903fd4acf5ba1f2541b4e3fb6b879043 +Z 736dda2988ee033d8b53d1cbdc026654 diff --git a/manifest.uuid b/manifest.uuid index d520ade2d9..407d6ba990 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1f9c1f359e4693954ba7e2bc7b172ef34eb046e4ca2796df8336975b9d6aa92b \ No newline at end of file +7d3cb39f60951dcec1ff87da2c4ec998f993de5edf49ee5e5f480c6fe4e5a052 \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index beeb1924d6..f9c29e0f04 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -2057,7 +2057,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( continue; } - if( iNext==1 && !sqlite3ExprCoveredByIndex(pE, pLevel->iTabCur, pIdx) ){ + if( iLoop==1 && !sqlite3ExprCoveredByIndex(pE, pLevel->iTabCur, pIdx) ){ iNext = 2; continue; } From d3930b12666b60ef78158ade0041745796d17224 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 10 Jul 2017 15:17:30 +0000 Subject: [PATCH 29/64] Fix another problem on this branch. FossilOrigin-Name: a4fc98113aeb10860834f68a2fdcef690ea15d8303d23b6dd416994a4b7edab6 --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/sqliteInt.h | 2 +- src/whereInt.h | 2 ++ src/wherecode.c | 2 +- src/whereexpr.c | 3 +++ test/pushdown.test | 33 +++++++++++++++++++++++++++++++++ 7 files changed, 51 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 07340e2948..4ed0317b02 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\scausing\snon-covered\sWHERE\sterms\sto\sbe\sevaluated\sbefore\scovered\nWHERE\sterms. -D 2017-07-10T14:39:42.059 +C Fix\sanother\sproblem\son\sthis\sbranch. +D 2017-07-10T15:17:30.050 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba @@ -453,7 +453,7 @@ F src/shell.c a7067f647aef4b81569bbfd025f4fd120a4e7576a647d2aad05028eb50e50e48 F src/sqlite.h.in 03a422ba13da1dfef7f1aaa1ba344acf18dc867112620b1fdb2a1426cabba634 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 58fd0676d3111d02e62e5a35992a7d3da5d3f88753acc174f2d37b774fbbdd28 -F src/sqliteInt.h 44398832c9eea319c618fd046678dd929127010a0923a0af97c6b2bc1a18fb81 +F src/sqliteInt.h 7a7cd6f682471cce4afe64216f71fd64c622712aeb9d947c33c38337a7cf19a9 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -530,9 +530,9 @@ F src/wal.c 40c543f0a2195d1b0dc88ef12142bea690009344 F src/wal.h 06b2a0b599cc0f53ea97f497cf8c6b758c999f71 F src/walker.c a7ca64ce08a83a20d32186fbe06bca9234e348cfcf07959ee322fdc3e8a6173a F src/where.c e7cc80943459ade4ccaeb5c7c10f8a0db8b797e0b0f2509de7efc557b76bf7b6 -F src/whereInt.h 2a4b634d63ce488b46d4b0da8f2eaa8f9aeab202bc25ef76f007de5e3fba1f20 -F src/wherecode.c 39bddb38a402acf4c191f4a6e69b37d0deb18bbfd01b28ab433653b7a91d7ef4 -F src/whereexpr.c fa51927cc6830b9d3155cafa4e589452ec023fe313a56550d2079dca6c52fbd8 +F src/whereInt.h 93bb90b77d39901eda31b44d8e90da1351193ccfe96876f89b58a93a33b84c3d +F src/wherecode.c cd923f921c31158c1a771f0332294e01790e13a2e3d166c40c08d78c8d85e9d6 +F src/whereexpr.c 16bb63556da573364ffbebde0effe3bf124bde4381934d2d56f2cd8a3b24d1a1 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d @@ -1091,7 +1091,7 @@ F test/printf.test b3ff34e73d59124140eaf89f7672e21bc2ca5fcc F test/printf2.test 9e6db85f81c63f2367c34a9d7db384088bd374ad F test/progress.test ebab27f670bd0d4eb9d20d49cef96e68141d92fb F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc -F test/pushdown.test a5d2e5e66cc94cfb0989a5dd23e77427dd6c4313019155ba9051f52dfc5326aa +F test/pushdown.test df9a5d1822531fc79fa46b622a7ee5fdf5cdc81fd2740443df59cc90b746abb6 F test/queryonly.test 5f653159e0f552f0552d43259890c1089391dcca F test/quick.test 1681febc928d686362d50057c642f77a02c62e57 F test/quota-glob.test 32901e9eed6705d68ca3faee2a06b73b57cb3c26 @@ -1628,7 +1628,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1f9c1f359e4693954ba7e2bc7b172ef34eb046e4ca2796df8336975b9d6aa92b -R 053f7bb60ad55030babe7702fd1ffbbc +P 7d3cb39f60951dcec1ff87da2c4ec998f993de5edf49ee5e5f480c6fe4e5a052 +R 47bcde6cd81a52404ad35aa15c46b8b4 U dan -Z 736dda2988ee033d8b53d1cbdc026654 +Z 69f60f9a722dd7ebaee7a7905b2effee diff --git a/manifest.uuid b/manifest.uuid index 407d6ba990..4c9e2ba76a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7d3cb39f60951dcec1ff87da2c4ec998f993de5edf49ee5e5f480c6fe4e5a052 \ No newline at end of file +a4fc98113aeb10860834f68a2fdcef690ea15d8303d23b6dd416994a4b7edab6 \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index e48ff05441..4acd100be2 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2398,7 +2398,7 @@ struct Expr { /* ** Combinations of two or more EP_* flags */ -#define EP_Propagate (EP_Collate|EP_Subquery|EP_VarSelect) /* Prop. up tree */ +#define EP_Propagate (EP_Collate|EP_Subquery) /* Propagate these bits up tree */ /* ** These macros can be used to test, set, or clear bits in the diff --git a/src/whereInt.h b/src/whereInt.h index 435f4b3efa..bac81da721 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -284,6 +284,7 @@ struct WhereTerm { #define TERM_LIKECOND 0x200 /* Conditionally this LIKE operator term */ #define TERM_LIKE 0x400 /* The original LIKE operator */ #define TERM_IS 0x800 /* Term.pExpr is an IS operator */ +#define TERM_VARSELECT 0x1000 /* Term.pExpr contains a correlated sub-query */ /* ** An instance of the WhereScan object is used as an iterator for locating @@ -373,6 +374,7 @@ struct WhereAndInfo { ** no gaps. */ struct WhereMaskSet { + int bVarSelect; /* Used by sqlite3WhereExprUsage() */ int n; /* Number of assigned cursor values */ int ix[BMS]; /* Cursor assigned to each bit */ }; diff --git a/src/wherecode.c b/src/wherecode.c index f9c29e0f04..63972b0202 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -2061,7 +2061,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( iNext = 2; continue; } - if( iLoop<3 && (pE->flags & EP_VarSelect) ){ + if( iLoop<3 && (pTerm->wtFlags & TERM_VARSELECT) ){ if( iNext==0 ) iNext = 3; continue; } diff --git a/src/whereexpr.c b/src/whereexpr.c index 633fdaff39..6ad41d46d3 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -951,7 +951,9 @@ static void exprAnalyze( }else{ pTerm->prereqRight = sqlite3WhereExprUsage(pMaskSet, pExpr->pRight); } + pMaskSet->bVarSelect = 0; prereqAll = sqlite3WhereExprUsage(pMaskSet, pExpr); + if( pMaskSet->bVarSelect ) pTerm->wtFlags |= TERM_VARSELECT; if( ExprHasProperty(pExpr, EP_FromJoin) ){ Bitmask x = sqlite3WhereGetMask(pMaskSet, pExpr->iRightJoinTable); prereqAll |= x; @@ -1385,6 +1387,7 @@ Bitmask sqlite3WhereExprUsage(WhereMaskSet *pMaskSet, Expr *p){ if( p->pRight ) mask |= sqlite3WhereExprUsage(pMaskSet, p->pRight); if( p->pLeft ) mask |= sqlite3WhereExprUsage(pMaskSet, p->pLeft); if( ExprHasProperty(p, EP_xIsSelect) ){ + if( ExprHasProperty(p, EP_VarSelect) ) pMaskSet->bVarSelect = 1; mask |= exprSelectUsage(pMaskSet, p->x.pSelect); }else if( p->x.pList ){ mask |= sqlite3WhereExprListUsage(pMaskSet, p->x.pList); diff --git a/test/pushdown.test b/test/pushdown.test index 5be6054c08..8cdfd32360 100644 --- a/test/pushdown.test +++ b/test/pushdown.test @@ -55,5 +55,38 @@ do_test 1.5 { execsql { SELECT * FROM t1 WHERE a=3 AND f(c) AND f(b) } set L } {b3} + +#----------------------------------------------- + +do_execsql_test 2.0 { + CREATE TABLE u1(a, b, c); + CREATE TABLE u2(x, y, z); + + INSERT INTO u1 VALUES('a1', 'b1', 'c1'); + INSERT INTO u2 VALUES('a1', 'b1', 'c1'); +} + +do_test 2.1 { + set L [list] + execsql { + SELECT * FROM u1 WHERE f('one')=123 AND 123=( + SELECT x FROM u2 WHERE x=a AND f('two') + ) + } + set L +} {one} + +do_test 2.2 { + set L [list] + breakpoint + execsql { + SELECT * FROM u1 WHERE 123=( + SELECT x FROM u2 WHERE x=a AND f('two') + ) AND f('three')=123 + } + set L +} {three} + + finish_test From e24b92bce7318f196e390d878b45ac69dabfde40 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 10 Jul 2017 15:26:09 +0000 Subject: [PATCH 30/64] Small performance optimization in sqlite3WhereExprUsage(). FossilOrigin-Name: 38edc6770e54e456500e77389d42fdf39e9a7ed258a4e1fed3c6dd8fdf4dfcb7 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/whereexpr.c | 6 ++++-- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 4ed0317b02..4911a97bba 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sanother\sproblem\son\sthis\sbranch. -D 2017-07-10T15:17:30.050 +C Small\sperformance\soptimization\sin\ssqlite3WhereExprUsage(). +D 2017-07-10T15:26:09.382 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba @@ -532,7 +532,7 @@ F src/walker.c a7ca64ce08a83a20d32186fbe06bca9234e348cfcf07959ee322fdc3e8a6173a F src/where.c e7cc80943459ade4ccaeb5c7c10f8a0db8b797e0b0f2509de7efc557b76bf7b6 F src/whereInt.h 93bb90b77d39901eda31b44d8e90da1351193ccfe96876f89b58a93a33b84c3d F src/wherecode.c cd923f921c31158c1a771f0332294e01790e13a2e3d166c40c08d78c8d85e9d6 -F src/whereexpr.c 16bb63556da573364ffbebde0effe3bf124bde4381934d2d56f2cd8a3b24d1a1 +F src/whereexpr.c bf983d2d33e325cd63a36c40b8de289fd3d7b4d9f2db9052fb8f59f7161a34a0 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d @@ -1628,7 +1628,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7d3cb39f60951dcec1ff87da2c4ec998f993de5edf49ee5e5f480c6fe4e5a052 -R 47bcde6cd81a52404ad35aa15c46b8b4 -U dan -Z 69f60f9a722dd7ebaee7a7905b2effee +P a4fc98113aeb10860834f68a2fdcef690ea15d8303d23b6dd416994a4b7edab6 +R 68686794179912ee0f124d7b66b93bd8 +U drh +Z a9547d4838023b821662e4eab7778dcd diff --git a/manifest.uuid b/manifest.uuid index 4c9e2ba76a..2eadd0644d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a4fc98113aeb10860834f68a2fdcef690ea15d8303d23b6dd416994a4b7edab6 \ No newline at end of file +38edc6770e54e456500e77389d42fdf39e9a7ed258a4e1fed3c6dd8fdf4dfcb7 \ No newline at end of file diff --git a/src/whereexpr.c b/src/whereexpr.c index 6ad41d46d3..461c14af19 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -1384,9 +1384,11 @@ Bitmask sqlite3WhereExprUsage(WhereMaskSet *pMaskSet, Expr *p){ } mask = (p->op==TK_IF_NULL_ROW) ? sqlite3WhereGetMask(pMaskSet, p->iTable) : 0; assert( !ExprHasProperty(p, EP_TokenOnly) ); - if( p->pRight ) mask |= sqlite3WhereExprUsage(pMaskSet, p->pRight); if( p->pLeft ) mask |= sqlite3WhereExprUsage(pMaskSet, p->pLeft); - if( ExprHasProperty(p, EP_xIsSelect) ){ + if( p->pRight ){ + mask |= sqlite3WhereExprUsage(pMaskSet, p->pRight); + assert( p->x.pList==0 ); + }else if( ExprHasProperty(p, EP_xIsSelect) ){ if( ExprHasProperty(p, EP_VarSelect) ) pMaskSet->bVarSelect = 1; mask |= exprSelectUsage(pMaskSet, p->x.pSelect); }else if( p->x.pList ){ From 66a0bf31cc812a7b046f6280c6eea757f8298e19 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 10 Jul 2017 16:38:14 +0000 Subject: [PATCH 31/64] Additional debugging Noop-comment in the constraint generator when wheretrace is enabled. FossilOrigin-Name: 0ca7474f05e9f27f53f8c71f5a3ff99963ffef9be9c147869e096246d552d6f1 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/wherecode.c | 6 ++++++ 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 4911a97bba..d7121fcc18 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Small\sperformance\soptimization\sin\ssqlite3WhereExprUsage(). -D 2017-07-10T15:26:09.382 +C Additional\sdebugging\sNoop-comment\sin\sthe\sconstraint\sgenerator\swhen\nwheretrace\sis\senabled. +D 2017-07-10T16:38:14.687 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba @@ -531,7 +531,7 @@ F src/wal.h 06b2a0b599cc0f53ea97f497cf8c6b758c999f71 F src/walker.c a7ca64ce08a83a20d32186fbe06bca9234e348cfcf07959ee322fdc3e8a6173a F src/where.c e7cc80943459ade4ccaeb5c7c10f8a0db8b797e0b0f2509de7efc557b76bf7b6 F src/whereInt.h 93bb90b77d39901eda31b44d8e90da1351193ccfe96876f89b58a93a33b84c3d -F src/wherecode.c cd923f921c31158c1a771f0332294e01790e13a2e3d166c40c08d78c8d85e9d6 +F src/wherecode.c c0c4c31573486cd14bb2cbfc63e41eda591609e5190416261999f211bf97abc1 F src/whereexpr.c bf983d2d33e325cd63a36c40b8de289fd3d7b4d9f2db9052fb8f59f7161a34a0 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1628,7 +1628,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a4fc98113aeb10860834f68a2fdcef690ea15d8303d23b6dd416994a4b7edab6 -R 68686794179912ee0f124d7b66b93bd8 +P 38edc6770e54e456500e77389d42fdf39e9a7ed258a4e1fed3c6dd8fdf4dfcb7 +R 6bf4c162edf7ff6903aaf314bb0ae2fb U drh -Z a9547d4838023b821662e4eab7778dcd +Z 38d25901c93de0cd7a8af907f32d80a9 diff --git a/manifest.uuid b/manifest.uuid index 2eadd0644d..fea24416b7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -38edc6770e54e456500e77389d42fdf39e9a7ed258a4e1fed3c6dd8fdf4dfcb7 \ No newline at end of file +0ca7474f05e9f27f53f8c71f5a3ff99963ffef9be9c147869e096246d552d6f1 \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index 63972b0202..d577f1d3f6 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -2081,6 +2081,12 @@ Bitmask sqlite3WhereCodeOneLoopStart( VdbeCoverage(v); #endif } +#ifdef WHERETRACE_ENABLED /* 0xffff */ + if( sqlite3WhereTrace ){ + VdbeNoopComment((v, "WhereTerm[%d] (%p) priority=%d", + pWC->nTerm-j, pTerm, iLoop)); + } +#endif sqlite3ExprIfFalse(pParse, pE, addrCont, SQLITE_JUMPIFNULL); if( skipLikeAddr ) sqlite3VdbeJumpHere(v, skipLikeAddr); pTerm->wtFlags |= TERM_CODED; From dbc26722cd1f96abc919e8f05091ffe4e9897c0a Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 10 Jul 2017 18:04:41 +0000 Subject: [PATCH 32/64] Add the "--newlines" option to the ".dump" command in the shell to disable the newline escaping mechanism. FossilOrigin-Name: bde431b1e332feaeb516dc46d180e2b2f42820c471feed7eda89452ada898dc9 --- manifest | 15 +++++++-------- manifest.uuid | 2 +- src/shell.c | 21 ++++++++++++++++----- test/shell1.test | 2 +- 4 files changed, 25 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 5e78844516..7fab63a580 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\smultiple\sconstraints\sneed\sto\sbe\sevaluated\sfor\sa\srow,\sdo\sany\sconstraints\nthat\sinvolve\scorrelated\ssubqueries\slast.\s\sHence,\sthe\spriority\sis\sindex-covered\nconstraints\sfirst,\scorrelated\ssubquery\sconstraints\slast,\sand\sall\sothers\sin\nthe\smiddle.\s\sThis\sis\sa\nfollow-on\sand\simprovement\sto\sthe\spush-down\soptimization\sof\scheck-in\s[d7bb79ed]. -D 2017-07-10T17:00:31.898 +C Add\sthe\s"--newlines"\soption\sto\sthe\s".dump"\scommand\sin\sthe\sshell\sto\sdisable\nthe\snewline\sescaping\smechanism. +D 2017-07-10T18:04:41.835 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba @@ -449,7 +449,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 6aa1fb1212e601f65b983ee1215d69a591986c8f97a3805c425c625a53839539 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 6aa7e8ee53dcb9d0b77b05670bb44a1076d6747bc9b2c1f12a365b553ab6c828 -F src/shell.c a7067f647aef4b81569bbfd025f4fd120a4e7576a647d2aad05028eb50e50e48 +F src/shell.c c042ed1f74e80097f7a322bb05457d65c20e1df43459f065f76ad886da7331e0 F src/sqlite.h.in 03a422ba13da1dfef7f1aaa1ba344acf18dc867112620b1fdb2a1426cabba634 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 58fd0676d3111d02e62e5a35992a7d3da5d3f88753acc174f2d37b774fbbdd28 @@ -1170,7 +1170,7 @@ F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5 F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e F test/shared_err.test 32634e404a3317eeb94abc7a099c556a346fdb8fb3858dbe222a4cbb8926a939 F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304 -F test/shell1.test 76ae80ab24af6cdb994cff6df5f21f8cdbb0dc0f7229e937e8f1beb653611e26 +F test/shell1.test f78ea0e2637ae9f497cb41206f6346f983052ffc7a359e664aaf6847fc704ea7 F test/shell2.test e242a9912f44f4c23c3d1d802a83e934e84c853b F test/shell3.test 9b95ba643eaa228376f06a898fb410ee9b6e57c1 F test/shell4.test 89ad573879a745974ff2df20ff97c5d6ffffbd5d @@ -1628,8 +1628,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P dc857a96b00f13ffdf77bc222bc5acbbe14a36ca51e5368b568b3177d1be737a 0ca7474f05e9f27f53f8c71f5a3ff99963ffef9be9c147869e096246d552d6f1 -R 6bf4c162edf7ff6903aaf314bb0ae2fb -T +closed 0ca7474f05e9f27f53f8c71f5a3ff99963ffef9be9c147869e096246d552d6f1 +P c4cb90487f34937605732c3959891075e2aabfb0bd05e55c44565d65867093ea +R 6d35197f305c27266246f32d8a4834d8 U drh -Z acda2b95cccbca8a55a4e5255bd0a430 +Z a3a7e11cbaa224fa5a8714694bd756ab diff --git a/manifest.uuid b/manifest.uuid index 71dc779008..f4093af146 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c4cb90487f34937605732c3959891075e2aabfb0bd05e55c44565d65867093ea \ No newline at end of file +bde431b1e332feaeb516dc46d180e2b2f42820c471feed7eda89452ada898dc9 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index bc7fd44abd..c2c0d68c68 100644 --- a/src/shell.c +++ b/src/shell.c @@ -1523,8 +1523,9 @@ struct ShellState { #define SHFLG_Lookaside 0x00000004 /* Lookaside memory is used */ #define SHFLG_Backslash 0x00000008 /* The --backslash option is used */ #define SHFLG_PreserveRowid 0x00000010 /* .dump preserves rowid values */ -#define SHFLG_CountChanges 0x00000020 /* .changes setting */ -#define SHFLG_Echo 0x00000040 /* .echo or --echo setting */ +#define SHFLG_Newlines 0x00000020 /* .dump --newline flag */ +#define SHFLG_CountChanges 0x00000040 /* .changes setting */ +#define SHFLG_Echo 0x00000080 /* .echo or --echo setting */ /* ** Macros for testing and setting shellFlgs @@ -2195,7 +2196,11 @@ static int shell_callback( if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){ utf8_printf(p->out,"NULL"); }else if( aiType && aiType[i]==SQLITE_TEXT ){ - output_quoted_escaped_string(p->out, azArg[i]); + if( ShellHasFlag(p, SHFLG_Newlines) ){ + output_quoted_string(p->out, azArg[i]); + }else{ + output_quoted_escaped_string(p->out, azArg[i]); + } }else if( aiType && aiType[i]==SQLITE_INTEGER ){ utf8_printf(p->out,"%s", azArg[i]); }else if( aiType && aiType[i]==SQLITE_FLOAT ){ @@ -2209,6 +2214,8 @@ static int shell_callback( output_hex_blob(p->out, pBlob, nBlob); }else if( isNumber(azArg[i], 0) ){ utf8_printf(p->out,"%s", azArg[i]); + }else if( ShellHasFlag(p, SHFLG_Newlines) ){ + output_quoted_string(p->out, azArg[i]); }else{ output_quoted_escaped_string(p->out, azArg[i]); } @@ -4930,7 +4937,7 @@ static int do_meta_command(char *zLine, ShellState *p){ const char *zLike = 0; int i; int savedShowHeader = p->showHeader; - ShellClearFlag(p, SHFLG_PreserveRowid); + ShellClearFlag(p, SHFLG_PreserveRowid|SHFLG_Newlines); for(i=1; i Date: Mon, 10 Jul 2017 18:33:41 +0000 Subject: [PATCH 33/64] In LSM, avoid calling the VFS xTestLock method to test for a lock that conflicts with one held by the same process. The results of such a call are considered undefined (since they are different under win32 and posix). FossilOrigin-Name: a82a9bea624caf6b24d8e3f3c596817968b258f06e54288022f6df8226281057 --- ext/lsm1/lsm_shared.c | 17 ++++++++++++++--- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/ext/lsm1/lsm_shared.c b/ext/lsm1/lsm_shared.c index f00338979f..6b31961ce1 100644 --- a/ext/lsm1/lsm_shared.c +++ b/ext/lsm1/lsm_shared.c @@ -253,6 +253,8 @@ static void doDbDisconnect(lsm_db *pDb){ rc = lsmShmLock(pDb, LSM_LOCK_DMS1, LSM_LOCK_EXCL, 1); if( rc==LSM_OK ){ + lsmShmLock(pDb, LSM_LOCK_DMS2, LSM_LOCK_UNLOCK, 0); + /* Try an exclusive lock on DMS2. If successful, this is the last ** connection to the database. In this case flush the contents of the ** in-memory tree to disk and write a checkpoint. */ @@ -324,7 +326,6 @@ static void doDbDisconnect(lsm_db *pDb){ pDb->iRwclient = -1; } - lsmShmLock(pDb, LSM_LOCK_DMS2, LSM_LOCK_UNLOCK, 0); lsmShmLock(pDb, LSM_LOCK_DMS1, LSM_LOCK_UNLOCK, 0); } pDb->pShmhdr = 0; @@ -477,8 +478,15 @@ int lsmDbDatabaseConnect( } if( rc==LSM_OK && p->bMultiProc==0 ){ + /* Hold an exclusive lock DMS1 while grabbing DMS2. This ensures + ** that any ongoing call to doDbDisconnect() (even one in another + ** process) is finished before proceeding. */ assert( p->bReadonly==0 ); - rc = lsmEnvLock(pDb->pEnv, p->pFile, LSM_LOCK_DMS2, LSM_LOCK_EXCL); + rc = lsmEnvLock(pDb->pEnv, p->pFile, LSM_LOCK_DMS1, LSM_LOCK_EXCL); + if( rc==LSM_OK ){ + rc = lsmEnvLock(pDb->pEnv, p->pFile, LSM_LOCK_DMS2, LSM_LOCK_EXCL); + lsmEnvLock(pDb->pEnv, p->pFile, LSM_LOCK_DMS1, LSM_LOCK_UNLOCK); + } } if( rc==LSM_OK ){ @@ -1747,7 +1755,10 @@ int lsmShmTestLock( lsmMutexEnter(db->pEnv, p->pClientMutex); for(pIter=p->pConn; pIter; pIter=pIter->pNext){ - if( pIter!=db && (pIter->mLock & mask) ) break; + if( pIter!=db && (pIter->mLock & mask) ){ + assert( pIter!=db ); + break; + } } if( pIter ){ diff --git a/manifest b/manifest index 7fab63a580..80dac22142 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s"--newlines"\soption\sto\sthe\s".dump"\scommand\sin\sthe\sshell\sto\sdisable\nthe\snewline\sescaping\smechanism. -D 2017-07-10T18:04:41.835 +C In\sLSM,\savoid\scalling\sthe\sVFS\sxTestLock\smethod\sto\stest\sfor\sa\slock\sthat\nconflicts\swith\sone\sheld\sby\sthe\ssame\sprocess.\sThe\sresults\sof\ssuch\sa\scall\sare\nconsidered\sundefined\s(since\sthey\sare\sdifferent\sunder\swin32\sand\sposix). +D 2017-07-10T18:33:41.229 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba @@ -243,7 +243,7 @@ F ext/lsm1/lsm_log.c 8308714659b9fe4a995c239528520c57d26a03baf1d1c973967493a089a F ext/lsm1/lsm_main.c 15e73ccdafdd44ddeefc29e332079d88ba8f00c12c797b3c2b63d3171b5afce8 F ext/lsm1/lsm_mem.c 4c51ea9fa285ee6e35301b33491642d071740a0a F ext/lsm1/lsm_mutex.c 378edf0a2b142b4f7640ee982df06d50b98788ea -F ext/lsm1/lsm_shared.c 54cc3a5157c6abd77f7d3ae60708b9f7bf022b3c +F ext/lsm1/lsm_shared.c 54185ae27b7580a959127c700459b3358e39723afce12b6281f2dfe408cb0efd F ext/lsm1/lsm_sorted.c 9bc5251a54a5cb24c2f003c10595fa81ffc7178c4f200c6b0f83d50a2272bb1d F ext/lsm1/lsm_str.c 65e361b488c87b10bf3e5c0070b14ffc602cf84f094880bece77bbf6678bca82 F ext/lsm1/lsm_tree.c 53b657439e0fcb1117b0559ad3567ac417f81f2ed0fff9bab79948a00ea3cacb @@ -1628,7 +1628,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c4cb90487f34937605732c3959891075e2aabfb0bd05e55c44565d65867093ea -R 6d35197f305c27266246f32d8a4834d8 -U drh -Z a3a7e11cbaa224fa5a8714694bd756ab +P bde431b1e332feaeb516dc46d180e2b2f42820c471feed7eda89452ada898dc9 +R 71f00994c33b502fb1928c2468689120 +U dan +Z 83fb5bcc897af021df9d77183bfae0e8 diff --git a/manifest.uuid b/manifest.uuid index f4093af146..5c9fda145d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bde431b1e332feaeb516dc46d180e2b2f42820c471feed7eda89452ada898dc9 \ No newline at end of file +a82a9bea624caf6b24d8e3f3c596817968b258f06e54288022f6df8226281057 \ No newline at end of file From 7ff64dc2bc700a2e06ab75e26632dff7fd6bd7f4 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 10 Jul 2017 18:52:29 +0000 Subject: [PATCH 34/64] Updates to the repository README.md file. FossilOrigin-Name: 7bfd3ab7996bf869eb2705495f3f2cd8bd6d1f4d029a1f26041e95049a9bfd3b --- README.md | 47 ++++++++++++++++++++++++++++++----------------- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 38 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 7b860c211e..eec30ee794 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,9 @@ archives as follows: If you do want to use Fossil to check out the source tree, first install Fossil version 2.0 or later. (Source tarballs and precompiled binaries available -[here](https://www.fossil-scm.org/fossil/uv/download.html).) +[here](https://www.fossil-scm.org/fossil/uv/download.html). Fossil is +a stand-alone program. To install, simply download or build the single +executable file and put that file someplace on your $PATH.) Then run commands like this: mkdir ~/sqlite @@ -106,19 +108,22 @@ The makefiles also require AWK. ## Source Code Tour -Most of the core source files are in the **src/** subdirectory. But -src/ also contains files used to build the "testfixture" test harness; -those file all begin with "test". And src/ contains the "shell.c" file -which is the main program for the "sqlite3.exe" command-line shell and -the "tclsqlite.c" file which implements the bindings to SQLite from the -Tcl programming language. (Historical note: SQLite began as a Tcl +Most of the core source files are in the **src/** subdirectory. The +**src/** folder also contains files used to build the "testfixture" test +harness. The names of the source files used "by testfixture" all begin +with "test". +The **src/** also contains the "shell.c" file +which is the main program for the "sqlite3.exe" +[command-line shell](https://sqlite.org/cli.html) and +the "tclsqlite.c" file which implements the +[TCL bindings](https://sqlite.org/tclsqlite.html) for SQLite. +(Historical note: SQLite began as a Tcl extension and only later escaped to the wild as an independent library.) Test scripts and programs are found in the **test/** subdirectory. -There are other test suites for SQLite (see -[How SQLite Is Tested](http://www.sqlite.org/testing.html)) -but those other test suites are -in separate source repositories. +Addtional test code is found in other source repositories. +See [How SQLite Is Tested](http://www.sqlite.org/testing.html) for +additional information. The **ext/** subdirectory contains code for extensions. The Full-text search engine is in **ext/fts3**. The R-Tree engine is in @@ -142,7 +147,7 @@ manually-edited files and automatically-generated files. The SQLite interface is defined by the **sqlite3.h** header file, which is generated from src/sqlite.h.in, ./manifest.uuid, and ./VERSION. The [Tcl script](http://www.tcl.tk) at tool/mksqlite3h.tcl does the conversion. -The manifest.uuid file contains the SHA1 hash of the particular check-in +The manifest.uuid file contains the SHA3 hash of the particular check-in and is used to generate the SQLITE\_SOURCE\_ID macro. The VERSION file contains the current SQLite version number. The sqlite3.h header is really just a copy of src/sqlite.h.in with the source-id and version number inserted @@ -175,6 +180,13 @@ that maps SQL language keywords (ex: "CREATE", "SELECT", "INDEX", etc.) into the numeric codes used by the parse.c parser. The keywordhash.h file is generated by a C-language program at tool mkkeywordhash.c. +Th3 **pragma.h** header file contains various definitions used to parse +and implement the PRAGMA statements. The header is generated by a +script **tool/mkpragmatab.tcl**. If you want to add a new PRAGMA, edit +the **tool/mkpragmatab.tcl** file to insert the information needed by the +parser for your new PRAGMA, then run the script to regenerate the +**pragma.h** header file. + ### The Amalgamation All of the individual C source code and header files (both manually-edited @@ -192,7 +204,7 @@ subdirectory (using the equivalent of "make target_source") then the tool/mksqlite3c.tcl script is run to copy them all together in just the right order while resolving internal "#include" references. -The amalgamation source file is more than 100K lines long. Some symbolic +The amalgamation source file is more than 200K lines long. Some symbolic debuggers (most notably MSVC) are unable to deal with files longer than 64K lines. To work around this, a separate Tcl script, tool/split-sqlite3c.tcl, can be run on the amalgamation to break it up into a single small C file @@ -209,14 +221,15 @@ See the [architectural description](http://www.sqlite.org/arch.html) for details. Other documents that are useful in (helping to understand how SQLite works include the [file format](http://www.sqlite.org/fileformat2.html) description, -the [virtual machine](http://www.sqlite.org/vdbe.html) that runs +the [virtual machine](http://www.sqlite.org/opcode.html) that runs prepared statements, the description of [how transactions work](http://www.sqlite.org/atomiccommit.html), and the [overview of the query planner](http://www.sqlite.org/optoverview.html). -Unfortunately, years of effort have gone into optimizating SQLite, both +Years of effort have gone into optimizating SQLite, both for small size and high performance. And optimizations tend to result in -complex code. So there is a lot of complexity in the SQLite implementation. +complex code. So there is a lot of complexity in the current SQLite +implementation. It will not be the easiest library in the world to hack. Key files: @@ -267,6 +280,6 @@ describes its purpose and role within the larger system. ## Contacts The main SQLite webpage is [http://www.sqlite.org/](http://www.sqlite.org/) -with geographically distributed backup servers at +with geographically distributed backups at [http://www2.sqlite.org/](http://www2.sqlite.org) and [http://www3.sqlite.org/](http://www3.sqlite.org). diff --git a/manifest b/manifest index 80dac22142..bbdba493d2 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C In\sLSM,\savoid\scalling\sthe\sVFS\sxTestLock\smethod\sto\stest\sfor\sa\slock\sthat\nconflicts\swith\sone\sheld\sby\sthe\ssame\sprocess.\sThe\sresults\sof\ssuch\sa\scall\sare\nconsidered\sundefined\s(since\sthey\sare\sdifferent\sunder\swin32\sand\sposix). -D 2017-07-10T18:33:41.229 +C Updates\sto\sthe\srepository\sREADME.md\sfile. +D 2017-07-10T18:52:29.772 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba -F README.md 2b15fae33852f2f53996774c21fb41e1d94181c4401a0e43ac93e11f2cc901b9 +F README.md 7149d20d5301d984700f873ddcfdff2b1e500e130b7731945519ab656a7c1ddd F VERSION 87f1498f27e398bce3da2fa8125c9879a38ed9d87e4b5fb922b351de1e25cadb F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 @@ -1628,7 +1628,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P bde431b1e332feaeb516dc46d180e2b2f42820c471feed7eda89452ada898dc9 -R 71f00994c33b502fb1928c2468689120 -U dan -Z 83fb5bcc897af021df9d77183bfae0e8 +P a82a9bea624caf6b24d8e3f3c596817968b258f06e54288022f6df8226281057 +R e665dbe909654ef048a5f33418983d75 +U drh +Z cc6da2795dbc87bb104a139fac1657c5 diff --git a/manifest.uuid b/manifest.uuid index 5c9fda145d..a2fe9a416a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a82a9bea624caf6b24d8e3f3c596817968b258f06e54288022f6df8226281057 \ No newline at end of file +7bfd3ab7996bf869eb2705495f3f2cd8bd6d1f4d029a1f26041e95049a9bfd3b \ No newline at end of file From 91ea8cf4acbd4dec1735c8aa1908cbd2dc716999 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Mon, 10 Jul 2017 18:57:03 +0000 Subject: [PATCH 35/64] Cleanup header usage in lsmtest for files that require _O_BINARY. FossilOrigin-Name: f3a6a64ec90e6cf24aadf62aef4f92104be5ba6790f7fca040eff7abc31f1061 --- ext/lsm1/lsm-test/lsmtest.h | 18 ++++++++++++++---- ext/lsm1/lsm-test/lsmtest6.c | 7 ------- ext/lsm1/lsm-test/lsmtest_io.c | 8 -------- ext/lsm1/lsm-test/lsmtest_main.c | 16 ---------------- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- 6 files changed, 25 insertions(+), 46 deletions(-) diff --git a/ext/lsm1/lsm-test/lsmtest.h b/ext/lsm1/lsm-test/lsmtest.h index f5d03e8f3d..249bc999e0 100644 --- a/ext/lsm1/lsm-test/lsmtest.h +++ b/ext/lsm1/lsm-test/lsmtest.h @@ -7,18 +7,24 @@ #include "lsm.h" #include +#include #include #include #include +#ifndef _WIN32 +# include +#endif +#include +#include +#include +#include +#include +#include #ifdef __cplusplus extern "C" { #endif -#ifndef _O_BINARY -# define _O_BINARY (0) -#endif - #ifdef _WIN32 # include "windows.h" # define gettimeofday win32GetTimeOfDay @@ -56,6 +62,10 @@ typedef unsigned long long int u64; #define TESTDB_DEFAULT_PAGE_SIZE 4096 #define TESTDB_DEFAULT_CACHE_SIZE 2048 +#ifndef _O_BINARY +# define _O_BINARY (0) +#endif + /* ** Ideally, these should be in wrapper.c. But they are here instead so that ** they can be used by the C++ database wrappers in wrapper2.cc. diff --git a/ext/lsm1/lsm-test/lsmtest6.c b/ext/lsm1/lsm-test/lsmtest6.c index b795465990..03eee01cef 100644 --- a/ext/lsm1/lsm-test/lsmtest6.c +++ b/ext/lsm1/lsm-test/lsmtest6.c @@ -240,13 +240,6 @@ static void testOomScan( #define LSMTEST6_TESTDB "testdb.lsm" -#ifndef _WIN32 -# include -#endif -#include -#include -#include - void testDeleteLsmdb(const char *zFile){ char *zLog = testMallocPrintf("%s-log", zFile); char *zShm = testMallocPrintf("%s-shm", zFile); diff --git a/ext/lsm1/lsm-test/lsmtest_io.c b/ext/lsm1/lsm-test/lsmtest_io.c index f5599719b1..707a23f283 100644 --- a/ext/lsm1/lsm-test/lsmtest_io.c +++ b/ext/lsm1/lsm-test/lsmtest_io.c @@ -55,14 +55,6 @@ #include "lsmtest.h" -#include -#include -#include -#ifndef _WIN32 -# include -#endif -#include - typedef struct IoContext IoContext; struct IoContext { diff --git a/ext/lsm1/lsm-test/lsmtest_main.c b/ext/lsm1/lsm-test/lsmtest_main.c index 447f9849a2..3468547563 100644 --- a/ext/lsm1/lsm-test/lsmtest_main.c +++ b/ext/lsm1/lsm-test/lsmtest_main.c @@ -1,23 +1,7 @@ -#include "stdarg.h" #include "lsmtest.h" -#include "stdio.h" -#include "assert.h" -#include "string.h" -#include "stdlib.h" - #include -#ifndef _WIN32 -# include -#endif -#include -#include -#include -#include -#include - - void test_failed(){ assert( 0 ); return; diff --git a/manifest b/manifest index bbdba493d2..22dac51ed5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Updates\sto\sthe\srepository\sREADME.md\sfile. -D 2017-07-10T18:52:29.772 +C Cleanup\sheader\susage\sin\slsmtest\sfor\sfiles\sthat\srequire\s_O_BINARY. +D 2017-07-10T18:57:03.034 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba @@ -212,21 +212,21 @@ F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37 F ext/lsm1/Makefile a2ea4975162be8932b5efa727080f4982715d34c32035d9eb7a015ae78404981 F ext/lsm1/Makefile.msc 8b195e7b1567990cf2590802f59bda48005c601addb4deb3e1b8ee74c0ed3813 F ext/lsm1/lsm-test/README 87ea529d2abe615e856d4714bfe8bb185e6c2771b8612aa6298588b7b43e6f86 -F ext/lsm1/lsm-test/lsmtest.h b608c88f4f509fb030be55692e2d6c22389f92acf6911fbad76080a5b7a67bd4 +F ext/lsm1/lsm-test/lsmtest.h 5847594d4b43ec3412e1fd97104f7eb5fd770be55e691e6cb2e80929f86bebe3 F ext/lsm1/lsm-test/lsmtest1.c 33158978327f800e82b6a47c09b86ace809f56a9ff10b0162273ec1186cc3153 F ext/lsm1/lsm-test/lsmtest2.c 188b09aec776516aeedcfd13b9c6faf85ba16b3671a0897a2c740ee00a5dc4f8 F ext/lsm1/lsm-test/lsmtest3.c 9ab87528a36dbf4a61d7c8ad954f5ee368c0878c127b84b942b2e2abe522de26 F ext/lsm1/lsm-test/lsmtest4.c d258d6a245db5d8eaede096e2368d23f859c5e92c80ab9122463f708514fe10c F ext/lsm1/lsm-test/lsmtest5.c 8d5242a0f870d65eeada191c8945781fed9cb8ece3886573790ebd373b62dac5 -F ext/lsm1/lsm-test/lsmtest6.c de2932c87f4cd255de18f334aaffe999922274fc73537839bb000389d7e6aab0 +F ext/lsm1/lsm-test/lsmtest6.c 48dd139ccfd25cf640720aed834a5f3f8ee7fee3cd0b09ffe241dddbf3bc23c1 F ext/lsm1/lsm-test/lsmtest7.c 7a917455a0f956a8ed3f44f5c9387ec0ea6627714874464cc3fa5c5a9cabb2f2 F ext/lsm1/lsm-test/lsmtest8.c b87a1279b0cfbb39df1fff50074696fbf5d83822349f65706fab6d618a7a52fa F ext/lsm1/lsm-test/lsmtest9.c dd1a0ebf41134933a744d1e00e60429a2a21fc50d587ae7dd6bdb6e96d805bdc F ext/lsm1/lsm-test/lsmtest_bt.c d70d9a9be5eef9360af1251dd083948d74fd30137a08f61bef995f7ac04e037f F ext/lsm1/lsm-test/lsmtest_datasource.c 5d770be191d0ca51315926723009b2c25c0b4b8136840494ef710ac324aa916c F ext/lsm1/lsm-test/lsmtest_func.c 159aa401bc8032bfa3d8cf2977bd687abebab880255895a5eb45770d626fa38d -F ext/lsm1/lsm-test/lsmtest_io.c 76d88fd3307977bac646766270c3c3550e35db84c30d912ce9ed5209954dbff9 -F ext/lsm1/lsm-test/lsmtest_main.c 5c09d83771684d312f05900a9baaec36de35ba944f50de18d3cd048d77ddad8e +F ext/lsm1/lsm-test/lsmtest_io.c dacba0cce9a2315c7ec3a8f972aa2fdbbfae2f10067b6d340ab4a08b9796f010 +F ext/lsm1/lsm-test/lsmtest_main.c 6b78f4c303151cfbe938ff5bb8f29f5793ea122d741a23bc3c09ba53b5ab9f53 F ext/lsm1/lsm-test/lsmtest_mem.c c2980abdbc5024628d10910acb703354f2606b4a6f9624679da4e9a56bcee3e9 F ext/lsm1/lsm-test/lsmtest_tdb.c e46c3f44880d45fd444daf2b2a53bca7a64f9df3f6480cbb1b47a039cc95626a F ext/lsm1/lsm-test/lsmtest_tdb.h 8733eee249b12956a9df8322994b43d19bd8c02ad2e8b0bb5164db4d6ccc1735 @@ -1628,7 +1628,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a82a9bea624caf6b24d8e3f3c596817968b258f06e54288022f6df8226281057 -R e665dbe909654ef048a5f33418983d75 -U drh -Z cc6da2795dbc87bb104a139fac1657c5 +P 7bfd3ab7996bf869eb2705495f3f2cd8bd6d1f4d029a1f26041e95049a9bfd3b +R 4f46cf4e9e96a26da22bdd0734a7e05d +U mistachkin +Z f4701cd25a76177b05fde09e8a1c54fd diff --git a/manifest.uuid b/manifest.uuid index a2fe9a416a..835542ea1c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7bfd3ab7996bf869eb2705495f3f2cd8bd6d1f4d029a1f26041e95049a9bfd3b \ No newline at end of file +f3a6a64ec90e6cf24aadf62aef4f92104be5ba6790f7fca040eff7abc31f1061 \ No newline at end of file From 14d5ff4202d0a5fe1b8222311c178f2c22fc38f8 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 10 Jul 2017 19:03:04 +0000 Subject: [PATCH 36/64] Fix an obsolete statement about Lemon in the README.md file. FossilOrigin-Name: 4f6ce7a38baef24e00818926b9b8dc852334e3d4011f1d3a577c8c7e5f7ed93e --- README.md | 5 ++--- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index eec30ee794..9f039b69e0 100644 --- a/README.md +++ b/README.md @@ -158,9 +158,8 @@ used to generate that documentation are in a separate source repository. The SQL language parser is **parse.c** which is generate from a grammar in the src/parse.y file. The conversion of "parse.y" into "parse.c" is done by the [lemon](./doc/lemon.html) LALR(1) parser generator. The source code -for lemon is at tool/lemon.c. Lemon uses a -template for generating its parser. A generic template is in tool/lempar.c, -but SQLite uses a slightly modified template found in src/lempar.c. +for lemon is at tool/lemon.c. Lemon uses the tool/lempar.c file as a +template for generating its parser. Lemon also generates the **parse.h** header file, at the same time it generates parse.c. But the parse.h header file is diff --git a/manifest b/manifest index 22dac51ed5..b983575ce0 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Cleanup\sheader\susage\sin\slsmtest\sfor\sfiles\sthat\srequire\s_O_BINARY. -D 2017-07-10T18:57:03.034 +C Fix\san\sobsolete\sstatement\sabout\sLemon\sin\sthe\sREADME.md\sfile. +D 2017-07-10T19:03:04.499 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba -F README.md 7149d20d5301d984700f873ddcfdff2b1e500e130b7731945519ab656a7c1ddd +F README.md d1c5d991ff52f4c909f183c5d4fbc317e414c0f45b94d886361d221925625745 F VERSION 87f1498f27e398bce3da2fa8125c9879a38ed9d87e4b5fb922b351de1e25cadb F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 @@ -1628,7 +1628,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7bfd3ab7996bf869eb2705495f3f2cd8bd6d1f4d029a1f26041e95049a9bfd3b -R 4f46cf4e9e96a26da22bdd0734a7e05d -U mistachkin -Z f4701cd25a76177b05fde09e8a1c54fd +P f3a6a64ec90e6cf24aadf62aef4f92104be5ba6790f7fca040eff7abc31f1061 +R 3085f173f8d199aef904ba3338310af3 +U drh +Z 0fe6ee642b737cf9ab7f147ba1ed1105 diff --git a/manifest.uuid b/manifest.uuid index 835542ea1c..ade2de6032 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f3a6a64ec90e6cf24aadf62aef4f92104be5ba6790f7fca040eff7abc31f1061 \ No newline at end of file +4f6ce7a38baef24e00818926b9b8dc852334e3d4011f1d3a577c8c7e5f7ed93e \ No newline at end of file From 67d5bf9118a3520e6fd51525f550d93ee8601c16 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 10 Jul 2017 19:05:58 +0000 Subject: [PATCH 37/64] Fix another README.md typo. FossilOrigin-Name: 20b1f0eff175aa8be9a7a631ede0a434f6c340fcdb931633e1f228d1fb35abde --- README.md | 2 +- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 9f039b69e0..bb8f359d57 100644 --- a/README.md +++ b/README.md @@ -110,7 +110,7 @@ The makefiles also require AWK. Most of the core source files are in the **src/** subdirectory. The **src/** folder also contains files used to build the "testfixture" test -harness. The names of the source files used "by testfixture" all begin +harness. The names of the source files used by "testfixture" all begin with "test". The **src/** also contains the "shell.c" file which is the main program for the "sqlite3.exe" diff --git a/manifest b/manifest index b983575ce0..a2128aacc2 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Fix\san\sobsolete\sstatement\sabout\sLemon\sin\sthe\sREADME.md\sfile. -D 2017-07-10T19:03:04.499 +C Fix\sanother\sREADME.md\stypo. +D 2017-07-10T19:05:58.156 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba -F README.md d1c5d991ff52f4c909f183c5d4fbc317e414c0f45b94d886361d221925625745 +F README.md 6847fa1efc878e11b03b6defa7fa25cfd71a366f9b2ce31da930a387f4d2c162 F VERSION 87f1498f27e398bce3da2fa8125c9879a38ed9d87e4b5fb922b351de1e25cadb F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 @@ -1628,7 +1628,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f3a6a64ec90e6cf24aadf62aef4f92104be5ba6790f7fca040eff7abc31f1061 -R 3085f173f8d199aef904ba3338310af3 +P 4f6ce7a38baef24e00818926b9b8dc852334e3d4011f1d3a577c8c7e5f7ed93e +R 471e84035524deda9946a0216bd83546 U drh -Z 0fe6ee642b737cf9ab7f147ba1ed1105 +Z 0b3a090576fbb540ed981e72dd351b5c diff --git a/manifest.uuid b/manifest.uuid index ade2de6032..9ac7ae3523 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4f6ce7a38baef24e00818926b9b8dc852334e3d4011f1d3a577c8c7e5f7ed93e \ No newline at end of file +20b1f0eff175aa8be9a7a631ede0a434f6c340fcdb931633e1f228d1fb35abde \ No newline at end of file From 764fb30330911a15b26205d646272829bdd2b806 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 10 Jul 2017 19:07:11 +0000 Subject: [PATCH 38/64] Yet another typo in README.md FossilOrigin-Name: 75c9327b551d072effbb37efebf5fbe1a45965f89fe285df364dda06ca866cd7 --- README.md | 2 +- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index bb8f359d57..ad6e08fc4f 100644 --- a/README.md +++ b/README.md @@ -179,7 +179,7 @@ that maps SQL language keywords (ex: "CREATE", "SELECT", "INDEX", etc.) into the numeric codes used by the parse.c parser. The keywordhash.h file is generated by a C-language program at tool mkkeywordhash.c. -Th3 **pragma.h** header file contains various definitions used to parse +The **pragma.h** header file contains various definitions used to parse and implement the PRAGMA statements. The header is generated by a script **tool/mkpragmatab.tcl**. If you want to add a new PRAGMA, edit the **tool/mkpragmatab.tcl** file to insert the information needed by the diff --git a/manifest b/manifest index a2128aacc2..1673aa1dfe 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Fix\sanother\sREADME.md\stypo. -D 2017-07-10T19:05:58.156 +C Yet\sanother\stypo\sin\sREADME.md +D 2017-07-10T19:07:11.329 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba -F README.md 6847fa1efc878e11b03b6defa7fa25cfd71a366f9b2ce31da930a387f4d2c162 +F README.md 963a2ccaf76d739d84846a713c5915cbaf38894a5a558656cd3a888b17f1490b F VERSION 87f1498f27e398bce3da2fa8125c9879a38ed9d87e4b5fb922b351de1e25cadb F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 @@ -1628,7 +1628,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4f6ce7a38baef24e00818926b9b8dc852334e3d4011f1d3a577c8c7e5f7ed93e -R 471e84035524deda9946a0216bd83546 +P 20b1f0eff175aa8be9a7a631ede0a434f6c340fcdb931633e1f228d1fb35abde +R d14707a7b1c1b5ef5f78a7a9de58298d U drh -Z 0b3a090576fbb540ed981e72dd351b5c +Z d77cc73ab3a65115b5fe21eac81f9768 diff --git a/manifest.uuid b/manifest.uuid index 9ac7ae3523..3746704018 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -20b1f0eff175aa8be9a7a631ede0a434f6c340fcdb931633e1f228d1fb35abde \ No newline at end of file +75c9327b551d072effbb37efebf5fbe1a45965f89fe285df364dda06ca866cd7 \ No newline at end of file From e1869a91d6f9a4d9df05af511495e71338f70111 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 10 Jul 2017 19:08:59 +0000 Subject: [PATCH 39/64] Spelling error in README.md FossilOrigin-Name: 12bc47c50252f1307b224d171069b93192d0c905aadf480829bba390c059aee4 --- README.md | 2 +- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index ad6e08fc4f..4a0b12ef8c 100644 --- a/README.md +++ b/README.md @@ -272,7 +272,7 @@ Key files: is not part of the core SQLite library. But as most of the tests in this repository are written in Tcl, the Tcl language bindings are important. -There are many other source files. Each has a suscinct header comment that +There are many other source files. Each has a succinct header comment that describes its purpose and role within the larger system. diff --git a/manifest b/manifest index 1673aa1dfe..fa8d18b58a 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Yet\sanother\stypo\sin\sREADME.md -D 2017-07-10T19:07:11.329 +C Spelling\serror\sin\sREADME.md +D 2017-07-10T19:08:59.942 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba -F README.md 963a2ccaf76d739d84846a713c5915cbaf38894a5a558656cd3a888b17f1490b +F README.md 43bb4cffc37febf89079b6af4a76552019f5024b8ae9cb45b2e76fc9a16444f4 F VERSION 87f1498f27e398bce3da2fa8125c9879a38ed9d87e4b5fb922b351de1e25cadb F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 @@ -1628,7 +1628,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 20b1f0eff175aa8be9a7a631ede0a434f6c340fcdb931633e1f228d1fb35abde -R d14707a7b1c1b5ef5f78a7a9de58298d +P 75c9327b551d072effbb37efebf5fbe1a45965f89fe285df364dda06ca866cd7 +R 9b484dba98142e9766d49d019db2f0bc U drh -Z d77cc73ab3a65115b5fe21eac81f9768 +Z 745b27131441596a1708629826a79171 diff --git a/manifest.uuid b/manifest.uuid index 3746704018..7b87bc5422 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -75c9327b551d072effbb37efebf5fbe1a45965f89fe285df364dda06ca866cd7 \ No newline at end of file +12bc47c50252f1307b224d171069b93192d0c905aadf480829bba390c059aee4 \ No newline at end of file From a8686396568e11bbaa9587a1bd764a2f5af626e0 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 10 Jul 2017 19:54:48 +0000 Subject: [PATCH 40/64] Another spelling error in the README.md file. FossilOrigin-Name: 0512937425df6f274153f1d822fc4fe358601c2944745c0039c40e645ebedd82 --- README.md | 2 +- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 4a0b12ef8c..a7b8701106 100644 --- a/README.md +++ b/README.md @@ -239,7 +239,7 @@ Key files: * **sqliteInt.h** - this header file defines many of the data objects used internally by SQLite. - * **parse.y** - This file describes the LALR(1) grammer that SQLite uses + * **parse.y** - This file describes the LALR(1) grammar that SQLite uses to parse SQL statements, and the actions that are taken at each step in the parsing process. diff --git a/manifest b/manifest index fa8d18b58a..e2db31e4ee 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Spelling\serror\sin\sREADME.md -D 2017-07-10T19:08:59.942 +C Another\sspelling\serror\sin\sthe\sREADME.md\sfile. +D 2017-07-10T19:54:48.282 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba -F README.md 43bb4cffc37febf89079b6af4a76552019f5024b8ae9cb45b2e76fc9a16444f4 +F README.md f5c87359573c4d255425e588a56554b50fdcc2afba4e017a2e02a43701456afd F VERSION 87f1498f27e398bce3da2fa8125c9879a38ed9d87e4b5fb922b351de1e25cadb F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 @@ -1628,7 +1628,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 75c9327b551d072effbb37efebf5fbe1a45965f89fe285df364dda06ca866cd7 -R 9b484dba98142e9766d49d019db2f0bc +P 12bc47c50252f1307b224d171069b93192d0c905aadf480829bba390c059aee4 +R 760b18f77d254e39c1233bdd5abb0ed8 U drh -Z 745b27131441596a1708629826a79171 +Z 78eeda4b1b2ef6d92a2436796c56cbe3 diff --git a/manifest.uuid b/manifest.uuid index 7b87bc5422..94e247d756 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -12bc47c50252f1307b224d171069b93192d0c905aadf480829bba390c059aee4 \ No newline at end of file +0512937425df6f274153f1d822fc4fe358601c2944745c0039c40e645ebedd82 \ No newline at end of file From 240e7ef4bb1c7de09e19bab6fc245f5375be7409 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Mon, 10 Jul 2017 20:33:50 +0000 Subject: [PATCH 41/64] Minor cleanup and refactoring of the Win32 VFS for lsm1. FossilOrigin-Name: bf7eda67c8124c3cd5d9150f2f2694cd3f991b20e0a527398885976d0d787242 --- ext/lsm1/lsm_win32.c | 45 +++++++++++++++++++------------------------- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 27 insertions(+), 34 deletions(-) diff --git a/ext/lsm1/lsm_win32.c b/ext/lsm1/lsm_win32.c index 34a1c8a0b2..f7a02612a7 100644 --- a/ext/lsm1/lsm_win32.c +++ b/ext/lsm1/lsm_win32.c @@ -587,22 +587,27 @@ static int lsmWin32OsUnlink(lsm_env *pEnv, const char *zFile){ ((a)==ERROR_IO_PENDING)) #endif -static int lsmWin32OsLock(lsm_file *pFile, int iLock, int eType){ - Win32File *pWin32File = (Win32File *)pFile; +static int win32LockFile( + Win32File *pWin32File, + int iLock, + int nLock, + int eType +){ OVERLAPPED ovlp; assert( LSM_LOCK_UNLOCK==0 ); assert( LSM_LOCK_SHARED==1 ); assert( LSM_LOCK_EXCL==2 ); assert( eType>=LSM_LOCK_UNLOCK && eType<=LSM_LOCK_EXCL ); + assert( nLock>=0 ); assert( iLock>0 && iLock<=32 ); memset(&ovlp, 0, sizeof(OVERLAPPED)); - ovlp.Offset = (4096-iLock); + ovlp.Offset = (4096-iLock-nLock+1); if( eType>LSM_LOCK_UNLOCK ){ DWORD flags = LOCKFILE_FAIL_IMMEDIATELY; if( eType>=LSM_LOCK_EXCL ) flags |= LOCKFILE_EXCLUSIVE_LOCK; - if( !LockFileEx(pWin32File->hFile, flags, 0, 1, 0, &ovlp) ){ + if( !LockFileEx(pWin32File->hFile, flags, 0, (DWORD)nLock, 0, &ovlp) ){ if( win32IsLockBusy(GetLastError()) ){ return LSM_BUSY; }else{ @@ -610,36 +615,24 @@ static int lsmWin32OsLock(lsm_file *pFile, int iLock, int eType){ } } }else{ - if( !UnlockFileEx(pWin32File->hFile, 0, 1, 0, &ovlp) ){ + if( !UnlockFileEx(pWin32File->hFile, 0, (DWORD)nLock, 0, &ovlp) ){ return LSM_IOERR_BKPT; } } return LSM_OK; } -static int lsmWin32OsTestLock(lsm_file *pFile, int iLock, int nLock, int eType){ +static int lsmWin32OsLock(lsm_file *pFile, int iLock, int eType){ Win32File *pWin32File = (Win32File *)pFile; - DWORD flags = LOCKFILE_FAIL_IMMEDIATELY; - OVERLAPPED ovlp; + return win32LockFile(pWin32File, iLock, 1, eType); +} - assert( LSM_LOCK_UNLOCK==0 ); - assert( LSM_LOCK_SHARED==1 ); - assert( LSM_LOCK_EXCL==2 ); - assert( eType==LSM_LOCK_SHARED || eType==LSM_LOCK_EXCL ); - assert( nLock>=0 ); - assert( iLock>0 && iLock<=32 ); - - if( eType>=LSM_LOCK_EXCL ) flags |= LOCKFILE_EXCLUSIVE_LOCK; - memset(&ovlp, 0, sizeof(OVERLAPPED)); - ovlp.Offset = (4096-iLock-nLock+1); - if( !LockFileEx(pWin32File->hFile, flags, 0, (DWORD)nLock, 0, &ovlp) ){ - if( win32IsLockBusy(GetLastError()) ){ - return LSM_BUSY; - }else{ - return LSM_IOERR_BKPT; - } - } - UnlockFileEx(pWin32File->hFile, 0, (DWORD)nLock, 0, &ovlp); +static int lsmWin32OsTestLock(lsm_file *pFile, int iLock, int nLock, int eType){ + int rc; + Win32File *pWin32File = (Win32File *)pFile; + rc = win32LockFile(pWin32File, iLock, nLock, eType); + if( rc!=LSM_OK ) return rc; + win32LockFile(pWin32File, iLock, nLock, LSM_LOCK_UNLOCK); return LSM_OK; } diff --git a/manifest b/manifest index e2db31e4ee..9bf1d013e9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Another\sspelling\serror\sin\sthe\sREADME.md\sfile. -D 2017-07-10T19:54:48.282 +C Minor\scleanup\sand\srefactoring\sof\sthe\sWin32\sVFS\sfor\slsm1. +D 2017-07-10T20:33:50.763 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba @@ -250,7 +250,7 @@ F ext/lsm1/lsm_tree.c 53b657439e0fcb1117b0559ad3567ac417f81f2ed0fff9bab79948a00e F ext/lsm1/lsm_unix.c 57361bcf5b1a1a028f5d66571ee490e9064d2cfb145a2cc9e5ddade467bb551b F ext/lsm1/lsm_varint.c b19ae9bd26b5a1e8402fb8a564b25d9542338a41 F ext/lsm1/lsm_vtab.c 812b74a9a7539e8cab49761591ffddc1b3580735fac5d638826c8d2be95ff38b -F ext/lsm1/lsm_win32.c 646b20f966e834bbf91ce763050bd6cf2732095b8165e6b1f09da22493149bc5 +F ext/lsm1/lsm_win32.c 515f8298982e0e8aa7c6677389ffc66c65a5ff294baf678eefa19b6e61c239c3 F ext/misc/README.md 8e008c8d2b02e09096b31dfba033253ac27c6c06a18aa5826e299fa7601d90b2 F ext/misc/amatch.c 6db4607cb17c54b853a2d7c7c36046d004853f65b9b733e6f019d543d5dfae87 F ext/misc/anycollseq.c 5ffdfde9829eeac52219136ad6aa7cd9a4edb3b15f4f2532de52f4a22525eddb @@ -1628,7 +1628,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 12bc47c50252f1307b224d171069b93192d0c905aadf480829bba390c059aee4 -R 760b18f77d254e39c1233bdd5abb0ed8 -U drh -Z 78eeda4b1b2ef6d92a2436796c56cbe3 +P 0512937425df6f274153f1d822fc4fe358601c2944745c0039c40e645ebedd82 +R 23297e96404b1121c3ff346849386fe8 +U mistachkin +Z 580805a1ed03998ae70db1e05b484fcc diff --git a/manifest.uuid b/manifest.uuid index 94e247d756..e6af1288fc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0512937425df6f274153f1d822fc4fe358601c2944745c0039c40e645ebedd82 \ No newline at end of file +bf7eda67c8124c3cd5d9150f2f2694cd3f991b20e0a527398885976d0d787242 \ No newline at end of file From 4a9e14077e2d3f9072e75f84bf3f7cb85d38c3ba Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 10 Jul 2017 20:39:59 +0000 Subject: [PATCH 42/64] Fix errors in comments in the STMT virtual table. No code changes. FossilOrigin-Name: 9a8f045d62f5c6593a5a2842e817b49fa9d00c74e329a15a326f74e583c1f767 --- ext/misc/stmt.c | 8 ++++---- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/ext/misc/stmt.c b/ext/misc/stmt.c index 533642837e..a74e6b877c 100644 --- a/ext/misc/stmt.c +++ b/ext/misc/stmt.c @@ -70,7 +70,7 @@ struct stmt_cursor { /* ** The stmtConnect() method is invoked to create a new -** stmt_vtab that describes the generate_stmt virtual table. +** stmt_vtab that describes the stmt virtual table. ** ** Think of this routine as the constructor for stmt_vtab objects. ** @@ -79,7 +79,7 @@ struct stmt_cursor { ** (1) Allocate the stmt_vtab object and initialize all fields. ** ** (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the -** result set of queries against generate_stmt will look like. +** result set of queries against stmt will look like. */ static int stmtConnect( sqlite3 *db, @@ -247,7 +247,7 @@ static int stmtFilter( /* ** SQLite will invoke this method one or more times while planning a query -** that uses the generate_stmt virtual table. This routine needs to create +** that uses the stmt virtual table. This routine needs to create ** a query plan for each invocation and compute an estimated cost for that ** plan. */ @@ -262,7 +262,7 @@ static int stmtBestIndex( /* ** This following structure defines all the methods for the -** generate_stmt virtual table. +** stmt virtual table. */ static sqlite3_module stmtModule = { 0, /* iVersion */ diff --git a/manifest b/manifest index 9bf1d013e9..5def8e7b70 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\scleanup\sand\srefactoring\sof\sthe\sWin32\sVFS\sfor\slsm1. -D 2017-07-10T20:33:50.763 +C Fix\serrors\sin\scomments\sin\sthe\sSTMT\svirtual\stable.\s\sNo\scode\schanges. +D 2017-07-10T20:39:59.430 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba @@ -276,7 +276,7 @@ F ext/misc/sha1.c 0b9e9b855354910d3ca467bf39099d570e73db56 F ext/misc/shathree.c fa185d7aee0ad0aca5e091b4a2db7baff11796170e5793b5de99e511a13af448 F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 F ext/misc/spellfix.c a4723b6aff748a417b5091b68a46443265c40f0d -F ext/misc/stmt.c 619222bc1752a7a8412bda2d9b97337c4bc67a1ddee0efcba0eb6f439f25ce5a +F ext/misc/stmt.c e517a1e3e0075e17f3bb274544439db91f121e714da4a0f19f7c9693c20c3fcf F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512 F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95 F ext/misc/vfsstat.c bf10ef0bc51e1ad6756629e1edb142f7a8db1178 @@ -1628,7 +1628,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0512937425df6f274153f1d822fc4fe358601c2944745c0039c40e645ebedd82 -R 23297e96404b1121c3ff346849386fe8 -U mistachkin -Z 580805a1ed03998ae70db1e05b484fcc +P bf7eda67c8124c3cd5d9150f2f2694cd3f991b20e0a527398885976d0d787242 +R 9fceecba0169b6f2b7addd3b0ba00915 +U drh +Z b447d5a5b4804979281a5e6bb9f00809 diff --git a/manifest.uuid b/manifest.uuid index e6af1288fc..315f04b66e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bf7eda67c8124c3cd5d9150f2f2694cd3f991b20e0a527398885976d0d787242 \ No newline at end of file +9a8f045d62f5c6593a5a2842e817b49fa9d00c74e329a15a326f74e583c1f767 \ No newline at end of file From b2950c48e155e00d476797f2fd1df2a3956ca41d Mon Sep 17 00:00:00 2001 From: mistachkin Date: Mon, 10 Jul 2017 21:32:11 +0000 Subject: [PATCH 43/64] Fix harmless compiler warnings in lsmtest. FossilOrigin-Name: bd8a1fb9b33418717c786a7275f636cd4d5facd66de9a416f948b61c6490c743 --- ext/lsm1/Makefile.msc | 2 +- ext/lsm1/lsm-test/lsmtest6.c | 8 ++++---- ext/lsm1/lsm-test/lsmtest8.c | 6 ++++-- ext/lsm1/lsm-test/lsmtest_io.c | 6 +++--- ext/lsm1/lsm-test/lsmtest_main.c | 2 +- ext/lsm1/lsm-test/lsmtest_mem.c | 16 ++++++++-------- ext/lsm1/lsm-test/lsmtest_tdb.c | 3 ++- ext/lsm1/lsm-test/lsmtest_tdb3.c | 30 ++++++++++++++++-------------- manifest | 28 ++++++++++++++-------------- manifest.uuid | 2 +- 10 files changed, 54 insertions(+), 49 deletions(-) diff --git a/ext/lsm1/Makefile.msc b/ext/lsm1/Makefile.msc index 23b4dd9ade..469887728a 100644 --- a/ext/lsm1/Makefile.msc +++ b/ext/lsm1/Makefile.msc @@ -41,7 +41,7 @@ LSMTESTSRC = $(LSMDIR)\lsm-test\lsmtest1.c $(LSMDIR)\lsm-test\lsmtest2.c \ # all: lsm.dll -LSMOPTS = -DLSM_MUTEX_WIN32=1 -I$(LSMDIR) +LSMOPTS = $(NO_WARN) -DLSM_MUTEX_WIN32=1 -I$(LSMDIR) !IF $(DEBUG)>2 LSMOPTS = $(LSMOPTS) -DLSM_DEBUG=1 diff --git a/ext/lsm1/lsm-test/lsmtest6.c b/ext/lsm1/lsm-test/lsmtest6.c index 03eee01cef..a61b738b8f 100644 --- a/ext/lsm1/lsm-test/lsmtest6.c +++ b/ext/lsm1/lsm-test/lsmtest6.c @@ -200,7 +200,7 @@ static void testOomScan( int rc; int iScan = 0; lsm_cursor *pCsr; - int (*xAdvance)(lsm_cursor *); + int (*xAdvance)(lsm_cursor *) = 0; rc = lsm_csr_open(pDb, &pCsr); @@ -353,7 +353,7 @@ static int lsmWriteStr(lsm_db *pDb, const char *zKey, const char *zVal){ return lsm_insert(pDb, (void *)zKey, nKey, (void *)zVal, nVal); } -static void setup_delete_db(){ +static void setup_delete_db(void){ testDeleteLsmdb(LSMTEST6_TESTDB); } @@ -369,7 +369,7 @@ static void setup_delete_db(){ ** "seven" -> "fourtynine" ** "eight" -> "sixtyfour" */ -static void setup_populate_db(){ +static void setup_populate_db(void){ const char *azStr[] = { "one", "one", "two", "four", @@ -411,7 +411,7 @@ static Datasource *getDatasource(void){ ** * Contains 5000 key-value pairs starting at 0 from the ** datasource returned getDatasource(). */ -static void setup_populate_db2(){ +static void setup_populate_db2(void){ Datasource *pData; int ii; int rc; diff --git a/ext/lsm1/lsm-test/lsmtest8.c b/ext/lsm1/lsm-test/lsmtest8.c index d4f8d8ff54..dfc4cae069 100644 --- a/ext/lsm1/lsm-test/lsmtest8.c +++ b/ext/lsm1/lsm-test/lsmtest8.c @@ -92,7 +92,8 @@ void testReadFile(const char *zFile, int iOff, void *pOut, int nByte, int *pRc){ if( 0!=fseek(fd, iOff, SEEK_SET) ){ *pRc = 1; }else{ - if( nByte!=fread(pOut, 1, nByte, fd) ){ + assert( nByte>=0 ); + if( (size_t)nByte!=fread(pOut, 1, nByte, fd) ){ *pRc = 1; } } @@ -117,7 +118,8 @@ void testWriteFile( if( 0!=fseek(fd, iOff, SEEK_SET) ){ *pRc = 1; }else{ - if( nByte!=fwrite(pOut, 1, nByte, fd) ){ + assert( nByte>=0 ); + if( (size_t)nByte!=fwrite(pOut, 1, nByte, fd) ){ *pRc = 1; } } diff --git a/ext/lsm1/lsm-test/lsmtest_io.c b/ext/lsm1/lsm-test/lsmtest_io.c index 707a23f283..7aa5d10948 100644 --- a/ext/lsm1/lsm-test/lsmtest_io.c +++ b/ext/lsm1/lsm-test/lsmtest_io.c @@ -147,7 +147,7 @@ static int doOneCmd( int nPg; int iPg; - nByte = getNextSize(z, &z, &rc); + nByte = (int)getNextSize(z, &z, &rc); if( rc || *z!='@' ) goto bad_command; z++; iOff = getNextSize(z, &z, &rc); @@ -155,7 +155,7 @@ static int doOneCmd( if( pzOut ) *pzOut = z; nPg = (nByte+pgsz-1) / pgsz; - lseek(pCtx->fd, iOff, SEEK_SET); + lseek(pCtx->fd, (off_t)iOff, SEEK_SET); for(iPg=0; iPgfd, aData, pgsz); } @@ -211,7 +211,7 @@ int do_io(int nArg, char **azArg){ zFile = azArg[0]; zPgsz = azArg[1]; - pgsz = getNextSize(zPgsz, 0, &rc); + pgsz = (int)getNextSize(zPgsz, 0, &rc); if( pgsz<=0 ){ testPrintError("Ridiculous page size: %d", pgsz); return -1; diff --git a/ext/lsm1/lsm-test/lsmtest_main.c b/ext/lsm1/lsm-test/lsmtest_main.c index 3468547563..f4a3ac0d56 100644 --- a/ext/lsm1/lsm-test/lsmtest_main.c +++ b/ext/lsm1/lsm-test/lsmtest_main.c @@ -902,7 +902,7 @@ int do_speed_tests(int nArg, char **azArg){ testTimeInit(); for(i=0; iiForeGuard==FOREGUARD ); assert( 0==memcmp(&pUser[pHdr->nByte], &rearguard, 4) ); @@ -218,7 +218,7 @@ static void *tmRealloc(TmGlobal *pTm, void *p, int nByte){ if( pNew && p ){ TmBlockHdr *pHdr; u8 *pUser = (u8 *)p; - pHdr = (TmBlockHdr *)&pUser[BLOCK_HDR_SIZE * -1]; + pHdr = (TmBlockHdr *)(pUser - BLOCK_HDR_SIZE); memcpy(pNew, p, MIN(nByte, pHdr->nByte)); tmFree(pTm, p); } @@ -355,9 +355,9 @@ void testMallocInstall(lsm_env *pEnv){ pGlobal->xDelMutex = tmLsmMutexDel; pGlobal->pMutex = (void *)pMutex; - pGlobal->xSaveMalloc = (void *)pEnv->xMalloc; - pGlobal->xSaveRealloc = (void *)pEnv->xRealloc; - pGlobal->xSaveFree = (void *)pEnv->xFree; + pGlobal->xSaveMalloc = pEnv->xMalloc; + pGlobal->xSaveRealloc = pEnv->xRealloc; + pGlobal->xSaveFree = pEnv->xFree; /* Set up pEnv to the use the new TmGlobal */ pEnv->pMemCtx = (void *)pGlobal; diff --git a/ext/lsm1/lsm-test/lsmtest_tdb.c b/ext/lsm1/lsm-test/lsmtest_tdb.c index 51d145cb7b..8377bc2ed2 100644 --- a/ext/lsm1/lsm-test/lsmtest_tdb.c +++ b/ext/lsm1/lsm-test/lsmtest_tdb.c @@ -767,7 +767,8 @@ int tdb_open(const char *zLib, const char *zDb, int bClear, TestDb **ppDb){ if( *zSpec=='\0' ) zSpec = 0; for(i=0; izLibrary = aLib[i].zName; diff --git a/ext/lsm1/lsm-test/lsmtest_tdb3.c b/ext/lsm1/lsm-test/lsmtest_tdb3.c index d78b787f78..1862023bad 100644 --- a/ext/lsm1/lsm-test/lsmtest_tdb3.c +++ b/ext/lsm1/lsm-test/lsmtest_tdb3.c @@ -199,33 +199,33 @@ static int testEnvWrite(lsm_file *pFile, lsm_i64 iOff, void *pData, int nData){ if( pDb->bCrashed ) return LSM_IOERR; if( pDb->bPrepareCrash ){ - FileData *pData = &pDb->aFile[p->bLog]; + FileData *pData2 = &pDb->aFile[p->bLog]; int iFirst; int iLast; int iSector; - iFirst = (iOff / pDb->szSector); - iLast = ((iOff + nData - 1) / pDb->szSector); + iFirst = (int)(iOff / pDb->szSector); + iLast = (int)((iOff + nData - 1) / pDb->szSector); - if( pData->nSector<(iLast+1) ){ + if( pData2->nSector<(iLast+1) ){ int nNew = ( ((iLast + 1) + 63) / 64 ) * 64; assert( nNew>iLast ); - pData->aSector = (FileSector *)testRealloc( - pData->aSector, nNew*sizeof(FileSector) + pData2->aSector = (FileSector *)testRealloc( + pData2->aSector, nNew*sizeof(FileSector) ); - memset(&pData->aSector[pData->nSector], - 0, (nNew - pData->nSector) * sizeof(FileSector) + memset(&pData2->aSector[pData2->nSector], + 0, (nNew - pData2->nSector) * sizeof(FileSector) ); - pData->nSector = nNew; + pData2->nSector = nNew; } for(iSector=iFirst; iSector<=iLast; iSector++){ - if( pData->aSector[iSector].aOld==0 ){ + if( pData2->aSector[iSector].aOld==0 ){ u8 *aOld = (u8 *)testMalloc(pDb->szSector); pRealEnv->xRead( p->pReal, (lsm_i64)iSector*pDb->szSector, aOld, pDb->szSector ); - pData->aSector[iSector].aOld = aOld; + pData2->aSector[iSector].aOld = aOld; } } } @@ -547,9 +547,9 @@ static int waitOnWorker(LsmDb *pDb){ rc = lsm_config(pDb->db, LSM_CONFIG_AUTOFLUSH, &nLimit); do { - int nOld, nNew, rc; - rc = lsm_info(pDb->db, LSM_INFO_TREE_SIZE, &nOld, &nNew); - if( rc!=LSM_OK ) return rc; + int nOld, nNew, rc2; + rc2 = lsm_info(pDb->db, LSM_INFO_TREE_SIZE, &nOld, &nNew); + if( rc2!=LSM_OK ) return rc2; if( nOld==0 || nNew<(nLimit/2) ) break; #ifdef LSM_MUTEX_PTHREADS mt_signal_worker(pDb, 0); @@ -888,7 +888,9 @@ int test_lsm_config_str( int tdb_lsm_config_str(TestDb *pDb, const char *zStr){ int rc = 0; if( tdb_lsm(pDb) ){ +#ifdef LSM_MUTEX_PTHREADS int i; +#endif LsmDb *pLsm = (LsmDb *)pDb; rc = test_lsm_config_str(pLsm, pLsm->db, 0, zStr, 0); diff --git a/manifest b/manifest index 5def8e7b70..b93b909920 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\serrors\sin\scomments\sin\sthe\sSTMT\svirtual\stable.\s\sNo\scode\schanges. -D 2017-07-10T20:39:59.430 +C Fix\sharmless\scompiler\swarnings\sin\slsmtest. +D 2017-07-10T21:32:11.229 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba @@ -210,7 +210,7 @@ F ext/icu/README.txt d9fbbad0c2f647c3fdf715fc9fd64af53aedfc43 F ext/icu/icu.c 84900472a088a3a172c6c079f58a1d3a1952c332 F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37 F ext/lsm1/Makefile a2ea4975162be8932b5efa727080f4982715d34c32035d9eb7a015ae78404981 -F ext/lsm1/Makefile.msc 8b195e7b1567990cf2590802f59bda48005c601addb4deb3e1b8ee74c0ed3813 +F ext/lsm1/Makefile.msc b9227a1d308f1e408b25557b32ce722517bc22343bd7b728b3ab3979cf2c8a1d F ext/lsm1/lsm-test/README 87ea529d2abe615e856d4714bfe8bb185e6c2771b8612aa6298588b7b43e6f86 F ext/lsm1/lsm-test/lsmtest.h 5847594d4b43ec3412e1fd97104f7eb5fd770be55e691e6cb2e80929f86bebe3 F ext/lsm1/lsm-test/lsmtest1.c 33158978327f800e82b6a47c09b86ace809f56a9ff10b0162273ec1186cc3153 @@ -218,20 +218,20 @@ F ext/lsm1/lsm-test/lsmtest2.c 188b09aec776516aeedcfd13b9c6faf85ba16b3671a0897a2 F ext/lsm1/lsm-test/lsmtest3.c 9ab87528a36dbf4a61d7c8ad954f5ee368c0878c127b84b942b2e2abe522de26 F ext/lsm1/lsm-test/lsmtest4.c d258d6a245db5d8eaede096e2368d23f859c5e92c80ab9122463f708514fe10c F ext/lsm1/lsm-test/lsmtest5.c 8d5242a0f870d65eeada191c8945781fed9cb8ece3886573790ebd373b62dac5 -F ext/lsm1/lsm-test/lsmtest6.c 48dd139ccfd25cf640720aed834a5f3f8ee7fee3cd0b09ffe241dddbf3bc23c1 +F ext/lsm1/lsm-test/lsmtest6.c 869cb4a172cd07d1a75b3aeaecd61d0a477787b3b8668bad0d3ff0f43b642b7c F ext/lsm1/lsm-test/lsmtest7.c 7a917455a0f956a8ed3f44f5c9387ec0ea6627714874464cc3fa5c5a9cabb2f2 -F ext/lsm1/lsm-test/lsmtest8.c b87a1279b0cfbb39df1fff50074696fbf5d83822349f65706fab6d618a7a52fa +F ext/lsm1/lsm-test/lsmtest8.c ab8c30c08540c7cd21e32b678e6c7090ae138c00faf84fdd0ba517361b710861 F ext/lsm1/lsm-test/lsmtest9.c dd1a0ebf41134933a744d1e00e60429a2a21fc50d587ae7dd6bdb6e96d805bdc F ext/lsm1/lsm-test/lsmtest_bt.c d70d9a9be5eef9360af1251dd083948d74fd30137a08f61bef995f7ac04e037f F ext/lsm1/lsm-test/lsmtest_datasource.c 5d770be191d0ca51315926723009b2c25c0b4b8136840494ef710ac324aa916c F ext/lsm1/lsm-test/lsmtest_func.c 159aa401bc8032bfa3d8cf2977bd687abebab880255895a5eb45770d626fa38d -F ext/lsm1/lsm-test/lsmtest_io.c dacba0cce9a2315c7ec3a8f972aa2fdbbfae2f10067b6d340ab4a08b9796f010 -F ext/lsm1/lsm-test/lsmtest_main.c 6b78f4c303151cfbe938ff5bb8f29f5793ea122d741a23bc3c09ba53b5ab9f53 -F ext/lsm1/lsm-test/lsmtest_mem.c c2980abdbc5024628d10910acb703354f2606b4a6f9624679da4e9a56bcee3e9 -F ext/lsm1/lsm-test/lsmtest_tdb.c e46c3f44880d45fd444daf2b2a53bca7a64f9df3f6480cbb1b47a039cc95626a +F ext/lsm1/lsm-test/lsmtest_io.c cf11b27b129c6bd5818fa1d440176502dc27229f0db892b4479118d61993ea20 +F ext/lsm1/lsm-test/lsmtest_main.c a9bc647738c0dcaebf205d6d194b3ce4a6ef3925801cd2d919f0a4ea33a15aeb +F ext/lsm1/lsm-test/lsmtest_mem.c 4e63c764345ab1df59d4f13a77980c6f3643798210b10d6cdbd785b4b888fda5 +F ext/lsm1/lsm-test/lsmtest_tdb.c 555fb101d2fe638abdd133e9294536c857fb38e0f227e049c00a67f51eaece06 F ext/lsm1/lsm-test/lsmtest_tdb.h 8733eee249b12956a9df8322994b43d19bd8c02ad2e8b0bb5164db4d6ccc1735 F ext/lsm1/lsm-test/lsmtest_tdb2.cc 99ea7f2dd9c7536c8fb9bdd329e4cfeb76899f3ddf6f48bdd3926e016922b715 -F ext/lsm1/lsm-test/lsmtest_tdb3.c 91b7f16b7cf7d883552bcf5301c1ce59396d7c3ec73fb7e2c5f673341dfbd0d4 +F ext/lsm1/lsm-test/lsmtest_tdb3.c e44bf94e8bd724cd6ac161fd2cd44ffe43193932ad3a6bee1b07d80bb74012bb F ext/lsm1/lsm-test/lsmtest_tdb4.c 47e8bb5eba266472d690fb8264f1855ebdba0ae5a0e541e35fcda61ebf1d277f F ext/lsm1/lsm-test/lsmtest_util.c 241622db5a332a09c8e6e7606b617d288a37b557f7d3bce0bb97809f67cc2806 F ext/lsm1/lsm-test/lsmtest_win32.c 5605aac3bf3852dcc2509fb1d097f5f11556418c1cc9cf0fdd09f9af53c97fb4 @@ -1628,7 +1628,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P bf7eda67c8124c3cd5d9150f2f2694cd3f991b20e0a527398885976d0d787242 -R 9fceecba0169b6f2b7addd3b0ba00915 -U drh -Z b447d5a5b4804979281a5e6bb9f00809 +P 9a8f045d62f5c6593a5a2842e817b49fa9d00c74e329a15a326f74e583c1f767 +R 4826077b144be43a7ed321a8e8c27dc4 +U mistachkin +Z 5556057292ec12960fe9453577b50312 diff --git a/manifest.uuid b/manifest.uuid index 315f04b66e..a462892ce0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9a8f045d62f5c6593a5a2842e817b49fa9d00c74e329a15a326f74e583c1f767 \ No newline at end of file +bd8a1fb9b33418717c786a7275f636cd4d5facd66de9a416f948b61c6490c743 \ No newline at end of file From 3265b5649ec87ca82026c7cd177434993a00c482 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 11 Jul 2017 00:09:44 +0000 Subject: [PATCH 44/64] Incomplete implementation of the COMPLETION table-valued function. So far it only works for SQL keywords. FossilOrigin-Name: caefbc723b5f67afc5ef10b92b20400cbb76cb03e7e75e18d2726cc552083e09 --- ext/misc/completion.c | 402 ++++++++++++++++++++++++++++++++++++++++++ manifest | 13 +- manifest.uuid | 2 +- 3 files changed, 410 insertions(+), 7 deletions(-) create mode 100644 ext/misc/completion.c diff --git a/ext/misc/completion.c b/ext/misc/completion.c new file mode 100644 index 0000000000..f4cd1b91b7 --- /dev/null +++ b/ext/misc/completion.c @@ -0,0 +1,402 @@ +/* +** 2017-07-10 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file implements an eponymous virtual table that returns suggested +** completions for a partial SQL input. +** +*/ +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_COMPLETIONVTAB) +#if !defined(SQLITEINT_H) +#include "sqlite3ext.h" +#endif +SQLITE_EXTENSION_INIT1 +#include +#include +#include + +#ifndef SQLITE_OMIT_VIRTUALTABLE + +/* completion_vtab is a subclass of sqlite3_vtab which will +** serve as the underlying representation of a completion virtual table +*/ +typedef struct completion_vtab completion_vtab; +struct completion_vtab { + sqlite3_vtab base; /* Base class - must be first */ + sqlite3 *db; /* Database connection for this completion vtab */ +}; + +/* completion_cursor is a subclass of sqlite3_vtab_cursor which will +** serve as the underlying representation of a cursor that scans +** over rows of the result +*/ +typedef struct completion_cursor completion_cursor; +struct completion_cursor { + sqlite3_vtab_cursor base; /* Base class - must be first */ + sqlite3 *db; /* Database connection for this cursor */ + int nPrefix, nLine; /* Number of bytes in zPrefix and zLine */ + char *zPrefix; /* The prefix for the word we want to complete */ + char *zLine; /* The whole that we want to complete */ + const char *zCurrentRow; /* Current output row */ + sqlite3_stmt *pStmt; /* Current statement */ + sqlite3_int64 iRowid; /* The rowid */ + int ePhase; /* Current phase */ + int j; /* inter-phase counter */ +}; + +/* Values for ePhase: +*/ +#define COMPLETION_FIRST_PHASE 0 +#define COMPLETION_KEYWORDS 1 +#define COMPLETION_PRAGMAS 2 +#define COMPLETION_FUNCTIONS 3 +#define COMPLETION_COLLATIONS 4 +#define COMPLETION_INDEXES 5 +#define COMPLETION_TRIGGERS 6 +#define COMPLETION_DATABASES 7 +#define COMPLETION_TABLES 8 +#define COMPLETION_MODULES 9 +#define COMPLETION_LAST_PHASE 10 + +/* +** The completionConnect() method is invoked to create a new +** completion_vtab that describes the completion virtual table. +** +** Think of this routine as the constructor for completion_vtab objects. +** +** All this routine needs to do is: +** +** (1) Allocate the completion_vtab object and initialize all fields. +** +** (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the +** result set of queries against completion will look like. +*/ +static int completionConnect( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + completion_vtab *pNew; + int rc; + +/* Column numbers */ +#define COMPLETION_COLUMN_CANDIDATE 0 /* Suggested completion of the input */ +#define COMPLETION_COLUMN_PREFIX 1 /* Prefix of the word to be completed */ +#define COMPLETION_COLUMN_WHOLELINE 2 /* Entire line seen so far */ + + rc = sqlite3_declare_vtab(db, + "CREATE TABLE x(" + " candidate TEXT," + " prefix TEXT HIDDEN," + " wholeline TEXT HIDDEN" + ")"); + if( rc==SQLITE_OK ){ + pNew = sqlite3_malloc( sizeof(*pNew) ); + *ppVtab = (sqlite3_vtab*)pNew; + if( pNew==0 ) return SQLITE_NOMEM; + memset(pNew, 0, sizeof(*pNew)); + pNew->db = db; + } + return rc; +} + +/* +** This method is the destructor for completion_cursor objects. +*/ +static int completionDisconnect(sqlite3_vtab *pVtab){ + sqlite3_free(pVtab); + return SQLITE_OK; +} + +/* +** Constructor for a new completion_cursor object. +*/ +static int completionOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ + completion_cursor *pCur; + pCur = sqlite3_malloc( sizeof(*pCur) ); + if( pCur==0 ) return SQLITE_NOMEM; + memset(pCur, 0, sizeof(*pCur)); + pCur->db = ((completion_vtab*)p)->db; + *ppCursor = &pCur->base; + return SQLITE_OK; +} + +/* +** Reset the completion_cursor. +*/ +static void completionCursorReset(completion_cursor *pCur){ + sqlite3_free(pCur->zPrefix); pCur->zPrefix = 0; pCur->nPrefix = 0; + sqlite3_free(pCur->zLine); pCur->zLine = 0; pCur->nLine = 0; + sqlite3_finalize(pCur->pStmt); pCur->pStmt = 0; +} + +/* +** Destructor for a completion_cursor. +*/ +static int completionClose(sqlite3_vtab_cursor *cur){ + completionCursorReset((completion_cursor*)cur); + sqlite3_free(cur); + return SQLITE_OK; +} + +/* +** All SQL keywords understood by SQLite +*/ +static const char *completionKwrds[] = { + "ABORT", "ACTION", "ADD", "AFTER", "ALL", "ALTER", "ANALYZE", "AND", "AS", + "ASC", "ATTACH", "AUTOINCREMENT", "BEFORE", "BEGIN", "BETWEEN", "BY", + "CASCADE", "CASE", "CAST", "CHECK", "COLLATE", "COLUMN", "COMMIT", + "CONFLICT", "CONSTRAINT", "CREATE", "CROSS", "CURRENT_DATE", + "CURRENT_TIME", "CURRENT_TIMESTAMP", "DATABASE", "DEFAULT", "DEFERRABLE", + "DEFERRED", "DELETE", "DESC", "DETACH", "DISTINCT", "DROP", "EACH", + "ELSE", "END", "ESCAPE", "EXCEPT", "EXCLUSIVE", "EXISTS", "EXPLAIN", + "FAIL", "FOR", "FOREIGN", "FROM", "FULL", "GLOB", "GROUP", "HAVING", "IF", + "IGNORE", "IMMEDIATE", "IN", "INDEX", "INDEXED", "INITIALLY", "INNER", + "INSERT", "INSTEAD", "INTERSECT", "INTO", "IS", "ISNULL", "JOIN", "KEY", + "LEFT", "LIKE", "LIMIT", "MATCH", "NATURAL", "NO", "NOT", "NOTNULL", + "NULL", "OF", "OFFSET", "ON", "OR", "ORDER", "OUTER", "PLAN", "PRAGMA", + "PRIMARY", "QUERY", "RAISE", "RECURSIVE", "REFERENCES", "REGEXP", + "REINDEX", "RELEASE", "RENAME", "REPLACE", "RESTRICT", "RIGHT", + "ROLLBACK", "ROW", "SAVEPOINT", "SELECT", "SET", "TABLE", "TEMP", + "TEMPORARY", "THEN", "TO", "TRANSACTION", "TRIGGER", "UNION", "UNIQUE", + "UPDATE", "USING", "VACUUM", "VALUES", "VIEW", "VIRTUAL", "WHEN", "WHERE", + "WITH", "WITHOUT", +}; + +/* +** Advance a completion_cursor to its next row of output. +*/ +static int completionNext(sqlite3_vtab_cursor *cur){ + completion_cursor *pCur = (completion_cursor*)cur; + pCur->iRowid++; + if( pCur->ePhase==COMPLETION_FIRST_PHASE ){ + pCur->ePhase = COMPLETION_KEYWORDS; + pCur->j = -1; + } + if( pCur->ePhase==COMPLETION_KEYWORDS ){ + while(1){ + const char *z; + pCur->j++; + if( pCur->j >= sizeof(completionKwrds)/sizeof(completionKwrds[0]) ){ + pCur->ePhase = COMPLETION_LAST_PHASE; + break; + } + z = completionKwrds[pCur->j]; + if( pCur->nPrefix==0 + || sqlite3_strnicmp(pCur->zPrefix, z, pCur->nPrefix)==0 + ){ + pCur->zCurrentRow = z; + break; + } + } + } + return SQLITE_OK; +} + +/* +** Return values of columns for the row at which the completion_cursor +** is currently pointing. +*/ +static int completionColumn( + sqlite3_vtab_cursor *cur, /* The cursor */ + sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ + int i /* Which column to return */ +){ + completion_cursor *pCur = (completion_cursor*)cur; + switch( i ){ + case COMPLETION_COLUMN_CANDIDATE: { + sqlite3_result_text(ctx, pCur->zCurrentRow, -1, SQLITE_TRANSIENT); + break; + } + case COMPLETION_COLUMN_PREFIX: { + sqlite3_result_text(ctx, pCur->zPrefix, -1, SQLITE_TRANSIENT); + break; + } + case COMPLETION_COLUMN_WHOLELINE: { + sqlite3_result_text(ctx, pCur->zLine, -1, SQLITE_TRANSIENT); + break; + } + } + return SQLITE_OK; +} + +/* +** Return the rowid for the current row. In this implementation, the +** rowid is the same as the output value. +*/ +static int completionRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ + completion_cursor *pCur = (completion_cursor*)cur; + *pRowid = pCur->iRowid; + return SQLITE_OK; +} + +/* +** Return TRUE if the cursor has been moved off of the last +** row of output. +*/ +static int completionEof(sqlite3_vtab_cursor *cur){ + completion_cursor *pCur = (completion_cursor*)cur; + return pCur->ePhase >= COMPLETION_LAST_PHASE; +} + +/* +** This method is called to "rewind" the completion_cursor object back +** to the first row of output. This method is always called at least +** once prior to any call to completionColumn() or completionRowid() or +** completionEof(). +*/ +static int completionFilter( + sqlite3_vtab_cursor *pVtabCursor, + int idxNum, const char *idxStr, + int argc, sqlite3_value **argv +){ + completion_cursor *pCur = (completion_cursor *)pVtabCursor; + int iArg = 0; + completionCursorReset(pCur); + if( idxNum & 1 ){ + pCur->nPrefix = sqlite3_value_bytes(argv[iArg]); + if( pCur->nPrefix>0 ){ + pCur->zPrefix = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg])); + if( pCur->zPrefix==0 ) return SQLITE_NOMEM; + } + iArg++; + } + if( idxNum & 2 ){ + pCur->nLine = sqlite3_value_bytes(argv[iArg]); + if( pCur->nLine>0 ){ + pCur->zLine = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg])); + if( pCur->zLine==0 ) return SQLITE_NOMEM; + } + iArg++; + } + if( pCur->zLine!=0 && pCur->zPrefix==0 ){ + int i = pCur->nLine; + while( i>0 && (isalnum(pCur->zLine[i-1]) || pCur->zLine[i-1]=='_') ){ + i--; + } + pCur->nPrefix = pCur->nLine - i; + if( pCur->nPrefix>0 ){ + pCur->zPrefix = sqlite3_mprintf("%.*s", pCur->nPrefix, pCur->zLine + i); + if( pCur->zPrefix==0 ) return SQLITE_NOMEM; + } + } + pCur->iRowid = 0; + pCur->ePhase = COMPLETION_FIRST_PHASE; + return completionNext(pVtabCursor); +} + +/* +** SQLite will invoke this method one or more times while planning a query +** that uses the completion virtual table. This routine needs to create +** a query plan for each invocation and compute an estimated cost for that +** plan. +** +** There are two hidden parameters that act as arguments to the table-valued +** function: "prefix" and "wholeline". Bit 0 of idxNum is set if "prefix" +** is available and bit 1 is set if "wholeline" is available. +*/ +static int completionBestIndex( + sqlite3_vtab *tab, + sqlite3_index_info *pIdxInfo +){ + int i; /* Loop over constraints */ + int idxNum = 0; /* The query plan bitmask */ + int prefixIdx = -1; /* Index of the start= constraint, or -1 if none */ + int wholelineIdx = -1; /* Index of the stop= constraint, or -1 if none */ + int nArg = 0; /* Number of arguments that completeFilter() expects */ + const struct sqlite3_index_constraint *pConstraint; + + pConstraint = pIdxInfo->aConstraint; + for(i=0; inConstraint; i++, pConstraint++){ + if( pConstraint->usable==0 ) continue; + if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue; + switch( pConstraint->iColumn ){ + case COMPLETION_COLUMN_PREFIX: + prefixIdx = i; + idxNum |= 1; + break; + case COMPLETION_COLUMN_WHOLELINE: + wholelineIdx = i; + idxNum |= 2; + break; + } + } + if( prefixIdx>=0 ){ + pIdxInfo->aConstraintUsage[prefixIdx].argvIndex = ++nArg; + pIdxInfo->aConstraintUsage[prefixIdx].omit = 1; + } + if( wholelineIdx>=0 ){ + pIdxInfo->aConstraintUsage[wholelineIdx].argvIndex = ++nArg; + pIdxInfo->aConstraintUsage[wholelineIdx].omit = 1; + } + pIdxInfo->idxNum = idxNum; + pIdxInfo->estimatedCost = (double)5000 - 1000*nArg; + pIdxInfo->estimatedRows = 500 - 100*nArg; + return SQLITE_OK; +} + +/* +** This following structure defines all the methods for the +** completion virtual table. +*/ +static sqlite3_module completionModule = { + 0, /* iVersion */ + 0, /* xCreate */ + completionConnect, /* xConnect */ + completionBestIndex, /* xBestIndex */ + completionDisconnect, /* xDisconnect */ + 0, /* xDestroy */ + completionOpen, /* xOpen - open a cursor */ + completionClose, /* xClose - close a cursor */ + completionFilter, /* xFilter - configure scan constraints */ + completionNext, /* xNext - advance a cursor */ + completionEof, /* xEof - check for end of scan */ + completionColumn, /* xColumn - read data */ + completionRowid, /* xRowid - read data */ + 0, /* xUpdate */ + 0, /* xBegin */ + 0, /* xSync */ + 0, /* xCommit */ + 0, /* xRollback */ + 0, /* xFindMethod */ + 0, /* xRename */ +}; + +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +int sqlite3CompletionVtabInit(sqlite3 *db){ + int rc = SQLITE_OK; +#ifndef SQLITE_OMIT_VIRTUALTABLE + rc = sqlite3_create_module(db, "completion", &completionModule, 0); +#endif + return rc; +} + +#ifndef SQLITE_CORE +#ifdef _WIN32 +__declspec(dllexport) +#endif +int sqlite3_completion_init( + sqlite3 *db, + char **pzErrMsg, + const sqlite3_api_routines *pApi +){ + int rc = SQLITE_OK; + SQLITE_EXTENSION_INIT2(pApi); +#ifndef SQLITE_OMIT_VIRTUALTABLE + rc = sqlite3CompletionVtabInit(db); +#endif + return rc; +} +#endif /* SQLITE_CORE */ +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_COMPLETIONVTAB) */ diff --git a/manifest b/manifest index b93b909920..1325b5b8ae 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings\sin\slsmtest. -D 2017-07-10T21:32:11.229 +C Incomplete\simplementation\sof\sthe\sCOMPLETION\stable-valued\sfunction.\s\sSo\sfar\sit\nonly\sworks\sfor\sSQL\skeywords. +D 2017-07-11T00:09:44.330 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba @@ -256,6 +256,7 @@ F ext/misc/amatch.c 6db4607cb17c54b853a2d7c7c36046d004853f65b9b733e6f019d543d5df F ext/misc/anycollseq.c 5ffdfde9829eeac52219136ad6aa7cd9a4edb3b15f4f2532de52f4a22525eddb F ext/misc/carray.c 40c27641010a4dc67e3690bdb7c9d36ca58b3c2d F ext/misc/closure.c 0d2a038df8fbae7f19de42e7c7d71f2e4dc88704 +F ext/misc/completion.c 1b58092f73e9c6025d055b5e01f22273f378de2bf3a1db0d6b5dfe79dddce5f7 F ext/misc/compress.c 122faa92d25033d6c3f07c39231de074ab3d2e83 F ext/misc/csv.c d91c0388445b08f6e373dd0e8fc024d4551b1fcaf64e876a1c3f4fac8a63adc2 F ext/misc/dbdump.c 3509fa6b8932d04e932d6b6b827b6a82ca362781b8e8f3c77336f416793e215e @@ -1628,7 +1629,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9a8f045d62f5c6593a5a2842e817b49fa9d00c74e329a15a326f74e583c1f767 -R 4826077b144be43a7ed321a8e8c27dc4 -U mistachkin -Z 5556057292ec12960fe9453577b50312 +P bd8a1fb9b33418717c786a7275f636cd4d5facd66de9a416f948b61c6490c743 +R c31437c94c579e099f5c663f8abfebe7 +U drh +Z 2bab86907269899ac4b24013169de866 diff --git a/manifest.uuid b/manifest.uuid index a462892ce0..ec03a9d963 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bd8a1fb9b33418717c786a7275f636cd4d5facd66de9a416f948b61c6490c743 \ No newline at end of file +caefbc723b5f67afc5ef10b92b20400cbb76cb03e7e75e18d2726cc552083e09 \ No newline at end of file From dc4dde6bd9ee6409ce5987e38f0e3d667f906679 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 11 Jul 2017 01:38:45 +0000 Subject: [PATCH 45/64] The COMPLETION virtual table now looks at the names of databases, tables, and columns in addition to SQL keywords. FossilOrigin-Name: 1cc97711fa86a3938f0930200476d1b0991e4b893a8be3a19015423a3de56bef --- ext/misc/completion.c | 115 +++++++++++++++++++++++++++++++++++------- manifest | 12 ++--- manifest.uuid | 2 +- 3 files changed, 103 insertions(+), 26 deletions(-) diff --git a/ext/misc/completion.c b/ext/misc/completion.c index f4cd1b91b7..ae11ef4220 100644 --- a/ext/misc/completion.c +++ b/ext/misc/completion.c @@ -54,7 +54,7 @@ struct completion_cursor { /* Values for ePhase: */ -#define COMPLETION_FIRST_PHASE 0 +#define COMPLETION_FIRST_PHASE 1 #define COMPLETION_KEYWORDS 1 #define COMPLETION_PRAGMAS 2 #define COMPLETION_FUNCTIONS 3 @@ -63,8 +63,9 @@ struct completion_cursor { #define COMPLETION_TRIGGERS 6 #define COMPLETION_DATABASES 7 #define COMPLETION_TABLES 8 -#define COMPLETION_MODULES 9 -#define COMPLETION_LAST_PHASE 10 +#define COMPLETION_COLUMNS 9 +#define COMPLETION_MODULES 10 +#define COMPLETION_EOF 11 /* ** The completionConnect() method is invoked to create a new @@ -138,6 +139,7 @@ static void completionCursorReset(completion_cursor *pCur){ sqlite3_free(pCur->zPrefix); pCur->zPrefix = 0; pCur->nPrefix = 0; sqlite3_free(pCur->zLine); pCur->zLine = 0; pCur->nLine = 0; sqlite3_finalize(pCur->pStmt); pCur->pStmt = 0; + pCur->j = 0; } /* @@ -178,28 +180,103 @@ static const char *completionKwrds[] = { */ static int completionNext(sqlite3_vtab_cursor *cur){ completion_cursor *pCur = (completion_cursor*)cur; + int eNextPhase = 0;/* Next phase to try if current phase reaches end */ + int iCol = -1; /* If >=0 then step pCur->pStmt and use the i-th column */ pCur->iRowid++; - if( pCur->ePhase==COMPLETION_FIRST_PHASE ){ - pCur->ePhase = COMPLETION_KEYWORDS; - pCur->j = -1; - } - if( pCur->ePhase==COMPLETION_KEYWORDS ){ - while(1){ - const char *z; - pCur->j++; - if( pCur->j >= sizeof(completionKwrds)/sizeof(completionKwrds[0]) ){ - pCur->ePhase = COMPLETION_LAST_PHASE; + while( pCur->ePhase!=COMPLETION_EOF ){ + switch( pCur->ePhase ){ + case COMPLETION_KEYWORDS: { + if( pCur->j >= sizeof(completionKwrds)/sizeof(completionKwrds[0]) ){ + pCur->zCurrentRow = 0; + pCur->ePhase = COMPLETION_DATABASES; + }else{ + pCur->zCurrentRow = completionKwrds[pCur->j++]; + } + iCol = -1; break; } - z = completionKwrds[pCur->j]; - if( pCur->nPrefix==0 - || sqlite3_strnicmp(pCur->zPrefix, z, pCur->nPrefix)==0 - ){ - pCur->zCurrentRow = z; + case COMPLETION_DATABASES: { + if( pCur->pStmt==0 ){ + sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1, + &pCur->pStmt, 0); + } + iCol = 1; + eNextPhase = COMPLETION_TABLES; + break; + } + case COMPLETION_TABLES: { + if( pCur->pStmt==0 ){ + sqlite3_stmt *pS2; + char *zSql = 0; + const char *zSep = ""; + sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1, &pS2, 0); + while( sqlite3_step(pS2)==SQLITE_ROW ){ + const char *zDb = (const char*)sqlite3_column_text(pS2, 1); + zSql = sqlite3_mprintf( + "%z%s" + "SELECT name FROM \"%w\".sqlite_master" + " WHERE type='table'", + zSql, zSep, zDb + ); + if( zSql==0 ) return SQLITE_NOMEM; + zSep = " UNION "; + } + sqlite3_finalize(pS2); + sqlite3_prepare_v2(pCur->db, zSql, -1, &pCur->pStmt, 0); + sqlite3_free(zSql); + } + iCol = 0; + eNextPhase = COMPLETION_COLUMNS; + break; + } + case COMPLETION_COLUMNS: { + if( pCur->pStmt==0 ){ + sqlite3_stmt *pS2; + char *zSql = 0; + const char *zSep = ""; + sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1, &pS2, 0); + while( sqlite3_step(pS2)==SQLITE_ROW ){ + const char *zDb = (const char*)sqlite3_column_text(pS2, 1); + zSql = sqlite3_mprintf( + "%z%s" + "SELECT pti.name FROM \"%w\".sqlite_master AS sm" + " JOIN pragma_table_info(sm.name,%Q) AS pti" + " WHERE sm.type='table'", + zSql, zSep, zDb, zDb + ); + if( zSql==0 ) return SQLITE_NOMEM; + zSep = " UNION "; + } + sqlite3_finalize(pS2); + sqlite3_prepare_v2(pCur->db, zSql, -1, &pCur->pStmt, 0); + sqlite3_free(zSql); + } + iCol = 0; + eNextPhase = COMPLETION_EOF; break; } } + if( iCol<0 ){ + /* This case is when the phase presets zCurrentRow */ + if( pCur->zCurrentRow==0 ) continue; + }else{ + if( sqlite3_step(pCur->pStmt)==SQLITE_ROW ){ + /* Extract the next row of content */ + pCur->zCurrentRow = (const char*)sqlite3_column_text(pCur->pStmt, iCol); + }else{ + /* When all rows are finished, advance to the next phase */ + sqlite3_finalize(pCur->pStmt); + pCur->pStmt = 0; + pCur->ePhase = eNextPhase; + continue; + } + } + if( pCur->nPrefix==0 ) break; + if( sqlite3_strnicmp(pCur->zPrefix, pCur->zCurrentRow, pCur->nPrefix)==0 ){ + break; + } } + return SQLITE_OK; } @@ -246,7 +323,7 @@ static int completionRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ */ static int completionEof(sqlite3_vtab_cursor *cur){ completion_cursor *pCur = (completion_cursor*)cur; - return pCur->ePhase >= COMPLETION_LAST_PHASE; + return pCur->ePhase >= COMPLETION_EOF; } /* diff --git a/manifest b/manifest index 1325b5b8ae..2900651ce0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Incomplete\simplementation\sof\sthe\sCOMPLETION\stable-valued\sfunction.\s\sSo\sfar\sit\nonly\sworks\sfor\sSQL\skeywords. -D 2017-07-11T00:09:44.330 +C The\sCOMPLETION\svirtual\stable\snow\slooks\sat\sthe\snames\sof\sdatabases,\stables,\nand\scolumns\sin\saddition\sto\sSQL\skeywords. +D 2017-07-11T01:38:45.049 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba @@ -256,7 +256,7 @@ F ext/misc/amatch.c 6db4607cb17c54b853a2d7c7c36046d004853f65b9b733e6f019d543d5df F ext/misc/anycollseq.c 5ffdfde9829eeac52219136ad6aa7cd9a4edb3b15f4f2532de52f4a22525eddb F ext/misc/carray.c 40c27641010a4dc67e3690bdb7c9d36ca58b3c2d F ext/misc/closure.c 0d2a038df8fbae7f19de42e7c7d71f2e4dc88704 -F ext/misc/completion.c 1b58092f73e9c6025d055b5e01f22273f378de2bf3a1db0d6b5dfe79dddce5f7 +F ext/misc/completion.c 813c7faecc8fe3dd5c5503b87d4bb44ed6b841ff3398d19fbccec251da0af25f F ext/misc/compress.c 122faa92d25033d6c3f07c39231de074ab3d2e83 F ext/misc/csv.c d91c0388445b08f6e373dd0e8fc024d4551b1fcaf64e876a1c3f4fac8a63adc2 F ext/misc/dbdump.c 3509fa6b8932d04e932d6b6b827b6a82ca362781b8e8f3c77336f416793e215e @@ -1629,7 +1629,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P bd8a1fb9b33418717c786a7275f636cd4d5facd66de9a416f948b61c6490c743 -R c31437c94c579e099f5c663f8abfebe7 +P caefbc723b5f67afc5ef10b92b20400cbb76cb03e7e75e18d2726cc552083e09 +R 1115796824efacad1a0f50faf8b6a73d U drh -Z 2bab86907269899ac4b24013169de866 +Z e368c5a978df04c5e378d21fe41e060f diff --git a/manifest.uuid b/manifest.uuid index ec03a9d963..d37dfde610 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -caefbc723b5f67afc5ef10b92b20400cbb76cb03e7e75e18d2726cc552083e09 \ No newline at end of file +1cc97711fa86a3938f0930200476d1b0991e4b893a8be3a19015423a3de56bef \ No newline at end of file From f3c0009d8b9208123e41da64b2c757c2f307c95f Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 11 Jul 2017 02:05:21 +0000 Subject: [PATCH 46/64] Add the "phase" output column on the COMPLETION table-valued function, for debugging. Improved comments on the implementation. FossilOrigin-Name: 0e2135552757cc6566ac959475d3b87254b6d462425ee6c457c743001f3370e2 --- ext/misc/completion.c | 42 +++++++++++++++++++++++++++++++++++++++--- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 46 insertions(+), 10 deletions(-) diff --git a/ext/misc/completion.c b/ext/misc/completion.c index ae11ef4220..a3189ad154 100644 --- a/ext/misc/completion.c +++ b/ext/misc/completion.c @@ -13,6 +13,25 @@ ** This file implements an eponymous virtual table that returns suggested ** completions for a partial SQL input. ** +** Suggested usage: +** +** SELECT DISTINCT candidate COLLATE nocase +** FROM completion($prefix,$wholeline) +** ORDER BY 1; +** +** The two query parameters are optional. $prefix is the text of the +** current word being typed and that is to be completed. $wholeline is +** the complete input line, used for context. +** +** The raw completion() table might return the same candidate multiple +** times, for example if the same column name is used to two or more +** tables. And the candidates are returned in an arbitrary order. Hence, +** the DISTINCT and ORDER BY are recommended. +** +** This virtual table operates at the speed of human typing, and so there +** is no attempt to make it fast. Even a slow implementation will be much +** faster than any human can type. +** */ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_COMPLETIONVTAB) #if !defined(SQLITEINT_H) @@ -94,12 +113,14 @@ static int completionConnect( #define COMPLETION_COLUMN_CANDIDATE 0 /* Suggested completion of the input */ #define COMPLETION_COLUMN_PREFIX 1 /* Prefix of the word to be completed */ #define COMPLETION_COLUMN_WHOLELINE 2 /* Entire line seen so far */ +#define COMPLETION_COLUMN_PHASE 3 /* ePhase - used for debugging only */ rc = sqlite3_declare_vtab(db, "CREATE TABLE x(" " candidate TEXT," " prefix TEXT HIDDEN," - " wholeline TEXT HIDDEN" + " wholeline TEXT HIDDEN," + " phase INT HIDDEN" /* Used for debugging only */ ")"); if( rc==SQLITE_OK ){ pNew = sqlite3_malloc( sizeof(*pNew) ); @@ -177,11 +198,22 @@ static const char *completionKwrds[] = { /* ** Advance a completion_cursor to its next row of output. +** +** The ->ePhase, ->j, and ->pStmt fields of the completion_cursor object +** record the current state of the scan. This routine sets ->zCurrentRow +** to the current row of output and then returns. If no more rows remain, +** then ->ePhase is set to COMPLETION_EOF which will signal the virtual +** table that has reached the end of its scan. +** +** The current implementation just lists potential identifiers and +** keywords and filters them by zPrefix. Future enhancements should +** take zLine into account to try to restrict the set of identifiers and +** keywords based on what would be legal at the current point of input. */ static int completionNext(sqlite3_vtab_cursor *cur){ completion_cursor *pCur = (completion_cursor*)cur; - int eNextPhase = 0;/* Next phase to try if current phase reaches end */ - int iCol = -1; /* If >=0 then step pCur->pStmt and use the i-th column */ + int eNextPhase = 0; /* Next phase to try if current phase reaches end */ + int iCol = -1; /* If >=0, step pCur->pStmt and use the i-th column */ pCur->iRowid++; while( pCur->ePhase!=COMPLETION_EOF ){ switch( pCur->ePhase ){ @@ -303,6 +335,10 @@ static int completionColumn( sqlite3_result_text(ctx, pCur->zLine, -1, SQLITE_TRANSIENT); break; } + case COMPLETION_COLUMN_PHASE: { + sqlite3_result_int(ctx, pCur->ePhase); + break; + } } return SQLITE_OK; } diff --git a/manifest b/manifest index 2900651ce0..c66c5490f5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\sCOMPLETION\svirtual\stable\snow\slooks\sat\sthe\snames\sof\sdatabases,\stables,\nand\scolumns\sin\saddition\sto\sSQL\skeywords. -D 2017-07-11T01:38:45.049 +C Add\sthe\s"phase"\soutput\scolumn\son\sthe\sCOMPLETION\stable-valued\sfunction,\sfor\ndebugging.\s\sImproved\scomments\son\sthe\simplementation. +D 2017-07-11T02:05:21.668 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba @@ -256,7 +256,7 @@ F ext/misc/amatch.c 6db4607cb17c54b853a2d7c7c36046d004853f65b9b733e6f019d543d5df F ext/misc/anycollseq.c 5ffdfde9829eeac52219136ad6aa7cd9a4edb3b15f4f2532de52f4a22525eddb F ext/misc/carray.c 40c27641010a4dc67e3690bdb7c9d36ca58b3c2d F ext/misc/closure.c 0d2a038df8fbae7f19de42e7c7d71f2e4dc88704 -F ext/misc/completion.c 813c7faecc8fe3dd5c5503b87d4bb44ed6b841ff3398d19fbccec251da0af25f +F ext/misc/completion.c 637c016977809c2c3174472e7a416c9dbefc89dadb0efbd33f1516114b43900e F ext/misc/compress.c 122faa92d25033d6c3f07c39231de074ab3d2e83 F ext/misc/csv.c d91c0388445b08f6e373dd0e8fc024d4551b1fcaf64e876a1c3f4fac8a63adc2 F ext/misc/dbdump.c 3509fa6b8932d04e932d6b6b827b6a82ca362781b8e8f3c77336f416793e215e @@ -1629,7 +1629,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P caefbc723b5f67afc5ef10b92b20400cbb76cb03e7e75e18d2726cc552083e09 -R 1115796824efacad1a0f50faf8b6a73d +P 1cc97711fa86a3938f0930200476d1b0991e4b893a8be3a19015423a3de56bef +R 5f96666448f8bc2a00b6b737201e92f6 U drh -Z e368c5a978df04c5e378d21fe41e060f +Z 37fc96f83608b2443df93123a3a88569 diff --git a/manifest.uuid b/manifest.uuid index d37dfde610..48e5077089 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1cc97711fa86a3938f0930200476d1b0991e4b893a8be3a19015423a3de56bef \ No newline at end of file +0e2135552757cc6566ac959475d3b87254b6d462425ee6c457c743001f3370e2 \ No newline at end of file From e2b01012bc219d32df2cdc6888218ec645defdd3 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 11 Jul 2017 02:53:38 +0000 Subject: [PATCH 47/64] Fix a backup2 test case so that it works on FreeBSD. FossilOrigin-Name: 724819b456ca7a5ca6d68415b3b3554741c3ddbb5c416cb6b6b5fc54177f426e --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/backup2.test | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index c66c5490f5..401cb7c0e4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s"phase"\soutput\scolumn\son\sthe\sCOMPLETION\stable-valued\sfunction,\sfor\ndebugging.\s\sImproved\scomments\son\sthe\simplementation. -D 2017-07-11T02:05:21.668 +C Fix\sa\sbackup2\stest\scase\sso\sthat\sit\sworks\son\sFreeBSD. +D 2017-07-11T02:53:38.630 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba @@ -588,7 +588,7 @@ F test/autovacuum_ioerr2.test 8a367b224183ad801e0e24dcb7d1501f45f244b4 F test/avtrans.test 0252654f4295ddda3b2cce0e894812259e655a85 F test/backcompat.test 3e64cedda754c778ef6bbe417b6e7a295e662a4d F test/backup.test dd4a5ff756e3df3931dacb1791db0584d4bad989 -F test/backup2.test 24e84f0b2b43199f5aed49ef8a43183bfc550de5772162ed7721223dbdf56b4e +F test/backup2.test 1fd1ad8c5b3d2d5b9c0cce4143a4fc610d51ddc6ae16a7a122973d43e6b50bbd F test/backup4.test 8f6fd48e0dfde77b9a3bb26dc471ede3e101df32 F test/backup5.test ee5da6d7fe5082f5b9b0bbfa31d016f52412a2e4 F test/backup_ioerr.test 4c3c7147cee85b024ecf6e150e090c32fdbb5135 @@ -1629,7 +1629,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1cc97711fa86a3938f0930200476d1b0991e4b893a8be3a19015423a3de56bef -R 5f96666448f8bc2a00b6b737201e92f6 +P 0e2135552757cc6566ac959475d3b87254b6d462425ee6c457c743001f3370e2 +R 07f4dd76f51d4ef1e51aa1dac340573b U drh -Z 37fc96f83608b2443df93123a3a88569 +Z 31bd69a2dcea4c4a51c6ef1c3a8fdda1 diff --git a/manifest.uuid b/manifest.uuid index 48e5077089..0b57405b23 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0e2135552757cc6566ac959475d3b87254b6d462425ee6c457c743001f3370e2 \ No newline at end of file +724819b456ca7a5ca6d68415b3b3554741c3ddbb5c416cb6b6b5fc54177f426e \ No newline at end of file diff --git a/test/backup2.test b/test/backup2.test index ad2d9a491b..b58c6a3cd3 100644 --- a/test/backup2.test +++ b/test/backup2.test @@ -143,7 +143,7 @@ do_test backup2-9 { # if {$tcl_platform(platform)=="windows"} { set msg {cannot open source database: unable to open database file} -} elseif {$tcl_platform(os)=="OpenBSD"} { +} elseif {[string match *BSD $tcl_platform(os)]} { set msg {restore failed: file is not a database} } else { set msg {cannot open source database: disk I/O error} From 2ce15c3f4c909028c17a9e43ef99c89cea11a1bc Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 11 Jul 2017 13:34:40 +0000 Subject: [PATCH 48/64] Change the src/shell.c file so that it is generated from a new script at tool/mkshellc.tcl and the template file src/shell.c.in, and automatically includes the extensions it needs out of ext/misc. FossilOrigin-Name: 17e0bb12d82b510b86b6886b9fd0faf39b60b1374027344f89d7b89a32b842b9 --- manifest | 14 +- manifest.uuid | 2 +- src/shell.c | 279 +- src/shell.c.in | 6968 +++++++++++++++++++++++++++++++++++++++++++++ tool/mkshellc.tcl | 46 + 5 files changed, 7225 insertions(+), 84 deletions(-) create mode 100644 src/shell.c.in create mode 100644 tool/mkshellc.tcl diff --git a/manifest b/manifest index 401cb7c0e4..056c17b447 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sbackup2\stest\scase\sso\sthat\sit\sworks\son\sFreeBSD. -D 2017-07-11T02:53:38.630 +C Change\sthe\ssrc/shell.c\sfile\sso\sthat\sit\sis\sgenerated\sfrom\sa\snew\sscript\sat\ntool/mkshellc.tcl\sand\sthe\stemplate\sfile\ssrc/shell.c.in,\sand\sautomatically\nincludes\sthe\sextensions\sit\sneeds\sout\sof\sext/misc. +D 2017-07-11T13:34:40.462 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba @@ -450,7 +450,8 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 6aa1fb1212e601f65b983ee1215d69a591986c8f97a3805c425c625a53839539 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 6aa7e8ee53dcb9d0b77b05670bb44a1076d6747bc9b2c1f12a365b553ab6c828 -F src/shell.c c042ed1f74e80097f7a322bb05457d65c20e1df43459f065f76ad886da7331e0 +F src/shell.c 71a338b3a29502a4a7290fa646bc4547d911777aba55ebc040b5940786435833 +F src/shell.c.in 9d75c83c13fb1b96e60c56cce96146d84c4c8b3d18d11bd85e0759ebf744bcb2 F src/sqlite.h.in 03a422ba13da1dfef7f1aaa1ba344acf18dc867112620b1fdb2a1426cabba634 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 58fd0676d3111d02e62e5a35992a7d3da5d3f88753acc174f2d37b774fbbdd28 @@ -1568,6 +1569,7 @@ F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c F tool/mkopcodeh.tcl a01d2c1d8a6205b03fc635adf3735b4c523befd3 F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e F tool/mkpragmatab.tcl 2144bc8550a6471a029db262a132d2df4b9e0db61b90398bf64f5b7b3f8d92cd +F tool/mkshellc.tcl 69c38ecd7b74b2b0799a35ce20e1e3998e504d8c99c100ca4b98ae9d8f6279bc F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl fef88397668ae83166735c41af99d79f56afaabb F tool/mksqlite3c.tcl f6214285bec900d28441366ca31af327aade18bbc424b0480497966ec05bc43c @@ -1629,7 +1631,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0e2135552757cc6566ac959475d3b87254b6d462425ee6c457c743001f3370e2 -R 07f4dd76f51d4ef1e51aa1dac340573b +P 724819b456ca7a5ca6d68415b3b3554741c3ddbb5c416cb6b6b5fc54177f426e +R 60a762ef308a5ae7a380cb2ce07b0a0c U drh -Z 31bd69a2dcea4c4a51c6ef1c3a8fdda1 +Z 1a54bd7eb9eb8ff312901d65383e16cf diff --git a/manifest.uuid b/manifest.uuid index 0b57405b23..b24374cf1b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -724819b456ca7a5ca6d68415b3b3554741c3ddbb5c416cb6b6b5fc54177f426e \ No newline at end of file +17e0bb12d82b510b86b6886b9fd0faf39b60b1374027344f89d7b89a32b842b9 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index c2c0d68c68..8a10fc02b6 100644 --- a/src/shell.c +++ b/src/shell.c @@ -1,3 +1,21 @@ +/* DO NOT EDIT! +** This file is automatically generated by the script in the canonical +** SQLite source tree at tool/mkshellc.tcl. That script combines source +** code from various constituent source files of SQLite into this single +** "shell.c" file used to implement the SQLite command-line shell. +** +** Most of the code found below comes from the "src/shell.c.in" file in +** the canonical SQLite source tree. That main file contains "INCLUDE" +** lines that specify other files in the canonical source tree that are +** inserted to getnerate this complete program source file. +** +** The code from multiple files is combined into this single "shell.c" +** source file to help make the command-line program easier to compile. +** +** To modify this program, get a copy of the canonical SQLite source tree, +** edit the src/shell.c.in" and/or some of the other files that are included +** by "src/shell.c.in", then rerun the tool/mkshellc.tcl script. +*/ /* ** 2001 September 15 ** @@ -784,10 +802,53 @@ static void shellAddSchemaName( sqlite3_result_value(pCtx, apVal[0]); } -/****************************************************************************** -** SHA3 hash implementation copied from ../ext/misc/shathree.c +/* +** The source code for several run-time loadable extensions is inserted +** below by the ../tool/mkshellc.tcl script. Before processing that included +** code, we need to override some macros to make the included program code +** work here in the middle of this regular program. */ +#define SQLITE_EXTENSION_INIT1 +#define SQLITE_EXTENSION_INIT2(X) + +/************************* Begin ../ext/misc/shathree.c ******************/ +/* +** 2017-03-08 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This SQLite extension implements a functions that compute SHA1 hashes. +** Two SQL functions are implemented: +** +** sha3(X,SIZE) +** sha3_query(Y,SIZE) +** +** The sha3(X) function computes the SHA3 hash of the input X, or NULL if +** X is NULL. +** +** The sha3_query(Y) function evalutes all queries in the SQL statements of Y +** and returns a hash of their results. +** +** The SIZE argument is optional. If omitted, the SHA3-256 hash algorithm +** is used. If SIZE is included it must be one of the integers 224, 256, +** 384, or 512, to determine SHA3 hash variant that is computed. +*/ +SQLITE_EXTENSION_INIT1 +#include +#include +#include typedef sqlite3_uint64 u64; + +/****************************************************************************** +** The Hash Engine +*/ /* ** Macros to determine whether the machine is big or little endian, ** and whether or not that determination is run-time or compile-time. @@ -825,10 +886,6 @@ struct SHA3Context { unsigned ixMask; /* Insert next input into u.x[nLoaded^ixMask]. */ }; -/* Allow the following routine to use the B0 variable, which is also -** a macro in the termios.h header file */ -#undef B0 - /* ** A single step of the Keccak mixing function for a 1600-bit state */ @@ -1239,12 +1296,14 @@ static unsigned char *SHA3Final(SHA3Context *p){ } return &p->u.x[p->nRate]; } +/* End of the hashing logic +*****************************************************************************/ /* ** Implementation of the sha3(X,SIZE) function. ** ** Return a BLOB which is the SIZE-bit SHA3 hash of X. The default -** size is 256. If X is a BLOB, it is hashed as is. +** size is 256. If X is a BLOB, it is hashed as is. ** For all other non-NULL types of input, X is converted into a UTF-8 string ** and the string is hashed without the trailing 0x00 terminator. The hash ** of a NULL value is NULL. @@ -1375,10 +1434,6 @@ static void sha3QueryFunc( } nCol = sqlite3_column_count(pStmt); z = sqlite3_sql(pStmt); - if( z==0 ){ - sqlite3_finalize(pStmt); - continue; - } n = (int)strlen(z); hash_step_vformat(&cx,"S%d:",n); SHA3Update(&cx,(unsigned char*)z,n); @@ -1441,8 +1496,139 @@ static void sha3QueryFunc( } sqlite3_result_blob(context, SHA3Final(&cx), iSize/8, SQLITE_TRANSIENT); } -/* End of SHA3 hashing logic copy/pasted from ../ext/misc/shathree.c -********************************************************************************/ + + +#ifdef _WIN32 +__declspec(dllexport) +#endif +int sqlite3_shathree_init( + sqlite3 *db, + char **pzErrMsg, + const sqlite3_api_routines *pApi +){ + int rc = SQLITE_OK; + SQLITE_EXTENSION_INIT2(pApi); + (void)pzErrMsg; /* Unused parameter */ + rc = sqlite3_create_function(db, "sha3", 1, SQLITE_UTF8, 0, + sha3Func, 0, 0); + if( rc==SQLITE_OK ){ + rc = sqlite3_create_function(db, "sha3", 2, SQLITE_UTF8, 0, + sha3Func, 0, 0); + } + if( rc==SQLITE_OK ){ + rc = sqlite3_create_function(db, "sha3_query", 1, SQLITE_UTF8, 0, + sha3QueryFunc, 0, 0); + } + if( rc==SQLITE_OK ){ + rc = sqlite3_create_function(db, "sha3_query", 2, SQLITE_UTF8, 0, + sha3QueryFunc, 0, 0); + } + return rc; +} + +/************************* End ../ext/misc/shathree.c ********************/ +/************************* Begin ../ext/misc/fileio.c ******************/ +/* +** 2014-06-13 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This SQLite extension implements SQL functions readfile() and +** writefile(). +*/ +SQLITE_EXTENSION_INIT1 +#include + +/* +** Implementation of the "readfile(X)" SQL function. The entire content +** of the file named X is read and returned as a BLOB. NULL is returned +** if the file does not exist or is unreadable. +*/ +static void readfileFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const char *zName; + FILE *in; + long nIn; + void *pBuf; + + zName = (const char*)sqlite3_value_text(argv[0]); + if( zName==0 ) return; + in = fopen(zName, "rb"); + if( in==0 ) return; + fseek(in, 0, SEEK_END); + nIn = ftell(in); + rewind(in); + pBuf = sqlite3_malloc( nIn ); + if( pBuf && 1==fread(pBuf, nIn, 1, in) ){ + sqlite3_result_blob(context, pBuf, nIn, sqlite3_free); + }else{ + sqlite3_free(pBuf); + } + fclose(in); +} + +/* +** Implementation of the "writefile(X,Y)" SQL function. The argument Y +** is written into file X. The number of bytes written is returned. Or +** NULL is returned if something goes wrong, such as being unable to open +** file X for writing. +*/ +static void writefileFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + FILE *out; + const char *z; + sqlite3_int64 rc; + const char *zFile; + + zFile = (const char*)sqlite3_value_text(argv[0]); + if( zFile==0 ) return; + out = fopen(zFile, "wb"); + if( out==0 ) return; + z = (const char*)sqlite3_value_blob(argv[1]); + if( z==0 ){ + rc = 0; + }else{ + rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out); + } + fclose(out); + sqlite3_result_int64(context, rc); +} + + +#ifdef _WIN32 +__declspec(dllexport) +#endif +int sqlite3_fileio_init( + sqlite3 *db, + char **pzErrMsg, + const sqlite3_api_routines *pApi +){ + int rc = SQLITE_OK; + SQLITE_EXTENSION_INIT2(pApi); + (void)pzErrMsg; /* Unused parameter */ + rc = sqlite3_create_function(db, "readfile", 1, SQLITE_UTF8, 0, + readfileFunc, 0, 0); + if( rc==SQLITE_OK ){ + rc = sqlite3_create_function(db, "writefile", 2, SQLITE_UTF8, 0, + writefileFunc, 0, 0); + } + return rc; +} + +/************************* End ../ext/misc/fileio.c ********************/ #if defined(SQLITE_ENABLE_SESSION) /* @@ -3471,58 +3657,6 @@ static char *readFile(const char *zName, int *pnByte){ return pBuf; } -/* -** Implementation of the "readfile(X)" SQL function. The entire content -** of the file named X is read and returned as a BLOB. NULL is returned -** if the file does not exist or is unreadable. -*/ -static void readfileFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - const char *zName; - void *pBuf; - int nBuf; - - UNUSED_PARAMETER(argc); - zName = (const char*)sqlite3_value_text(argv[0]); - if( zName==0 ) return; - pBuf = readFile(zName, &nBuf); - if( pBuf ) sqlite3_result_blob(context, pBuf, nBuf, sqlite3_free); -} - -/* -** Implementation of the "writefile(X,Y)" SQL function. The argument Y -** is written into file X. The number of bytes written is returned. Or -** NULL is returned if something goes wrong, such as being unable to open -** file X for writing. -*/ -static void writefileFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - FILE *out; - const char *z; - sqlite3_int64 rc; - const char *zFile; - - UNUSED_PARAMETER(argc); - zFile = (const char*)sqlite3_value_text(argv[0]); - if( zFile==0 ) return; - out = fopen(zFile, "wb"); - if( out==0 ) return; - z = (const char*)sqlite3_value_blob(argv[1]); - if( z==0 ){ - rc = 0; - }else{ - rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out); - } - fclose(out); - sqlite3_result_int64(context, rc); -} - #if defined(SQLITE_ENABLE_SESSION) /* ** Close a single OpenSession object and release all of its associated @@ -3588,18 +3722,8 @@ static void open_db(ShellState *p, int keepAlive){ #ifndef SQLITE_OMIT_LOAD_EXTENSION sqlite3_enable_load_extension(p->db, 1); #endif - sqlite3_create_function(p->db, "readfile", 1, SQLITE_UTF8, 0, - readfileFunc, 0, 0); - sqlite3_create_function(p->db, "writefile", 2, SQLITE_UTF8, 0, - writefileFunc, 0, 0); - sqlite3_create_function(p->db, "sha3", 1, SQLITE_UTF8, 0, - sha3Func, 0, 0); - sqlite3_create_function(p->db, "sha3", 2, SQLITE_UTF8, 0, - sha3Func, 0, 0); - sqlite3_create_function(p->db, "sha3_query", 1, SQLITE_UTF8, 0, - sha3QueryFunc, 0, 0); - sqlite3_create_function(p->db, "sha3_query", 2, SQLITE_UTF8, 0, - sha3QueryFunc, 0, 0); + sqlite3_fileio_init(p->db, 0, 0); + sqlite3_shathree_init(p->db, 0, 0); sqlite3_create_function(p->db, "shell_add_schema", 2, SQLITE_UTF8, 0, shellAddSchemaName, 0, 0); @@ -7676,3 +7800,4 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ #endif return rc; } + diff --git a/src/shell.c.in b/src/shell.c.in new file mode 100644 index 0000000000..70d6c0e5e7 --- /dev/null +++ b/src/shell.c.in @@ -0,0 +1,6968 @@ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains code to implement the "sqlite" command line +** utility for accessing SQLite databases. +*/ +#if (defined(_WIN32) || defined(WIN32)) && !defined(_CRT_SECURE_NO_WARNINGS) +/* This needs to come before any includes for MSVC compiler */ +#define _CRT_SECURE_NO_WARNINGS +#endif + +/* +** Warning pragmas copied from msvc.h in the core. +*/ +#if defined(_MSC_VER) +#pragma warning(disable : 4054) +#pragma warning(disable : 4055) +#pragma warning(disable : 4100) +#pragma warning(disable : 4127) +#pragma warning(disable : 4130) +#pragma warning(disable : 4152) +#pragma warning(disable : 4189) +#pragma warning(disable : 4206) +#pragma warning(disable : 4210) +#pragma warning(disable : 4232) +#pragma warning(disable : 4244) +#pragma warning(disable : 4305) +#pragma warning(disable : 4306) +#pragma warning(disable : 4702) +#pragma warning(disable : 4706) +#endif /* defined(_MSC_VER) */ + +/* +** No support for loadable extensions in VxWorks. +*/ +#if (defined(__RTP__) || defined(_WRS_KERNEL)) && !SQLITE_OMIT_LOAD_EXTENSION +# define SQLITE_OMIT_LOAD_EXTENSION 1 +#endif + +/* +** Enable large-file support for fopen() and friends on unix. +*/ +#ifndef SQLITE_DISABLE_LFS +# define _LARGE_FILE 1 +# ifndef _FILE_OFFSET_BITS +# define _FILE_OFFSET_BITS 64 +# endif +# define _LARGEFILE_SOURCE 1 +#endif + +#include +#include +#include +#include +#include "sqlite3.h" +#if SQLITE_USER_AUTHENTICATION +# include "sqlite3userauth.h" +#endif +#include +#include + +#if !defined(_WIN32) && !defined(WIN32) +# include +# if !defined(__RTP__) && !defined(_WRS_KERNEL) +# include +# endif +# include +# include +#endif + +#if HAVE_READLINE +# include +# include +#endif + +#if HAVE_EDITLINE +# include +#endif + +#if HAVE_EDITLINE || HAVE_READLINE + +# define shell_add_history(X) add_history(X) +# define shell_read_history(X) read_history(X) +# define shell_write_history(X) write_history(X) +# define shell_stifle_history(X) stifle_history(X) +# define shell_readline(X) readline(X) + +#elif HAVE_LINENOISE + +# include "linenoise.h" +# define shell_add_history(X) linenoiseHistoryAdd(X) +# define shell_read_history(X) linenoiseHistoryLoad(X) +# define shell_write_history(X) linenoiseHistorySave(X) +# define shell_stifle_history(X) linenoiseHistorySetMaxLen(X) +# define shell_readline(X) linenoise(X) + +#else + +# define shell_read_history(X) +# define shell_write_history(X) +# define shell_stifle_history(X) + +# define SHELL_USE_LOCAL_GETLINE 1 +#endif + + +#if defined(_WIN32) || defined(WIN32) +# include +# include +# define isatty(h) _isatty(h) +# ifndef access +# define access(f,m) _access((f),(m)) +# endif +# undef popen +# define popen _popen +# undef pclose +# define pclose _pclose +#else + /* Make sure isatty() has a prototype. */ + extern int isatty(int); + +# if !defined(__RTP__) && !defined(_WRS_KERNEL) + /* popen and pclose are not C89 functions and so are + ** sometimes omitted from the header */ + extern FILE *popen(const char*,const char*); + extern int pclose(FILE*); +# else +# define SQLITE_OMIT_POPEN 1 +# endif +#endif + +#if defined(_WIN32_WCE) +/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty() + * thus we always assume that we have a console. That can be + * overridden with the -batch command line option. + */ +#define isatty(x) 1 +#endif + +/* ctype macros that work with signed characters */ +#define IsSpace(X) isspace((unsigned char)X) +#define IsDigit(X) isdigit((unsigned char)X) +#define ToLower(X) (char)tolower((unsigned char)X) + +#if defined(_WIN32) || defined(WIN32) +#include + +/* string conversion routines only needed on Win32 */ +extern char *sqlite3_win32_unicode_to_utf8(LPCWSTR); +extern char *sqlite3_win32_mbcs_to_utf8_v2(const char *, int); +extern char *sqlite3_win32_utf8_to_mbcs_v2(const char *, int); +extern LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText); +#endif + +/* On Windows, we normally run with output mode of TEXT so that \n characters +** are automatically translated into \r\n. However, this behavior needs +** to be disabled in some cases (ex: when generating CSV output and when +** rendering quoted strings that contain \n characters). The following +** routines take care of that. +*/ +#if defined(_WIN32) || defined(WIN32) +static void setBinaryMode(FILE *file, int isOutput){ + if( isOutput ) fflush(file); + _setmode(_fileno(file), _O_BINARY); +} +static void setTextMode(FILE *file, int isOutput){ + if( isOutput ) fflush(file); + _setmode(_fileno(file), _O_TEXT); +} +#else +# define setBinaryMode(X,Y) +# define setTextMode(X,Y) +#endif + + +/* True if the timer is enabled */ +static int enableTimer = 0; + +/* Return the current wall-clock time */ +static sqlite3_int64 timeOfDay(void){ + static sqlite3_vfs *clockVfs = 0; + sqlite3_int64 t; + if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0); + if( clockVfs->iVersion>=2 && clockVfs->xCurrentTimeInt64!=0 ){ + clockVfs->xCurrentTimeInt64(clockVfs, &t); + }else{ + double r; + clockVfs->xCurrentTime(clockVfs, &r); + t = (sqlite3_int64)(r*86400000.0); + } + return t; +} + +#if !defined(_WIN32) && !defined(WIN32) && !defined(__minux) +#include +#include + +/* VxWorks does not support getrusage() as far as we can determine */ +#if defined(_WRS_KERNEL) || defined(__RTP__) +struct rusage { + struct timeval ru_utime; /* user CPU time used */ + struct timeval ru_stime; /* system CPU time used */ +}; +#define getrusage(A,B) memset(B,0,sizeof(*B)) +#endif + +/* Saved resource information for the beginning of an operation */ +static struct rusage sBegin; /* CPU time at start */ +static sqlite3_int64 iBegin; /* Wall-clock time at start */ + +/* +** Begin timing an operation +*/ +static void beginTimer(void){ + if( enableTimer ){ + getrusage(RUSAGE_SELF, &sBegin); + iBegin = timeOfDay(); + } +} + +/* Return the difference of two time_structs in seconds */ +static double timeDiff(struct timeval *pStart, struct timeval *pEnd){ + return (pEnd->tv_usec - pStart->tv_usec)*0.000001 + + (double)(pEnd->tv_sec - pStart->tv_sec); +} + +/* +** Print the timing results. +*/ +static void endTimer(void){ + if( enableTimer ){ + sqlite3_int64 iEnd = timeOfDay(); + struct rusage sEnd; + getrusage(RUSAGE_SELF, &sEnd); + printf("Run Time: real %.3f user %f sys %f\n", + (iEnd - iBegin)*0.001, + timeDiff(&sBegin.ru_utime, &sEnd.ru_utime), + timeDiff(&sBegin.ru_stime, &sEnd.ru_stime)); + } +} + +#define BEGIN_TIMER beginTimer() +#define END_TIMER endTimer() +#define HAS_TIMER 1 + +#elif (defined(_WIN32) || defined(WIN32)) + +/* Saved resource information for the beginning of an operation */ +static HANDLE hProcess; +static FILETIME ftKernelBegin; +static FILETIME ftUserBegin; +static sqlite3_int64 ftWallBegin; +typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME, + LPFILETIME, LPFILETIME); +static GETPROCTIMES getProcessTimesAddr = NULL; + +/* +** Check to see if we have timer support. Return 1 if necessary +** support found (or found previously). +*/ +static int hasTimer(void){ + if( getProcessTimesAddr ){ + return 1; + } else { + /* GetProcessTimes() isn't supported in WIN95 and some other Windows + ** versions. See if the version we are running on has it, and if it + ** does, save off a pointer to it and the current process handle. + */ + hProcess = GetCurrentProcess(); + if( hProcess ){ + HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll")); + if( NULL != hinstLib ){ + getProcessTimesAddr = + (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes"); + if( NULL != getProcessTimesAddr ){ + return 1; + } + FreeLibrary(hinstLib); + } + } + } + return 0; +} + +/* +** Begin timing an operation +*/ +static void beginTimer(void){ + if( enableTimer && getProcessTimesAddr ){ + FILETIME ftCreation, ftExit; + getProcessTimesAddr(hProcess,&ftCreation,&ftExit, + &ftKernelBegin,&ftUserBegin); + ftWallBegin = timeOfDay(); + } +} + +/* Return the difference of two FILETIME structs in seconds */ +static double timeDiff(FILETIME *pStart, FILETIME *pEnd){ + sqlite_int64 i64Start = *((sqlite_int64 *) pStart); + sqlite_int64 i64End = *((sqlite_int64 *) pEnd); + return (double) ((i64End - i64Start) / 10000000.0); +} + +/* +** Print the timing results. +*/ +static void endTimer(void){ + if( enableTimer && getProcessTimesAddr){ + FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd; + sqlite3_int64 ftWallEnd = timeOfDay(); + getProcessTimesAddr(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd); + printf("Run Time: real %.3f user %f sys %f\n", + (ftWallEnd - ftWallBegin)*0.001, + timeDiff(&ftUserBegin, &ftUserEnd), + timeDiff(&ftKernelBegin, &ftKernelEnd)); + } +} + +#define BEGIN_TIMER beginTimer() +#define END_TIMER endTimer() +#define HAS_TIMER hasTimer() + +#else +#define BEGIN_TIMER +#define END_TIMER +#define HAS_TIMER 0 +#endif + +/* +** Used to prevent warnings about unused parameters +*/ +#define UNUSED_PARAMETER(x) (void)(x) + +/* +** If the following flag is set, then command execution stops +** at an error if we are not interactive. +*/ +static int bail_on_error = 0; + +/* +** Threat stdin as an interactive input if the following variable +** is true. Otherwise, assume stdin is connected to a file or pipe. +*/ +static int stdin_is_interactive = 1; + +/* +** On Windows systems we have to know if standard output is a console +** in order to translate UTF-8 into MBCS. The following variable is +** true if translation is required. +*/ +static int stdout_is_console = 1; + +/* +** The following is the open SQLite database. We make a pointer +** to this database a static variable so that it can be accessed +** by the SIGINT handler to interrupt database processing. +*/ +static sqlite3 *globalDb = 0; + +/* +** True if an interrupt (Control-C) has been received. +*/ +static volatile int seenInterrupt = 0; + +/* +** This is the name of our program. It is set in main(), used +** in a number of other places, mostly for error messages. +*/ +static char *Argv0; + +/* +** Prompt strings. Initialized in main. Settable with +** .prompt main continue +*/ +static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/ +static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */ + +/* +** Render output like fprintf(). Except, if the output is going to the +** console and if this is running on a Windows machine, translate the +** output from UTF-8 into MBCS. +*/ +#if defined(_WIN32) || defined(WIN32) +void utf8_printf(FILE *out, const char *zFormat, ...){ + va_list ap; + va_start(ap, zFormat); + if( stdout_is_console && (out==stdout || out==stderr) ){ + char *z1 = sqlite3_vmprintf(zFormat, ap); + char *z2 = sqlite3_win32_utf8_to_mbcs_v2(z1, 0); + sqlite3_free(z1); + fputs(z2, out); + sqlite3_free(z2); + }else{ + vfprintf(out, zFormat, ap); + } + va_end(ap); +} +#elif !defined(utf8_printf) +# define utf8_printf fprintf +#endif + +/* +** Render output like fprintf(). This should not be used on anything that +** includes string formatting (e.g. "%s"). +*/ +#if !defined(raw_printf) +# define raw_printf fprintf +#endif + +/* +** Write I/O traces to the following stream. +*/ +#ifdef SQLITE_ENABLE_IOTRACE +static FILE *iotrace = 0; +#endif + +/* +** This routine works like printf in that its first argument is a +** format string and subsequent arguments are values to be substituted +** in place of % fields. The result of formatting this string +** is written to iotrace. +*/ +#ifdef SQLITE_ENABLE_IOTRACE +static void SQLITE_CDECL iotracePrintf(const char *zFormat, ...){ + va_list ap; + char *z; + if( iotrace==0 ) return; + va_start(ap, zFormat); + z = sqlite3_vmprintf(zFormat, ap); + va_end(ap); + utf8_printf(iotrace, "%s", z); + sqlite3_free(z); +} +#endif + +/* +** Output string zUtf to stream pOut as w characters. If w is negative, +** then right-justify the text. W is the width in UTF-8 characters, not +** in bytes. This is different from the %*.*s specification in printf +** since with %*.*s the width is measured in bytes, not characters. +*/ +static void utf8_width_print(FILE *pOut, int w, const char *zUtf){ + int i; + int n; + int aw = w<0 ? -w : w; + char zBuf[1000]; + if( aw>(int)sizeof(zBuf)/3 ) aw = (int)sizeof(zBuf)/3; + for(i=n=0; zUtf[i]; i++){ + if( (zUtf[i]&0xc0)!=0x80 ){ + n++; + if( n==aw ){ + do{ i++; }while( (zUtf[i]&0xc0)==0x80 ); + break; + } + } + } + if( n>=aw ){ + utf8_printf(pOut, "%.*s", i, zUtf); + }else if( w<0 ){ + utf8_printf(pOut, "%*s%s", aw-n, "", zUtf); + }else{ + utf8_printf(pOut, "%s%*s", zUtf, aw-n, ""); + } +} + + +/* +** Determines if a string is a number of not. +*/ +static int isNumber(const char *z, int *realnum){ + if( *z=='-' || *z=='+' ) z++; + if( !IsDigit(*z) ){ + return 0; + } + z++; + if( realnum ) *realnum = 0; + while( IsDigit(*z) ){ z++; } + if( *z=='.' ){ + z++; + if( !IsDigit(*z) ) return 0; + while( IsDigit(*z) ){ z++; } + if( realnum ) *realnum = 1; + } + if( *z=='e' || *z=='E' ){ + z++; + if( *z=='+' || *z=='-' ) z++; + if( !IsDigit(*z) ) return 0; + while( IsDigit(*z) ){ z++; } + if( realnum ) *realnum = 1; + } + return *z==0; +} + +/* +** Compute a string length that is limited to what can be stored in +** lower 30 bits of a 32-bit signed integer. +*/ +static int strlen30(const char *z){ + const char *z2 = z; + while( *z2 ){ z2++; } + return 0x3fffffff & (int)(z2 - z); +} + +/* +** Return the length of a string in characters. Multibyte UTF8 characters +** count as a single character. +*/ +static int strlenChar(const char *z){ + int n = 0; + while( *z ){ + if( (0xc0&*(z++))!=0x80 ) n++; + } + return n; +} + +/* +** This routine reads a line of text from FILE in, stores +** the text in memory obtained from malloc() and returns a pointer +** to the text. NULL is returned at end of file, or if malloc() +** fails. +** +** If zLine is not NULL then it is a malloced buffer returned from +** a previous call to this routine that may be reused. +*/ +static char *local_getline(char *zLine, FILE *in){ + int nLine = zLine==0 ? 0 : 100; + int n = 0; + + while( 1 ){ + if( n+100>nLine ){ + nLine = nLine*2 + 100; + zLine = realloc(zLine, nLine); + if( zLine==0 ) return 0; + } + if( fgets(&zLine[n], nLine - n, in)==0 ){ + if( n==0 ){ + free(zLine); + return 0; + } + zLine[n] = 0; + break; + } + while( zLine[n] ) n++; + if( n>0 && zLine[n-1]=='\n' ){ + n--; + if( n>0 && zLine[n-1]=='\r' ) n--; + zLine[n] = 0; + break; + } + } +#if defined(_WIN32) || defined(WIN32) + /* For interactive input on Windows systems, translate the + ** multi-byte characterset characters into UTF-8. */ + if( stdin_is_interactive && in==stdin ){ + char *zTrans = sqlite3_win32_mbcs_to_utf8_v2(zLine, 0); + if( zTrans ){ + int nTrans = strlen30(zTrans)+1; + if( nTrans>nLine ){ + zLine = realloc(zLine, nTrans); + if( zLine==0 ){ + sqlite3_free(zTrans); + return 0; + } + } + memcpy(zLine, zTrans, nTrans); + sqlite3_free(zTrans); + } + } +#endif /* defined(_WIN32) || defined(WIN32) */ + return zLine; +} + +/* +** Retrieve a single line of input text. +** +** If in==0 then read from standard input and prompt before each line. +** 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(FILE *in, char *zPrior, int isContinuation){ + char *zPrompt; + char *zResult; + if( in!=0 ){ + zResult = local_getline(zPrior, in); + }else{ + zPrompt = isContinuation ? continuePrompt : mainPrompt; +#if SHELL_USE_LOCAL_GETLINE + printf("%s", zPrompt); + fflush(stdout); + zResult = local_getline(zPrior, stdin); +#else + free(zPrior); + zResult = shell_readline(zPrompt); + if( zResult && *zResult ) shell_add_history(zResult); +#endif + } + return zResult; +} +/* +** A variable length string to which one can append text. +*/ +typedef struct ShellText ShellText; +struct ShellText { + char *z; + int n; + int nAlloc; +}; + +/* +** Initialize and destroy a ShellText object +*/ +static void initText(ShellText *p){ + memset(p, 0, sizeof(*p)); +} +static void freeText(ShellText *p){ + free(p->z); + initText(p); +} + +/* zIn is either a pointer to a NULL-terminated string in memory obtained +** from malloc(), or a NULL pointer. The string pointed to by zAppend is +** added to zIn, and the result returned in memory obtained from malloc(). +** zIn, if it was not NULL, is freed. +** +** If the third argument, quote, is not '\0', then it is used as a +** quote character for zAppend. +*/ +static void appendText(ShellText *p, char const *zAppend, char quote){ + int len; + int i; + int nAppend = strlen30(zAppend); + + len = nAppend+p->n+1; + if( quote ){ + len += 2; + for(i=0; in+len>=p->nAlloc ){ + p->nAlloc = p->nAlloc*2 + len + 20; + p->z = realloc(p->z, p->nAlloc); + if( p->z==0 ){ + memset(p, 0, sizeof(*p)); + return; + } + } + + if( quote ){ + char *zCsr = p->z+p->n; + *zCsr++ = quote; + for(i=0; in = (int)(zCsr - p->z); + *zCsr = '\0'; + }else{ + memcpy(p->z+p->n, zAppend, nAppend); + p->n += nAppend; + p->z[p->n] = '\0'; + } +} + +/* +** Attempt to determine if identifier zName needs to be quoted, either +** because it contains non-alphanumeric characters, or because it is an +** SQLite keyword. Be conservative in this estimate: When in doubt assume +** that quoting is required. +** +** Return '"' if quoting is required. Return 0 if no quoting is required. +*/ +static char quoteChar(const char *zName){ + /* All SQLite keywords, in alphabetical order */ + static const char *azKeywords[] = { + "ABORT", "ACTION", "ADD", "AFTER", "ALL", "ALTER", "ANALYZE", "AND", "AS", + "ASC", "ATTACH", "AUTOINCREMENT", "BEFORE", "BEGIN", "BETWEEN", "BY", + "CASCADE", "CASE", "CAST", "CHECK", "COLLATE", "COLUMN", "COMMIT", + "CONFLICT", "CONSTRAINT", "CREATE", "CROSS", "CURRENT_DATE", + "CURRENT_TIME", "CURRENT_TIMESTAMP", "DATABASE", "DEFAULT", "DEFERRABLE", + "DEFERRED", "DELETE", "DESC", "DETACH", "DISTINCT", "DROP", "EACH", + "ELSE", "END", "ESCAPE", "EXCEPT", "EXCLUSIVE", "EXISTS", "EXPLAIN", + "FAIL", "FOR", "FOREIGN", "FROM", "FULL", "GLOB", "GROUP", "HAVING", "IF", + "IGNORE", "IMMEDIATE", "IN", "INDEX", "INDEXED", "INITIALLY", "INNER", + "INSERT", "INSTEAD", "INTERSECT", "INTO", "IS", "ISNULL", "JOIN", "KEY", + "LEFT", "LIKE", "LIMIT", "MATCH", "NATURAL", "NO", "NOT", "NOTNULL", + "NULL", "OF", "OFFSET", "ON", "OR", "ORDER", "OUTER", "PLAN", "PRAGMA", + "PRIMARY", "QUERY", "RAISE", "RECURSIVE", "REFERENCES", "REGEXP", + "REINDEX", "RELEASE", "RENAME", "REPLACE", "RESTRICT", "RIGHT", + "ROLLBACK", "ROW", "SAVEPOINT", "SELECT", "SET", "TABLE", "TEMP", + "TEMPORARY", "THEN", "TO", "TRANSACTION", "TRIGGER", "UNION", "UNIQUE", + "UPDATE", "USING", "VACUUM", "VALUES", "VIEW", "VIRTUAL", "WHEN", "WHERE", + "WITH", "WITHOUT", + }; + int i, lwr, upr, mid, c; + if( !isalpha((unsigned char)zName[0]) && zName[0]!='_' ) return '"'; + for(i=0; zName[i]; i++){ + if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ) return '"'; + } + lwr = 0; + upr = sizeof(azKeywords)/sizeof(azKeywords[0]) - 1; + while( lwr<=upr ){ + mid = (lwr+upr)/2; + c = sqlite3_stricmp(azKeywords[mid], zName); + if( c==0 ) return '"'; + if( c<0 ){ + lwr = mid+1; + }else{ + upr = mid-1; + } + } + return 0; +} + +/* +** SQL function: shell_add_schema(S,X) +** +** Add the schema name X to the CREATE statement in S and return the result. +** Examples: +** +** CREATE TABLE t1(x) -> CREATE TABLE xyz.t1(x); +** +** Also works on +** +** CREATE INDEX +** CREATE UNIQUE INDEX +** CREATE VIEW +** CREATE TRIGGER +** CREATE VIRTUAL TABLE +** +** This UDF is used by the .schema command to insert the schema name of +** attached databases into the middle of the sqlite_master.sql field. +*/ +static void shellAddSchemaName( + sqlite3_context *pCtx, + int nVal, + sqlite3_value **apVal +){ + static const char *aPrefix[] = { + "TABLE", + "INDEX", + "UNIQUE INDEX", + "VIEW", + "TRIGGER", + "VIRTUAL TABLE" + }; + int i = 0; + const char *zIn = (const char*)sqlite3_value_text(apVal[0]); + const char *zSchema = (const char*)sqlite3_value_text(apVal[1]); + assert( nVal==2 ); + if( zIn!=0 && strncmp(zIn, "CREATE ", 7)==0 ){ + for(i=0; ishellFlgs & (X))!=0) +#define ShellSetFlag(P,X) ((P)->shellFlgs|=(X)) +#define ShellClearFlag(P,X) ((P)->shellFlgs&=(~(X))) + +/* +** These are the allowed modes. +*/ +#define MODE_Line 0 /* One column per line. Blank line between records */ +#define MODE_Column 1 /* One record per line in neat columns */ +#define MODE_List 2 /* One record per line with a separator */ +#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */ +#define MODE_Html 4 /* Generate an XHTML table */ +#define MODE_Insert 5 /* Generate SQL "insert" statements */ +#define MODE_Quote 6 /* Quote values as for SQL */ +#define MODE_Tcl 7 /* Generate ANSI-C or TCL quoted elements */ +#define MODE_Csv 8 /* Quote strings, numbers are plain */ +#define MODE_Explain 9 /* Like MODE_Column, but do not truncate data */ +#define MODE_Ascii 10 /* Use ASCII unit and record separators (0x1F/0x1E) */ +#define MODE_Pretty 11 /* Pretty-print schemas */ + +static const char *modeDescr[] = { + "line", + "column", + "list", + "semi", + "html", + "insert", + "quote", + "tcl", + "csv", + "explain", + "ascii", + "prettyprint", +}; + +/* +** These are the column/row/line separators used by the various +** import/export modes. +*/ +#define SEP_Column "|" +#define SEP_Row "\n" +#define SEP_Tab "\t" +#define SEP_Space " " +#define SEP_Comma "," +#define SEP_CrLf "\r\n" +#define SEP_Unit "\x1F" +#define SEP_Record "\x1E" + +/* +** Number of elements in an array +*/ +#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0])) + +/* +** A callback for the sqlite3_log() interface. +*/ +static void shellLog(void *pArg, int iErrCode, const char *zMsg){ + ShellState *p = (ShellState*)pArg; + if( p->pLog==0 ) return; + utf8_printf(p->pLog, "(%d) %s\n", iErrCode, zMsg); + fflush(p->pLog); +} + +/* +** Output the given string as a hex-encoded blob (eg. X'1234' ) +*/ +static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){ + int i; + char *zBlob = (char *)pBlob; + raw_printf(out,"X'"); + for(i=0; i0 ){ + utf8_printf(out,"%.*s",i,z); + } + if( z[i]=='<' ){ + raw_printf(out,"<"); + }else if( z[i]=='&' ){ + raw_printf(out,"&"); + }else if( z[i]=='>' ){ + raw_printf(out,">"); + }else if( z[i]=='\"' ){ + raw_printf(out,"""); + }else if( z[i]=='\'' ){ + raw_printf(out,"'"); + }else{ + break; + } + z += i + 1; + } +} + +/* +** If a field contains any character identified by a 1 in the following +** array, then the string must be quoted for CSV. +*/ +static const char needCsvQuote[] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +}; + +/* +** Output a single term of CSV. Actually, p->colSeparator is used for +** the separator, which may or may not be a comma. p->nullValue is +** the null value. Strings are quoted if necessary. The separator +** is only issued if bSep is true. +*/ +static void output_csv(ShellState *p, const char *z, int bSep){ + FILE *out = p->out; + if( z==0 ){ + utf8_printf(out,"%s",p->nullValue); + }else{ + int i; + int nSep = strlen30(p->colSeparator); + for(i=0; z[i]; i++){ + if( needCsvQuote[((unsigned char*)z)[i]] + || (z[i]==p->colSeparator[0] && + (nSep==1 || memcmp(z, p->colSeparator, nSep)==0)) ){ + i = 0; + break; + } + } + if( i==0 ){ + putc('"', out); + for(i=0; z[i]; i++){ + if( z[i]=='"' ) putc('"', out); + putc(z[i], out); + } + putc('"', out); + }else{ + utf8_printf(out, "%s", z); + } + } + if( bSep ){ + utf8_printf(p->out, "%s", p->colSeparator); + } +} + +#ifdef SIGINT +/* +** This routine runs when the user presses Ctrl-C +*/ +static void interrupt_handler(int NotUsed){ + UNUSED_PARAMETER(NotUsed); + seenInterrupt++; + if( seenInterrupt>2 ) exit(1); + if( globalDb ) sqlite3_interrupt(globalDb); +} +#endif + +#ifndef SQLITE_OMIT_AUTHORIZATION +/* +** When the ".auth ON" is set, the following authorizer callback is +** invoked. It always returns SQLITE_OK. +*/ +static int shellAuth( + void *pClientData, + int op, + const char *zA1, + const char *zA2, + const char *zA3, + const char *zA4 +){ + ShellState *p = (ShellState*)pClientData; + static const char *azAction[] = { 0, + "CREATE_INDEX", "CREATE_TABLE", "CREATE_TEMP_INDEX", + "CREATE_TEMP_TABLE", "CREATE_TEMP_TRIGGER", "CREATE_TEMP_VIEW", + "CREATE_TRIGGER", "CREATE_VIEW", "DELETE", + "DROP_INDEX", "DROP_TABLE", "DROP_TEMP_INDEX", + "DROP_TEMP_TABLE", "DROP_TEMP_TRIGGER", "DROP_TEMP_VIEW", + "DROP_TRIGGER", "DROP_VIEW", "INSERT", + "PRAGMA", "READ", "SELECT", + "TRANSACTION", "UPDATE", "ATTACH", + "DETACH", "ALTER_TABLE", "REINDEX", + "ANALYZE", "CREATE_VTABLE", "DROP_VTABLE", + "FUNCTION", "SAVEPOINT", "RECURSIVE" + }; + int i; + const char *az[4]; + az[0] = zA1; + az[1] = zA2; + az[2] = zA3; + az[3] = zA4; + utf8_printf(p->out, "authorizer: %s", azAction[op]); + for(i=0; i<4; i++){ + raw_printf(p->out, " "); + if( az[i] ){ + output_c_string(p->out, az[i]); + }else{ + raw_printf(p->out, "NULL"); + } + } + raw_printf(p->out, "\n"); + return SQLITE_OK; +} +#endif + +/* +** Print a schema statement. Part of MODE_Semi and MODE_Pretty output. +** +** This routine converts some CREATE TABLE statements for shadow tables +** in FTS3/4/5 into CREATE TABLE IF NOT EXISTS statements. +*/ +static void printSchemaLine(FILE *out, const char *z, const char *zTail){ + if( sqlite3_strglob("CREATE TABLE ['\"]*", z)==0 ){ + utf8_printf(out, "CREATE TABLE IF NOT EXISTS %s%s", z+13, zTail); + }else{ + utf8_printf(out, "%s%s", z, zTail); + } +} +static void printSchemaLineN(FILE *out, char *z, int n, const char *zTail){ + char c = z[n]; + z[n] = 0; + printSchemaLine(out, z, zTail); + z[n] = c; +} + +/* +** This is the callback routine that the shell +** invokes for each row of a query result. +*/ +static int shell_callback( + void *pArg, + int nArg, /* Number of result columns */ + char **azArg, /* Text of each result column */ + char **azCol, /* Column names */ + int *aiType /* Column types */ +){ + int i; + ShellState *p = (ShellState*)pArg; + + switch( p->cMode ){ + case MODE_Line: { + int w = 5; + if( azArg==0 ) break; + for(i=0; iw ) w = len; + } + if( p->cnt++>0 ) utf8_printf(p->out, "%s", p->rowSeparator); + for(i=0; iout,"%*s = %s%s", w, azCol[i], + azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator); + } + break; + } + case MODE_Explain: + case MODE_Column: { + static const int aExplainWidths[] = {4, 13, 4, 4, 4, 13, 2, 13}; + const int *colWidth; + int showHdr; + char *rowSep; + if( p->cMode==MODE_Column ){ + colWidth = p->colWidth; + showHdr = p->showHeader; + rowSep = p->rowSeparator; + }else{ + colWidth = aExplainWidths; + showHdr = 1; + rowSep = SEP_Row; + } + if( p->cnt++==0 ){ + for(i=0; icolWidth) ){ + w = colWidth[i]; + }else{ + w = 0; + } + if( w==0 ){ + w = strlenChar(azCol[i] ? azCol[i] : ""); + if( w<10 ) w = 10; + n = strlenChar(azArg && azArg[i] ? azArg[i] : p->nullValue); + if( wactualWidth) ){ + p->actualWidth[i] = w; + } + if( showHdr ){ + utf8_width_print(p->out, w, azCol[i]); + utf8_printf(p->out, "%s", i==nArg-1 ? rowSep : " "); + } + } + if( showHdr ){ + for(i=0; iactualWidth) ){ + w = p->actualWidth[i]; + if( w<0 ) w = -w; + }else{ + w = 10; + } + utf8_printf(p->out,"%-*.*s%s",w,w, + "----------------------------------------------------------" + "----------------------------------------------------------", + i==nArg-1 ? rowSep : " "); + } + } + } + if( azArg==0 ) break; + for(i=0; iactualWidth) ){ + w = p->actualWidth[i]; + }else{ + w = 10; + } + if( p->cMode==MODE_Explain && azArg[i] && strlenChar(azArg[i])>w ){ + w = strlenChar(azArg[i]); + } + if( i==1 && p->aiIndent && p->pStmt ){ + if( p->iIndentnIndent ){ + utf8_printf(p->out, "%*.s", p->aiIndent[p->iIndent], ""); + } + p->iIndent++; + } + utf8_width_print(p->out, w, azArg[i] ? azArg[i] : p->nullValue); + utf8_printf(p->out, "%s", i==nArg-1 ? rowSep : " "); + } + break; + } + case MODE_Semi: { /* .schema and .fullschema output */ + printSchemaLine(p->out, azArg[0], ";\n"); + break; + } + case MODE_Pretty: { /* .schema and .fullschema with --indent */ + char *z; + int j; + int nParen = 0; + char cEnd = 0; + char c; + int nLine = 0; + assert( nArg==1 ); + if( azArg[0]==0 ) break; + if( sqlite3_strlike("CREATE VIEW%", azArg[0], 0)==0 + || sqlite3_strlike("CREATE TRIG%", azArg[0], 0)==0 + ){ + utf8_printf(p->out, "%s;\n", azArg[0]); + break; + } + z = sqlite3_mprintf("%s", azArg[0]); + j = 0; + for(i=0; IsSpace(z[i]); i++){} + for(; (c = z[i])!=0; i++){ + if( IsSpace(c) ){ + if( IsSpace(z[j-1]) || z[j-1]=='(' ) continue; + }else if( (c=='(' || c==')') && j>0 && IsSpace(z[j-1]) ){ + j--; + } + z[j++] = c; + } + while( j>0 && IsSpace(z[j-1]) ){ j--; } + z[j] = 0; + if( strlen30(z)>=79 ){ + for(i=j=0; (c = z[i])!=0; i++){ + if( c==cEnd ){ + cEnd = 0; + }else if( c=='"' || c=='\'' || c=='`' ){ + cEnd = c; + }else if( c=='[' ){ + cEnd = ']'; + }else if( c=='(' ){ + nParen++; + }else if( c==')' ){ + nParen--; + if( nLine>0 && nParen==0 && j>0 ){ + printSchemaLineN(p->out, z, j, "\n"); + j = 0; + } + } + z[j++] = c; + if( nParen==1 && (c=='(' || c==',' || c=='\n') ){ + if( c=='\n' ) j--; + printSchemaLineN(p->out, z, j, "\n "); + j = 0; + nLine++; + while( IsSpace(z[i+1]) ){ i++; } + } + } + z[j] = 0; + } + printSchemaLine(p->out, z, ";\n"); + sqlite3_free(z); + break; + } + case MODE_List: { + if( p->cnt++==0 && p->showHeader ){ + for(i=0; iout,"%s%s",azCol[i], + i==nArg-1 ? p->rowSeparator : p->colSeparator); + } + } + if( azArg==0 ) break; + for(i=0; inullValue; + utf8_printf(p->out, "%s", z); + if( iout, "%s", p->colSeparator); + }else{ + utf8_printf(p->out, "%s", p->rowSeparator); + } + } + break; + } + case MODE_Html: { + if( p->cnt++==0 && p->showHeader ){ + raw_printf(p->out,""); + for(i=0; iout,""); + output_html_string(p->out, azCol[i]); + raw_printf(p->out,"\n"); + } + raw_printf(p->out,"\n"); + } + if( azArg==0 ) break; + raw_printf(p->out,""); + for(i=0; iout,""); + output_html_string(p->out, azArg[i] ? azArg[i] : p->nullValue); + raw_printf(p->out,"\n"); + } + raw_printf(p->out,"\n"); + break; + } + case MODE_Tcl: { + if( p->cnt++==0 && p->showHeader ){ + for(i=0; iout,azCol[i] ? azCol[i] : ""); + if(iout, "%s", p->colSeparator); + } + utf8_printf(p->out, "%s", p->rowSeparator); + } + if( azArg==0 ) break; + for(i=0; iout, azArg[i] ? azArg[i] : p->nullValue); + if(iout, "%s", p->colSeparator); + } + utf8_printf(p->out, "%s", p->rowSeparator); + break; + } + case MODE_Csv: { + setBinaryMode(p->out, 1); + if( p->cnt++==0 && p->showHeader ){ + for(i=0; iout, "%s", p->rowSeparator); + } + if( nArg>0 ){ + for(i=0; iout, "%s", p->rowSeparator); + } + setTextMode(p->out, 1); + break; + } + case MODE_Insert: { + if( azArg==0 ) break; + utf8_printf(p->out,"INSERT INTO %s",p->zDestTable); + if( p->showHeader ){ + raw_printf(p->out,"("); + for(i=0; i0 ) raw_printf(p->out, ","); + if( quoteChar(azCol[i]) ){ + char *z = sqlite3_mprintf("\"%w\"", azCol[i]); + utf8_printf(p->out, "%s", z); + sqlite3_free(z); + }else{ + raw_printf(p->out, "%s", azCol[i]); + } + } + raw_printf(p->out,")"); + } + p->cnt++; + for(i=0; iout, i>0 ? "," : " VALUES("); + if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){ + utf8_printf(p->out,"NULL"); + }else if( aiType && aiType[i]==SQLITE_TEXT ){ + if( ShellHasFlag(p, SHFLG_Newlines) ){ + output_quoted_string(p->out, azArg[i]); + }else{ + output_quoted_escaped_string(p->out, azArg[i]); + } + }else if( aiType && aiType[i]==SQLITE_INTEGER ){ + utf8_printf(p->out,"%s", azArg[i]); + }else if( aiType && aiType[i]==SQLITE_FLOAT ){ + char z[50]; + double r = sqlite3_column_double(p->pStmt, i); + sqlite3_snprintf(50,z,"%!.20g", r); + raw_printf(p->out, "%s", z); + }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){ + const void *pBlob = sqlite3_column_blob(p->pStmt, i); + int nBlob = sqlite3_column_bytes(p->pStmt, i); + output_hex_blob(p->out, pBlob, nBlob); + }else if( isNumber(azArg[i], 0) ){ + utf8_printf(p->out,"%s", azArg[i]); + }else if( ShellHasFlag(p, SHFLG_Newlines) ){ + output_quoted_string(p->out, azArg[i]); + }else{ + output_quoted_escaped_string(p->out, azArg[i]); + } + } + raw_printf(p->out,");\n"); + break; + } + case MODE_Quote: { + if( azArg==0 ) break; + if( p->cnt==0 && p->showHeader ){ + for(i=0; i0 ) raw_printf(p->out, ","); + output_quoted_string(p->out, azCol[i]); + } + raw_printf(p->out,"\n"); + } + p->cnt++; + for(i=0; i0 ) raw_printf(p->out, ","); + if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){ + utf8_printf(p->out,"NULL"); + }else if( aiType && aiType[i]==SQLITE_TEXT ){ + output_quoted_string(p->out, azArg[i]); + }else if( aiType && aiType[i]==SQLITE_INTEGER ){ + utf8_printf(p->out,"%s", azArg[i]); + }else if( aiType && aiType[i]==SQLITE_FLOAT ){ + char z[50]; + double r = sqlite3_column_double(p->pStmt, i); + sqlite3_snprintf(50,z,"%!.20g", r); + raw_printf(p->out, "%s", z); + }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){ + const void *pBlob = sqlite3_column_blob(p->pStmt, i); + int nBlob = sqlite3_column_bytes(p->pStmt, i); + output_hex_blob(p->out, pBlob, nBlob); + }else if( isNumber(azArg[i], 0) ){ + utf8_printf(p->out,"%s", azArg[i]); + }else{ + output_quoted_string(p->out, azArg[i]); + } + } + raw_printf(p->out,"\n"); + break; + } + case MODE_Ascii: { + if( p->cnt++==0 && p->showHeader ){ + for(i=0; i0 ) utf8_printf(p->out, "%s", p->colSeparator); + utf8_printf(p->out,"%s",azCol[i] ? azCol[i] : ""); + } + utf8_printf(p->out, "%s", p->rowSeparator); + } + if( azArg==0 ) break; + for(i=0; i0 ) utf8_printf(p->out, "%s", p->colSeparator); + utf8_printf(p->out,"%s",azArg[i] ? azArg[i] : p->nullValue); + } + utf8_printf(p->out, "%s", p->rowSeparator); + break; + } + } + return 0; +} + +/* +** This is the callback routine that the SQLite library +** invokes for each row of a query result. +*/ +static int callback(void *pArg, int nArg, char **azArg, char **azCol){ + /* since we don't have type info, call the shell_callback with a NULL value */ + return shell_callback(pArg, nArg, azArg, azCol, NULL); +} + +/* +** This is the callback routine from sqlite3_exec() that appends all +** output onto the end of a ShellText object. +*/ +static int captureOutputCallback(void *pArg, int nArg, char **azArg, char **az){ + ShellText *p = (ShellText*)pArg; + int i; + UNUSED_PARAMETER(az); + if( p->n ) appendText(p, "|", 0); + for(i=0; idb, + "SAVEPOINT selftest_init;\n" + "CREATE TABLE IF NOT EXISTS selftest(\n" + " tno INTEGER PRIMARY KEY,\n" /* Test number */ + " op TEXT,\n" /* Operator: memo run */ + " cmd TEXT,\n" /* Command text */ + " ans TEXT\n" /* Desired answer */ + ");" + "CREATE TEMP TABLE [_shell$self](op,cmd,ans);\n" + "INSERT INTO [_shell$self](rowid,op,cmd)\n" + " VALUES(coalesce((SELECT (max(tno)+100)/10 FROM selftest),10),\n" + " 'memo','Tests generated by --init');\n" + "INSERT INTO [_shell$self]\n" + " SELECT 'run',\n" + " 'SELECT hex(sha3_query(''SELECT type,name,tbl_name,sql " + "FROM sqlite_master ORDER BY 2'',224))',\n" + " hex(sha3_query('SELECT type,name,tbl_name,sql " + "FROM sqlite_master ORDER BY 2',224));\n" + "INSERT INTO [_shell$self]\n" + " SELECT 'run'," + " 'SELECT hex(sha3_query(''SELECT * FROM \"' ||" + " printf('%w',name) || '\" NOT INDEXED'',224))',\n" + " hex(sha3_query(printf('SELECT * FROM \"%w\" NOT INDEXED',name),224))\n" + " FROM (\n" + " SELECT name FROM sqlite_master\n" + " WHERE type='table'\n" + " AND name<>'selftest'\n" + " AND coalesce(rootpage,0)>0\n" + " )\n" + " ORDER BY name;\n" + "INSERT INTO [_shell$self]\n" + " VALUES('run','PRAGMA integrity_check','ok');\n" + "INSERT INTO selftest(tno,op,cmd,ans)" + " SELECT rowid*10,op,cmd,ans FROM [_shell$self];\n" + "DROP TABLE [_shell$self];" + ,0,0,&zErrMsg); + if( zErrMsg ){ + utf8_printf(stderr, "SELFTEST initialization failure: %s\n", zErrMsg); + sqlite3_free(zErrMsg); + } + sqlite3_exec(p->db, "RELEASE selftest_init",0,0,0); +} + + +/* +** Set the destination table field of the ShellState structure to +** the name of the table given. Escape any quote characters in the +** table name. +*/ +static void set_table_name(ShellState *p, const char *zName){ + int i, n; + int cQuote; + char *z; + + if( p->zDestTable ){ + free(p->zDestTable); + p->zDestTable = 0; + } + if( zName==0 ) return; + cQuote = quoteChar(zName); + n = strlen30(zName); + if( cQuote ) n += n+2; + z = p->zDestTable = malloc( n+1 ); + if( z==0 ){ + raw_printf(stderr,"Error: out of memory\n"); + exit(1); + } + n = 0; + if( cQuote ) z[n++] = cQuote; + for(i=0; zName[i]; i++){ + z[n++] = zName[i]; + if( zName[i]==cQuote ) z[n++] = cQuote; + } + if( cQuote ) z[n++] = cQuote; + z[n] = 0; +} + + +/* +** Execute a query statement that will generate SQL output. Print +** the result columns, comma-separated, on a line and then add a +** semicolon terminator to the end of that line. +** +** If the number of columns is 1 and that column contains text "--" +** then write the semicolon on a separate line. That way, if a +** "--" comment occurs at the end of the statement, the comment +** won't consume the semicolon terminator. +*/ +static int run_table_dump_query( + ShellState *p, /* Query context */ + const char *zSelect, /* SELECT statement to extract content */ + const char *zFirstRow /* Print before first row, if not NULL */ +){ + sqlite3_stmt *pSelect; + int rc; + int nResult; + int i; + const char *z; + rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0); + if( rc!=SQLITE_OK || !pSelect ){ + utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, + sqlite3_errmsg(p->db)); + if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++; + return rc; + } + rc = sqlite3_step(pSelect); + nResult = sqlite3_column_count(pSelect); + while( rc==SQLITE_ROW ){ + if( zFirstRow ){ + utf8_printf(p->out, "%s", zFirstRow); + zFirstRow = 0; + } + z = (const char*)sqlite3_column_text(pSelect, 0); + utf8_printf(p->out, "%s", z); + for(i=1; iout, ",%s", sqlite3_column_text(pSelect, i)); + } + if( z==0 ) z = ""; + while( z[0] && (z[0]!='-' || z[1]!='-') ) z++; + if( z[0] ){ + raw_printf(p->out, "\n;\n"); + }else{ + raw_printf(p->out, ";\n"); + } + rc = sqlite3_step(pSelect); + } + rc = sqlite3_finalize(pSelect); + if( rc!=SQLITE_OK ){ + utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, + sqlite3_errmsg(p->db)); + if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++; + } + return rc; +} + +/* +** Allocate space and save off current error string. +*/ +static char *save_err_msg( + sqlite3 *db /* Database to query */ +){ + int nErrMsg = 1+strlen30(sqlite3_errmsg(db)); + char *zErrMsg = sqlite3_malloc64(nErrMsg); + if( zErrMsg ){ + memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg); + } + return zErrMsg; +} + +#ifdef __linux__ +/* +** Attempt to display I/O stats on Linux using /proc/PID/io +*/ +static void displayLinuxIoStats(FILE *out){ + FILE *in; + char z[200]; + sqlite3_snprintf(sizeof(z), z, "/proc/%d/io", getpid()); + in = fopen(z, "rb"); + if( in==0 ) return; + while( fgets(z, sizeof(z), in)!=0 ){ + static const struct { + const char *zPattern; + const char *zDesc; + } aTrans[] = { + { "rchar: ", "Bytes received by read():" }, + { "wchar: ", "Bytes sent to write():" }, + { "syscr: ", "Read() system calls:" }, + { "syscw: ", "Write() system calls:" }, + { "read_bytes: ", "Bytes read from storage:" }, + { "write_bytes: ", "Bytes written to storage:" }, + { "cancelled_write_bytes: ", "Cancelled write bytes:" }, + }; + int i; + for(i=0; i1 ){ + sqlite3_snprintf(sizeof(zLine), zLine, zFormat, iCur, iHiwtr); + }else{ + sqlite3_snprintf(sizeof(zLine), zLine, zFormat, iHiwtr); + } + raw_printf(p->out, "%-36s %s\n", zLabel, zLine); +} + +/* +** Display memory stats. +*/ +static int display_stats( + sqlite3 *db, /* Database to query */ + ShellState *pArg, /* Pointer to ShellState */ + int bReset /* True to reset the stats */ +){ + int iCur; + int iHiwtr; + + if( pArg && pArg->out ){ + displayStatLine(pArg, "Memory Used:", + "%lld (max %lld) bytes", SQLITE_STATUS_MEMORY_USED, bReset); + displayStatLine(pArg, "Number of Outstanding Allocations:", + "%lld (max %lld)", SQLITE_STATUS_MALLOC_COUNT, bReset); + if( pArg->shellFlgs & SHFLG_Pagecache ){ + displayStatLine(pArg, "Number of Pcache Pages Used:", + "%lld (max %lld) pages", SQLITE_STATUS_PAGECACHE_USED, bReset); + } + displayStatLine(pArg, "Number of Pcache Overflow Bytes:", + "%lld (max %lld) bytes", SQLITE_STATUS_PAGECACHE_OVERFLOW, bReset); + if( pArg->shellFlgs & SHFLG_Scratch ){ + displayStatLine(pArg, "Number of Scratch Allocations Used:", + "%lld (max %lld)", SQLITE_STATUS_SCRATCH_USED, bReset); + } + displayStatLine(pArg, "Number of Scratch Overflow Bytes:", + "%lld (max %lld) bytes", SQLITE_STATUS_SCRATCH_OVERFLOW, bReset); + displayStatLine(pArg, "Largest Allocation:", + "%lld bytes", SQLITE_STATUS_MALLOC_SIZE, bReset); + displayStatLine(pArg, "Largest Pcache Allocation:", + "%lld bytes", SQLITE_STATUS_PAGECACHE_SIZE, bReset); + displayStatLine(pArg, "Largest Scratch Allocation:", + "%lld bytes", SQLITE_STATUS_SCRATCH_SIZE, bReset); +#ifdef YYTRACKMAXSTACKDEPTH + displayStatLine(pArg, "Deepest Parser Stack:", + "%lld (max %lld)", SQLITE_STATUS_PARSER_STACK, bReset); +#endif + } + + if( pArg && pArg->out && db ){ + if( pArg->shellFlgs & SHFLG_Lookaside ){ + iHiwtr = iCur = -1; + sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED, + &iCur, &iHiwtr, bReset); + raw_printf(pArg->out, + "Lookaside Slots Used: %d (max %d)\n", + iCur, iHiwtr); + sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT, + &iCur, &iHiwtr, bReset); + raw_printf(pArg->out, "Successful lookaside attempts: %d\n", + iHiwtr); + sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, + &iCur, &iHiwtr, bReset); + raw_printf(pArg->out, "Lookaside failures due to size: %d\n", + iHiwtr); + sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, + &iCur, &iHiwtr, bReset); + raw_printf(pArg->out, "Lookaside failures due to OOM: %d\n", + iHiwtr); + } + iHiwtr = iCur = -1; + sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset); + raw_printf(pArg->out, "Pager Heap Usage: %d bytes\n", + iCur); + iHiwtr = iCur = -1; + sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1); + raw_printf(pArg->out, "Page cache hits: %d\n", iCur); + iHiwtr = iCur = -1; + sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1); + raw_printf(pArg->out, "Page cache misses: %d\n", iCur); + iHiwtr = iCur = -1; + sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1); + raw_printf(pArg->out, "Page cache writes: %d\n", iCur); + iHiwtr = iCur = -1; + sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset); + raw_printf(pArg->out, "Schema Heap Usage: %d bytes\n", + iCur); + iHiwtr = iCur = -1; + sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset); + raw_printf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n", + iCur); + } + + if( pArg && pArg->out && db && pArg->pStmt ){ + iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, + bReset); + raw_printf(pArg->out, "Fullscan Steps: %d\n", iCur); + iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset); + raw_printf(pArg->out, "Sort Operations: %d\n", iCur); + iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset); + raw_printf(pArg->out, "Autoindex Inserts: %d\n", iCur); + iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset); + raw_printf(pArg->out, "Virtual Machine Steps: %d\n", iCur); + } + +#ifdef __linux__ + displayLinuxIoStats(pArg->out); +#endif + + /* Do not remove this machine readable comment: extra-stats-output-here */ + + return 0; +} + +/* +** Display scan stats. +*/ +static void display_scanstats( + sqlite3 *db, /* Database to query */ + ShellState *pArg /* Pointer to ShellState */ +){ +#ifndef SQLITE_ENABLE_STMT_SCANSTATUS + UNUSED_PARAMETER(db); + UNUSED_PARAMETER(pArg); +#else + int i, k, n, mx; + raw_printf(pArg->out, "-------- scanstats --------\n"); + mx = 0; + for(k=0; k<=mx; k++){ + double rEstLoop = 1.0; + for(i=n=0; 1; i++){ + sqlite3_stmt *p = pArg->pStmt; + sqlite3_int64 nLoop, nVisit; + double rEst; + int iSid; + const char *zExplain; + if( sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NLOOP, (void*)&nLoop) ){ + break; + } + sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_SELECTID, (void*)&iSid); + if( iSid>mx ) mx = iSid; + if( iSid!=k ) continue; + if( n==0 ){ + rEstLoop = (double)nLoop; + if( k>0 ) raw_printf(pArg->out, "-------- subquery %d -------\n", k); + } + n++; + sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NVISIT, (void*)&nVisit); + sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EST, (void*)&rEst); + sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EXPLAIN, (void*)&zExplain); + utf8_printf(pArg->out, "Loop %2d: %s\n", n, zExplain); + rEstLoop *= rEst; + raw_printf(pArg->out, + " nLoop=%-8lld nRow=%-8lld estRow=%-8lld estRow/Loop=%-8g\n", + nLoop, nVisit, (sqlite3_int64)(rEstLoop+0.5), rEst + ); + } + } + raw_printf(pArg->out, "---------------------------\n"); +#endif +} + +/* +** Parameter azArray points to a zero-terminated array of strings. zStr +** points to a single nul-terminated string. Return non-zero if zStr +** is equal, according to strcmp(), to any of the strings in the array. +** Otherwise, return zero. +*/ +static int str_in_array(const char *zStr, const char **azArray){ + int i; + for(i=0; azArray[i]; i++){ + if( 0==strcmp(zStr, azArray[i]) ) return 1; + } + return 0; +} + +/* +** If compiled statement pSql appears to be an EXPLAIN statement, allocate +** and populate the ShellState.aiIndent[] array with the number of +** spaces each opcode should be indented before it is output. +** +** The indenting rules are: +** +** * For each "Next", "Prev", "VNext" or "VPrev" instruction, indent +** all opcodes that occur between the p2 jump destination and the opcode +** itself by 2 spaces. +** +** * For each "Goto", if the jump destination is earlier in the program +** and ends on one of: +** Yield SeekGt SeekLt RowSetRead Rewind +** or if the P1 parameter is one instead of zero, +** then indent all opcodes between the earlier instruction +** and "Goto" by 2 spaces. +*/ +static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){ + const char *zSql; /* The text of the SQL statement */ + const char *z; /* Used to check if this is an EXPLAIN */ + int *abYield = 0; /* True if op is an OP_Yield */ + int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */ + int iOp; /* Index of operation in p->aiIndent[] */ + + const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext", + "NextIfOpen", "PrevIfOpen", 0 }; + const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead", + "Rewind", 0 }; + const char *azGoto[] = { "Goto", 0 }; + + /* Try to figure out if this is really an EXPLAIN statement. If this + ** cannot be verified, return early. */ + if( sqlite3_column_count(pSql)!=8 ){ + p->cMode = p->mode; + return; + } + zSql = sqlite3_sql(pSql); + if( zSql==0 ) return; + for(z=zSql; *z==' ' || *z=='\t' || *z=='\n' || *z=='\f' || *z=='\r'; z++); + if( sqlite3_strnicmp(z, "explain", 7) ){ + p->cMode = p->mode; + return; + } + + for(iOp=0; SQLITE_ROW==sqlite3_step(pSql); iOp++){ + int i; + int iAddr = sqlite3_column_int(pSql, 0); + const char *zOp = (const char*)sqlite3_column_text(pSql, 1); + + /* Set p2 to the P2 field of the current opcode. Then, assuming that + ** p2 is an instruction address, set variable p2op to the index of that + ** instruction in the aiIndent[] array. p2 and p2op may be different if + ** the current instruction is part of a sub-program generated by an + ** SQL trigger or foreign key. */ + int p2 = sqlite3_column_int(pSql, 3); + int p2op = (p2 + (iOp-iAddr)); + + /* Grow the p->aiIndent array as required */ + if( iOp>=nAlloc ){ + if( iOp==0 ){ + /* Do further verfication that this is explain output. Abort if + ** it is not */ + static const char *explainCols[] = { + "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment" }; + int jj; + for(jj=0; jjcMode = p->mode; + sqlite3_reset(pSql); + return; + } + } + } + nAlloc += 100; + p->aiIndent = (int*)sqlite3_realloc64(p->aiIndent, nAlloc*sizeof(int)); + abYield = (int*)sqlite3_realloc64(abYield, nAlloc*sizeof(int)); + } + abYield[iOp] = str_in_array(zOp, azYield); + p->aiIndent[iOp] = 0; + p->nIndent = iOp+1; + + if( str_in_array(zOp, azNext) ){ + for(i=p2op; iaiIndent[i] += 2; + } + if( str_in_array(zOp, azGoto) && p2opnIndent + && (abYield[p2op] || sqlite3_column_int(pSql, 2)) + ){ + for(i=p2op; iaiIndent[i] += 2; + } + } + + p->iIndent = 0; + sqlite3_free(abYield); + sqlite3_reset(pSql); +} + +/* +** Free the array allocated by explain_data_prepare(). +*/ +static void explain_data_delete(ShellState *p){ + sqlite3_free(p->aiIndent); + p->aiIndent = 0; + p->nIndent = 0; + p->iIndent = 0; +} + +/* +** Disable and restore .wheretrace and .selecttrace settings. +*/ +#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE) +extern int sqlite3SelectTrace; +static int savedSelectTrace; +#endif +#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE) +extern int sqlite3WhereTrace; +static int savedWhereTrace; +#endif +static void disable_debug_trace_modes(void){ +#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE) + savedSelectTrace = sqlite3SelectTrace; + sqlite3SelectTrace = 0; +#endif +#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE) + savedWhereTrace = sqlite3WhereTrace; + sqlite3WhereTrace = 0; +#endif +} +static void restore_debug_trace_modes(void){ +#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE) + sqlite3SelectTrace = savedSelectTrace; +#endif +#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE) + sqlite3WhereTrace = savedWhereTrace; +#endif +} + +/* +** Run a prepared statement +*/ +static void exec_prepared_stmt( + ShellState *pArg, /* Pointer to ShellState */ + sqlite3_stmt *pStmt, /* Statment to run */ + int (*xCallback)(void*,int,char**,char**,int*) /* Callback function */ +){ + int rc; + + /* perform the first step. this will tell us if we + ** have a result set or not and how wide it is. + */ + rc = sqlite3_step(pStmt); + /* if we have a result set... */ + if( SQLITE_ROW == rc ){ + /* if we have a callback... */ + if( xCallback ){ + /* allocate space for col name ptr, value ptr, and type */ + int nCol = sqlite3_column_count(pStmt); + void *pData = sqlite3_malloc64(3*nCol*sizeof(const char*) + 1); + if( !pData ){ + rc = SQLITE_NOMEM; + }else{ + char **azCols = (char **)pData; /* Names of result columns */ + char **azVals = &azCols[nCol]; /* Results */ + int *aiTypes = (int *)&azVals[nCol]; /* Result types */ + int i, x; + assert(sizeof(int) <= sizeof(char *)); + /* save off ptrs to column names */ + for(i=0; icMode==MODE_Insert ){ + azVals[i] = ""; + }else{ + azVals[i] = (char*)sqlite3_column_text(pStmt, i); + } + if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){ + rc = SQLITE_NOMEM; + break; /* from for */ + } + } /* end for */ + + /* if data and types extracted successfully... */ + if( SQLITE_ROW == rc ){ + /* call the supplied callback with the result row data */ + if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){ + rc = SQLITE_ABORT; + }else{ + rc = sqlite3_step(pStmt); + } + } + } while( SQLITE_ROW == rc ); + sqlite3_free(pData); + } + }else{ + do{ + rc = sqlite3_step(pStmt); + } while( rc == SQLITE_ROW ); + } + } +} + +/* +** Execute a statement or set of statements. Print +** any result rows/columns depending on the current mode +** set via the supplied callback. +** +** This is very similar to SQLite's built-in sqlite3_exec() +** function except it takes a slightly different callback +** and callback data argument. +*/ +static int shell_exec( + sqlite3 *db, /* An open database */ + const char *zSql, /* SQL to be evaluated */ + int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */ + /* (not the same as sqlite3_exec) */ + ShellState *pArg, /* Pointer to ShellState */ + char **pzErrMsg /* Error msg written here */ +){ + sqlite3_stmt *pStmt = NULL; /* Statement to execute. */ + int rc = SQLITE_OK; /* Return Code */ + int rc2; + const char *zLeftover; /* Tail of unprocessed SQL */ + + if( pzErrMsg ){ + *pzErrMsg = NULL; + } + + while( zSql[0] && (SQLITE_OK == rc) ){ + static const char *zStmtSql; + rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover); + if( SQLITE_OK != rc ){ + if( pzErrMsg ){ + *pzErrMsg = save_err_msg(db); + } + }else{ + if( !pStmt ){ + /* this happens for a comment or white-space */ + zSql = zLeftover; + while( IsSpace(zSql[0]) ) zSql++; + continue; + } + zStmtSql = sqlite3_sql(pStmt); + if( zStmtSql==0 ) zStmtSql = ""; + while( IsSpace(zStmtSql[0]) ) zStmtSql++; + + /* save off the prepared statment handle and reset row count */ + if( pArg ){ + pArg->pStmt = pStmt; + pArg->cnt = 0; + } + + /* echo the sql statement if echo on */ + if( pArg && ShellHasFlag(pArg, SHFLG_Echo) ){ + utf8_printf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql); + } + + /* Show the EXPLAIN QUERY PLAN if .eqp is on */ + if( pArg && pArg->autoEQP && sqlite3_strlike("EXPLAIN%",zStmtSql,0)!=0 ){ + sqlite3_stmt *pExplain; + char *zEQP; + disable_debug_trace_modes(); + zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s", zStmtSql); + rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0); + if( rc==SQLITE_OK ){ + while( sqlite3_step(pExplain)==SQLITE_ROW ){ + raw_printf(pArg->out,"--EQP-- %d,",sqlite3_column_int(pExplain, 0)); + raw_printf(pArg->out,"%d,", sqlite3_column_int(pExplain, 1)); + raw_printf(pArg->out,"%d,", sqlite3_column_int(pExplain, 2)); + utf8_printf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3)); + } + } + sqlite3_finalize(pExplain); + sqlite3_free(zEQP); + if( pArg->autoEQP>=2 ){ + /* Also do an EXPLAIN for ".eqp full" mode */ + zEQP = sqlite3_mprintf("EXPLAIN %s", zStmtSql); + rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0); + if( rc==SQLITE_OK ){ + pArg->cMode = MODE_Explain; + explain_data_prepare(pArg, pExplain); + exec_prepared_stmt(pArg, pExplain, xCallback); + explain_data_delete(pArg); + } + sqlite3_finalize(pExplain); + sqlite3_free(zEQP); + } + restore_debug_trace_modes(); + } + + if( pArg ){ + pArg->cMode = pArg->mode; + if( pArg->autoExplain + && sqlite3_column_count(pStmt)==8 + && sqlite3_strlike("EXPLAIN%", zStmtSql,0)==0 + ){ + pArg->cMode = MODE_Explain; + } + + /* If the shell is currently in ".explain" mode, gather the extra + ** data required to add indents to the output.*/ + if( pArg->cMode==MODE_Explain ){ + explain_data_prepare(pArg, pStmt); + } + } + + exec_prepared_stmt(pArg, pStmt, xCallback); + explain_data_delete(pArg); + + /* print usage stats if stats on */ + if( pArg && pArg->statsOn ){ + display_stats(db, pArg, 0); + } + + /* print loop-counters if required */ + if( pArg && pArg->scanstatsOn ){ + display_scanstats(db, pArg); + } + + /* Finalize the statement just executed. If this fails, save a + ** copy of the error message. Otherwise, set zSql to point to the + ** next statement to execute. */ + rc2 = sqlite3_finalize(pStmt); + if( rc!=SQLITE_NOMEM ) rc = rc2; + if( rc==SQLITE_OK ){ + zSql = zLeftover; + while( IsSpace(zSql[0]) ) zSql++; + }else if( pzErrMsg ){ + *pzErrMsg = save_err_msg(db); + } + + /* clear saved stmt handle */ + if( pArg ){ + pArg->pStmt = NULL; + } + } + } /* end while */ + + return rc; +} + +/* +** Release memory previously allocated by tableColumnList(). +*/ +static void freeColumnList(char **azCol){ + int i; + for(i=1; azCol[i]; i++){ + sqlite3_free(azCol[i]); + } + /* azCol[0] is a static string */ + sqlite3_free(azCol); +} + +/* +** Return a list of pointers to strings which are the names of all +** columns in table zTab. The memory to hold the names is dynamically +** allocated and must be released by the caller using a subsequent call +** to freeColumnList(). +** +** The azCol[0] entry is usually NULL. However, if zTab contains a rowid +** value that needs to be preserved, then azCol[0] is filled in with the +** name of the rowid column. +** +** The first regular column in the table is azCol[1]. The list is terminated +** by an entry with azCol[i]==0. +*/ +static char **tableColumnList(ShellState *p, const char *zTab){ + char **azCol = 0; + sqlite3_stmt *pStmt; + char *zSql; + int nCol = 0; + int nAlloc = 0; + int nPK = 0; /* Number of PRIMARY KEY columns seen */ + int isIPK = 0; /* True if one PRIMARY KEY column of type INTEGER */ + int preserveRowid = ShellHasFlag(p, SHFLG_PreserveRowid); + int rc; + + zSql = sqlite3_mprintf("PRAGMA table_info=%Q", zTab); + rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); + sqlite3_free(zSql); + if( rc ) return 0; + while( sqlite3_step(pStmt)==SQLITE_ROW ){ + if( nCol>=nAlloc-2 ){ + nAlloc = nAlloc*2 + nCol + 10; + azCol = sqlite3_realloc(azCol, nAlloc*sizeof(azCol[0])); + if( azCol==0 ){ + raw_printf(stderr, "Error: out of memory\n"); + exit(1); + } + } + azCol[++nCol] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 1)); + if( sqlite3_column_int(pStmt, 5) ){ + nPK++; + if( nPK==1 + && sqlite3_stricmp((const char*)sqlite3_column_text(pStmt,2), + "INTEGER")==0 + ){ + isIPK = 1; + }else{ + isIPK = 0; + } + } + } + sqlite3_finalize(pStmt); + azCol[0] = 0; + azCol[nCol+1] = 0; + + /* The decision of whether or not a rowid really needs to be preserved + ** is tricky. We never need to preserve a rowid for a WITHOUT ROWID table + ** or a table with an INTEGER PRIMARY KEY. We are unable to preserve + ** rowids on tables where the rowid is inaccessible because there are other + ** columns in the table named "rowid", "_rowid_", and "oid". + */ + if( preserveRowid && isIPK ){ + /* If a single PRIMARY KEY column with type INTEGER was seen, then it + ** might be an alise for the ROWID. But it might also be a WITHOUT ROWID + ** table or a INTEGER PRIMARY KEY DESC column, neither of which are + ** ROWID aliases. To distinguish these cases, check to see if + ** there is a "pk" entry in "PRAGMA index_list". There will be + ** no "pk" index if the PRIMARY KEY really is an alias for the ROWID. + */ + zSql = sqlite3_mprintf("SELECT 1 FROM pragma_index_list(%Q)" + " WHERE origin='pk'", zTab); + rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); + sqlite3_free(zSql); + if( rc ){ + freeColumnList(azCol); + return 0; + } + rc = sqlite3_step(pStmt); + sqlite3_finalize(pStmt); + preserveRowid = rc==SQLITE_ROW; + } + if( preserveRowid ){ + /* Only preserve the rowid if we can find a name to use for the + ** rowid */ + static char *azRowid[] = { "rowid", "_rowid_", "oid" }; + int i, j; + for(j=0; j<3; j++){ + for(i=1; i<=nCol; i++){ + if( sqlite3_stricmp(azRowid[j],azCol[i])==0 ) break; + } + if( i>nCol ){ + /* At this point, we know that azRowid[j] is not the name of any + ** ordinary column in the table. Verify that azRowid[j] is a valid + ** name for the rowid before adding it to azCol[0]. WITHOUT ROWID + ** tables will fail this last check */ + rc = sqlite3_table_column_metadata(p->db,0,zTab,azRowid[j],0,0,0,0,0); + if( rc==SQLITE_OK ) azCol[0] = azRowid[j]; + break; + } + } + } + return azCol; +} + +/* +** Toggle the reverse_unordered_selects setting. +*/ +static void toggleSelectOrder(sqlite3 *db){ + sqlite3_stmt *pStmt = 0; + int iSetting = 0; + char zStmt[100]; + sqlite3_prepare_v2(db, "PRAGMA reverse_unordered_selects", -1, &pStmt, 0); + if( sqlite3_step(pStmt)==SQLITE_ROW ){ + iSetting = sqlite3_column_int(pStmt, 0); + } + sqlite3_finalize(pStmt); + sqlite3_snprintf(sizeof(zStmt), zStmt, + "PRAGMA reverse_unordered_selects(%d)", !iSetting); + sqlite3_exec(db, zStmt, 0, 0, 0); +} + +/* +** This is a different callback routine used for dumping the database. +** Each row received by this callback consists of a table name, +** the table type ("index" or "table") and SQL to create the table. +** This routine should print text sufficient to recreate the table. +*/ +static int dump_callback(void *pArg, int nArg, char **azArg, char **azNotUsed){ + int rc; + const char *zTable; + const char *zType; + const char *zSql; + ShellState *p = (ShellState *)pArg; + + UNUSED_PARAMETER(azNotUsed); + if( nArg!=3 ) return 1; + zTable = azArg[0]; + zType = azArg[1]; + zSql = azArg[2]; + + if( strcmp(zTable, "sqlite_sequence")==0 ){ + raw_printf(p->out, "DELETE FROM sqlite_sequence;\n"); + }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){ + raw_printf(p->out, "ANALYZE sqlite_master;\n"); + }else if( strncmp(zTable, "sqlite_", 7)==0 ){ + return 0; + }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){ + char *zIns; + if( !p->writableSchema ){ + raw_printf(p->out, "PRAGMA writable_schema=ON;\n"); + p->writableSchema = 1; + } + zIns = sqlite3_mprintf( + "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)" + "VALUES('table','%q','%q',0,'%q');", + zTable, zTable, zSql); + utf8_printf(p->out, "%s\n", zIns); + sqlite3_free(zIns); + return 0; + }else{ + printSchemaLine(p->out, zSql, ";\n"); + } + + if( strcmp(zType, "table")==0 ){ + ShellText sSelect; + ShellText sTable; + char **azCol; + int i; + char *savedDestTable; + int savedMode; + + azCol = tableColumnList(p, zTable); + if( azCol==0 ){ + p->nErr++; + return 0; + } + + /* Always quote the table name, even if it appears to be pure ascii, + ** in case it is a keyword. Ex: INSERT INTO "table" ... */ + initText(&sTable); + appendText(&sTable, zTable, quoteChar(zTable)); + /* If preserving the rowid, add a column list after the table name. + ** In other words: "INSERT INTO tab(rowid,a,b,c,...) VALUES(...)" + ** instead of the usual "INSERT INTO tab VALUES(...)". + */ + if( azCol[0] ){ + appendText(&sTable, "(", 0); + appendText(&sTable, azCol[0], 0); + for(i=1; azCol[i]; i++){ + appendText(&sTable, ",", 0); + appendText(&sTable, azCol[i], quoteChar(azCol[i])); + } + appendText(&sTable, ")", 0); + } + + /* Build an appropriate SELECT statement */ + initText(&sSelect); + appendText(&sSelect, "SELECT ", 0); + if( azCol[0] ){ + appendText(&sSelect, azCol[0], 0); + appendText(&sSelect, ",", 0); + } + for(i=1; azCol[i]; i++){ + appendText(&sSelect, azCol[i], quoteChar(azCol[i])); + if( azCol[i+1] ){ + appendText(&sSelect, ",", 0); + } + } + freeColumnList(azCol); + appendText(&sSelect, " FROM ", 0); + appendText(&sSelect, zTable, quoteChar(zTable)); + + savedDestTable = p->zDestTable; + savedMode = p->mode; + p->zDestTable = sTable.z; + p->mode = p->cMode = MODE_Insert; + rc = shell_exec(p->db, sSelect.z, shell_callback, p, 0); + if( (rc&0xff)==SQLITE_CORRUPT ){ + raw_printf(p->out, "/****** CORRUPTION ERROR *******/\n"); + toggleSelectOrder(p->db); + shell_exec(p->db, sSelect.z, shell_callback, p, 0); + toggleSelectOrder(p->db); + } + p->zDestTable = savedDestTable; + p->mode = savedMode; + freeText(&sTable); + freeText(&sSelect); + if( rc ) p->nErr++; + } + return 0; +} + +/* +** Run zQuery. Use dump_callback() as the callback routine so that +** the contents of the query are output as SQL statements. +** +** If we get a SQLITE_CORRUPT error, rerun the query after appending +** "ORDER BY rowid DESC" to the end. +*/ +static int run_schema_dump_query( + ShellState *p, + const char *zQuery +){ + int rc; + char *zErr = 0; + rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr); + if( rc==SQLITE_CORRUPT ){ + char *zQ2; + int len = strlen30(zQuery); + raw_printf(p->out, "/****** CORRUPTION ERROR *******/\n"); + if( zErr ){ + utf8_printf(p->out, "/****** %s ******/\n", zErr); + sqlite3_free(zErr); + zErr = 0; + } + zQ2 = malloc( len+100 ); + if( zQ2==0 ) return rc; + sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery); + rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr); + if( rc ){ + utf8_printf(p->out, "/****** ERROR: %s ******/\n", zErr); + }else{ + rc = SQLITE_CORRUPT; + } + sqlite3_free(zErr); + free(zQ2); + } + return rc; +} + +/* +** Text of a help message +*/ +static char zHelp[] = +#ifndef SQLITE_OMIT_AUTHORIZATION + ".auth ON|OFF Show authorizer callbacks\n" +#endif + ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n" + ".bail on|off Stop after hitting an error. Default OFF\n" + ".binary on|off Turn binary output on or off. Default OFF\n" + ".cd DIRECTORY Change the working directory to DIRECTORY\n" + ".changes on|off Show number of rows changed by SQL\n" + ".check GLOB Fail if output since .testcase does not match\n" + ".clone NEWDB Clone data into NEWDB from the existing database\n" + ".databases List names and files of attached databases\n" + ".dbinfo ?DB? Show status information about the database\n" + ".dump ?TABLE? ... Dump the database in an SQL text format\n" + " If TABLE specified, only dump tables matching\n" + " LIKE pattern TABLE.\n" + ".echo on|off Turn command echo on or off\n" + ".eqp on|off|full Enable or disable automatic EXPLAIN QUERY PLAN\n" + ".exit Exit this program\n" +/* Because explain mode comes on automatically now, the ".explain" mode +** is removed from the help screen. It is still supported for legacy, however */ +/*".explain ?on|off|auto? Turn EXPLAIN output mode on or off or to automatic\n"*/ + ".fullschema ?--indent? Show schema and the content of sqlite_stat tables\n" + ".headers on|off Turn display of headers on or off\n" + ".help Show this message\n" + ".import FILE TABLE Import data from FILE into TABLE\n" +#ifndef SQLITE_OMIT_TEST_CONTROL + ".imposter INDEX TABLE Create imposter table TABLE on index INDEX\n" +#endif + ".indexes ?TABLE? Show names of all indexes\n" + " If TABLE specified, only show indexes for tables\n" + " matching LIKE pattern TABLE.\n" +#ifdef SQLITE_ENABLE_IOTRACE + ".iotrace FILE Enable I/O diagnostic logging to FILE\n" +#endif + ".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT\n" + ".lint OPTIONS Report potential schema issues. Options:\n" + " fkey-indexes Find missing foreign key indexes\n" +#ifndef SQLITE_OMIT_LOAD_EXTENSION + ".load FILE ?ENTRY? Load an extension library\n" +#endif + ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n" + ".mode MODE ?TABLE? Set output mode where MODE is one of:\n" + " ascii Columns/rows delimited by 0x1F and 0x1E\n" + " csv Comma-separated values\n" + " column Left-aligned columns. (See .width)\n" + " html HTML code\n" + " insert SQL insert statements for TABLE\n" + " line One value per line\n" + " list Values delimited by \"|\"\n" + " quote Escape answers as for SQL\n" + " tabs Tab-separated values\n" + " tcl TCL list elements\n" + ".nullvalue STRING Use STRING in place of NULL values\n" + ".once FILENAME Output for the next SQL command only to FILENAME\n" + ".open ?OPTIONS? ?FILE? Close existing database and reopen FILE\n" + " The --new option starts with an empty file\n" + ".output ?FILENAME? Send output to FILENAME or stdout\n" + ".print STRING... Print literal STRING\n" + ".prompt MAIN CONTINUE Replace the standard prompts\n" + ".quit Exit this program\n" + ".read FILENAME Execute SQL in FILENAME\n" + ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n" + ".save FILE Write in-memory database into FILE\n" + ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off\n" + ".schema ?PATTERN? Show the CREATE statements matching PATTERN\n" + " Add --indent for pretty-printing\n" + ".selftest ?--init? Run tests defined in the SELFTEST table\n" + ".separator COL ?ROW? Change the column separator and optionally the row\n" + " separator for both the output mode and .import\n" +#if defined(SQLITE_ENABLE_SESSION) + ".session CMD ... Create or control sessions\n" +#endif + ".sha3sum ?OPTIONS...? Compute a SHA3 hash of database content\n" + ".shell CMD ARGS... Run CMD ARGS... in a system shell\n" + ".show Show the current values for various settings\n" + ".stats ?on|off? Show stats or turn stats on or off\n" + ".system CMD ARGS... Run CMD ARGS... in a system shell\n" + ".tables ?TABLE? List names of tables\n" + " If TABLE specified, only list tables matching\n" + " LIKE pattern TABLE.\n" + ".testcase NAME Begin redirecting output to 'testcase-out.txt'\n" + ".timeout MS Try opening locked tables for MS milliseconds\n" + ".timer on|off Turn SQL timer on or off\n" + ".trace FILE|off Output each SQL statement as it is run\n" + ".vfsinfo ?AUX? Information about the top-level VFS\n" + ".vfslist List all available VFSes\n" + ".vfsname ?AUX? Print the name of the VFS stack\n" + ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n" + " Negative values right-justify\n" +; + +#if defined(SQLITE_ENABLE_SESSION) +/* +** Print help information for the ".sessions" command +*/ +void session_help(ShellState *p){ + raw_printf(p->out, + ".session ?NAME? SUBCOMMAND ?ARGS...?\n" + "If ?NAME? is omitted, the first defined session is used.\n" + "Subcommands:\n" + " attach TABLE Attach TABLE\n" + " changeset FILE Write a changeset into FILE\n" + " close Close one session\n" + " enable ?BOOLEAN? Set or query the enable bit\n" + " filter GLOB... Reject tables matching GLOBs\n" + " indirect ?BOOLEAN? Mark or query the indirect status\n" + " isempty Query whether the session is empty\n" + " list List currently open session names\n" + " open DB NAME Open a new session on DB\n" + " patchset FILE Write a patchset into FILE\n" + ); +} +#endif + + +/* Forward reference */ +static int process_input(ShellState *p, FILE *in); + +/* +** Read the content of file zName into memory obtained from sqlite3_malloc64() +** and return a pointer to the buffer. The caller is responsible for freeing +** the memory. +** +** If parameter pnByte is not NULL, (*pnByte) is set to the number of bytes +** read. +** +** For convenience, a nul-terminator byte is always appended to the data read +** from the file before the buffer is returned. This byte is not included in +** the final value of (*pnByte), if applicable. +** +** NULL is returned if any error is encountered. The final value of *pnByte +** is undefined in this case. +*/ +static char *readFile(const char *zName, int *pnByte){ + FILE *in = fopen(zName, "rb"); + long nIn; + size_t nRead; + char *pBuf; + if( in==0 ) return 0; + fseek(in, 0, SEEK_END); + nIn = ftell(in); + rewind(in); + pBuf = sqlite3_malloc64( nIn+1 ); + if( pBuf==0 ) return 0; + nRead = fread(pBuf, nIn, 1, in); + fclose(in); + if( nRead!=1 ){ + sqlite3_free(pBuf); + return 0; + } + pBuf[nIn] = 0; + if( pnByte ) *pnByte = nIn; + return pBuf; +} + +#if defined(SQLITE_ENABLE_SESSION) +/* +** Close a single OpenSession object and release all of its associated +** resources. +*/ +static void session_close(OpenSession *pSession){ + int i; + sqlite3session_delete(pSession->p); + sqlite3_free(pSession->zName); + for(i=0; inFilter; i++){ + sqlite3_free(pSession->azFilter[i]); + } + sqlite3_free(pSession->azFilter); + memset(pSession, 0, sizeof(OpenSession)); +} +#endif + +/* +** Close all OpenSession objects and release all associated resources. +*/ +#if defined(SQLITE_ENABLE_SESSION) +static void session_close_all(ShellState *p){ + int i; + for(i=0; inSession; i++){ + session_close(&p->aSession[i]); + } + p->nSession = 0; +} +#else +# define session_close_all(X) +#endif + +/* +** Implementation of the xFilter function for an open session. Omit +** any tables named by ".session filter" but let all other table through. +*/ +#if defined(SQLITE_ENABLE_SESSION) +static int session_filter(void *pCtx, const char *zTab){ + OpenSession *pSession = (OpenSession*)pCtx; + int i; + for(i=0; inFilter; i++){ + if( sqlite3_strglob(pSession->azFilter[i], zTab)==0 ) return 0; + } + return 1; +} +#endif + +/* +** Make sure the database is open. If it is not, then open it. If +** the database fails to open, print an error message and exit. +*/ +static void open_db(ShellState *p, int keepAlive){ + if( p->db==0 ){ + sqlite3_initialize(); + sqlite3_open(p->zDbFilename, &p->db); + globalDb = p->db; + if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){ + utf8_printf(stderr,"Error: unable to open database \"%s\": %s\n", + p->zDbFilename, sqlite3_errmsg(p->db)); + if( keepAlive ) return; + exit(1); + } +#ifndef SQLITE_OMIT_LOAD_EXTENSION + sqlite3_enable_load_extension(p->db, 1); +#endif + sqlite3_fileio_init(p->db, 0, 0); + sqlite3_shathree_init(p->db, 0, 0); + sqlite3_create_function(p->db, "shell_add_schema", 2, SQLITE_UTF8, 0, + shellAddSchemaName, 0, 0); + + } +} + +/* +** Do C-language style dequoting. +** +** \a -> alarm +** \b -> backspace +** \t -> tab +** \n -> newline +** \v -> vertical tab +** \f -> form feed +** \r -> carriage return +** \s -> space +** \" -> " +** \' -> ' +** \\ -> backslash +** \NNN -> ascii character NNN in octal +*/ +static void resolve_backslashes(char *z){ + int i, j; + char c; + while( *z && *z!='\\' ) z++; + for(i=j=0; (c = z[i])!=0; i++, j++){ + if( c=='\\' && z[i+1]!=0 ){ + c = z[++i]; + if( c=='a' ){ + c = '\a'; + }else if( c=='b' ){ + c = '\b'; + }else if( c=='t' ){ + c = '\t'; + }else if( c=='n' ){ + c = '\n'; + }else if( c=='v' ){ + c = '\v'; + }else if( c=='f' ){ + c = '\f'; + }else if( c=='r' ){ + c = '\r'; + }else if( c=='"' ){ + c = '"'; + }else if( c=='\'' ){ + c = '\''; + }else if( c=='\\' ){ + c = '\\'; + }else if( c>='0' && c<='7' ){ + c -= '0'; + if( z[i+1]>='0' && z[i+1]<='7' ){ + i++; + c = (c<<3) + z[i] - '0'; + if( z[i+1]>='0' && z[i+1]<='7' ){ + i++; + c = (c<<3) + z[i] - '0'; + } + } + } + } + z[j] = c; + } + if( j='0' && c<='9' ) return c - '0'; + if( c>='a' && c<='f' ) return c - 'a' + 10; + if( c>='A' && c<='F' ) return c - 'A' + 10; + return -1; +} + +/* +** Interpret zArg as an integer value, possibly with suffixes. +*/ +static sqlite3_int64 integerValue(const char *zArg){ + sqlite3_int64 v = 0; + static const struct { char *zSuffix; int iMult; } aMult[] = { + { "KiB", 1024 }, + { "MiB", 1024*1024 }, + { "GiB", 1024*1024*1024 }, + { "KB", 1000 }, + { "MB", 1000000 }, + { "GB", 1000000000 }, + { "K", 1000 }, + { "M", 1000000 }, + { "G", 1000000000 }, + }; + int i; + int isNeg = 0; + if( zArg[0]=='-' ){ + isNeg = 1; + zArg++; + }else if( zArg[0]=='+' ){ + zArg++; + } + if( zArg[0]=='0' && zArg[1]=='x' ){ + int x; + zArg += 2; + while( (x = hexDigitValue(zArg[0]))>=0 ){ + v = (v<<4) + x; + zArg++; + } + }else{ + while( IsDigit(zArg[0]) ){ + v = v*10 + zArg[0] - '0'; + zArg++; + } + } + for(i=0; i=0; i++){} + }else{ + for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){} + } + if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff); + if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){ + return 1; + } + if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){ + return 0; + } + utf8_printf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n", + zArg); + return 0; +} + +/* +** Set or clear a shell flag according to a boolean value. +*/ +static void setOrClearFlag(ShellState *p, unsigned mFlag, const char *zArg){ + if( booleanValue(zArg) ){ + ShellSetFlag(p, mFlag); + }else{ + ShellClearFlag(p, mFlag); + } +} + +/* +** Close an output file, assuming it is not stderr or stdout +*/ +static void output_file_close(FILE *f){ + if( f && f!=stdout && f!=stderr ) fclose(f); +} + +/* +** Try to open an output file. The names "stdout" and "stderr" are +** recognized and do the right thing. NULL is returned if the output +** filename is "off". +*/ +static FILE *output_file_open(const char *zFile){ + FILE *f; + if( strcmp(zFile,"stdout")==0 ){ + f = stdout; + }else if( strcmp(zFile, "stderr")==0 ){ + f = stderr; + }else if( strcmp(zFile, "off")==0 ){ + f = 0; + }else{ + f = fopen(zFile, "wb"); + if( f==0 ){ + utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile); + } + } + return f; +} + +#if !defined(SQLITE_UNTESTABLE) +#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) +/* +** A routine for handling output from sqlite3_trace(). +*/ +static int sql_trace_callback( + unsigned mType, + void *pArg, + void *pP, + void *pX +){ + FILE *f = (FILE*)pArg; + UNUSED_PARAMETER(mType); + UNUSED_PARAMETER(pP); + if( f ){ + const char *z = (const char*)pX; + int i = (int)strlen(z); + while( i>0 && z[i-1]==';' ){ i--; } + utf8_printf(f, "%.*s;\n", i, z); + } + return 0; +} +#endif +#endif + +/* +** A no-op routine that runs with the ".breakpoint" doc-command. This is +** a useful spot to set a debugger breakpoint. +*/ +static void test_breakpoint(void){ + static int nCall = 0; + nCall++; +} + +/* +** An object used to read a CSV and other files for import. +*/ +typedef struct ImportCtx ImportCtx; +struct ImportCtx { + const char *zFile; /* Name of the input file */ + FILE *in; /* Read the CSV text from this input stream */ + char *z; /* Accumulated text for a field */ + int n; /* Number of bytes in z */ + int nAlloc; /* Space allocated for z[] */ + int nLine; /* Current line number */ + int bNotFirst; /* True if one or more bytes already read */ + int cTerm; /* Character that terminated the most recent field */ + int cColSep; /* The column separator character. (Usually ",") */ + int cRowSep; /* The row separator character. (Usually "\n") */ +}; + +/* Append a single byte to z[] */ +static void import_append_char(ImportCtx *p, int c){ + if( p->n+1>=p->nAlloc ){ + p->nAlloc += p->nAlloc + 100; + p->z = sqlite3_realloc64(p->z, p->nAlloc); + if( p->z==0 ){ + raw_printf(stderr, "out of memory\n"); + exit(1); + } + } + p->z[p->n++] = (char)c; +} + +/* Read a single field of CSV text. Compatible with rfc4180 and extended +** with the option of having a separator other than ",". +** +** + Input comes from p->in. +** + Store results in p->z of length p->n. Space to hold p->z comes +** from sqlite3_malloc64(). +** + Use p->cSep as the column separator. The default is ",". +** + Use p->rSep as the row separator. The default is "\n". +** + Keep track of the line number in p->nLine. +** + Store the character that terminates the field in p->cTerm. Store +** EOF on end-of-file. +** + Report syntax errors on stderr +*/ +static char *SQLITE_CDECL csv_read_one_field(ImportCtx *p){ + int c; + int cSep = p->cColSep; + int rSep = p->cRowSep; + p->n = 0; + c = fgetc(p->in); + if( c==EOF || seenInterrupt ){ + p->cTerm = EOF; + return 0; + } + if( c=='"' ){ + int pc, ppc; + int startLine = p->nLine; + int cQuote = c; + pc = ppc = 0; + while( 1 ){ + c = fgetc(p->in); + if( c==rSep ) p->nLine++; + if( c==cQuote ){ + if( pc==cQuote ){ + pc = 0; + continue; + } + } + if( (c==cSep && pc==cQuote) + || (c==rSep && pc==cQuote) + || (c==rSep && pc=='\r' && ppc==cQuote) + || (c==EOF && pc==cQuote) + ){ + do{ p->n--; }while( p->z[p->n]!=cQuote ); + p->cTerm = c; + break; + } + if( pc==cQuote && c!='\r' ){ + utf8_printf(stderr, "%s:%d: unescaped %c character\n", + p->zFile, p->nLine, cQuote); + } + if( c==EOF ){ + utf8_printf(stderr, "%s:%d: unterminated %c-quoted field\n", + p->zFile, startLine, cQuote); + p->cTerm = c; + break; + } + import_append_char(p, c); + ppc = pc; + pc = c; + } + }else{ + /* If this is the first field being parsed and it begins with the + ** UTF-8 BOM (0xEF BB BF) then skip the BOM */ + if( (c&0xff)==0xef && p->bNotFirst==0 ){ + import_append_char(p, c); + c = fgetc(p->in); + if( (c&0xff)==0xbb ){ + import_append_char(p, c); + c = fgetc(p->in); + if( (c&0xff)==0xbf ){ + p->bNotFirst = 1; + p->n = 0; + return csv_read_one_field(p); + } + } + } + while( c!=EOF && c!=cSep && c!=rSep ){ + import_append_char(p, c); + c = fgetc(p->in); + } + if( c==rSep ){ + p->nLine++; + if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--; + } + p->cTerm = c; + } + if( p->z ) p->z[p->n] = 0; + p->bNotFirst = 1; + return p->z; +} + +/* Read a single field of ASCII delimited text. +** +** + Input comes from p->in. +** + Store results in p->z of length p->n. Space to hold p->z comes +** from sqlite3_malloc64(). +** + Use p->cSep as the column separator. The default is "\x1F". +** + Use p->rSep as the row separator. The default is "\x1E". +** + Keep track of the row number in p->nLine. +** + Store the character that terminates the field in p->cTerm. Store +** EOF on end-of-file. +** + Report syntax errors on stderr +*/ +static char *SQLITE_CDECL ascii_read_one_field(ImportCtx *p){ + int c; + int cSep = p->cColSep; + int rSep = p->cRowSep; + p->n = 0; + c = fgetc(p->in); + if( c==EOF || seenInterrupt ){ + p->cTerm = EOF; + return 0; + } + while( c!=EOF && c!=cSep && c!=rSep ){ + import_append_char(p, c); + c = fgetc(p->in); + } + if( c==rSep ){ + p->nLine++; + } + p->cTerm = c; + if( p->z ) p->z[p->n] = 0; + return p->z; +} + +/* +** Try to transfer data for table zTable. If an error is seen while +** moving forward, try to go backwards. The backwards movement won't +** work for WITHOUT ROWID tables. +*/ +static void tryToCloneData( + ShellState *p, + sqlite3 *newDb, + const char *zTable +){ + sqlite3_stmt *pQuery = 0; + sqlite3_stmt *pInsert = 0; + char *zQuery = 0; + char *zInsert = 0; + int rc; + int i, j, n; + int nTable = (int)strlen(zTable); + int k = 0; + int cnt = 0; + const int spinRate = 10000; + + zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable); + rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0); + if( rc ){ + utf8_printf(stderr, "Error %d: %s on [%s]\n", + sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db), + zQuery); + goto end_data_xfer; + } + n = sqlite3_column_count(pQuery); + zInsert = sqlite3_malloc64(200 + nTable + n*3); + if( zInsert==0 ){ + raw_printf(stderr, "out of memory\n"); + goto end_data_xfer; + } + sqlite3_snprintf(200+nTable,zInsert, + "INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable); + i = (int)strlen(zInsert); + for(j=1; jdb, zQuery, -1, &pQuery, 0); + if( rc ){ + utf8_printf(stderr, "Warning: cannot step \"%s\" backwards", zTable); + break; + } + } /* End for(k=0...) */ + +end_data_xfer: + sqlite3_finalize(pQuery); + sqlite3_finalize(pInsert); + sqlite3_free(zQuery); + sqlite3_free(zInsert); +} + + +/* +** Try to transfer all rows of the schema that match zWhere. For +** each row, invoke xForEach() on the object defined by that row. +** If an error is encountered while moving forward through the +** sqlite_master table, try again moving backwards. +*/ +static void tryToCloneSchema( + ShellState *p, + sqlite3 *newDb, + const char *zWhere, + void (*xForEach)(ShellState*,sqlite3*,const char*) +){ + sqlite3_stmt *pQuery = 0; + char *zQuery = 0; + int rc; + const unsigned char *zName; + const unsigned char *zSql; + char *zErrMsg = 0; + + zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master" + " WHERE %s", zWhere); + rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0); + if( rc ){ + utf8_printf(stderr, "Error: (%d) %s on [%s]\n", + sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db), + zQuery); + goto end_schema_xfer; + } + while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){ + zName = sqlite3_column_text(pQuery, 0); + zSql = sqlite3_column_text(pQuery, 1); + printf("%s... ", zName); fflush(stdout); + sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg); + if( zErrMsg ){ + utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql); + sqlite3_free(zErrMsg); + zErrMsg = 0; + } + if( xForEach ){ + xForEach(p, newDb, (const char*)zName); + } + printf("done\n"); + } + if( rc!=SQLITE_DONE ){ + sqlite3_finalize(pQuery); + sqlite3_free(zQuery); + zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master" + " WHERE %s ORDER BY rowid DESC", zWhere); + rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0); + if( rc ){ + utf8_printf(stderr, "Error: (%d) %s on [%s]\n", + sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db), + zQuery); + goto end_schema_xfer; + } + while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){ + zName = sqlite3_column_text(pQuery, 0); + zSql = sqlite3_column_text(pQuery, 1); + printf("%s... ", zName); fflush(stdout); + sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg); + if( zErrMsg ){ + utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql); + sqlite3_free(zErrMsg); + zErrMsg = 0; + } + if( xForEach ){ + xForEach(p, newDb, (const char*)zName); + } + printf("done\n"); + } + } +end_schema_xfer: + sqlite3_finalize(pQuery); + sqlite3_free(zQuery); +} + +/* +** Open a new database file named "zNewDb". Try to recover as much information +** as possible out of the main database (which might be corrupt) and write it +** into zNewDb. +*/ +static void tryToClone(ShellState *p, const char *zNewDb){ + int rc; + sqlite3 *newDb = 0; + if( access(zNewDb,0)==0 ){ + utf8_printf(stderr, "File \"%s\" already exists.\n", zNewDb); + return; + } + rc = sqlite3_open(zNewDb, &newDb); + if( rc ){ + utf8_printf(stderr, "Cannot create output database: %s\n", + sqlite3_errmsg(newDb)); + }else{ + sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0); + sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0); + tryToCloneSchema(p, newDb, "type='table'", tryToCloneData); + tryToCloneSchema(p, newDb, "type!='table'", 0); + sqlite3_exec(newDb, "COMMIT;", 0, 0, 0); + sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0); + } + sqlite3_close(newDb); +} + +/* +** Change the output file back to stdout +*/ +static void output_reset(ShellState *p){ + if( p->outfile[0]=='|' ){ +#ifndef SQLITE_OMIT_POPEN + pclose(p->out); +#endif + }else{ + output_file_close(p->out); + } + p->outfile[0] = 0; + p->out = stdout; +} + +/* +** Run an SQL command and return the single integer result. +*/ +static int db_int(ShellState *p, const char *zSql){ + sqlite3_stmt *pStmt; + int res = 0; + sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); + if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){ + res = sqlite3_column_int(pStmt,0); + } + sqlite3_finalize(pStmt); + return res; +} + +/* +** Convert a 2-byte or 4-byte big-endian integer into a native integer +*/ +static unsigned int get2byteInt(unsigned char *a){ + return (a[0]<<8) + a[1]; +} +static unsigned int get4byteInt(unsigned char *a){ + return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3]; +} + +/* +** Implementation of the ".info" command. +** +** Return 1 on error, 2 to exit, and 0 otherwise. +*/ +static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){ + static const struct { const char *zName; int ofst; } aField[] = { + { "file change counter:", 24 }, + { "database page count:", 28 }, + { "freelist page count:", 36 }, + { "schema cookie:", 40 }, + { "schema format:", 44 }, + { "default cache size:", 48 }, + { "autovacuum top root:", 52 }, + { "incremental vacuum:", 64 }, + { "text encoding:", 56 }, + { "user version:", 60 }, + { "application id:", 68 }, + { "software version:", 96 }, + }; + static const struct { const char *zName; const char *zSql; } aQuery[] = { + { "number of tables:", + "SELECT count(*) FROM %s WHERE type='table'" }, + { "number of indexes:", + "SELECT count(*) FROM %s WHERE type='index'" }, + { "number of triggers:", + "SELECT count(*) FROM %s WHERE type='trigger'" }, + { "number of views:", + "SELECT count(*) FROM %s WHERE type='view'" }, + { "schema size:", + "SELECT total(length(sql)) FROM %s" }, + }; + sqlite3_file *pFile = 0; + int i; + char *zSchemaTab; + char *zDb = nArg>=2 ? azArg[1] : "main"; + unsigned char aHdr[100]; + open_db(p, 0); + if( p->db==0 ) return 1; + sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_FILE_POINTER, &pFile); + if( pFile==0 || pFile->pMethods==0 || pFile->pMethods->xRead==0 ){ + return 1; + } + i = pFile->pMethods->xRead(pFile, aHdr, 100, 0); + if( i!=SQLITE_OK ){ + raw_printf(stderr, "unable to read database header\n"); + return 1; + } + i = get2byteInt(aHdr+16); + if( i==1 ) i = 65536; + utf8_printf(p->out, "%-20s %d\n", "database page size:", i); + utf8_printf(p->out, "%-20s %d\n", "write format:", aHdr[18]); + utf8_printf(p->out, "%-20s %d\n", "read format:", aHdr[19]); + utf8_printf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]); + for(i=0; iout, "%-20s %u", aField[i].zName, val); + switch( ofst ){ + case 56: { + if( val==1 ) raw_printf(p->out, " (utf8)"); + if( val==2 ) raw_printf(p->out, " (utf16le)"); + if( val==3 ) raw_printf(p->out, " (utf16be)"); + } + } + raw_printf(p->out, "\n"); + } + if( zDb==0 ){ + zSchemaTab = sqlite3_mprintf("main.sqlite_master"); + }else if( strcmp(zDb,"temp")==0 ){ + zSchemaTab = sqlite3_mprintf("%s", "sqlite_temp_master"); + }else{ + zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_master", zDb); + } + for(i=0; iout, "%-20s %d\n", aQuery[i].zName, val); + } + sqlite3_free(zSchemaTab); + return 0; +} + +/* +** Print the current sqlite3_errmsg() value to stderr and return 1. +*/ +static int shellDatabaseError(sqlite3 *db){ + const char *zErr = sqlite3_errmsg(db); + utf8_printf(stderr, "Error: %s\n", zErr); + return 1; +} + +/* +** Print an out-of-memory message to stderr and return 1. +*/ +static int shellNomemError(void){ + raw_printf(stderr, "Error: out of memory\n"); + return 1; +} + +/* +** Compare the pattern in zGlob[] against the text in z[]. Return TRUE +** if they match and FALSE (0) if they do not match. +** +** Globbing rules: +** +** '*' Matches any sequence of zero or more characters. +** +** '?' Matches exactly one character. +** +** [...] Matches one character from the enclosed list of +** characters. +** +** [^...] Matches one character not in the enclosed list. +** +** '#' Matches any sequence of one or more digits with an +** optional + or - sign in front +** +** ' ' Any span of whitespace matches any other span of +** whitespace. +** +** Extra whitespace at the end of z[] is ignored. +*/ +static int testcase_glob(const char *zGlob, const char *z){ + int c, c2; + int invert; + int seen; + + while( (c = (*(zGlob++)))!=0 ){ + if( IsSpace(c) ){ + if( !IsSpace(*z) ) return 0; + while( IsSpace(*zGlob) ) zGlob++; + while( IsSpace(*z) ) z++; + }else if( c=='*' ){ + while( (c=(*(zGlob++))) == '*' || c=='?' ){ + if( c=='?' && (*(z++))==0 ) return 0; + } + if( c==0 ){ + return 1; + }else if( c=='[' ){ + while( *z && testcase_glob(zGlob-1,z)==0 ){ + z++; + } + return (*z)!=0; + } + while( (c2 = (*(z++)))!=0 ){ + while( c2!=c ){ + c2 = *(z++); + if( c2==0 ) return 0; + } + if( testcase_glob(zGlob,z) ) return 1; + } + return 0; + }else if( c=='?' ){ + if( (*(z++))==0 ) return 0; + }else if( c=='[' ){ + int prior_c = 0; + seen = 0; + invert = 0; + c = *(z++); + if( c==0 ) return 0; + c2 = *(zGlob++); + if( c2=='^' ){ + invert = 1; + c2 = *(zGlob++); + } + if( c2==']' ){ + if( c==']' ) seen = 1; + c2 = *(zGlob++); + } + while( c2 && c2!=']' ){ + if( c2=='-' && zGlob[0]!=']' && zGlob[0]!=0 && prior_c>0 ){ + c2 = *(zGlob++); + if( c>=prior_c && c<=c2 ) seen = 1; + prior_c = 0; + }else{ + if( c==c2 ){ + seen = 1; + } + prior_c = c2; + } + c2 = *(zGlob++); + } + if( c2==0 || (seen ^ invert)==0 ) return 0; + }else if( c=='#' ){ + if( (z[0]=='-' || z[0]=='+') && IsDigit(z[1]) ) z++; + if( !IsDigit(z[0]) ) return 0; + z++; + while( IsDigit(z[0]) ){ z++; } + }else{ + if( c!=(*(z++)) ) return 0; + } + } + while( IsSpace(*z) ){ z++; } + return *z==0; +} + + +/* +** Compare the string as a command-line option with either one or two +** initial "-" characters. +*/ +static int optionMatch(const char *zStr, const char *zOpt){ + if( zStr[0]!='-' ) return 0; + zStr++; + if( zStr[0]=='-' ) zStr++; + return strcmp(zStr, zOpt)==0; +} + +/* +** Delete a file. +*/ +int shellDeleteFile(const char *zFilename){ + int rc; +#ifdef _WIN32 + wchar_t *z = sqlite3_win32_utf8_to_unicode(zFilename); + rc = _wunlink(z); + sqlite3_free(z); +#else + rc = unlink(zFilename); +#endif + return rc; +} + + +/* +** The implementation of SQL scalar function fkey_collate_clause(), used +** by the ".lint fkey-indexes" command. This scalar function is always +** called with four arguments - the parent table name, the parent column name, +** the child table name and the child column name. +** +** fkey_collate_clause('parent-tab', 'parent-col', 'child-tab', 'child-col') +** +** If either of the named tables or columns do not exist, this function +** returns an empty string. An empty string is also returned if both tables +** and columns exist but have the same default collation sequence. Or, +** if both exist but the default collation sequences are different, this +** function returns the string " COLLATE ", where +** is the default collation sequence of the parent column. +*/ +static void shellFkeyCollateClause( + sqlite3_context *pCtx, + int nVal, + sqlite3_value **apVal +){ + sqlite3 *db = sqlite3_context_db_handle(pCtx); + const char *zParent; + const char *zParentCol; + const char *zParentSeq; + const char *zChild; + const char *zChildCol; + const char *zChildSeq = 0; /* Initialize to avoid false-positive warning */ + int rc; + + assert( nVal==4 ); + zParent = (const char*)sqlite3_value_text(apVal[0]); + zParentCol = (const char*)sqlite3_value_text(apVal[1]); + zChild = (const char*)sqlite3_value_text(apVal[2]); + zChildCol = (const char*)sqlite3_value_text(apVal[3]); + + sqlite3_result_text(pCtx, "", -1, SQLITE_STATIC); + rc = sqlite3_table_column_metadata( + db, "main", zParent, zParentCol, 0, &zParentSeq, 0, 0, 0 + ); + if( rc==SQLITE_OK ){ + rc = sqlite3_table_column_metadata( + db, "main", zChild, zChildCol, 0, &zChildSeq, 0, 0, 0 + ); + } + + if( rc==SQLITE_OK && sqlite3_stricmp(zParentSeq, zChildSeq) ){ + char *z = sqlite3_mprintf(" COLLATE %s", zParentSeq); + sqlite3_result_text(pCtx, z, -1, SQLITE_TRANSIENT); + sqlite3_free(z); + } +} + + +/* +** The implementation of dot-command ".lint fkey-indexes". +*/ +static int lintFkeyIndexes( + ShellState *pState, /* Current shell tool state */ + char **azArg, /* Array of arguments passed to dot command */ + int nArg /* Number of entries in azArg[] */ +){ + sqlite3 *db = pState->db; /* Database handle to query "main" db of */ + FILE *out = pState->out; /* Stream to write non-error output to */ + int bVerbose = 0; /* If -verbose is present */ + int bGroupByParent = 0; /* If -groupbyparent is present */ + int i; /* To iterate through azArg[] */ + const char *zIndent = ""; /* How much to indent CREATE INDEX by */ + int rc; /* Return code */ + sqlite3_stmt *pSql = 0; /* Compiled version of SQL statement below */ + + /* + ** This SELECT statement returns one row for each foreign key constraint + ** in the schema of the main database. The column values are: + ** + ** 0. The text of an SQL statement similar to: + ** + ** "EXPLAIN QUERY PLAN SELECT rowid FROM child_table WHERE child_key=?" + ** + ** This is the same SELECT that the foreign keys implementation needs + ** to run internally on child tables. If there is an index that can + ** be used to optimize this query, then it can also be used by the FK + ** implementation to optimize DELETE or UPDATE statements on the parent + ** table. + ** + ** 1. A GLOB pattern suitable for sqlite3_strglob(). If the plan output by + ** the EXPLAIN QUERY PLAN command matches this pattern, then the schema + ** contains an index that can be used to optimize the query. + ** + ** 2. Human readable text that describes the child table and columns. e.g. + ** + ** "child_table(child_key1, child_key2)" + ** + ** 3. Human readable text that describes the parent table and columns. e.g. + ** + ** "parent_table(parent_key1, parent_key2)" + ** + ** 4. A full CREATE INDEX statement for an index that could be used to + ** optimize DELETE or UPDATE statements on the parent table. e.g. + ** + ** "CREATE INDEX child_table_child_key ON child_table(child_key)" + ** + ** 5. The name of the parent table. + ** + ** These six values are used by the C logic below to generate the report. + */ + const char *zSql = + "SELECT " + " 'EXPLAIN QUERY PLAN SELECT rowid FROM ' || quote(s.name) || ' WHERE '" + " || group_concat(quote(s.name) || '.' || quote(f.[from]) || '=?' " + " || fkey_collate_clause(" + " f.[table], COALESCE(f.[to], p.[name]), s.name, f.[from]),' AND ')" + ", " + " 'SEARCH TABLE ' || s.name || ' USING COVERING INDEX*('" + " || group_concat('*=?', ' AND ') || ')'" + ", " + " s.name || '(' || group_concat(f.[from], ', ') || ')'" + ", " + " f.[table] || '(' || group_concat(COALESCE(f.[to], p.[name])) || ')'" + ", " + " 'CREATE INDEX ' || quote(s.name ||'_'|| group_concat(f.[from], '_'))" + " || ' ON ' || quote(s.name) || '('" + " || group_concat(quote(f.[from]) ||" + " fkey_collate_clause(" + " f.[table], COALESCE(f.[to], p.[name]), s.name, f.[from]), ', ')" + " || ');'" + ", " + " f.[table] " + "FROM sqlite_master AS s, pragma_foreign_key_list(s.name) AS f " + "LEFT JOIN pragma_table_info AS p ON (pk-1=seq AND p.arg=f.[table]) " + "GROUP BY s.name, f.id " + "ORDER BY (CASE WHEN ? THEN f.[table] ELSE s.name END)" + ; + const char *zGlobIPK = "SEARCH TABLE * USING INTEGER PRIMARY KEY (rowid=?)"; + + for(i=2; i1 && sqlite3_strnicmp("-verbose", azArg[i], n)==0 ){ + bVerbose = 1; + } + else if( n>1 && sqlite3_strnicmp("-groupbyparent", azArg[i], n)==0 ){ + bGroupByParent = 1; + zIndent = " "; + } + else{ + raw_printf(stderr, "Usage: %s %s ?-verbose? ?-groupbyparent?\n", + azArg[0], azArg[1] + ); + return SQLITE_ERROR; + } + } + + /* Register the fkey_collate_clause() SQL function */ + rc = sqlite3_create_function(db, "fkey_collate_clause", 4, SQLITE_UTF8, + 0, shellFkeyCollateClause, 0, 0 + ); + + + if( rc==SQLITE_OK ){ + rc = sqlite3_prepare_v2(db, zSql, -1, &pSql, 0); + } + if( rc==SQLITE_OK ){ + sqlite3_bind_int(pSql, 1, bGroupByParent); + } + + if( rc==SQLITE_OK ){ + int rc2; + char *zPrev = 0; + while( SQLITE_ROW==sqlite3_step(pSql) ){ + int res = -1; + sqlite3_stmt *pExplain = 0; + const char *zEQP = (const char*)sqlite3_column_text(pSql, 0); + const char *zGlob = (const char*)sqlite3_column_text(pSql, 1); + const char *zFrom = (const char*)sqlite3_column_text(pSql, 2); + const char *zTarget = (const char*)sqlite3_column_text(pSql, 3); + const char *zCI = (const char*)sqlite3_column_text(pSql, 4); + const char *zParent = (const char*)sqlite3_column_text(pSql, 5); + + rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0); + if( rc!=SQLITE_OK ) break; + if( SQLITE_ROW==sqlite3_step(pExplain) ){ + const char *zPlan = (const char*)sqlite3_column_text(pExplain, 3); + res = ( + 0==sqlite3_strglob(zGlob, zPlan) + || 0==sqlite3_strglob(zGlobIPK, zPlan) + ); + } + rc = sqlite3_finalize(pExplain); + if( rc!=SQLITE_OK ) break; + + if( res<0 ){ + raw_printf(stderr, "Error: internal error"); + break; + }else{ + if( bGroupByParent + && (bVerbose || res==0) + && (zPrev==0 || sqlite3_stricmp(zParent, zPrev)) + ){ + raw_printf(out, "-- Parent table %s\n", zParent); + sqlite3_free(zPrev); + zPrev = sqlite3_mprintf("%s", zParent); + } + + if( res==0 ){ + raw_printf(out, "%s%s --> %s\n", zIndent, zCI, zTarget); + }else if( bVerbose ){ + raw_printf(out, "%s/* no extra indexes required for %s -> %s */\n", + zIndent, zFrom, zTarget + ); + } + } + } + sqlite3_free(zPrev); + + if( rc!=SQLITE_OK ){ + raw_printf(stderr, "%s\n", sqlite3_errmsg(db)); + } + + rc2 = sqlite3_finalize(pSql); + if( rc==SQLITE_OK && rc2!=SQLITE_OK ){ + rc = rc2; + raw_printf(stderr, "%s\n", sqlite3_errmsg(db)); + } + }else{ + raw_printf(stderr, "%s\n", sqlite3_errmsg(db)); + } + + return rc; +} + +/* +** Implementation of ".lint" dot command. +*/ +static int lintDotCommand( + ShellState *pState, /* Current shell tool state */ + char **azArg, /* Array of arguments passed to dot command */ + int nArg /* Number of entries in azArg[] */ +){ + int n; + n = (nArg>=2 ? (int)strlen(azArg[1]) : 0); + if( n<1 || sqlite3_strnicmp(azArg[1], "fkey-indexes", n) ) goto usage; + return lintFkeyIndexes(pState, azArg, nArg); + + usage: + raw_printf(stderr, "Usage %s sub-command ?switches...?\n", azArg[0]); + raw_printf(stderr, "Where sub-commands are:\n"); + raw_printf(stderr, " fkey-indexes\n"); + return SQLITE_ERROR; +} + + +/* +** If an input line begins with "." then invoke this routine to +** process that line. +** +** Return 1 on error, 2 to exit, and 0 otherwise. +*/ +static int do_meta_command(char *zLine, ShellState *p){ + int h = 1; + int nArg = 0; + int n, c; + int rc = 0; + char *azArg[50]; + + /* Parse the input line into tokens. + */ + while( zLine[h] && nArgdb, shellAuth, p); + }else{ + sqlite3_set_authorizer(p->db, 0, 0); + } + }else +#endif + + if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0) + || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0) + ){ + const char *zDestFile = 0; + const char *zDb = 0; + sqlite3 *pDest; + sqlite3_backup *pBackup; + int j; + for(j=1; jdb, zDb); + if( pBackup==0 ){ + utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest)); + sqlite3_close(pDest); + return 1; + } + while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){} + sqlite3_backup_finish(pBackup); + if( rc==SQLITE_DONE ){ + rc = 0; + }else{ + utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest)); + rc = 1; + } + sqlite3_close(pDest); + }else + + if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){ + if( nArg==2 ){ + bail_on_error = booleanValue(azArg[1]); + }else{ + raw_printf(stderr, "Usage: .bail on|off\n"); + rc = 1; + } + }else + + if( c=='b' && n>=3 && strncmp(azArg[0], "binary", n)==0 ){ + if( nArg==2 ){ + if( booleanValue(azArg[1]) ){ + setBinaryMode(p->out, 1); + }else{ + setTextMode(p->out, 1); + } + }else{ + raw_printf(stderr, "Usage: .binary on|off\n"); + rc = 1; + } + }else + + if( c=='c' && strcmp(azArg[0],"cd")==0 ){ + if( nArg==2 ){ +#if defined(_WIN32) || defined(WIN32) + wchar_t *z = sqlite3_win32_utf8_to_unicode(azArg[1]); + rc = !SetCurrentDirectoryW(z); + sqlite3_free(z); +#else + rc = chdir(azArg[1]); +#endif + if( rc ){ + utf8_printf(stderr, "Cannot change to directory \"%s\"\n", azArg[1]); + rc = 1; + } + }else{ + raw_printf(stderr, "Usage: .cd DIRECTORY\n"); + rc = 1; + } + }else + + /* The undocumented ".breakpoint" command causes a call to the no-op + ** routine named test_breakpoint(). + */ + if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){ + test_breakpoint(); + }else + + if( c=='c' && n>=3 && strncmp(azArg[0], "changes", n)==0 ){ + if( nArg==2 ){ + setOrClearFlag(p, SHFLG_CountChanges, azArg[1]); + }else{ + raw_printf(stderr, "Usage: .changes on|off\n"); + rc = 1; + } + }else + + /* Cancel output redirection, if it is currently set (by .testcase) + ** Then read the content of the testcase-out.txt file and compare against + ** azArg[1]. If there are differences, report an error and exit. + */ + if( c=='c' && n>=3 && strncmp(azArg[0], "check", n)==0 ){ + char *zRes = 0; + output_reset(p); + if( nArg!=2 ){ + raw_printf(stderr, "Usage: .check GLOB-PATTERN\n"); + rc = 2; + }else if( (zRes = readFile("testcase-out.txt", 0))==0 ){ + raw_printf(stderr, "Error: cannot read 'testcase-out.txt'\n"); + rc = 2; + }else if( testcase_glob(azArg[1],zRes)==0 ){ + utf8_printf(stderr, + "testcase-%s FAILED\n Expected: [%s]\n Got: [%s]\n", + p->zTestcase, azArg[1], zRes); + rc = 2; + }else{ + utf8_printf(stdout, "testcase-%s ok\n", p->zTestcase); + p->nCheck++; + } + sqlite3_free(zRes); + }else + + if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){ + if( nArg==2 ){ + tryToClone(p, azArg[1]); + }else{ + raw_printf(stderr, "Usage: .clone FILENAME\n"); + rc = 1; + } + }else + + if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){ + ShellState data; + char *zErrMsg = 0; + open_db(p, 0); + memcpy(&data, p, sizeof(data)); + data.showHeader = 0; + data.cMode = data.mode = MODE_List; + sqlite3_snprintf(sizeof(data.colSeparator),data.colSeparator,": "); + data.cnt = 0; + sqlite3_exec(p->db, "SELECT name, file FROM pragma_database_list", + callback, &data, &zErrMsg); + if( zErrMsg ){ + utf8_printf(stderr,"Error: %s\n", zErrMsg); + sqlite3_free(zErrMsg); + rc = 1; + } + }else + + if( c=='d' && strncmp(azArg[0], "dbinfo", n)==0 ){ + rc = shell_dbinfo_command(p, nArg, azArg); + }else + + if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){ + const char *zLike = 0; + int i; + int savedShowHeader = p->showHeader; + ShellClearFlag(p, SHFLG_PreserveRowid|SHFLG_Newlines); + for(i=1; iout, "PRAGMA foreign_keys=OFF;\n"); + raw_printf(p->out, "BEGIN TRANSACTION;\n"); + p->writableSchema = 0; + p->showHeader = 0; + /* Set writable_schema=ON since doing so forces SQLite to initialize + ** as much of the schema as it can even if the sqlite_master table is + ** corrupt. */ + sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0); + p->nErr = 0; + if( zLike==0 ){ + run_schema_dump_query(p, + "SELECT name, type, sql FROM sqlite_master " + "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'" + ); + run_schema_dump_query(p, + "SELECT name, type, sql FROM sqlite_master " + "WHERE name=='sqlite_sequence'" + ); + run_table_dump_query(p, + "SELECT sql FROM sqlite_master " + "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0 + ); + }else{ + char *zSql; + zSql = sqlite3_mprintf( + "SELECT name, type, sql FROM sqlite_master " + "WHERE tbl_name LIKE %Q AND type=='table'" + " AND sql NOT NULL", zLike); + run_schema_dump_query(p,zSql); + sqlite3_free(zSql); + zSql = sqlite3_mprintf( + "SELECT sql FROM sqlite_master " + "WHERE sql NOT NULL" + " AND type IN ('index','trigger','view')" + " AND tbl_name LIKE %Q", zLike); + run_table_dump_query(p, zSql, 0); + sqlite3_free(zSql); + } + if( p->writableSchema ){ + raw_printf(p->out, "PRAGMA writable_schema=OFF;\n"); + p->writableSchema = 0; + } + sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0); + sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0); + raw_printf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n"); + p->showHeader = savedShowHeader; + }else + + if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){ + if( nArg==2 ){ + setOrClearFlag(p, SHFLG_Echo, azArg[1]); + }else{ + raw_printf(stderr, "Usage: .echo on|off\n"); + rc = 1; + } + }else + + if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){ + if( nArg==2 ){ + if( strcmp(azArg[1],"full")==0 ){ + p->autoEQP = 2; + }else{ + p->autoEQP = booleanValue(azArg[1]); + } + }else{ + raw_printf(stderr, "Usage: .eqp on|off|full\n"); + rc = 1; + } + }else + + if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){ + if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc); + rc = 2; + }else + + /* The ".explain" command is automatic now. It is largely pointless. It + ** retained purely for backwards compatibility */ + if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){ + int val = 1; + if( nArg>=2 ){ + if( strcmp(azArg[1],"auto")==0 ){ + val = 99; + }else{ + val = booleanValue(azArg[1]); + } + } + if( val==1 && p->mode!=MODE_Explain ){ + p->normalMode = p->mode; + p->mode = MODE_Explain; + p->autoExplain = 0; + }else if( val==0 ){ + if( p->mode==MODE_Explain ) p->mode = p->normalMode; + p->autoExplain = 0; + }else if( val==99 ){ + if( p->mode==MODE_Explain ) p->mode = p->normalMode; + p->autoExplain = 1; + } + }else + + if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){ + ShellState data; + char *zErrMsg = 0; + int doStats = 0; + memcpy(&data, p, sizeof(data)); + data.showHeader = 0; + data.cMode = data.mode = MODE_Semi; + if( nArg==2 && optionMatch(azArg[1], "indent") ){ + data.cMode = data.mode = MODE_Pretty; + nArg = 1; + } + if( nArg!=1 ){ + raw_printf(stderr, "Usage: .fullschema ?--indent?\n"); + rc = 1; + goto meta_command_exit; + } + open_db(p, 0); + rc = sqlite3_exec(p->db, + "SELECT sql FROM" + " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x" + " FROM sqlite_master UNION ALL" + " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) " + "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' " + "ORDER BY rowid", + callback, &data, &zErrMsg + ); + if( rc==SQLITE_OK ){ + sqlite3_stmt *pStmt; + rc = sqlite3_prepare_v2(p->db, + "SELECT rowid FROM sqlite_master" + " WHERE name GLOB 'sqlite_stat[134]'", + -1, &pStmt, 0); + doStats = sqlite3_step(pStmt)==SQLITE_ROW; + sqlite3_finalize(pStmt); + } + if( doStats==0 ){ + raw_printf(p->out, "/* No STAT tables available */\n"); + }else{ + raw_printf(p->out, "ANALYZE sqlite_master;\n"); + sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master'", + callback, &data, &zErrMsg); + data.cMode = data.mode = MODE_Insert; + data.zDestTable = "sqlite_stat1"; + shell_exec(p->db, "SELECT * FROM sqlite_stat1", + shell_callback, &data,&zErrMsg); + data.zDestTable = "sqlite_stat3"; + shell_exec(p->db, "SELECT * FROM sqlite_stat3", + shell_callback, &data,&zErrMsg); + data.zDestTable = "sqlite_stat4"; + shell_exec(p->db, "SELECT * FROM sqlite_stat4", + shell_callback, &data, &zErrMsg); + raw_printf(p->out, "ANALYZE sqlite_master;\n"); + } + }else + + if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){ + if( nArg==2 ){ + p->showHeader = booleanValue(azArg[1]); + }else{ + raw_printf(stderr, "Usage: .headers on|off\n"); + rc = 1; + } + }else + + if( c=='h' && strncmp(azArg[0], "help", n)==0 ){ + utf8_printf(p->out, "%s", zHelp); + }else + + if( c=='i' && strncmp(azArg[0], "import", n)==0 ){ + char *zTable; /* Insert data into this table */ + char *zFile; /* Name of file to extra content from */ + sqlite3_stmt *pStmt = NULL; /* A statement */ + int nCol; /* Number of columns in the table */ + int nByte; /* Number of bytes in an SQL string */ + int i, j; /* Loop counters */ + int needCommit; /* True to COMMIT or ROLLBACK at end */ + int nSep; /* Number of bytes in p->colSeparator[] */ + char *zSql; /* An SQL statement */ + ImportCtx sCtx; /* Reader context */ + char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */ + int (SQLITE_CDECL *xCloser)(FILE*); /* Func to close file */ + + if( nArg!=3 ){ + raw_printf(stderr, "Usage: .import FILE TABLE\n"); + goto meta_command_exit; + } + zFile = azArg[1]; + zTable = azArg[2]; + seenInterrupt = 0; + memset(&sCtx, 0, sizeof(sCtx)); + open_db(p, 0); + nSep = strlen30(p->colSeparator); + if( nSep==0 ){ + raw_printf(stderr, + "Error: non-null column separator required for import\n"); + return 1; + } + if( nSep>1 ){ + raw_printf(stderr, "Error: multi-character column separators not allowed" + " for import\n"); + return 1; + } + nSep = strlen30(p->rowSeparator); + if( nSep==0 ){ + raw_printf(stderr, "Error: non-null row separator required for import\n"); + return 1; + } + if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator, SEP_CrLf)==0 ){ + /* When importing CSV (only), if the row separator is set to the + ** default output row separator, change it to the default input + ** row separator. This avoids having to maintain different input + ** and output row separators. */ + sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row); + nSep = strlen30(p->rowSeparator); + } + if( nSep>1 ){ + raw_printf(stderr, "Error: multi-character row separators not allowed" + " for import\n"); + return 1; + } + sCtx.zFile = zFile; + sCtx.nLine = 1; + if( sCtx.zFile[0]=='|' ){ +#ifdef SQLITE_OMIT_POPEN + raw_printf(stderr, "Error: pipes are not supported in this OS\n"); + return 1; +#else + sCtx.in = popen(sCtx.zFile+1, "r"); + sCtx.zFile = ""; + xCloser = pclose; +#endif + }else{ + sCtx.in = fopen(sCtx.zFile, "rb"); + xCloser = fclose; + } + if( p->mode==MODE_Ascii ){ + xRead = ascii_read_one_field; + }else{ + xRead = csv_read_one_field; + } + if( sCtx.in==0 ){ + utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile); + return 1; + } + sCtx.cColSep = p->colSeparator[0]; + sCtx.cRowSep = p->rowSeparator[0]; + zSql = sqlite3_mprintf("SELECT * FROM %s", zTable); + if( zSql==0 ){ + raw_printf(stderr, "Error: out of memory\n"); + xCloser(sCtx.in); + return 1; + } + nByte = strlen30(zSql); + rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); + import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */ + if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){ + char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable); + char cSep = '('; + while( xRead(&sCtx) ){ + zCreate = sqlite3_mprintf("%z%c\n \"%w\" TEXT", zCreate, cSep, sCtx.z); + cSep = ','; + if( sCtx.cTerm!=sCtx.cColSep ) break; + } + if( cSep=='(' ){ + sqlite3_free(zCreate); + sqlite3_free(sCtx.z); + xCloser(sCtx.in); + utf8_printf(stderr,"%s: empty file\n", sCtx.zFile); + return 1; + } + zCreate = sqlite3_mprintf("%z\n)", zCreate); + rc = sqlite3_exec(p->db, zCreate, 0, 0, 0); + sqlite3_free(zCreate); + if( rc ){ + utf8_printf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable, + sqlite3_errmsg(p->db)); + sqlite3_free(sCtx.z); + xCloser(sCtx.in); + return 1; + } + rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); + } + sqlite3_free(zSql); + if( rc ){ + if (pStmt) sqlite3_finalize(pStmt); + utf8_printf(stderr,"Error: %s\n", sqlite3_errmsg(p->db)); + xCloser(sCtx.in); + return 1; + } + nCol = sqlite3_column_count(pStmt); + sqlite3_finalize(pStmt); + pStmt = 0; + if( nCol==0 ) return 0; /* no columns, no error */ + zSql = sqlite3_malloc64( nByte*2 + 20 + nCol*2 ); + if( zSql==0 ){ + raw_printf(stderr, "Error: out of memory\n"); + xCloser(sCtx.in); + return 1; + } + sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable); + j = strlen30(zSql); + for(i=1; idb, zSql, -1, &pStmt, 0); + sqlite3_free(zSql); + if( rc ){ + utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db)); + if (pStmt) sqlite3_finalize(pStmt); + xCloser(sCtx.in); + return 1; + } + needCommit = sqlite3_get_autocommit(p->db); + if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0); + do{ + int startLine = sCtx.nLine; + for(i=0; imode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break; + sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT); + if( i=nCol ){ + sqlite3_step(pStmt); + rc = sqlite3_reset(pStmt); + if( rc!=SQLITE_OK ){ + utf8_printf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile, + startLine, sqlite3_errmsg(p->db)); + } + } + }while( sCtx.cTerm!=EOF ); + + xCloser(sCtx.in); + sqlite3_free(sCtx.z); + sqlite3_finalize(pStmt); + if( needCommit ) sqlite3_exec(p->db, "COMMIT", 0, 0, 0); + }else + +#ifndef SQLITE_UNTESTABLE + if( c=='i' && strncmp(azArg[0], "imposter", n)==0 ){ + char *zSql; + char *zCollist = 0; + sqlite3_stmt *pStmt; + int tnum = 0; + int i; + if( nArg!=3 ){ + utf8_printf(stderr, "Usage: .imposter INDEX IMPOSTER\n"); + rc = 1; + goto meta_command_exit; + } + open_db(p, 0); + zSql = sqlite3_mprintf("SELECT rootpage FROM sqlite_master" + " WHERE name='%q' AND type='index'", azArg[1]); + sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); + sqlite3_free(zSql); + if( sqlite3_step(pStmt)==SQLITE_ROW ){ + tnum = sqlite3_column_int(pStmt, 0); + } + sqlite3_finalize(pStmt); + if( tnum==0 ){ + utf8_printf(stderr, "no such index: \"%s\"\n", azArg[1]); + rc = 1; + goto meta_command_exit; + } + zSql = sqlite3_mprintf("PRAGMA index_xinfo='%q'", azArg[1]); + rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); + sqlite3_free(zSql); + i = 0; + while( sqlite3_step(pStmt)==SQLITE_ROW ){ + char zLabel[20]; + const char *zCol = (const char*)sqlite3_column_text(pStmt,2); + i++; + if( zCol==0 ){ + if( sqlite3_column_int(pStmt,1)==-1 ){ + zCol = "_ROWID_"; + }else{ + sqlite3_snprintf(sizeof(zLabel),zLabel,"expr%d",i); + zCol = zLabel; + } + } + if( zCollist==0 ){ + zCollist = sqlite3_mprintf("\"%w\"", zCol); + }else{ + zCollist = sqlite3_mprintf("%z,\"%w\"", zCollist, zCol); + } + } + sqlite3_finalize(pStmt); + zSql = sqlite3_mprintf( + "CREATE TABLE \"%w\"(%s,PRIMARY KEY(%s))WITHOUT ROWID", + azArg[2], zCollist, zCollist); + sqlite3_free(zCollist); + rc = sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 1, tnum); + if( rc==SQLITE_OK ){ + rc = sqlite3_exec(p->db, zSql, 0, 0, 0); + sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 0, 0); + if( rc ){ + utf8_printf(stderr, "Error in [%s]: %s\n", zSql, sqlite3_errmsg(p->db)); + }else{ + utf8_printf(stdout, "%s;\n", zSql); + raw_printf(stdout, + "WARNING: writing to an imposter table will corrupt the index!\n" + ); + } + }else{ + raw_printf(stderr, "SQLITE_TESTCTRL_IMPOSTER returns %d\n", rc); + rc = 1; + } + sqlite3_free(zSql); + }else +#endif /* !defined(SQLITE_OMIT_TEST_CONTROL) */ + +#ifdef SQLITE_ENABLE_IOTRACE + if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){ + SQLITE_API extern void (SQLITE_CDECL *sqlite3IoTrace)(const char*, ...); + if( iotrace && iotrace!=stdout ) fclose(iotrace); + iotrace = 0; + if( nArg<2 ){ + sqlite3IoTrace = 0; + }else if( strcmp(azArg[1], "-")==0 ){ + sqlite3IoTrace = iotracePrintf; + iotrace = stdout; + }else{ + iotrace = fopen(azArg[1], "w"); + if( iotrace==0 ){ + utf8_printf(stderr, "Error: cannot open \"%s\"\n", azArg[1]); + sqlite3IoTrace = 0; + rc = 1; + }else{ + sqlite3IoTrace = iotracePrintf; + } + } + }else +#endif + + if( c=='l' && n>=5 && strncmp(azArg[0], "limits", n)==0 ){ + static const struct { + const char *zLimitName; /* Name of a limit */ + int limitCode; /* Integer code for that limit */ + } aLimit[] = { + { "length", SQLITE_LIMIT_LENGTH }, + { "sql_length", SQLITE_LIMIT_SQL_LENGTH }, + { "column", SQLITE_LIMIT_COLUMN }, + { "expr_depth", SQLITE_LIMIT_EXPR_DEPTH }, + { "compound_select", SQLITE_LIMIT_COMPOUND_SELECT }, + { "vdbe_op", SQLITE_LIMIT_VDBE_OP }, + { "function_arg", SQLITE_LIMIT_FUNCTION_ARG }, + { "attached", SQLITE_LIMIT_ATTACHED }, + { "like_pattern_length", SQLITE_LIMIT_LIKE_PATTERN_LENGTH }, + { "variable_number", SQLITE_LIMIT_VARIABLE_NUMBER }, + { "trigger_depth", SQLITE_LIMIT_TRIGGER_DEPTH }, + { "worker_threads", SQLITE_LIMIT_WORKER_THREADS }, + }; + int i, n2; + open_db(p, 0); + if( nArg==1 ){ + for(i=0; idb, aLimit[i].limitCode, -1)); + } + }else if( nArg>3 ){ + raw_printf(stderr, "Usage: .limit NAME ?NEW-VALUE?\n"); + rc = 1; + goto meta_command_exit; + }else{ + int iLimit = -1; + n2 = strlen30(azArg[1]); + for(i=0; idb, aLimit[iLimit].limitCode, + (int)integerValue(azArg[2])); + } + printf("%20s %d\n", aLimit[iLimit].zLimitName, + sqlite3_limit(p->db, aLimit[iLimit].limitCode, -1)); + } + }else + + if( c=='l' && n>2 && strncmp(azArg[0], "lint", n)==0 ){ + open_db(p, 0); + lintDotCommand(p, azArg, nArg); + }else + +#ifndef SQLITE_OMIT_LOAD_EXTENSION + if( c=='l' && strncmp(azArg[0], "load", n)==0 ){ + const char *zFile, *zProc; + char *zErrMsg = 0; + if( nArg<2 ){ + raw_printf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n"); + rc = 1; + goto meta_command_exit; + } + zFile = azArg[1]; + zProc = nArg>=3 ? azArg[2] : 0; + open_db(p, 0); + rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg); + if( rc!=SQLITE_OK ){ + utf8_printf(stderr, "Error: %s\n", zErrMsg); + sqlite3_free(zErrMsg); + rc = 1; + } + }else +#endif + + if( c=='l' && strncmp(azArg[0], "log", n)==0 ){ + if( nArg!=2 ){ + raw_printf(stderr, "Usage: .log FILENAME\n"); + rc = 1; + }else{ + const char *zFile = azArg[1]; + output_file_close(p->pLog); + p->pLog = output_file_open(zFile); + } + }else + + if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){ + const char *zMode = nArg>=2 ? azArg[1] : ""; + int n2 = (int)strlen(zMode); + int c2 = zMode[0]; + if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){ + p->mode = MODE_Line; + sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row); + }else if( c2=='c' && strncmp(azArg[1],"columns",n2)==0 ){ + p->mode = MODE_Column; + sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row); + }else if( c2=='l' && n2>2 && strncmp(azArg[1],"list",n2)==0 ){ + p->mode = MODE_List; + sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Column); + sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row); + }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){ + p->mode = MODE_Html; + }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){ + p->mode = MODE_Tcl; + sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space); + sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row); + }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){ + p->mode = MODE_Csv; + sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma); + sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf); + }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){ + p->mode = MODE_List; + sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab); + }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){ + p->mode = MODE_Insert; + set_table_name(p, nArg>=3 ? azArg[2] : "table"); + }else if( c2=='q' && strncmp(azArg[1],"quote",n2)==0 ){ + p->mode = MODE_Quote; + }else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){ + p->mode = MODE_Ascii; + sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit); + sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record); + }else if( nArg==1 ){ + raw_printf(p->out, "current output mode: %s\n", modeDescr[p->mode]); + }else{ + raw_printf(stderr, "Error: mode should be one of: " + "ascii column csv html insert line list quote tabs tcl\n"); + rc = 1; + } + p->cMode = p->mode; + }else + + if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){ + if( nArg==2 ){ + sqlite3_snprintf(sizeof(p->nullValue), p->nullValue, + "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]); + }else{ + raw_printf(stderr, "Usage: .nullvalue STRING\n"); + rc = 1; + } + }else + + if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){ + char *zNewFilename; /* Name of the database file to open */ + int iName = 1; /* Index in azArg[] of the filename */ + int newFlag = 0; /* True to delete file before opening */ + /* Close the existing database */ + session_close_all(p); + sqlite3_close(p->db); + p->db = 0; + p->zDbFilename = 0; + sqlite3_free(p->zFreeOnClose); + p->zFreeOnClose = 0; + /* Check for command-line arguments */ + for(iName=1; iNameiName ? sqlite3_mprintf("%s", azArg[iName]) : 0; + if( zNewFilename ){ + if( newFlag ) shellDeleteFile(zNewFilename); + p->zDbFilename = zNewFilename; + open_db(p, 1); + if( p->db==0 ){ + utf8_printf(stderr, "Error: cannot open '%s'\n", zNewFilename); + sqlite3_free(zNewFilename); + }else{ + p->zFreeOnClose = zNewFilename; + } + } + if( p->db==0 ){ + /* As a fall-back open a TEMP database */ + p->zDbFilename = 0; + open_db(p, 0); + } + }else + + if( c=='o' + && (strncmp(azArg[0], "output", n)==0 || strncmp(azArg[0], "once", n)==0) + ){ + const char *zFile = nArg>=2 ? azArg[1] : "stdout"; + if( nArg>2 ){ + utf8_printf(stderr, "Usage: .%s FILE\n", azArg[0]); + rc = 1; + goto meta_command_exit; + } + if( n>1 && strncmp(azArg[0], "once", n)==0 ){ + if( nArg<2 ){ + raw_printf(stderr, "Usage: .once FILE\n"); + rc = 1; + goto meta_command_exit; + } + p->outCount = 2; + }else{ + p->outCount = 0; + } + output_reset(p); + if( zFile[0]=='|' ){ +#ifdef SQLITE_OMIT_POPEN + raw_printf(stderr, "Error: pipes are not supported in this OS\n"); + rc = 1; + p->out = stdout; +#else + p->out = popen(zFile + 1, "w"); + if( p->out==0 ){ + utf8_printf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1); + p->out = stdout; + rc = 1; + }else{ + sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile); + } +#endif + }else{ + p->out = output_file_open(zFile); + if( p->out==0 ){ + if( strcmp(zFile,"off")!=0 ){ + utf8_printf(stderr,"Error: cannot write to \"%s\"\n", zFile); + } + p->out = stdout; + rc = 1; + } else { + sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile); + } + } + }else + + if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){ + int i; + for(i=1; i1 ) raw_printf(p->out, " "); + utf8_printf(p->out, "%s", azArg[i]); + } + raw_printf(p->out, "\n"); + }else + + if( c=='p' && strncmp(azArg[0], "prompt", n)==0 ){ + if( nArg >= 2) { + strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1); + } + if( nArg >= 3) { + strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1); + } + }else + + if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){ + rc = 2; + }else + + if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){ + FILE *alt; + if( nArg!=2 ){ + raw_printf(stderr, "Usage: .read FILE\n"); + rc = 1; + goto meta_command_exit; + } + alt = fopen(azArg[1], "rb"); + if( alt==0 ){ + utf8_printf(stderr,"Error: cannot open \"%s\"\n", azArg[1]); + rc = 1; + }else{ + rc = process_input(p, alt); + fclose(alt); + } + }else + + if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){ + const char *zSrcFile; + const char *zDb; + sqlite3 *pSrc; + sqlite3_backup *pBackup; + int nTimeout = 0; + + if( nArg==2 ){ + zSrcFile = azArg[1]; + zDb = "main"; + }else if( nArg==3 ){ + zSrcFile = azArg[2]; + zDb = azArg[1]; + }else{ + raw_printf(stderr, "Usage: .restore ?DB? FILE\n"); + rc = 1; + goto meta_command_exit; + } + rc = sqlite3_open(zSrcFile, &pSrc); + if( rc!=SQLITE_OK ){ + utf8_printf(stderr, "Error: cannot open \"%s\"\n", zSrcFile); + sqlite3_close(pSrc); + return 1; + } + open_db(p, 0); + pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main"); + if( pBackup==0 ){ + utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db)); + sqlite3_close(pSrc); + return 1; + } + while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK + || rc==SQLITE_BUSY ){ + if( rc==SQLITE_BUSY ){ + if( nTimeout++ >= 3 ) break; + sqlite3_sleep(100); + } + } + sqlite3_backup_finish(pBackup); + if( rc==SQLITE_DONE ){ + rc = 0; + }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){ + raw_printf(stderr, "Error: source database is busy\n"); + rc = 1; + }else{ + utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db)); + rc = 1; + } + sqlite3_close(pSrc); + }else + + + if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){ + if( nArg==2 ){ + p->scanstatsOn = booleanValue(azArg[1]); +#ifndef SQLITE_ENABLE_STMT_SCANSTATUS + raw_printf(stderr, "Warning: .scanstats not available in this build.\n"); +#endif + }else{ + raw_printf(stderr, "Usage: .scanstats on|off\n"); + rc = 1; + } + }else + + if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){ + ShellText sSelect; + ShellState data; + char *zErrMsg = 0; + const char *zDiv = 0; + int iSchema = 0; + + open_db(p, 0); + memcpy(&data, p, sizeof(data)); + data.showHeader = 0; + data.cMode = data.mode = MODE_Semi; + initText(&sSelect); + if( nArg>=2 && optionMatch(azArg[1], "indent") ){ + data.cMode = data.mode = MODE_Pretty; + nArg--; + if( nArg==2 ) azArg[1] = azArg[2]; + } + if( nArg==2 && azArg[1][0]!='-' ){ + int i; + for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]); + if( strcmp(azArg[1],"sqlite_master")==0 ){ + char *new_argv[2], *new_colv[2]; + new_argv[0] = "CREATE TABLE sqlite_master (\n" + " type text,\n" + " name text,\n" + " tbl_name text,\n" + " rootpage integer,\n" + " sql text\n" + ")"; + new_argv[1] = 0; + new_colv[0] = "sql"; + new_colv[1] = 0; + callback(&data, 1, new_argv, new_colv); + rc = SQLITE_OK; + }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){ + char *new_argv[2], *new_colv[2]; + new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n" + " type text,\n" + " name text,\n" + " tbl_name text,\n" + " rootpage integer,\n" + " sql text\n" + ")"; + new_argv[1] = 0; + new_colv[0] = "sql"; + new_colv[1] = 0; + callback(&data, 1, new_argv, new_colv); + rc = SQLITE_OK; + }else{ + zDiv = "("; + } + }else if( nArg==1 ){ + zDiv = "("; + }else{ + raw_printf(stderr, "Usage: .schema ?--indent? ?LIKE-PATTERN?\n"); + rc = 1; + goto meta_command_exit; + } + if( zDiv ){ + sqlite3_stmt *pStmt = 0; + rc = sqlite3_prepare_v2(p->db, "SELECT name FROM pragma_database_list", + -1, &pStmt, 0); + if( rc ){ + utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db)); + sqlite3_finalize(pStmt); + rc = 1; + goto meta_command_exit; + } + appendText(&sSelect, "SELECT sql FROM", 0); + iSchema = 0; + while( sqlite3_step(pStmt)==SQLITE_ROW ){ + const char *zDb = (const char*)sqlite3_column_text(pStmt, 0); + char zScNum[30]; + sqlite3_snprintf(sizeof(zScNum), zScNum, "%d", ++iSchema); + appendText(&sSelect, zDiv, 0); + zDiv = " UNION ALL "; + if( strcmp(zDb, "main")!=0 ){ + appendText(&sSelect, "SELECT shell_add_schema(sql,", 0); + appendText(&sSelect, zDb, '"'); + appendText(&sSelect, ") AS sql, type, tbl_name, name, rowid,", 0); + appendText(&sSelect, zScNum, 0); + appendText(&sSelect, " AS snum, ", 0); + appendText(&sSelect, zDb, '\''); + appendText(&sSelect, " AS sname FROM ", 0); + appendText(&sSelect, zDb, '"'); + appendText(&sSelect, ".sqlite_master", 0); + }else{ + appendText(&sSelect, "SELECT sql, type, tbl_name, name, rowid, ", 0); + appendText(&sSelect, zScNum, 0); + appendText(&sSelect, " AS snum, 'main' AS sname FROM sqlite_master",0); + } + } + sqlite3_finalize(pStmt); + appendText(&sSelect, ") WHERE ", 0); + if( nArg>1 ){ + char *zQarg = sqlite3_mprintf("%Q", azArg[1]); + if( strchr(azArg[1], '.') ){ + appendText(&sSelect, "lower(printf('%s.%s',sname,tbl_name))", 0); + }else{ + appendText(&sSelect, "lower(tbl_name)", 0); + } + appendText(&sSelect, strchr(azArg[1], '*') ? " GLOB " : " LIKE ", 0); + appendText(&sSelect, zQarg, 0); + appendText(&sSelect, " AND ", 0); + sqlite3_free(zQarg); + } + appendText(&sSelect, "type!='meta' AND sql IS NOT NULL" + " ORDER BY snum, rowid", 0); + rc = sqlite3_exec(p->db, sSelect.z, callback, &data, &zErrMsg); + freeText(&sSelect); + } + if( zErrMsg ){ + utf8_printf(stderr,"Error: %s\n", zErrMsg); + sqlite3_free(zErrMsg); + rc = 1; + }else if( rc != SQLITE_OK ){ + raw_printf(stderr,"Error: querying schema information\n"); + rc = 1; + }else{ + rc = 0; + } + }else + +#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE) + if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){ + sqlite3SelectTrace = (int)integerValue(azArg[1]); + }else +#endif + +#if defined(SQLITE_ENABLE_SESSION) + if( c=='s' && strncmp(azArg[0],"session",n)==0 && n>=3 ){ + OpenSession *pSession = &p->aSession[0]; + char **azCmd = &azArg[1]; + int iSes = 0; + int nCmd = nArg - 1; + int i; + if( nArg<=1 ) goto session_syntax_error; + open_db(p, 0); + if( nArg>=3 ){ + for(iSes=0; iSesnSession; iSes++){ + if( strcmp(p->aSession[iSes].zName, azArg[1])==0 ) break; + } + if( iSesnSession ){ + pSession = &p->aSession[iSes]; + azCmd++; + nCmd--; + }else{ + pSession = &p->aSession[0]; + iSes = 0; + } + } + + /* .session attach TABLE + ** Invoke the sqlite3session_attach() interface to attach a particular + ** table so that it is never filtered. + */ + if( strcmp(azCmd[0],"attach")==0 ){ + if( nCmd!=2 ) goto session_syntax_error; + if( pSession->p==0 ){ + session_not_open: + raw_printf(stderr, "ERROR: No sessions are open\n"); + }else{ + rc = sqlite3session_attach(pSession->p, azCmd[1]); + if( rc ){ + raw_printf(stderr, "ERROR: sqlite3session_attach() returns %d\n", rc); + rc = 0; + } + } + }else + + /* .session changeset FILE + ** .session patchset FILE + ** Write a changeset or patchset into a file. The file is overwritten. + */ + if( strcmp(azCmd[0],"changeset")==0 || strcmp(azCmd[0],"patchset")==0 ){ + FILE *out = 0; + if( nCmd!=2 ) goto session_syntax_error; + if( pSession->p==0 ) goto session_not_open; + out = fopen(azCmd[1], "wb"); + if( out==0 ){ + utf8_printf(stderr, "ERROR: cannot open \"%s\" for writing\n", azCmd[1]); + }else{ + int szChng; + void *pChng; + if( azCmd[0][0]=='c' ){ + rc = sqlite3session_changeset(pSession->p, &szChng, &pChng); + }else{ + rc = sqlite3session_patchset(pSession->p, &szChng, &pChng); + } + if( rc ){ + printf("Error: error code %d\n", rc); + rc = 0; + } + if( pChng + && fwrite(pChng, szChng, 1, out)!=1 ){ + raw_printf(stderr, "ERROR: Failed to write entire %d-byte output\n", + szChng); + } + sqlite3_free(pChng); + fclose(out); + } + }else + + /* .session close + ** Close the identified session + */ + if( strcmp(azCmd[0], "close")==0 ){ + if( nCmd!=1 ) goto session_syntax_error; + if( p->nSession ){ + session_close(pSession); + p->aSession[iSes] = p->aSession[--p->nSession]; + } + }else + + /* .session enable ?BOOLEAN? + ** Query or set the enable flag + */ + if( strcmp(azCmd[0], "enable")==0 ){ + int ii; + if( nCmd>2 ) goto session_syntax_error; + ii = nCmd==1 ? -1 : booleanValue(azCmd[1]); + if( p->nSession ){ + ii = sqlite3session_enable(pSession->p, ii); + utf8_printf(p->out, "session %s enable flag = %d\n", + pSession->zName, ii); + } + }else + + /* .session filter GLOB .... + ** Set a list of GLOB patterns of table names to be excluded. + */ + if( strcmp(azCmd[0], "filter")==0 ){ + int ii, nByte; + if( nCmd<2 ) goto session_syntax_error; + if( p->nSession ){ + for(ii=0; iinFilter; ii++){ + sqlite3_free(pSession->azFilter[ii]); + } + sqlite3_free(pSession->azFilter); + nByte = sizeof(pSession->azFilter[0])*(nCmd-1); + pSession->azFilter = sqlite3_malloc( nByte ); + if( pSession->azFilter==0 ){ + raw_printf(stderr, "Error: out or memory\n"); + exit(1); + } + for(ii=1; iiazFilter[ii-1] = sqlite3_mprintf("%s", azCmd[ii]); + } + pSession->nFilter = ii-1; + } + }else + + /* .session indirect ?BOOLEAN? + ** Query or set the indirect flag + */ + if( strcmp(azCmd[0], "indirect")==0 ){ + int ii; + if( nCmd>2 ) goto session_syntax_error; + ii = nCmd==1 ? -1 : booleanValue(azCmd[1]); + if( p->nSession ){ + ii = sqlite3session_indirect(pSession->p, ii); + utf8_printf(p->out, "session %s indirect flag = %d\n", + pSession->zName, ii); + } + }else + + /* .session isempty + ** Determine if the session is empty + */ + if( strcmp(azCmd[0], "isempty")==0 ){ + int ii; + if( nCmd!=1 ) goto session_syntax_error; + if( p->nSession ){ + ii = sqlite3session_isempty(pSession->p); + utf8_printf(p->out, "session %s isempty flag = %d\n", + pSession->zName, ii); + } + }else + + /* .session list + ** List all currently open sessions + */ + if( strcmp(azCmd[0],"list")==0 ){ + for(i=0; inSession; i++){ + utf8_printf(p->out, "%d %s\n", i, p->aSession[i].zName); + } + }else + + /* .session open DB NAME + ** Open a new session called NAME on the attached database DB. + ** DB is normally "main". + */ + if( strcmp(azCmd[0],"open")==0 ){ + char *zName; + if( nCmd!=3 ) goto session_syntax_error; + zName = azCmd[2]; + if( zName[0]==0 ) goto session_syntax_error; + for(i=0; inSession; i++){ + if( strcmp(p->aSession[i].zName,zName)==0 ){ + utf8_printf(stderr, "Session \"%s\" already exists\n", zName); + goto meta_command_exit; + } + } + if( p->nSession>=ArraySize(p->aSession) ){ + raw_printf(stderr, "Maximum of %d sessions\n", ArraySize(p->aSession)); + goto meta_command_exit; + } + pSession = &p->aSession[p->nSession]; + rc = sqlite3session_create(p->db, azCmd[1], &pSession->p); + if( rc ){ + raw_printf(stderr, "Cannot open session: error code=%d\n", rc); + rc = 0; + goto meta_command_exit; + } + pSession->nFilter = 0; + sqlite3session_table_filter(pSession->p, session_filter, pSession); + p->nSession++; + pSession->zName = sqlite3_mprintf("%s", zName); + }else + /* If no command name matches, show a syntax error */ + session_syntax_error: + session_help(p); + }else +#endif + +#ifdef SQLITE_DEBUG + /* Undocumented commands for internal testing. Subject to change + ** without notice. */ + if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){ + if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){ + int i, v; + for(i=1; iout, "%s: %d 0x%x\n", azArg[i], v, v); + } + } + if( strncmp(azArg[0]+9, "integer", n-9)==0 ){ + int i; sqlite3_int64 v; + for(i=1; iout, "%s", zBuf); + } + } + }else +#endif + + if( c=='s' && n>=4 && strncmp(azArg[0],"selftest",n)==0 ){ + int bIsInit = 0; /* True to initialize the SELFTEST table */ + int bVerbose = 0; /* Verbose output */ + int bSelftestExists; /* True if SELFTEST already exists */ + int i, k; /* Loop counters */ + int nTest = 0; /* Number of tests runs */ + int nErr = 0; /* Number of errors seen */ + ShellText str; /* Answer for a query */ + sqlite3_stmt *pStmt = 0; /* Query against the SELFTEST table */ + + open_db(p,0); + for(i=1; idb,"main","selftest",0,0,0,0,0,0) + != SQLITE_OK ){ + bSelftestExists = 0; + }else{ + bSelftestExists = 1; + } + if( bIsInit ){ + createSelftestTable(p); + bSelftestExists = 1; + } + initText(&str); + appendText(&str, "x", 0); + for(k=bSelftestExists; k>=0; k--){ + if( k==1 ){ + rc = sqlite3_prepare_v2(p->db, + "SELECT tno,op,cmd,ans FROM selftest ORDER BY tno", + -1, &pStmt, 0); + }else{ + rc = sqlite3_prepare_v2(p->db, + "VALUES(0,'memo','Missing SELFTEST table - default checks only','')," + " (1,'run','PRAGMA integrity_check','ok')", + -1, &pStmt, 0); + } + if( rc ){ + raw_printf(stderr, "Error querying the selftest table\n"); + rc = 1; + sqlite3_finalize(pStmt); + goto meta_command_exit; + } + for(i=1; sqlite3_step(pStmt)==SQLITE_ROW; i++){ + int tno = sqlite3_column_int(pStmt, 0); + const char *zOp = (const char*)sqlite3_column_text(pStmt, 1); + const char *zSql = (const char*)sqlite3_column_text(pStmt, 2); + const char *zAns = (const char*)sqlite3_column_text(pStmt, 3); + + k = 0; + if( bVerbose>0 ){ + char *zQuote = sqlite3_mprintf("%q", zSql); + printf("%d: %s %s\n", tno, zOp, zSql); + sqlite3_free(zQuote); + } + if( strcmp(zOp,"memo")==0 ){ + utf8_printf(p->out, "%s\n", zSql); + }else + if( strcmp(zOp,"run")==0 ){ + char *zErrMsg = 0; + str.n = 0; + str.z[0] = 0; + rc = sqlite3_exec(p->db, zSql, captureOutputCallback, &str, &zErrMsg); + nTest++; + if( bVerbose ){ + utf8_printf(p->out, "Result: %s\n", str.z); + } + if( rc || zErrMsg ){ + nErr++; + rc = 1; + utf8_printf(p->out, "%d: error-code-%d: %s\n", tno, rc, zErrMsg); + sqlite3_free(zErrMsg); + }else if( strcmp(zAns,str.z)!=0 ){ + nErr++; + rc = 1; + utf8_printf(p->out, "%d: Expected: [%s]\n", tno, zAns); + utf8_printf(p->out, "%d: Got: [%s]\n", tno, str.z); + } + }else + { + utf8_printf(stderr, + "Unknown operation \"%s\" on selftest line %d\n", zOp, tno); + rc = 1; + break; + } + } /* End loop over rows of content from SELFTEST */ + sqlite3_finalize(pStmt); + } /* End loop over k */ + freeText(&str); + utf8_printf(p->out, "%d errors out of %d tests\n", nErr, nTest); + }else + + if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){ + if( nArg<2 || nArg>3 ){ + raw_printf(stderr, "Usage: .separator COL ?ROW?\n"); + rc = 1; + } + if( nArg>=2 ){ + sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, + "%.*s", (int)ArraySize(p->colSeparator)-1, azArg[1]); + } + if( nArg>=3 ){ + sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, + "%.*s", (int)ArraySize(p->rowSeparator)-1, azArg[2]); + } + }else + + if( c=='s' && n>=4 && strncmp(azArg[0],"sha3sum",n)==0 ){ + const char *zLike = 0; /* Which table to checksum. 0 means everything */ + int i; /* Loop counter */ + int bSchema = 0; /* Also hash the schema */ + int bSeparate = 0; /* Hash each table separately */ + int iSize = 224; /* Hash algorithm to use */ + int bDebug = 0; /* Only show the query that would have run */ + sqlite3_stmt *pStmt; /* For querying tables names */ + char *zSql; /* SQL to be run */ + char *zSep; /* Separator */ + ShellText sSql; /* Complete SQL for the query to run the hash */ + ShellText sQuery; /* Set of queries used to read all content */ + open_db(p, 0); + for(i=1; i1" + " UNION ALL SELECT 'sqlite_master'" + " ORDER BY 1 collate nocase"; + }else{ + zSql = "SELECT lower(name) FROM sqlite_master" + " WHERE type='table' AND coalesce(rootpage,0)>1" + " AND name NOT LIKE 'sqlite_%'" + " ORDER BY 1 collate nocase"; + } + sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); + initText(&sQuery); + initText(&sSql); + appendText(&sSql, "WITH [sha3sum$query](a,b) AS(",0); + zSep = "VALUES("; + while( SQLITE_ROW==sqlite3_step(pStmt) ){ + const char *zTab = (const char*)sqlite3_column_text(pStmt,0); + if( zLike && sqlite3_strlike(zLike, zTab, 0)!=0 ) continue; + if( strncmp(zTab, "sqlite_",7)!=0 ){ + appendText(&sQuery,"SELECT * FROM ", 0); + appendText(&sQuery,zTab,'"'); + appendText(&sQuery," NOT INDEXED;", 0); + }else if( strcmp(zTab, "sqlite_master")==0 ){ + appendText(&sQuery,"SELECT type,name,tbl_name,sql FROM sqlite_master" + " ORDER BY name;", 0); + }else if( strcmp(zTab, "sqlite_sequence")==0 ){ + appendText(&sQuery,"SELECT name,seq FROM sqlite_sequence" + " ORDER BY name;", 0); + }else if( strcmp(zTab, "sqlite_stat1")==0 ){ + appendText(&sQuery,"SELECT tbl,idx,stat FROM sqlite_stat1" + " ORDER BY tbl,idx;", 0); + }else if( strcmp(zTab, "sqlite_stat3")==0 + || strcmp(zTab, "sqlite_stat4")==0 ){ + appendText(&sQuery, "SELECT * FROM ", 0); + appendText(&sQuery, zTab, 0); + appendText(&sQuery, " ORDER BY tbl, idx, rowid;\n", 0); + } + appendText(&sSql, zSep, 0); + appendText(&sSql, sQuery.z, '\''); + sQuery.n = 0; + appendText(&sSql, ",", 0); + appendText(&sSql, zTab, '\''); + zSep = "),("; + } + sqlite3_finalize(pStmt); + if( bSeparate ){ + zSql = sqlite3_mprintf( + "%s))" + " SELECT lower(hex(sha3_query(a,%d))) AS hash, b AS label" + " FROM [sha3sum$query]", + sSql.z, iSize); + }else{ + zSql = sqlite3_mprintf( + "%s))" + " SELECT lower(hex(sha3_query(group_concat(a,''),%d))) AS hash" + " FROM [sha3sum$query]", + sSql.z, iSize); + } + freeText(&sQuery); + freeText(&sSql); + if( bDebug ){ + utf8_printf(p->out, "%s\n", zSql); + }else{ + shell_exec(p->db, zSql, shell_callback, p, 0); + } + sqlite3_free(zSql); + }else + + if( c=='s' + && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0) + ){ + char *zCmd; + int i, x; + if( nArg<2 ){ + raw_printf(stderr, "Usage: .system COMMAND\n"); + rc = 1; + goto meta_command_exit; + } + zCmd = sqlite3_mprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]); + for(i=2; iout, "%12.12s: %s\n","echo", + azBool[ShellHasFlag(p, SHFLG_Echo)]); + utf8_printf(p->out, "%12.12s: %s\n","eqp", azBool[p->autoEQP&3]); + utf8_printf(p->out, "%12.12s: %s\n","explain", + p->mode==MODE_Explain ? "on" : p->autoExplain ? "auto" : "off"); + utf8_printf(p->out,"%12.12s: %s\n","headers", azBool[p->showHeader!=0]); + utf8_printf(p->out, "%12.12s: %s\n","mode", modeDescr[p->mode]); + utf8_printf(p->out, "%12.12s: ", "nullvalue"); + output_c_string(p->out, p->nullValue); + raw_printf(p->out, "\n"); + utf8_printf(p->out,"%12.12s: %s\n","output", + strlen30(p->outfile) ? p->outfile : "stdout"); + utf8_printf(p->out,"%12.12s: ", "colseparator"); + output_c_string(p->out, p->colSeparator); + raw_printf(p->out, "\n"); + utf8_printf(p->out,"%12.12s: ", "rowseparator"); + output_c_string(p->out, p->rowSeparator); + raw_printf(p->out, "\n"); + utf8_printf(p->out, "%12.12s: %s\n","stats", azBool[p->statsOn!=0]); + utf8_printf(p->out, "%12.12s: ", "width"); + for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) { + raw_printf(p->out, "%d ", p->colWidth[i]); + } + raw_printf(p->out, "\n"); + utf8_printf(p->out, "%12.12s: %s\n", "filename", + p->zDbFilename ? p->zDbFilename : ""); + }else + + if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){ + if( nArg==2 ){ + p->statsOn = booleanValue(azArg[1]); + }else if( nArg==1 ){ + display_stats(p->db, p, 0); + }else{ + raw_printf(stderr, "Usage: .stats ?on|off?\n"); + rc = 1; + } + }else + + if( (c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0) + || (c=='i' && (strncmp(azArg[0], "indices", n)==0 + || strncmp(azArg[0], "indexes", n)==0) ) + ){ + sqlite3_stmt *pStmt; + char **azResult; + int nRow, nAlloc; + int ii; + ShellText s; + initText(&s); + open_db(p, 0); + rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0); + if( rc ) return shellDatabaseError(p->db); + + if( nArg>2 && c=='i' ){ + /* It is an historical accident that the .indexes command shows an error + ** when called with the wrong number of arguments whereas the .tables + ** command does not. */ + raw_printf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n"); + rc = 1; + goto meta_command_exit; + } + for(ii=0; sqlite3_step(pStmt)==SQLITE_ROW; ii++){ + const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1); + if( zDbName==0 ) continue; + if( s.z && s.z[0] ) appendText(&s, " UNION ALL ", 0); + if( sqlite3_stricmp(zDbName, "main")==0 ){ + appendText(&s, "SELECT name FROM ", 0); + }else{ + appendText(&s, "SELECT ", 0); + appendText(&s, zDbName, '\''); + appendText(&s, "||'.'||name FROM ", 0); + } + appendText(&s, zDbName, '"'); + appendText(&s, ".sqlite_master ", 0); + if( c=='t' ){ + appendText(&s," WHERE type IN ('table','view')" + " AND name NOT LIKE 'sqlite_%'" + " AND name LIKE ?1", 0); + }else{ + appendText(&s," WHERE type='index'" + " AND tbl_name LIKE ?1", 0); + } + } + rc = sqlite3_finalize(pStmt); + appendText(&s, " ORDER BY 1", 0); + rc = sqlite3_prepare_v2(p->db, s.z, -1, &pStmt, 0); + freeText(&s); + if( rc ) return shellDatabaseError(p->db); + + /* Run the SQL statement prepared by the above block. Store the results + ** as an array of nul-terminated strings in azResult[]. */ + nRow = nAlloc = 0; + azResult = 0; + if( nArg>1 ){ + sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT); + }else{ + sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC); + } + while( sqlite3_step(pStmt)==SQLITE_ROW ){ + if( nRow>=nAlloc ){ + char **azNew; + int n2 = nAlloc*2 + 10; + azNew = sqlite3_realloc64(azResult, sizeof(azResult[0])*n2); + if( azNew==0 ){ + rc = shellNomemError(); + break; + } + nAlloc = n2; + azResult = azNew; + } + azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0)); + if( 0==azResult[nRow] ){ + rc = shellNomemError(); + break; + } + nRow++; + } + if( sqlite3_finalize(pStmt)!=SQLITE_OK ){ + rc = shellDatabaseError(p->db); + } + + /* Pretty-print the contents of array azResult[] to the output */ + if( rc==0 && nRow>0 ){ + int len, maxlen = 0; + int i, j; + int nPrintCol, nPrintRow; + for(i=0; imaxlen ) maxlen = len; + } + nPrintCol = 80/(maxlen+2); + if( nPrintCol<1 ) nPrintCol = 1; + nPrintRow = (nRow + nPrintCol - 1)/nPrintCol; + for(i=0; iout, "%s%-*s", zSp, maxlen, + azResult[j] ? azResult[j]:""); + } + raw_printf(p->out, "\n"); + } + } + + for(ii=0; iiout = output_file_open("testcase-out.txt"); + if( p->out==0 ){ + raw_printf(stderr, "Error: cannot open 'testcase-out.txt'\n"); + } + if( nArg>=2 ){ + sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "%s", azArg[1]); + }else{ + sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "?"); + } + }else + +#ifndef SQLITE_UNTESTABLE + if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){ + static const struct { + const char *zCtrlName; /* Name of a test-control option */ + int ctrlCode; /* Integer code for that option */ + } aCtrl[] = { + { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE }, + { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE }, + { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET }, + { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST }, + { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL }, + { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS }, + { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE }, + { "assert", SQLITE_TESTCTRL_ASSERT }, + { "always", SQLITE_TESTCTRL_ALWAYS }, + { "reserve", SQLITE_TESTCTRL_RESERVE }, + { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS }, + { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD }, + { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC }, + { "byteorder", SQLITE_TESTCTRL_BYTEORDER }, + { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT }, + { "imposter", SQLITE_TESTCTRL_IMPOSTER }, + }; + int testctrl = -1; + int rc2 = 0; + int i, n2; + open_db(p, 0); + + /* convert testctrl text option to value. allow any unique prefix + ** of the option name, or a numerical value. */ + n2 = strlen30(azArg[1]); + for(i=0; iSQLITE_TESTCTRL_LAST) ){ + utf8_printf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]); + }else{ + switch(testctrl){ + + /* sqlite3_test_control(int, db, int) */ + case SQLITE_TESTCTRL_OPTIMIZATIONS: + case SQLITE_TESTCTRL_RESERVE: + if( nArg==3 ){ + int opt = (int)strtol(azArg[2], 0, 0); + rc2 = sqlite3_test_control(testctrl, p->db, opt); + raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2); + } else { + utf8_printf(stderr,"Error: testctrl %s takes a single int option\n", + azArg[1]); + } + break; + + /* sqlite3_test_control(int) */ + case SQLITE_TESTCTRL_PRNG_SAVE: + case SQLITE_TESTCTRL_PRNG_RESTORE: + case SQLITE_TESTCTRL_PRNG_RESET: + case SQLITE_TESTCTRL_BYTEORDER: + if( nArg==2 ){ + rc2 = sqlite3_test_control(testctrl); + raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2); + } else { + utf8_printf(stderr,"Error: testctrl %s takes no options\n", + azArg[1]); + } + break; + + /* sqlite3_test_control(int, uint) */ + case SQLITE_TESTCTRL_PENDING_BYTE: + if( nArg==3 ){ + unsigned int opt = (unsigned int)integerValue(azArg[2]); + rc2 = sqlite3_test_control(testctrl, opt); + raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2); + } else { + utf8_printf(stderr,"Error: testctrl %s takes a single unsigned" + " int option\n", azArg[1]); + } + break; + + /* sqlite3_test_control(int, int) */ + case SQLITE_TESTCTRL_ASSERT: + case SQLITE_TESTCTRL_ALWAYS: + case SQLITE_TESTCTRL_NEVER_CORRUPT: + if( nArg==3 ){ + int opt = booleanValue(azArg[2]); + rc2 = sqlite3_test_control(testctrl, opt); + raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2); + } else { + utf8_printf(stderr,"Error: testctrl %s takes a single int option\n", + azArg[1]); + } + break; + + /* sqlite3_test_control(int, char *) */ +#ifdef SQLITE_N_KEYWORD + case SQLITE_TESTCTRL_ISKEYWORD: + if( nArg==3 ){ + const char *opt = azArg[2]; + rc2 = sqlite3_test_control(testctrl, opt); + raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2); + } else { + utf8_printf(stderr, + "Error: testctrl %s takes a single char * option\n", + azArg[1]); + } + break; +#endif + + case SQLITE_TESTCTRL_IMPOSTER: + if( nArg==5 ){ + rc2 = sqlite3_test_control(testctrl, p->db, + azArg[2], + integerValue(azArg[3]), + integerValue(azArg[4])); + raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2); + }else{ + raw_printf(stderr,"Usage: .testctrl imposter dbName onoff tnum\n"); + } + break; + + case SQLITE_TESTCTRL_BITVEC_TEST: + case SQLITE_TESTCTRL_FAULT_INSTALL: + case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS: + case SQLITE_TESTCTRL_SCRATCHMALLOC: + default: + utf8_printf(stderr, + "Error: CLI support for testctrl %s not implemented\n", + azArg[1]); + break; + } + } + }else +#endif /* !defined(SQLITE_UNTESTABLE) */ + + if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 ){ + open_db(p, 0); + sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0); + }else + + if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 ){ + if( nArg==2 ){ + enableTimer = booleanValue(azArg[1]); + if( enableTimer && !HAS_TIMER ){ + raw_printf(stderr, "Error: timer not available on this system.\n"); + enableTimer = 0; + } + }else{ + raw_printf(stderr, "Usage: .timer on|off\n"); + rc = 1; + } + }else + + if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){ + open_db(p, 0); + if( nArg!=2 ){ + raw_printf(stderr, "Usage: .trace FILE|off\n"); + rc = 1; + goto meta_command_exit; + } + output_file_close(p->traceOut); + p->traceOut = output_file_open(azArg[1]); +#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) + if( p->traceOut==0 ){ + sqlite3_trace_v2(p->db, 0, 0, 0); + }else{ + sqlite3_trace_v2(p->db, SQLITE_TRACE_STMT, sql_trace_callback,p->traceOut); + } +#endif + }else + +#if SQLITE_USER_AUTHENTICATION + if( c=='u' && strncmp(azArg[0], "user", n)==0 ){ + if( nArg<2 ){ + raw_printf(stderr, "Usage: .user SUBCOMMAND ...\n"); + rc = 1; + goto meta_command_exit; + } + open_db(p, 0); + if( strcmp(azArg[1],"login")==0 ){ + if( nArg!=4 ){ + raw_printf(stderr, "Usage: .user login USER PASSWORD\n"); + rc = 1; + goto meta_command_exit; + } + rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3], + (int)strlen(azArg[3])); + if( rc ){ + utf8_printf(stderr, "Authentication failed for user %s\n", azArg[2]); + rc = 1; + } + }else if( strcmp(azArg[1],"add")==0 ){ + if( nArg!=5 ){ + raw_printf(stderr, "Usage: .user add USER PASSWORD ISADMIN\n"); + rc = 1; + goto meta_command_exit; + } + rc = sqlite3_user_add(p->db, azArg[2], + azArg[3], (int)strlen(azArg[3]), + booleanValue(azArg[4])); + if( rc ){ + raw_printf(stderr, "User-Add failed: %d\n", rc); + rc = 1; + } + }else if( strcmp(azArg[1],"edit")==0 ){ + if( nArg!=5 ){ + raw_printf(stderr, "Usage: .user edit USER PASSWORD ISADMIN\n"); + rc = 1; + goto meta_command_exit; + } + rc = sqlite3_user_change(p->db, azArg[2], + azArg[3], (int)strlen(azArg[3]), + booleanValue(azArg[4])); + if( rc ){ + raw_printf(stderr, "User-Edit failed: %d\n", rc); + rc = 1; + } + }else if( strcmp(azArg[1],"delete")==0 ){ + if( nArg!=3 ){ + raw_printf(stderr, "Usage: .user delete USER\n"); + rc = 1; + goto meta_command_exit; + } + rc = sqlite3_user_delete(p->db, azArg[2]); + if( rc ){ + raw_printf(stderr, "User-Delete failed: %d\n", rc); + rc = 1; + } + }else{ + raw_printf(stderr, "Usage: .user login|add|edit|delete ...\n"); + rc = 1; + goto meta_command_exit; + } + }else +#endif /* SQLITE_USER_AUTHENTICATION */ + + if( c=='v' && strncmp(azArg[0], "version", n)==0 ){ + utf8_printf(p->out, "SQLite %s %s\n" /*extra-version-info*/, + sqlite3_libversion(), sqlite3_sourceid()); + }else + + if( c=='v' && strncmp(azArg[0], "vfsinfo", n)==0 ){ + const char *zDbName = nArg==2 ? azArg[1] : "main"; + sqlite3_vfs *pVfs = 0; + if( p->db ){ + sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFS_POINTER, &pVfs); + if( pVfs ){ + utf8_printf(p->out, "vfs.zName = \"%s\"\n", pVfs->zName); + raw_printf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion); + raw_printf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile); + raw_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname); + } + } + }else + + if( c=='v' && strncmp(azArg[0], "vfslist", n)==0 ){ + sqlite3_vfs *pVfs; + sqlite3_vfs *pCurrent = 0; + if( p->db ){ + sqlite3_file_control(p->db, "main", SQLITE_FCNTL_VFS_POINTER, &pCurrent); + } + for(pVfs=sqlite3_vfs_find(0); pVfs; pVfs=pVfs->pNext){ + utf8_printf(p->out, "vfs.zName = \"%s\"%s\n", pVfs->zName, + pVfs==pCurrent ? " <--- CURRENT" : ""); + raw_printf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion); + raw_printf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile); + raw_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname); + if( pVfs->pNext ){ + raw_printf(p->out, "-----------------------------------\n"); + } + } + }else + + if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){ + const char *zDbName = nArg==2 ? azArg[1] : "main"; + char *zVfsName = 0; + if( p->db ){ + sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName); + if( zVfsName ){ + utf8_printf(p->out, "%s\n", zVfsName); + sqlite3_free(zVfsName); + } + } + }else + +#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE) + if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){ + sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff; + }else +#endif + + if( c=='w' && strncmp(azArg[0], "width", n)==0 ){ + int j; + assert( nArg<=ArraySize(azArg) ); + for(j=1; jcolWidth); j++){ + p->colWidth[j-1] = (int)integerValue(azArg[j]); + } + }else + + { + utf8_printf(stderr, "Error: unknown command or invalid arguments: " + " \"%s\". Enter \".help\" for help\n", azArg[0]); + rc = 1; + } + +meta_command_exit: + if( p->outCount ){ + p->outCount--; + if( p->outCount==0 ) output_reset(p); + } + return rc; +} + +/* +** Return TRUE if a semicolon occurs anywhere in the first N characters +** of string z[]. +*/ +static int line_contains_semicolon(const char *z, int N){ + int i; + for(i=0; idb, zSql, shell_callback, p, &zErrMsg); + END_TIMER; + if( rc || zErrMsg ){ + char zPrefix[100]; + if( in!=0 || !stdin_is_interactive ){ + sqlite3_snprintf(sizeof(zPrefix), zPrefix, + "Error: near line %d:", startline); + }else{ + sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:"); + } + if( zErrMsg!=0 ){ + utf8_printf(stderr, "%s %s\n", zPrefix, zErrMsg); + sqlite3_free(zErrMsg); + zErrMsg = 0; + }else{ + utf8_printf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db)); + } + return 1; + }else if( ShellHasFlag(p, SHFLG_CountChanges) ){ + raw_printf(p->out, "changes: %3d total_changes: %d\n", + sqlite3_changes(p->db), sqlite3_total_changes(p->db)); + } + return 0; +} + + +/* +** Read input from *in and process it. If *in==0 then input +** is interactive - the user is typing it it. Otherwise, input +** is coming from a file or device. A prompt is issued and history +** is saved only if input is interactive. An interrupt signal will +** cause this routine to exit immediately, unless input is interactive. +** +** Return the number of errors. +*/ +static int process_input(ShellState *p, FILE *in){ + char *zLine = 0; /* A single input line */ + char *zSql = 0; /* Accumulated SQL text */ + int nLine; /* Length of current line */ + int nSql = 0; /* Bytes of zSql[] used */ + int nAlloc = 0; /* Allocated zSql[] space */ + int nSqlPrior = 0; /* Bytes of zSql[] used by prior line */ + int rc; /* Error code */ + 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) ){ + fflush(p->out); + zLine = one_input_line(in, zLine, nSql>0); + if( zLine==0 ){ + /* End of input */ + if( in==0 && stdin_is_interactive ) printf("\n"); + break; + } + if( seenInterrupt ){ + if( in!=0 ) break; + seenInterrupt = 0; + } + lineno++; + if( nSql==0 && _all_whitespace(zLine) ){ + if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zLine); + continue; + } + if( zLine && zLine[0]=='.' && nSql==0 ){ + if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zLine); + rc = do_meta_command(zLine, p); + if( rc==2 ){ /* exit requested */ + break; + }else if( rc ){ + errCnt++; + } + continue; + } + if( line_is_command_terminator(zLine) && line_is_complete(zSql, nSql) ){ + memcpy(zLine,";",2); + } + nLine = strlen30(zLine); + if( nSql+nLine+2>=nAlloc ){ + nAlloc = nSql+nLine+100; + zSql = realloc(zSql, nAlloc); + if( zSql==0 ){ + raw_printf(stderr, "Error: out of memory\n"); + exit(1); + } + } + nSqlPrior = nSql; + if( nSql==0 ){ + int i; + for(i=0; zLine[i] && IsSpace(zLine[i]); i++){} + assert( nAlloc>0 && zSql!=0 ); + 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) ){ + errCnt += runOneSqlLine(p, zSql, in, startline); + nSql = 0; + if( p->outCount ){ + output_reset(p); + p->outCount = 0; + } + }else if( nSql && _all_whitespace(zSql) ){ + if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zSql); + nSql = 0; + } + } + if( nSql && !_all_whitespace(zSql) ){ + runOneSqlLine(p, zSql, in, startline); + } + free(zSql); + free(zLine); + return errCnt>0; +} + +/* +** Return a pathname which is the user's home directory. A +** 0 return indicates an error of some kind. +*/ +static char *find_home_dir(int clearFlag){ + static char *home_dir = NULL; + if( clearFlag ){ + free(home_dir); + home_dir = 0; + return 0; + } + if( home_dir ) return home_dir; + +#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) \ + && !defined(__RTP__) && !defined(_WRS_KERNEL) + { + struct passwd *pwent; + uid_t uid = getuid(); + if( (pwent=getpwuid(uid)) != NULL) { + home_dir = pwent->pw_dir; + } + } +#endif + +#if defined(_WIN32_WCE) + /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv() + */ + home_dir = "/"; +#else + +#if defined(_WIN32) || defined(WIN32) + if (!home_dir) { + home_dir = getenv("USERPROFILE"); + } +#endif + + if (!home_dir) { + home_dir = getenv("HOME"); + } + +#if defined(_WIN32) || defined(WIN32) + if (!home_dir) { + char *zDrive, *zPath; + int n; + zDrive = getenv("HOMEDRIVE"); + zPath = getenv("HOMEPATH"); + if( zDrive && zPath ){ + n = strlen30(zDrive) + strlen30(zPath) + 1; + home_dir = malloc( n ); + if( home_dir==0 ) return 0; + sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath); + return home_dir; + } + home_dir = "c:\\"; + } +#endif + +#endif /* !_WIN32_WCE */ + + if( home_dir ){ + int n = strlen30(home_dir) + 1; + char *z = malloc( n ); + if( z ) memcpy(z, home_dir, n); + home_dir = z; + } + + return home_dir; +} + +/* +** Read input from the file given by sqliterc_override. Or if that +** parameter is NULL, take input from ~/.sqliterc +** +** Returns the number of errors. +*/ +static void process_sqliterc( + ShellState *p, /* Configuration data */ + const char *sqliterc_override /* Name of config file. NULL to use default */ +){ + char *home_dir = NULL; + const char *sqliterc = sqliterc_override; + char *zBuf = 0; + FILE *in = NULL; + + if (sqliterc == NULL) { + home_dir = find_home_dir(0); + if( home_dir==0 ){ + raw_printf(stderr, "-- warning: cannot find home directory;" + " cannot read ~/.sqliterc\n"); + return; + } + sqlite3_initialize(); + zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir); + sqliterc = zBuf; + } + in = fopen(sqliterc,"rb"); + if( in ){ + if( stdin_is_interactive ){ + utf8_printf(stderr,"-- Loading resources from %s\n",sqliterc); + } + process_input(p,in); + fclose(in); + } + sqlite3_free(zBuf); +} + +/* +** Show available command line options +*/ +static const char zOptions[] = + " -ascii set output mode to 'ascii'\n" + " -bail stop after hitting an error\n" + " -batch force batch I/O\n" + " -column set output mode to 'column'\n" + " -cmd COMMAND run \"COMMAND\" before reading stdin\n" + " -csv set output mode to 'csv'\n" + " -echo print commands before execution\n" + " -init FILENAME read/process named file\n" + " -[no]header turn headers on or off\n" +#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5) + " -heap SIZE Size of heap for memsys3 or memsys5\n" +#endif + " -help show this message\n" + " -html set output mode to HTML\n" + " -interactive force interactive I/O\n" + " -line set output mode to 'line'\n" + " -list set output mode to 'list'\n" + " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n" + " -mmap N default mmap size set to N\n" +#ifdef SQLITE_ENABLE_MULTIPLEX + " -multiplex enable the multiplexor VFS\n" +#endif + " -newline SEP set output row separator. Default: '\\n'\n" + " -nullvalue TEXT set text string for NULL values. Default ''\n" + " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n" + " -quote set output mode to 'quote'\n" + " -scratch SIZE N use N slots of SZ bytes each for scratch memory\n" + " -separator SEP set output column separator. Default: '|'\n" + " -stats print memory stats before each finalize\n" + " -version show SQLite version\n" + " -vfs NAME use NAME as the default VFS\n" +#ifdef SQLITE_ENABLE_VFSTRACE + " -vfstrace enable tracing of all VFS calls\n" +#endif +; +static void usage(int showDetail){ + utf8_printf(stderr, + "Usage: %s [OPTIONS] FILENAME [SQL]\n" + "FILENAME is the name of an SQLite database. A new database is created\n" + "if the file does not previously exist.\n", Argv0); + if( showDetail ){ + utf8_printf(stderr, "OPTIONS include:\n%s", zOptions); + }else{ + raw_printf(stderr, "Use the -help option for additional information\n"); + } + exit(1); +} + +/* +** Initialize the state information in data +*/ +static void main_init(ShellState *data) { + memset(data, 0, sizeof(*data)); + data->normalMode = data->cMode = data->mode = MODE_List; + data->autoExplain = 1; + memcpy(data->colSeparator,SEP_Column, 2); + memcpy(data->rowSeparator,SEP_Row, 2); + data->showHeader = 0; + data->shellFlgs = SHFLG_Lookaside; + sqlite3_config(SQLITE_CONFIG_URI, 1); + sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data); + sqlite3_config(SQLITE_CONFIG_MULTITHREAD); + sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> "); + sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> "); +} + +/* +** Output text to the console in a font that attracts extra attention. +*/ +#ifdef _WIN32 +static void printBold(const char *zText){ + HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE); + CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo; + GetConsoleScreenBufferInfo(out, &defaultScreenInfo); + SetConsoleTextAttribute(out, + FOREGROUND_RED|FOREGROUND_INTENSITY + ); + printf("%s", zText); + SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes); +} +#else +static void printBold(const char *zText){ + printf("\033[1m%s\033[0m", zText); +} +#endif + +/* +** Get the argument to an --option. Throw an error and die if no argument +** is available. +*/ +static char *cmdline_option_value(int argc, char **argv, int i){ + if( i==argc ){ + utf8_printf(stderr, "%s: Error: missing argument to %s\n", + argv[0], argv[argc-1]); + exit(1); + } + return argv[i]; +} + +#ifndef SQLITE_SHELL_IS_UTF8 +# if (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER) +# define SQLITE_SHELL_IS_UTF8 (0) +# else +# define SQLITE_SHELL_IS_UTF8 (1) +# endif +#endif + +#if SQLITE_SHELL_IS_UTF8 +int SQLITE_CDECL main(int argc, char **argv){ +#else +int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ + char **argv; +#endif + char *zErrMsg = 0; + ShellState data; + const char *zInitFile = 0; + int i; + int rc = 0; + int warnInmemoryDb = 0; + int readStdin = 1; + int nCmd = 0; + char **azCmd = 0; + + setBinaryMode(stdin, 0); + setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */ + stdin_is_interactive = isatty(0); + stdout_is_console = isatty(1); + +#if USE_SYSTEM_SQLITE+0!=1 + if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){ + utf8_printf(stderr, "SQLite header and source version mismatch\n%s\n%s\n", + sqlite3_sourceid(), SQLITE_SOURCE_ID); + exit(1); + } +#endif + main_init(&data); +#if !SQLITE_SHELL_IS_UTF8 + sqlite3_initialize(); + argv = sqlite3_malloc64(sizeof(argv[0])*argc); + if( argv==0 ){ + raw_printf(stderr, "out of memory\n"); + exit(1); + } + for(i=0; i=1 && argv && argv[0] ); + Argv0 = argv[0]; + + /* Make sure we have a valid signal handler early, before anything + ** else is done. + */ +#ifdef SIGINT + signal(SIGINT, interrupt_handler); +#endif + +#ifdef SQLITE_SHELL_DBNAME_PROC + { + /* If the SQLITE_SHELL_DBNAME_PROC macro is defined, then it is the name + ** of a C-function that will provide the name of the database file. Use + ** this compile-time option to embed this shell program in larger + ** applications. */ + extern void SQLITE_SHELL_DBNAME_PROC(const char**); + SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename); + warnInmemoryDb = 0; + } +#endif + + /* Do an initial pass through the command-line argument to locate + ** the name of the database file, the name of the initialization file, + ** the size of the alternative malloc heap, + ** and the first command to execute. + */ + for(i=1; i0x7fff0000 ) szHeap = 0x7fff0000; + sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64); +#else + (void)cmdline_option_value(argc, argv, ++i); +#endif + }else if( strcmp(z,"-scratch")==0 ){ + int n, sz; + sz = (int)integerValue(cmdline_option_value(argc,argv,++i)); + if( sz>400000 ) sz = 400000; + if( sz<2500 ) sz = 2500; + n = (int)integerValue(cmdline_option_value(argc,argv,++i)); + if( n>10 ) n = 10; + if( n<1 ) n = 1; + sqlite3_config(SQLITE_CONFIG_SCRATCH, malloc(n*sz+1), sz, n); + data.shellFlgs |= SHFLG_Scratch; + }else if( strcmp(z,"-pagecache")==0 ){ + int n, sz; + sz = (int)integerValue(cmdline_option_value(argc,argv,++i)); + if( sz>70000 ) sz = 70000; + if( sz<0 ) sz = 0; + n = (int)integerValue(cmdline_option_value(argc,argv,++i)); + sqlite3_config(SQLITE_CONFIG_PAGECACHE, + (n>0 && sz>0) ? malloc(n*sz) : 0, sz, n); + data.shellFlgs |= SHFLG_Pagecache; + }else if( strcmp(z,"-lookaside")==0 ){ + int n, sz; + sz = (int)integerValue(cmdline_option_value(argc,argv,++i)); + if( sz<0 ) sz = 0; + n = (int)integerValue(cmdline_option_value(argc,argv,++i)); + if( n<0 ) n = 0; + sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, n); + if( sz*n==0 ) data.shellFlgs &= ~SHFLG_Lookaside; +#ifdef SQLITE_ENABLE_VFSTRACE + }else if( strcmp(z,"-vfstrace")==0 ){ + extern int vfstrace_register( + const char *zTraceName, + const char *zOldVfsName, + int (*xOut)(const char*,void*), + void *pOutArg, + int makeDefault + ); + vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1); +#endif +#ifdef SQLITE_ENABLE_MULTIPLEX + }else if( strcmp(z,"-multiplex")==0 ){ + extern int sqlite3_multiple_initialize(const char*,int); + sqlite3_multiplex_initialize(0, 1); +#endif + }else if( strcmp(z,"-mmap")==0 ){ + sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i)); + sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz); + }else if( strcmp(z,"-vfs")==0 ){ + sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i)); + if( pVfs ){ + sqlite3_vfs_register(pVfs, 1); + }else{ + utf8_printf(stderr, "no such VFS: \"%s\"\n", argv[i]); + exit(1); + } + } + } + if( data.zDbFilename==0 ){ +#ifndef SQLITE_OMIT_MEMORYDB + data.zDbFilename = ":memory:"; + warnInmemoryDb = argc==1; +#else + utf8_printf(stderr,"%s: Error: no database filename specified\n", Argv0); + return 1; +#endif + } + data.out = stdout; + + /* Go ahead and open the database file if it already exists. If the + ** file does not exist, delay opening it. This prevents empty database + ** files from being created if a user mistypes the database name argument + ** to the sqlite command-line tool. + */ + if( access(data.zDbFilename, 0)==0 ){ + open_db(&data, 0); + } + + /* Process the initialization file if there is one. If no -init option + ** is given on the command line, look for a file named ~/.sqliterc and + ** try to process it. + */ + process_sqliterc(&data,zInitFile); + + /* Make a second pass through the command-line argument and set + ** options. This second pass is delayed until after the initialization + ** file is processed so that the command-line arguments will override + ** settings in the initialization file. + */ + for(i=1; i Date: Tue, 11 Jul 2017 13:59:07 +0000 Subject: [PATCH 49/64] Add support for tab-completion (using the ext/misc/completion.c virtual table) to the command-line shell. FossilOrigin-Name: 95cd1d9f8baa6be305c9a8bfa26fef2a403f2d5b3b5c9c55382ec04f0bc98d40 --- ext/misc/completion.c | 6 - manifest | 16 +- manifest.uuid | 2 +- src/shell.c | 583 +++++++++++++++++++++++++++++++++++++++++- src/shell.c.in | 73 +++++- 5 files changed, 663 insertions(+), 17 deletions(-) diff --git a/ext/misc/completion.c b/ext/misc/completion.c index a3189ad154..8dc5d7dbaf 100644 --- a/ext/misc/completion.c +++ b/ext/misc/completion.c @@ -33,10 +33,7 @@ ** faster than any human can type. ** */ -#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_COMPLETIONVTAB) -#if !defined(SQLITEINT_H) #include "sqlite3ext.h" -#endif SQLITE_EXTENSION_INIT1 #include #include @@ -495,7 +492,6 @@ int sqlite3CompletionVtabInit(sqlite3 *db){ return rc; } -#ifndef SQLITE_CORE #ifdef _WIN32 __declspec(dllexport) #endif @@ -511,5 +507,3 @@ int sqlite3_completion_init( #endif return rc; } -#endif /* SQLITE_CORE */ -#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_COMPLETIONVTAB) */ diff --git a/manifest b/manifest index 056c17b447..c0ffe7578b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\ssrc/shell.c\sfile\sso\sthat\sit\sis\sgenerated\sfrom\sa\snew\sscript\sat\ntool/mkshellc.tcl\sand\sthe\stemplate\sfile\ssrc/shell.c.in,\sand\sautomatically\nincludes\sthe\sextensions\sit\sneeds\sout\sof\sext/misc. -D 2017-07-11T13:34:40.462 +C Add\ssupport\sfor\stab-completion\s(using\sthe\sext/misc/completion.c\svirtual\stable)\nto\sthe\scommand-line\sshell. +D 2017-07-11T13:59:07.400 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba @@ -256,7 +256,7 @@ F ext/misc/amatch.c 6db4607cb17c54b853a2d7c7c36046d004853f65b9b733e6f019d543d5df F ext/misc/anycollseq.c 5ffdfde9829eeac52219136ad6aa7cd9a4edb3b15f4f2532de52f4a22525eddb F ext/misc/carray.c 40c27641010a4dc67e3690bdb7c9d36ca58b3c2d F ext/misc/closure.c 0d2a038df8fbae7f19de42e7c7d71f2e4dc88704 -F ext/misc/completion.c 637c016977809c2c3174472e7a416c9dbefc89dadb0efbd33f1516114b43900e +F ext/misc/completion.c 821141b02a0313ce7dbe72f0260ef755f81d4b57eacb799864e4c40ad5ceb3f3 F ext/misc/compress.c 122faa92d25033d6c3f07c39231de074ab3d2e83 F ext/misc/csv.c d91c0388445b08f6e373dd0e8fc024d4551b1fcaf64e876a1c3f4fac8a63adc2 F ext/misc/dbdump.c 3509fa6b8932d04e932d6b6b827b6a82ca362781b8e8f3c77336f416793e215e @@ -450,8 +450,8 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 6aa1fb1212e601f65b983ee1215d69a591986c8f97a3805c425c625a53839539 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 6aa7e8ee53dcb9d0b77b05670bb44a1076d6747bc9b2c1f12a365b553ab6c828 -F src/shell.c 71a338b3a29502a4a7290fa646bc4547d911777aba55ebc040b5940786435833 -F src/shell.c.in 9d75c83c13fb1b96e60c56cce96146d84c4c8b3d18d11bd85e0759ebf744bcb2 +F src/shell.c 19726a6f28f66aa0488f5e9c7aacc399f2bbcd934bffc3a92a5de6d365389eee +F src/shell.c.in 18510e3fdd9216a6183ff93a48cac7d8d253d39f17750af597d90d3c5f27fc34 F src/sqlite.h.in 03a422ba13da1dfef7f1aaa1ba344acf18dc867112620b1fdb2a1426cabba634 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 58fd0676d3111d02e62e5a35992a7d3da5d3f88753acc174f2d37b774fbbdd28 @@ -1631,7 +1631,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 724819b456ca7a5ca6d68415b3b3554741c3ddbb5c416cb6b6b5fc54177f426e -R 60a762ef308a5ae7a380cb2ce07b0a0c +P 17e0bb12d82b510b86b6886b9fd0faf39b60b1374027344f89d7b89a32b842b9 +R 951f8f3a9284f3001be7f39a25c50055 U drh -Z 1a54bd7eb9eb8ff312901d65383e16cf +Z 55996074e61f063450435131cf82f298 diff --git a/manifest.uuid b/manifest.uuid index b24374cf1b..7a51d0481c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -17e0bb12d82b510b86b6886b9fd0faf39b60b1374027344f89d7b89a32b842b9 \ No newline at end of file +95cd1d9f8baa6be305c9a8bfa26fef2a403f2d5b3b5c9c55382ec04f0bc98d40 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 8a10fc02b6..443304616c 100644 --- a/src/shell.c +++ b/src/shell.c @@ -1629,6 +1629,517 @@ int sqlite3_fileio_init( } /************************* End ../ext/misc/fileio.c ********************/ +/************************* Begin ../ext/misc/completion.c ******************/ +/* +** 2017-07-10 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file implements an eponymous virtual table that returns suggested +** completions for a partial SQL input. +** +** Suggested usage: +** +** SELECT DISTINCT candidate COLLATE nocase +** FROM completion($prefix,$wholeline) +** ORDER BY 1; +** +** The two query parameters are optional. $prefix is the text of the +** current word being typed and that is to be completed. $wholeline is +** the complete input line, used for context. +** +** The raw completion() table might return the same candidate multiple +** times, for example if the same column name is used to two or more +** tables. And the candidates are returned in an arbitrary order. Hence, +** the DISTINCT and ORDER BY are recommended. +** +** This virtual table operates at the speed of human typing, and so there +** is no attempt to make it fast. Even a slow implementation will be much +** faster than any human can type. +** +*/ +SQLITE_EXTENSION_INIT1 +#include +#include +#include + +#ifndef SQLITE_OMIT_VIRTUALTABLE + +/* completion_vtab is a subclass of sqlite3_vtab which will +** serve as the underlying representation of a completion virtual table +*/ +typedef struct completion_vtab completion_vtab; +struct completion_vtab { + sqlite3_vtab base; /* Base class - must be first */ + sqlite3 *db; /* Database connection for this completion vtab */ +}; + +/* completion_cursor is a subclass of sqlite3_vtab_cursor which will +** serve as the underlying representation of a cursor that scans +** over rows of the result +*/ +typedef struct completion_cursor completion_cursor; +struct completion_cursor { + sqlite3_vtab_cursor base; /* Base class - must be first */ + sqlite3 *db; /* Database connection for this cursor */ + int nPrefix, nLine; /* Number of bytes in zPrefix and zLine */ + char *zPrefix; /* The prefix for the word we want to complete */ + char *zLine; /* The whole that we want to complete */ + const char *zCurrentRow; /* Current output row */ + sqlite3_stmt *pStmt; /* Current statement */ + sqlite3_int64 iRowid; /* The rowid */ + int ePhase; /* Current phase */ + int j; /* inter-phase counter */ +}; + +/* Values for ePhase: +*/ +#define COMPLETION_FIRST_PHASE 1 +#define COMPLETION_KEYWORDS 1 +#define COMPLETION_PRAGMAS 2 +#define COMPLETION_FUNCTIONS 3 +#define COMPLETION_COLLATIONS 4 +#define COMPLETION_INDEXES 5 +#define COMPLETION_TRIGGERS 6 +#define COMPLETION_DATABASES 7 +#define COMPLETION_TABLES 8 +#define COMPLETION_COLUMNS 9 +#define COMPLETION_MODULES 10 +#define COMPLETION_EOF 11 + +/* +** The completionConnect() method is invoked to create a new +** completion_vtab that describes the completion virtual table. +** +** Think of this routine as the constructor for completion_vtab objects. +** +** All this routine needs to do is: +** +** (1) Allocate the completion_vtab object and initialize all fields. +** +** (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the +** result set of queries against completion will look like. +*/ +static int completionConnect( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + completion_vtab *pNew; + int rc; + +/* Column numbers */ +#define COMPLETION_COLUMN_CANDIDATE 0 /* Suggested completion of the input */ +#define COMPLETION_COLUMN_PREFIX 1 /* Prefix of the word to be completed */ +#define COMPLETION_COLUMN_WHOLELINE 2 /* Entire line seen so far */ +#define COMPLETION_COLUMN_PHASE 3 /* ePhase - used for debugging only */ + + rc = sqlite3_declare_vtab(db, + "CREATE TABLE x(" + " candidate TEXT," + " prefix TEXT HIDDEN," + " wholeline TEXT HIDDEN," + " phase INT HIDDEN" /* Used for debugging only */ + ")"); + if( rc==SQLITE_OK ){ + pNew = sqlite3_malloc( sizeof(*pNew) ); + *ppVtab = (sqlite3_vtab*)pNew; + if( pNew==0 ) return SQLITE_NOMEM; + memset(pNew, 0, sizeof(*pNew)); + pNew->db = db; + } + return rc; +} + +/* +** This method is the destructor for completion_cursor objects. +*/ +static int completionDisconnect(sqlite3_vtab *pVtab){ + sqlite3_free(pVtab); + return SQLITE_OK; +} + +/* +** Constructor for a new completion_cursor object. +*/ +static int completionOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ + completion_cursor *pCur; + pCur = sqlite3_malloc( sizeof(*pCur) ); + if( pCur==0 ) return SQLITE_NOMEM; + memset(pCur, 0, sizeof(*pCur)); + pCur->db = ((completion_vtab*)p)->db; + *ppCursor = &pCur->base; + return SQLITE_OK; +} + +/* +** Reset the completion_cursor. +*/ +static void completionCursorReset(completion_cursor *pCur){ + sqlite3_free(pCur->zPrefix); pCur->zPrefix = 0; pCur->nPrefix = 0; + sqlite3_free(pCur->zLine); pCur->zLine = 0; pCur->nLine = 0; + sqlite3_finalize(pCur->pStmt); pCur->pStmt = 0; + pCur->j = 0; +} + +/* +** Destructor for a completion_cursor. +*/ +static int completionClose(sqlite3_vtab_cursor *cur){ + completionCursorReset((completion_cursor*)cur); + sqlite3_free(cur); + return SQLITE_OK; +} + +/* +** All SQL keywords understood by SQLite +*/ +static const char *completionKwrds[] = { + "ABORT", "ACTION", "ADD", "AFTER", "ALL", "ALTER", "ANALYZE", "AND", "AS", + "ASC", "ATTACH", "AUTOINCREMENT", "BEFORE", "BEGIN", "BETWEEN", "BY", + "CASCADE", "CASE", "CAST", "CHECK", "COLLATE", "COLUMN", "COMMIT", + "CONFLICT", "CONSTRAINT", "CREATE", "CROSS", "CURRENT_DATE", + "CURRENT_TIME", "CURRENT_TIMESTAMP", "DATABASE", "DEFAULT", "DEFERRABLE", + "DEFERRED", "DELETE", "DESC", "DETACH", "DISTINCT", "DROP", "EACH", + "ELSE", "END", "ESCAPE", "EXCEPT", "EXCLUSIVE", "EXISTS", "EXPLAIN", + "FAIL", "FOR", "FOREIGN", "FROM", "FULL", "GLOB", "GROUP", "HAVING", "IF", + "IGNORE", "IMMEDIATE", "IN", "INDEX", "INDEXED", "INITIALLY", "INNER", + "INSERT", "INSTEAD", "INTERSECT", "INTO", "IS", "ISNULL", "JOIN", "KEY", + "LEFT", "LIKE", "LIMIT", "MATCH", "NATURAL", "NO", "NOT", "NOTNULL", + "NULL", "OF", "OFFSET", "ON", "OR", "ORDER", "OUTER", "PLAN", "PRAGMA", + "PRIMARY", "QUERY", "RAISE", "RECURSIVE", "REFERENCES", "REGEXP", + "REINDEX", "RELEASE", "RENAME", "REPLACE", "RESTRICT", "RIGHT", + "ROLLBACK", "ROW", "SAVEPOINT", "SELECT", "SET", "TABLE", "TEMP", + "TEMPORARY", "THEN", "TO", "TRANSACTION", "TRIGGER", "UNION", "UNIQUE", + "UPDATE", "USING", "VACUUM", "VALUES", "VIEW", "VIRTUAL", "WHEN", "WHERE", + "WITH", "WITHOUT", +}; + +/* +** Advance a completion_cursor to its next row of output. +** +** The ->ePhase, ->j, and ->pStmt fields of the completion_cursor object +** record the current state of the scan. This routine sets ->zCurrentRow +** to the current row of output and then returns. If no more rows remain, +** then ->ePhase is set to COMPLETION_EOF which will signal the virtual +** table that has reached the end of its scan. +** +** The current implementation just lists potential identifiers and +** keywords and filters them by zPrefix. Future enhancements should +** take zLine into account to try to restrict the set of identifiers and +** keywords based on what would be legal at the current point of input. +*/ +static int completionNext(sqlite3_vtab_cursor *cur){ + completion_cursor *pCur = (completion_cursor*)cur; + int eNextPhase = 0; /* Next phase to try if current phase reaches end */ + int iCol = -1; /* If >=0, step pCur->pStmt and use the i-th column */ + pCur->iRowid++; + while( pCur->ePhase!=COMPLETION_EOF ){ + switch( pCur->ePhase ){ + case COMPLETION_KEYWORDS: { + if( pCur->j >= sizeof(completionKwrds)/sizeof(completionKwrds[0]) ){ + pCur->zCurrentRow = 0; + pCur->ePhase = COMPLETION_DATABASES; + }else{ + pCur->zCurrentRow = completionKwrds[pCur->j++]; + } + iCol = -1; + break; + } + case COMPLETION_DATABASES: { + if( pCur->pStmt==0 ){ + sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1, + &pCur->pStmt, 0); + } + iCol = 1; + eNextPhase = COMPLETION_TABLES; + break; + } + case COMPLETION_TABLES: { + if( pCur->pStmt==0 ){ + sqlite3_stmt *pS2; + char *zSql = 0; + const char *zSep = ""; + sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1, &pS2, 0); + while( sqlite3_step(pS2)==SQLITE_ROW ){ + const char *zDb = (const char*)sqlite3_column_text(pS2, 1); + zSql = sqlite3_mprintf( + "%z%s" + "SELECT name FROM \"%w\".sqlite_master" + " WHERE type='table'", + zSql, zSep, zDb + ); + if( zSql==0 ) return SQLITE_NOMEM; + zSep = " UNION "; + } + sqlite3_finalize(pS2); + sqlite3_prepare_v2(pCur->db, zSql, -1, &pCur->pStmt, 0); + sqlite3_free(zSql); + } + iCol = 0; + eNextPhase = COMPLETION_COLUMNS; + break; + } + case COMPLETION_COLUMNS: { + if( pCur->pStmt==0 ){ + sqlite3_stmt *pS2; + char *zSql = 0; + const char *zSep = ""; + sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1, &pS2, 0); + while( sqlite3_step(pS2)==SQLITE_ROW ){ + const char *zDb = (const char*)sqlite3_column_text(pS2, 1); + zSql = sqlite3_mprintf( + "%z%s" + "SELECT pti.name FROM \"%w\".sqlite_master AS sm" + " JOIN pragma_table_info(sm.name,%Q) AS pti" + " WHERE sm.type='table'", + zSql, zSep, zDb, zDb + ); + if( zSql==0 ) return SQLITE_NOMEM; + zSep = " UNION "; + } + sqlite3_finalize(pS2); + sqlite3_prepare_v2(pCur->db, zSql, -1, &pCur->pStmt, 0); + sqlite3_free(zSql); + } + iCol = 0; + eNextPhase = COMPLETION_EOF; + break; + } + } + if( iCol<0 ){ + /* This case is when the phase presets zCurrentRow */ + if( pCur->zCurrentRow==0 ) continue; + }else{ + if( sqlite3_step(pCur->pStmt)==SQLITE_ROW ){ + /* Extract the next row of content */ + pCur->zCurrentRow = (const char*)sqlite3_column_text(pCur->pStmt, iCol); + }else{ + /* When all rows are finished, advance to the next phase */ + sqlite3_finalize(pCur->pStmt); + pCur->pStmt = 0; + pCur->ePhase = eNextPhase; + continue; + } + } + if( pCur->nPrefix==0 ) break; + if( sqlite3_strnicmp(pCur->zPrefix, pCur->zCurrentRow, pCur->nPrefix)==0 ){ + break; + } + } + + return SQLITE_OK; +} + +/* +** Return values of columns for the row at which the completion_cursor +** is currently pointing. +*/ +static int completionColumn( + sqlite3_vtab_cursor *cur, /* The cursor */ + sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ + int i /* Which column to return */ +){ + completion_cursor *pCur = (completion_cursor*)cur; + switch( i ){ + case COMPLETION_COLUMN_CANDIDATE: { + sqlite3_result_text(ctx, pCur->zCurrentRow, -1, SQLITE_TRANSIENT); + break; + } + case COMPLETION_COLUMN_PREFIX: { + sqlite3_result_text(ctx, pCur->zPrefix, -1, SQLITE_TRANSIENT); + break; + } + case COMPLETION_COLUMN_WHOLELINE: { + sqlite3_result_text(ctx, pCur->zLine, -1, SQLITE_TRANSIENT); + break; + } + case COMPLETION_COLUMN_PHASE: { + sqlite3_result_int(ctx, pCur->ePhase); + break; + } + } + return SQLITE_OK; +} + +/* +** Return the rowid for the current row. In this implementation, the +** rowid is the same as the output value. +*/ +static int completionRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ + completion_cursor *pCur = (completion_cursor*)cur; + *pRowid = pCur->iRowid; + return SQLITE_OK; +} + +/* +** Return TRUE if the cursor has been moved off of the last +** row of output. +*/ +static int completionEof(sqlite3_vtab_cursor *cur){ + completion_cursor *pCur = (completion_cursor*)cur; + return pCur->ePhase >= COMPLETION_EOF; +} + +/* +** This method is called to "rewind" the completion_cursor object back +** to the first row of output. This method is always called at least +** once prior to any call to completionColumn() or completionRowid() or +** completionEof(). +*/ +static int completionFilter( + sqlite3_vtab_cursor *pVtabCursor, + int idxNum, const char *idxStr, + int argc, sqlite3_value **argv +){ + completion_cursor *pCur = (completion_cursor *)pVtabCursor; + int iArg = 0; + completionCursorReset(pCur); + if( idxNum & 1 ){ + pCur->nPrefix = sqlite3_value_bytes(argv[iArg]); + if( pCur->nPrefix>0 ){ + pCur->zPrefix = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg])); + if( pCur->zPrefix==0 ) return SQLITE_NOMEM; + } + iArg++; + } + if( idxNum & 2 ){ + pCur->nLine = sqlite3_value_bytes(argv[iArg]); + if( pCur->nLine>0 ){ + pCur->zLine = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg])); + if( pCur->zLine==0 ) return SQLITE_NOMEM; + } + iArg++; + } + if( pCur->zLine!=0 && pCur->zPrefix==0 ){ + int i = pCur->nLine; + while( i>0 && (isalnum(pCur->zLine[i-1]) || pCur->zLine[i-1]=='_') ){ + i--; + } + pCur->nPrefix = pCur->nLine - i; + if( pCur->nPrefix>0 ){ + pCur->zPrefix = sqlite3_mprintf("%.*s", pCur->nPrefix, pCur->zLine + i); + if( pCur->zPrefix==0 ) return SQLITE_NOMEM; + } + } + pCur->iRowid = 0; + pCur->ePhase = COMPLETION_FIRST_PHASE; + return completionNext(pVtabCursor); +} + +/* +** SQLite will invoke this method one or more times while planning a query +** that uses the completion virtual table. This routine needs to create +** a query plan for each invocation and compute an estimated cost for that +** plan. +** +** There are two hidden parameters that act as arguments to the table-valued +** function: "prefix" and "wholeline". Bit 0 of idxNum is set if "prefix" +** is available and bit 1 is set if "wholeline" is available. +*/ +static int completionBestIndex( + sqlite3_vtab *tab, + sqlite3_index_info *pIdxInfo +){ + int i; /* Loop over constraints */ + int idxNum = 0; /* The query plan bitmask */ + int prefixIdx = -1; /* Index of the start= constraint, or -1 if none */ + int wholelineIdx = -1; /* Index of the stop= constraint, or -1 if none */ + int nArg = 0; /* Number of arguments that completeFilter() expects */ + const struct sqlite3_index_constraint *pConstraint; + + pConstraint = pIdxInfo->aConstraint; + for(i=0; inConstraint; i++, pConstraint++){ + if( pConstraint->usable==0 ) continue; + if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue; + switch( pConstraint->iColumn ){ + case COMPLETION_COLUMN_PREFIX: + prefixIdx = i; + idxNum |= 1; + break; + case COMPLETION_COLUMN_WHOLELINE: + wholelineIdx = i; + idxNum |= 2; + break; + } + } + if( prefixIdx>=0 ){ + pIdxInfo->aConstraintUsage[prefixIdx].argvIndex = ++nArg; + pIdxInfo->aConstraintUsage[prefixIdx].omit = 1; + } + if( wholelineIdx>=0 ){ + pIdxInfo->aConstraintUsage[wholelineIdx].argvIndex = ++nArg; + pIdxInfo->aConstraintUsage[wholelineIdx].omit = 1; + } + pIdxInfo->idxNum = idxNum; + pIdxInfo->estimatedCost = (double)5000 - 1000*nArg; + pIdxInfo->estimatedRows = 500 - 100*nArg; + return SQLITE_OK; +} + +/* +** This following structure defines all the methods for the +** completion virtual table. +*/ +static sqlite3_module completionModule = { + 0, /* iVersion */ + 0, /* xCreate */ + completionConnect, /* xConnect */ + completionBestIndex, /* xBestIndex */ + completionDisconnect, /* xDisconnect */ + 0, /* xDestroy */ + completionOpen, /* xOpen - open a cursor */ + completionClose, /* xClose - close a cursor */ + completionFilter, /* xFilter - configure scan constraints */ + completionNext, /* xNext - advance a cursor */ + completionEof, /* xEof - check for end of scan */ + completionColumn, /* xColumn - read data */ + completionRowid, /* xRowid - read data */ + 0, /* xUpdate */ + 0, /* xBegin */ + 0, /* xSync */ + 0, /* xCommit */ + 0, /* xRollback */ + 0, /* xFindMethod */ + 0, /* xRename */ +}; + +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +int sqlite3CompletionVtabInit(sqlite3 *db){ + int rc = SQLITE_OK; +#ifndef SQLITE_OMIT_VIRTUALTABLE + rc = sqlite3_create_module(db, "completion", &completionModule, 0); +#endif + return rc; +} + +#ifdef _WIN32 +__declspec(dllexport) +#endif +int sqlite3_completion_init( + sqlite3 *db, + char **pzErrMsg, + const sqlite3_api_routines *pApi +){ + int rc = SQLITE_OK; + SQLITE_EXTENSION_INIT2(pApi); +#ifndef SQLITE_OMIT_VIRTUALTABLE + rc = sqlite3CompletionVtabInit(db); +#endif + return rc; +} + +/************************* End ../ext/misc/completion.c ********************/ #if defined(SQLITE_ENABLE_SESSION) /* @@ -3724,12 +4235,77 @@ static void open_db(ShellState *p, int keepAlive){ #endif sqlite3_fileio_init(p->db, 0, 0); sqlite3_shathree_init(p->db, 0, 0); + sqlite3_completion_init(p->db, 0, 0); sqlite3_create_function(p->db, "shell_add_schema", 2, SQLITE_UTF8, 0, shellAddSchemaName, 0, 0); - } } +#if HAVE_READLINE || HAVE_EDITLINE +/* +** Readline completion callbacks +*/ +static char *readline_completion_generator(const char *text, int state){ + static sqlite3_stmt *pStmt = 0; + char *zRet; + if( state==0 ){ + char *zSql; + int rc; + sqlite3_finalize(pStmt); + zSql = sqlite3_mprintf("SELECT DISTINCT candidate COLLATE nocase" + " FROM completion(%Q) ORDER BY 1", text); + sqlite3_prepare_v2(globalDb, zSql, -1, &pStmt, 0); + sqlite3_free(zSql); + } + if( sqlite3_step(pStmt)==SQLITE_ROW ){ + zRet = strdup(sqlite3_column_text(pStmt, 0)); + }else{ + sqlite3_finalize(pStmt); + pStmt = 0; + zRet = 0; + } + return zRet; +} +static char **readline_completion(const char *zText, int iStart, int iEnd){ + rl_attempted_completion_over = 1; + return rl_completion_matches(zText, readline_completion_generator); +} + +#elif HAVE_LINENOISE +/* +** Linenoise completion callback +*/ +static void linenoise_completion(const char *zLine, linenoiseCompletions *lc){ + int nLine = (int)strlen(zLine); + int i, iStart; + sqlite3_stmt *pStmt = 0; + char *zSql; + char zBuf[1000]; + + if( nLine>sizeof(zBuf)-30 ) return; + if( zLine[0]=='.' ) return; + for(i=nLine-1; i>=0 && (isalnum(zLine[i]) || zLine[i]=='_'); i--){} + if( i==nLine-1 ) return; + iStart = i+1; + memcpy(zBuf, zLine, iStart); + zSql = sqlite3_mprintf("SELECT DISTINCT candidate COLLATE nocase" + " FROM completion(%Q,%Q) ORDER BY 1", + &zLine[iStart], zLine); + sqlite3_prepare_v2(globalDb, zSql, -1, &pStmt, 0); + sqlite3_free(zSql); + sqlite3_exec(globalDb, "PRAGMA page_count", 0, 0, 0); /* Load the schema */ + while( sqlite3_step(pStmt)==SQLITE_ROW ){ + const char *zCompletion = (const char*)sqlite3_column_text(pStmt, 0); + int nCompletion = sqlite3_column_bytes(pStmt, 0); + if( iStart+nCompletion < sizeof(zBuf)-1 ){ + memcpy(zBuf+iStart, zCompletion, nCompletion+1); + linenoiseAddCompletion(lc, zBuf); + } + } + sqlite3_finalize(pStmt); +} +#endif + /* ** Do C-language style dequoting. ** @@ -7777,6 +8353,11 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ } } if( zHistory ){ shell_read_history(zHistory); } +#if HAVE_READLINE || HAVE_EDITLINE + rl_attempted_completion_function = readline_completion; +#elif HAVE_LINENOISE + linenoiseSetCompletionCallback(linenoise_completion); +#endif rc = process_input(&data, 0); if( zHistory ){ shell_stifle_history(100); diff --git a/src/shell.c.in b/src/shell.c.in index 70d6c0e5e7..72d07799ba 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -795,6 +795,7 @@ static void shellAddSchemaName( INCLUDE ../ext/misc/shathree.c INCLUDE ../ext/misc/fileio.c +INCLUDE ../ext/misc/completion.c #if defined(SQLITE_ENABLE_SESSION) /* @@ -2890,12 +2891,77 @@ static void open_db(ShellState *p, int keepAlive){ #endif sqlite3_fileio_init(p->db, 0, 0); sqlite3_shathree_init(p->db, 0, 0); + sqlite3_completion_init(p->db, 0, 0); sqlite3_create_function(p->db, "shell_add_schema", 2, SQLITE_UTF8, 0, shellAddSchemaName, 0, 0); - } } +#if HAVE_READLINE || HAVE_EDITLINE +/* +** Readline completion callbacks +*/ +static char *readline_completion_generator(const char *text, int state){ + static sqlite3_stmt *pStmt = 0; + char *zRet; + if( state==0 ){ + char *zSql; + int rc; + sqlite3_finalize(pStmt); + zSql = sqlite3_mprintf("SELECT DISTINCT candidate COLLATE nocase" + " FROM completion(%Q) ORDER BY 1", text); + sqlite3_prepare_v2(globalDb, zSql, -1, &pStmt, 0); + sqlite3_free(zSql); + } + if( sqlite3_step(pStmt)==SQLITE_ROW ){ + zRet = strdup(sqlite3_column_text(pStmt, 0)); + }else{ + sqlite3_finalize(pStmt); + pStmt = 0; + zRet = 0; + } + return zRet; +} +static char **readline_completion(const char *zText, int iStart, int iEnd){ + rl_attempted_completion_over = 1; + return rl_completion_matches(zText, readline_completion_generator); +} + +#elif HAVE_LINENOISE +/* +** Linenoise completion callback +*/ +static void linenoise_completion(const char *zLine, linenoiseCompletions *lc){ + int nLine = (int)strlen(zLine); + int i, iStart; + sqlite3_stmt *pStmt = 0; + char *zSql; + char zBuf[1000]; + + if( nLine>sizeof(zBuf)-30 ) return; + if( zLine[0]=='.' ) return; + for(i=nLine-1; i>=0 && (isalnum(zLine[i]) || zLine[i]=='_'); i--){} + if( i==nLine-1 ) return; + iStart = i+1; + memcpy(zBuf, zLine, iStart); + zSql = sqlite3_mprintf("SELECT DISTINCT candidate COLLATE nocase" + " FROM completion(%Q,%Q) ORDER BY 1", + &zLine[iStart], zLine); + sqlite3_prepare_v2(globalDb, zSql, -1, &pStmt, 0); + sqlite3_free(zSql); + sqlite3_exec(globalDb, "PRAGMA page_count", 0, 0, 0); /* Load the schema */ + while( sqlite3_step(pStmt)==SQLITE_ROW ){ + const char *zCompletion = (const char*)sqlite3_column_text(pStmt, 0); + int nCompletion = sqlite3_column_bytes(pStmt, 0); + if( iStart+nCompletion < sizeof(zBuf)-1 ){ + memcpy(zBuf+iStart, zCompletion, nCompletion+1); + linenoiseAddCompletion(lc, zBuf); + } + } + sqlite3_finalize(pStmt); +} +#endif + /* ** Do C-language style dequoting. ** @@ -6943,6 +7009,11 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ } } if( zHistory ){ shell_read_history(zHistory); } +#if HAVE_READLINE || HAVE_EDITLINE + rl_attempted_completion_function = readline_completion; +#elif HAVE_LINENOISE + linenoiseSetCompletionCallback(linenoise_completion); +#endif rc = process_input(&data, 0); if( zHistory ){ shell_stifle_history(100); From 1be505192387d3053ae12e09bcaedb0ead32e02f Mon Sep 17 00:00:00 2001 From: mistachkin Date: Tue, 11 Jul 2017 16:36:10 +0000 Subject: [PATCH 50/64] Fix harmless compiler warnings seen with MSVC for lsm1. FossilOrigin-Name: cf6da4a52f7f9047e653ef2972e4c0910b29d7182d789a9e30225dc1849e8779 --- ext/lsm1/Makefile.msc | 14 +++---- ext/lsm1/lsm_ckpt.c | 4 +- ext/lsm1/lsm_file.c | 32 +++++++-------- ext/lsm1/lsm_log.c | 8 ++-- ext/lsm1/lsm_shared.c | 13 ++++--- ext/lsm1/lsm_sorted.c | 90 +++++++++++++++++++++---------------------- ext/lsm1/lsm_tree.c | 53 ++++++++++++------------- ext/lsm1/lsm_varint.c | 2 +- ext/lsm1/lsm_vtab.c | 12 +++--- ext/lsm1/lsm_win32.c | 1 - manifest | 32 +++++++-------- manifest.uuid | 2 +- 12 files changed, 132 insertions(+), 131 deletions(-) diff --git a/ext/lsm1/Makefile.msc b/ext/lsm1/Makefile.msc index 469887728a..df4e045ea3 100644 --- a/ext/lsm1/Makefile.msc +++ b/ext/lsm1/Makefile.msc @@ -1,9 +1,9 @@ # -# This Makefile is designed for use with main.mk in the root directory of -# this project. After including main.mk, the users makefile should contain: +# This Makefile is designed for use with Makefile.msc in the root directory +# of this project. The Makefile.msc should contain: # -# LSMDIR=$(TOP)\ext\lsm1\ -# include $(LSMDIR)\Makefile.msc +# LSMDIR=$(TOP)\ext\lsm1 +# !INCLUDE $(LSMDIR)\Makefile.msc # # The most useful targets are [lsmtest.exe] and [lsm.dll]. # @@ -39,7 +39,7 @@ LSMTESTSRC = $(LSMDIR)\lsm-test\lsmtest1.c $(LSMDIR)\lsm-test\lsmtest2.c \ $(LSMDIR)\lsm-test\lsmtest_tdb.c $(LSMDIR)\lsm-test\lsmtest_tdb3.c \ $(LSMDIR)\lsm-test\lsmtest_util.c $(LSMDIR)\lsm-test\lsmtest_win32.c -# all: lsm.dll +# all: lsm.dll lsmtest.exe LSMOPTS = $(NO_WARN) -DLSM_MUTEX_WIN32=1 -I$(LSMDIR) @@ -96,5 +96,5 @@ lsm_vtab.lo: $(LSMDIR)\lsm_vtab.c $(LSMHDR) $(SQLITE3H) lsm.dll: $(LSMOBJ) $(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL /OUT:$@ $(LSMOBJ) -lsmtest.exe: $(LSMOBJ) $(LSMTESTSRC) $(LSMTESTHDR) $(LIBOBJS1) - $(LTLINK) $(LSMOPTS) $(LSMTESTSRC) /link $(LSMOBJ) $(LIBOBJS1) +lsmtest.exe: $(LSMOBJ) $(LSMTESTSRC) $(LSMTESTHDR) $(LIBOBJ) + $(LTLINK) $(LSMOPTS) $(LSMTESTSRC) /link $(LSMOBJ) $(LIBOBJ) diff --git a/ext/lsm1/lsm_ckpt.c b/ext/lsm1/lsm_ckpt.c index 8cc8539241..42fa41ee7b 100644 --- a/ext/lsm1/lsm_ckpt.c +++ b/ext/lsm1/lsm_ckpt.c @@ -222,7 +222,7 @@ struct CkptBuffer { ** at aCkpt[]. */ static void ckptChecksum(u32 *aCkpt, u32 nCkpt, u32 *piCksum1, u32 *piCksum2){ - int i; + u32 i; u32 cksum1 = 1; u32 cksum2 = 2; @@ -511,7 +511,7 @@ static void ckptNewSegment( pSegment->iFirst = ckptGobble64(aIn, piIn); pSegment->iLastPg = ckptGobble64(aIn, piIn); pSegment->iRoot = ckptGobble64(aIn, piIn); - pSegment->nSize = ckptGobble64(aIn, piIn); + pSegment->nSize = (int)ckptGobble64(aIn, piIn); assert( pSegment->iFirst ); } diff --git a/ext/lsm1/lsm_file.c b/ext/lsm1/lsm_file.c index 3ce99bde15..2248be2fa0 100644 --- a/ext/lsm1/lsm_file.c +++ b/ext/lsm1/lsm_file.c @@ -540,7 +540,7 @@ static int fsMmapPage(FileSystem *pFS, Pgno iReal){ ** Given that there are currently nHash slots in the hash table, return ** the hash key for file iFile, page iPg. */ -static int fsHashKey(int nHash, int iPg){ +static int fsHashKey(int nHash, Pgno iPg){ return (iPg % nHash); } @@ -922,9 +922,9 @@ static Pgno fsLastPageOnBlock(FileSystem *pFS, int iBlock){ */ static int fsPageToBlock(FileSystem *pFS, Pgno iPg){ if( pFS->pCompress ){ - return (iPg / pFS->nBlocksize) + 1; + return (int)((iPg / pFS->nBlocksize) + 1); }else{ - return 1 + ((iPg-1) / (pFS->nBlocksize / pFS->nPagesize)); + return (int)(1 + ((iPg-1) / (pFS->nBlocksize / pFS->nPagesize))); } } @@ -1286,7 +1286,7 @@ static int fsReadData( assert( pFS->pCompress ); iEob = fsLastPageOnPagesBlock(pFS, iOff) + 1; - nRead = LSM_MIN(iEob - iOff, nData); + nRead = (int)LSM_MIN(iEob - iOff, nData); rc = lsmEnvRead(pFS->pEnv, pFS->fdDb, iOff, aData, nRead); if( rc==LSM_OK && nRead!=nData ){ @@ -1722,8 +1722,8 @@ static int fsFreeBlock( int iBlk /* Block number of block to free */ ){ int rc = LSM_OK; /* Return code */ - int iFirst; /* First page on block iBlk */ - int iLast; /* Last page on block iBlk */ + Pgno iFirst; /* First page on block iBlk */ + Pgno iLast; /* Last page on block iBlk */ Level *pLevel; /* Used to iterate through levels */ int iIn; /* Used to iterate through append points */ @@ -1856,7 +1856,7 @@ void lsmFsGobble( assert( nPgno>0 && 0==fsPageRedirects(pFS, pRun, aPgno[0]) ); iBlk = fsPageToBlock(pFS, pRun->iFirst); - pRun->nSize += (pRun->iFirst - fsFirstPageOnBlock(pFS, iBlk)); + pRun->nSize += (int)(pRun->iFirst - fsFirstPageOnBlock(pFS, iBlk)); while( rc==LSM_OK ){ int iNext = 0; @@ -1867,13 +1867,13 @@ void lsmFsGobble( } rc = fsBlockNext(pFS, pRun, iBlk, &iNext); if( rc==LSM_OK ) rc = fsFreeBlock(pFS, pSnapshot, pRun, iBlk); - pRun->nSize -= ( + pRun->nSize -= (int)( 1 + fsLastPageOnBlock(pFS, iBlk) - fsFirstPageOnBlock(pFS, iBlk) ); iBlk = iNext; } - pRun->nSize -= (pRun->iFirst - fsFirstPageOnBlock(pFS, iBlk)); + pRun->nSize -= (int)(pRun->iFirst - fsFirstPageOnBlock(pFS, iBlk)); assert( pRun->nSize>0 ); } @@ -2087,10 +2087,10 @@ int lsmFsSortedAppend( ){ int rc = LSM_OK; Page *pPg = 0; - int iApp = 0; - int iNext = 0; + Pgno iApp = 0; + Pgno iNext = 0; Segment *p = &pLvl->lhs; - int iPrev = p->iLastPg; + Pgno iPrev = p->iLastPg; *ppOut = 0; assert( p->pRedirect==0 ); @@ -2457,8 +2457,8 @@ static Pgno fsAppendData( int rc = *pRc; assert( pFS->pCompress ); if( rc==LSM_OK ){ - int nRem; - int nWrite; + int nRem = 0; + int nWrite = 0; Pgno iLastOnBlock; Pgno iApp = pSeg->iLastPg+1; @@ -2477,7 +2477,7 @@ static Pgno fsAppendData( /* Write as much data as is possible at iApp (usually all of it). */ iLastOnBlock = fsLastPageOnPagesBlock(pFS, iApp); if( rc==LSM_OK ){ - int nSpace = iLastOnBlock - iApp + 1; + int nSpace = (int)(iLastOnBlock - iApp + 1); nWrite = LSM_MIN(nData, nSpace); nRem = nData - nWrite; assert( nWrite>=0 ); @@ -2800,7 +2800,7 @@ int lsmFsSortedPadding( iLast2 = (1 + iLast/pFS->szSector) * pFS->szSector - 1; assert( fsPageToBlock(pFS, iLast)==fsPageToBlock(pFS, iLast2) ); - nPad = iLast2 - iLast; + nPad = (int)(iLast2 - iLast); if( iLast2>fsLastPageOnPagesBlock(pFS, iLast) ){ nPad -= 4; diff --git a/ext/lsm1/lsm_log.c b/ext/lsm1/lsm_log.c index 43fbad79a6..a66e40bccd 100644 --- a/ext/lsm1/lsm_log.c +++ b/ext/lsm1/lsm_log.c @@ -545,7 +545,7 @@ static int jumpIfRequired( aPad[0] = LSM_LOG_PAD1; }else{ aPad[0] = LSM_LOG_PAD2; - aPad[1] = (nPad-2); + aPad[1] = (u8)(nPad-2); } rc = lsmStringBinAppend(&pLog->buf, aPad, nPad); if( rc!=LSM_OK ) return rc; @@ -627,7 +627,7 @@ static int logFlush(lsm_db *pDb, int eType){ }else{ int n = LSM_MIN(200, nPad-2); pLog->buf.z[pLog->buf.n++] = LSM_LOG_PAD2; - pLog->buf.z[pLog->buf.n++] = n; + pLog->buf.z[pLog->buf.n++] = (char)n; nPad -= 2; memset(&pLog->buf.z[pLog->buf.n], 0x2B, n); pLog->buf.n += n; @@ -640,7 +640,7 @@ static int logFlush(lsm_db *pDb, int eType){ ** record. Then add the first byte of it. */ rc = lsmStringExtend(&pLog->buf, 9); if( rc!=LSM_OK ) return rc; - pLog->buf.z[pLog->buf.n++] = eType; + pLog->buf.z[pLog->buf.n++] = (char)eType; memset(&pLog->buf.z[pLog->buf.n], 0, 8); rc = logCksumAndFlush(pDb); @@ -772,7 +772,7 @@ void lsmLogSeek( assert( pMark->iOff<=pLog->iOff+pLog->buf.n ); if( (pMark->iOff & 0xFFFFFFF8)>=pLog->iOff ){ - pLog->buf.n = pMark->iOff - pLog->iOff; + pLog->buf.n = (int)(pMark->iOff - pLog->iOff); pLog->iCksumBuf = (pLog->buf.n & 0xFFFFFFF8); }else{ pLog->buf.n = pMark->nBuf; diff --git a/ext/lsm1/lsm_shared.c b/ext/lsm1/lsm_shared.c index 6b31961ce1..6b41c1dc39 100644 --- a/ext/lsm1/lsm_shared.c +++ b/ext/lsm1/lsm_shared.c @@ -97,7 +97,7 @@ static void assertNotInFreelist(Freelist *p, int iBlk){ /* ** Append an entry to the free-list. If (iId==-1), this is a delete. */ -int freelistAppend(lsm_db *db, int iBlk, i64 iId){ +int freelistAppend(lsm_db *db, u32 iBlk, i64 iId){ lsm_env *pEnv = db->pEnv; Freelist *p; int i; @@ -639,11 +639,12 @@ static int walkFreelistCb(void *pCtx, int iBlk, i64 iSnapshot){ Freelist *pFree = p->pFreelist; assert( p->bDone==0 ); + assert( iBlk>=0 ); if( pFree ){ while( (p->iFree < pFree->nEntry) && p->iFree>=0 ){ FreelistEntry *pEntry = &pFree->aEntry[p->iFree]; - if( (p->bReverse==0 && pEntry->iBlk>iBlk) - || (p->bReverse!=0 && pEntry->iBlkbReverse==0 && pEntry->iBlk>(u32)iBlk) + || (p->bReverse!=0 && pEntry->iBlk<(u32)iBlk) ){ break; }else{ @@ -654,7 +655,7 @@ static int walkFreelistCb(void *pCtx, int iBlk, i64 iSnapshot){ p->bDone = 1; return 1; } - if( pEntry->iBlk==iBlk ) return 0; + if( pEntry->iBlk==(u32)iBlk ) return 0; } } } @@ -937,7 +938,7 @@ int lsmCheckpointWrite(lsm_db *pDb, int bTruncate, u32 *pnWrite){ u8 *aData; /* Meta-page data buffer */ int nData; /* Size of aData[] in bytes */ i64 iCkpt; /* Id of checkpoint just loaded */ - i64 iDisk; /* Id of checkpoint already stored in db */ + i64 iDisk = 0; /* Id of checkpoint already stored in db */ iCkpt = lsmCheckpointId(pDb->aSnapshot, 0); rc = lsmFsMetaPageGet(pDb->pFS, 0, pShm->iMetaPage, &pPg); if( rc==LSM_OK ){ @@ -1886,7 +1887,7 @@ int shmLockType(lsm_db *db, int iLock){ ** (eOp==LSM_LOCK_EXCL) -> true if db has an EXCLUSIVE lock on iLock. */ int lsmShmAssertLock(lsm_db *db, int iLock, int eOp){ - int ret; + int ret = 0; int eHave; assert( iLock>=1 && iLock<=LSM_LOCK_READER(LSM_LOCK_NREADER-1) ); diff --git a/ext/lsm1/lsm_sorted.c b/ext/lsm1/lsm_sorted.c index e7146468b5..9c09237691 100644 --- a/ext/lsm1/lsm_sorted.c +++ b/ext/lsm1/lsm_sorted.c @@ -662,9 +662,9 @@ static int btreeCursorPtr(u8 *aData, int nData, int iCell){ nCell = pageGetNRec(aData, nData); if( iCell>=nCell ){ - return pageGetPtr(aData, nData); + return (int)pageGetPtr(aData, nData); } - return pageGetRecordPtr(aData, nData, iCell); + return (int)pageGetRecordPtr(aData, nData, iCell); } static int btreeCursorNext(BtreeCursor *pCsr){ @@ -751,7 +751,7 @@ static int btreeCursorFirst(BtreeCursor *pCsr){ Page *pPg = 0; FileSystem *pFS = pCsr->pFS; - int iPg = pCsr->pSeg->iRoot; + int iPg = (int)pCsr->pSeg->iRoot; do { rc = lsmFsDbPageGet(pFS, pCsr->pSeg, iPg, &pPg); @@ -779,7 +779,7 @@ static int btreeCursorFirst(BtreeCursor *pCsr){ assert( pCsr->aPg[pCsr->nDepth].iCell==0 ); pCsr->aPg[pCsr->nDepth].pPage = pPg; pCsr->nDepth++; - iPg = pageGetRecordPtr(aData, nData, 0); + iPg = (int)pageGetRecordPtr(aData, nData, 0); } } }while( rc==LSM_OK ); @@ -871,7 +871,7 @@ static int btreeCursorRestore( int nSeek; int iTopicSeek; int iPg = 0; - int iLoad = pSeg->iRoot; + int iLoad = (int)pSeg->iRoot; Page *pPg = pCsr->aPg[nDepth-1].pPage; if( pageObjGetNRec(pPg)==0 ){ @@ -903,7 +903,7 @@ static int btreeCursorRestore( aData = fsPageData(pPg, &nData); assert( (pageGetFlags(aData, nData) & SEGMENT_BTREE_FLAG) ); - iLoad = pageGetPtr(aData, nData); + iLoad = (int)pageGetPtr(aData, nData); iCell = pageGetNRec(aData, nData); iMax = iCell-1; iMin = 0; @@ -926,7 +926,7 @@ static int btreeCursorRestore( assert( res!=0 ); if( res<0 ){ - iLoad = iPtr; + iLoad = (int)iPtr; iCell = iTry; iMax = iTry-1; }else{ @@ -1001,7 +1001,7 @@ static void segmentPtrSetPage(SegmentPtr *pPtr, Page *pNext){ int nData; u8 *aData = fsPageData(pNext, &nData); pPtr->nCell = pageGetNRec(aData, nData); - pPtr->flags = pageGetFlags(aData, nData); + pPtr->flags = (u16)pageGetFlags(aData, nData); pPtr->iPtr = pageGetPtr(aData, nData); } pPtr->pPg = pNext; @@ -1637,7 +1637,7 @@ static int segmentPtrSeek( int *pbStop ){ int (*xCmp)(void *, int, void *, int) = pCsr->pDb->xCmp; - int res; /* Result of comparison operation */ + int res = 0; /* Result of comparison operation */ int rc = LSM_OK; int iMin; int iMax; @@ -1759,7 +1759,7 @@ static int segmentPtrSeek( } assert( rc!=LSM_OK || assertSeekResult(pCsr,pPtr,iTopic,pKey,nKey,eSeek) ); - *piPtr = iPtrOut; + *piPtr = (int)iPtrOut; return rc; } @@ -1777,7 +1777,7 @@ static int seekInBtree( Page *pPg = 0; Blob blob = {0, 0, 0}; - iPg = pSeg->iRoot; + iPg = (int)pSeg->iRoot; do { Pgno *piFirst = 0; if( aPg ){ @@ -1799,7 +1799,7 @@ static int seekInBtree( flags = pageGetFlags(aData, nData); if( (flags & SEGMENT_BTREE_FLAG)==0 ) break; - iPg = pageGetPtr(aData, nData); + iPg = (int)pageGetPtr(aData, nData); nRec = pageGetNRec(aData, nData); iMin = 0; @@ -1825,7 +1825,7 @@ static int seekInBtree( pCsr->pDb->xCmp, iTopic, pKey, nKey, iTopicT, pKeyT, nKeyT ); if( res<0 ){ - iPg = iPtr; + iPg = (int)iPtr; iMax = iTry-1; }else{ iMin = iTry+1; @@ -1866,7 +1866,7 @@ static int seekInSegment( if( rc==LSM_OK ) segmentPtrSetPage(pPtr, pPg); }else{ if( iPtr==0 ){ - iPtr = pPtr->pSeg->iFirst; + iPtr = (int)pPtr->pSeg->iFirst; } if( rc==LSM_OK ){ rc = segmentPtrLoadPage(pCsr->pDb->pFS, pPtr, iPtr); @@ -1923,7 +1923,7 @@ static int seekInLevel( ** left-hand-side of the level in this case. */ if( res<0 ){ int iPtr = 0; - if( nRhs==0 ) iPtr = *piPgno; + if( nRhs==0 ) iPtr = (int)*piPgno; rc = seekInSegment( pCsr, &aPtr[0], iTopic, pKey, nKey, iPtr, eSeek, &iOut, &bStop @@ -1935,7 +1935,7 @@ static int seekInLevel( if( res>=0 ){ int bHit = 0; /* True if at least one rhs is not EOF */ - int iPtr = *piPgno; + int iPtr = (int)*piPgno; int i; for(i=1; rc==LSM_OK && i<=nRhs && bStop==0; i++){ SegmentPtr *pPtr = &aPtr[i]; @@ -2617,7 +2617,7 @@ int lsmSortedWalkFreelist( while( rc==LSM_OK && lsmMCursorValid(pCsr) && rtIsSystem(pCsr->eType) ){ void *pKey; int nKey; - void *pVal; int nVal; + void *pVal = 0; int nVal = 0; rc = lsmMCursorKey(pCsr, &pKey, &nKey); if( rc==LSM_OK ) rc = lsmMCursorValue(pCsr, &pVal, &nVal); @@ -3475,7 +3475,7 @@ static int mergeWorkerLoadHierarchy(MergeWorker *pMW){ lsm_env *pEnv = pMW->pDb->pEnv; Page **apHier = 0; int nHier = 0; - int iPg = pSeg->iRoot; + int iPg = (int)pSeg->iRoot; do { Page *pPg = 0; @@ -3501,7 +3501,7 @@ static int mergeWorkerLoadHierarchy(MergeWorker *pMW){ nHier++; apHier[0] = pPg; - iPg = pageGetPtr(aData, nData); + iPg = (int)pageGetPtr(aData, nData); }else{ lsmFsPageRelease(pPg); break; @@ -3620,9 +3620,9 @@ static int mergeWorkerBtreeWrite( assert( lsmFsPageWritable(pOld) ); aData = fsPageData(pOld, &nData); if( eType==0 ){ - nByte = 2 + 1 + lsmVarintLen32(iPtr) + lsmVarintLen32(iKeyPg); + nByte = 2 + 1 + lsmVarintLen32((int)iPtr) + lsmVarintLen32((int)iKeyPg); }else{ - nByte = 2 + 1 + lsmVarintLen32(iPtr) + lsmVarintLen32(nKey) + nKey; + nByte = 2 + 1 + lsmVarintLen32((int)iPtr) + lsmVarintLen32(nKey) + nKey; } nRec = pageGetNRec(aData, nData); nFree = SEGMENT_EOF(nData, nRec) - mergeWorkerPageOffset(aData, nData); @@ -3663,15 +3663,15 @@ static int mergeWorkerBtreeWrite( aData = fsPageData(p->apHier[iLevel], &nData); iOff = mergeWorkerPageOffset(aData, nData); nRec = pageGetNRec(aData, nData); - lsmPutU16(&aData[SEGMENT_CELLPTR_OFFSET(nData, nRec)], iOff); - lsmPutU16(&aData[SEGMENT_NRECORD_OFFSET(nData)], nRec+1); + lsmPutU16(&aData[SEGMENT_CELLPTR_OFFSET(nData, nRec)], (u16)iOff); + lsmPutU16(&aData[SEGMENT_NRECORD_OFFSET(nData)], (u16)(nRec+1)); if( eType==0 ){ aData[iOff++] = 0x00; - iOff += lsmVarintPut32(&aData[iOff], iPtr); - iOff += lsmVarintPut32(&aData[iOff], iKeyPg); + iOff += lsmVarintPut32(&aData[iOff], (int)iPtr); + iOff += lsmVarintPut32(&aData[iOff], (int)iKeyPg); }else{ aData[iOff++] = eType; - iOff += lsmVarintPut32(&aData[iOff], iPtr); + iOff += lsmVarintPut32(&aData[iOff], (int)iPtr); iOff += lsmVarintPut32(&aData[iOff], nKey); memcpy(&aData[iOff], pKey, nKey); } @@ -3918,7 +3918,7 @@ static int mergeWorkerFirstPage(MergeWorker *pMW){ if( pCsr->pBtCsr ){ rc = LSM_OK; - iFPtr = pMW->pLevel->pNext->lhs.iFirst; + iFPtr = (int)pMW->pLevel->pNext->lhs.iFirst; }else if( pCsr->nPtr>0 ){ Segment *pSeg; pSeg = pCsr->aPtr[pCsr->nPtr-1].pSeg; @@ -3927,7 +3927,7 @@ static int mergeWorkerFirstPage(MergeWorker *pMW){ u8 *aData; /* Buffer for page pPg */ int nData; /* Size of aData[] in bytes */ aData = fsPageData(pPg, &nData); - iFPtr = pageGetPtr(aData, nData); + iFPtr = (int)pageGetPtr(aData, nData); lsmFsPageRelease(pPg); } } @@ -3953,11 +3953,11 @@ static int mergeWorkerWrite( int nHdr; /* Space required for this record header */ Page *pPg; /* Page to write to */ u8 *aData; /* Data buffer for page pWriter->pPage */ - int nData; /* Size of buffer aData[] in bytes */ - int nRec; /* Number of records on page pPg */ - int iFPtr; /* Value of pointer in footer of pPg */ + int nData = 0; /* Size of buffer aData[] in bytes */ + int nRec = 0; /* Number of records on page pPg */ + int iFPtr = 0; /* Value of pointer in footer of pPg */ int iRPtr = 0; /* Value of pointer written into record */ - int iOff; /* Current write offset within page pPg */ + int iOff = 0; /* Current write offset within page pPg */ Segment *pSeg; /* Segment being written */ int flags = 0; /* If != 0, flags value for page footer */ int bFirst = 0; /* True for first key of output run */ @@ -3973,7 +3973,7 @@ static int mergeWorkerWrite( if( pPg ){ aData = fsPageData(pPg, &nData); nRec = pageGetNRec(aData, nData); - iFPtr = pageGetPtr(aData, nData); + iFPtr = (int)pageGetPtr(aData, nData); iRPtr = iPtr - iFPtr; } @@ -3999,7 +3999,7 @@ static int mergeWorkerWrite( ** marked read-only, advance to the next page of the output run. */ iOff = pMerge->iOutputOff; if( iOff<0 || pPg==0 || iOff+nHdr > SEGMENT_EOF(nData, nRec+1) ){ - iFPtr = *pMW->pCsr->pPrevMergePtr; + iFPtr = (int)*pMW->pCsr->pPrevMergePtr; iRPtr = iPtr - iFPtr; iOff = 0; nRec = 0; @@ -4033,12 +4033,12 @@ static int mergeWorkerWrite( aData = fsPageData(pPg, &nData); /* Update the page footer. */ - lsmPutU16(&aData[SEGMENT_NRECORD_OFFSET(nData)], nRec+1); - lsmPutU16(&aData[SEGMENT_CELLPTR_OFFSET(nData, nRec)], iOff); - if( flags ) lsmPutU16(&aData[SEGMENT_FLAGS_OFFSET(nData)], flags); + lsmPutU16(&aData[SEGMENT_NRECORD_OFFSET(nData)], (u16)(nRec+1)); + lsmPutU16(&aData[SEGMENT_CELLPTR_OFFSET(nData, nRec)], (u16)iOff); + if( flags ) lsmPutU16(&aData[SEGMENT_FLAGS_OFFSET(nData)], (u16)flags); /* Write the entry header into the current page. */ - aData[iOff++] = eType; /* 1 */ + aData[iOff++] = (u8)eType; /* 1 */ iOff += lsmVarintPut32(&aData[iOff], iRPtr); /* 2 */ iOff += lsmVarintPut32(&aData[iOff], nKey); /* 3 */ if( rtIsWrite(eType) ) iOff += lsmVarintPut32(&aData[iOff], nVal); /* 4 */ @@ -4260,7 +4260,7 @@ static int mergeWorkerStep(MergeWorker *pMW){ pVal = pCsr->val.pData; } if( rc==LSM_OK ){ - rc = mergeWorkerWrite(pMW, eType, pKey, nKey, pVal, nVal, iPtr); + rc = mergeWorkerWrite(pMW, eType, pKey, nKey, pVal, nVal, (int)iPtr); } } } @@ -4581,7 +4581,7 @@ static int mergeWorkerInit( SegmentPtr *pPtr; assert( pCsr->aPtr[i].pPg==0 ); pPtr = &pCsr->aPtr[i]; - rc = segmentPtrLoadPage(pDb->pFS, pPtr, pInput->iPg); + rc = segmentPtrLoadPage(pDb->pFS, pPtr, (int)pInput->iPg); if( rc==LSM_OK && pPtr->nCell>0 ){ rc = segmentPtrLoadCell(pPtr, pInput->iCell); } @@ -5184,7 +5184,7 @@ static int doLsmSingleWork( nUnsync = lsmCheckpointNWrite(pDb->pShmhdr->aSnap1, 0); nPgsz = lsmCheckpointPgsz(pDb->pShmhdr->aSnap1); - nMax = LSM_MIN(nMax, (pDb->nAutockpt/nPgsz) - (int)(nUnsync-nSync)); + nMax = (int)LSM_MIN(nMax, (pDb->nAutockpt/nPgsz) - (int)(nUnsync-nSync)); if( nMaxpEnv); @@ -5533,7 +5533,7 @@ void sortedDumpPage(lsm_db *pDb, Segment *pRun, Page *pPg, int bVals){ Page *pRef = 0; /* Pointer to page iRef */ int iChar; u8 *aKey; int nKey = 0; /* Key */ - u8 *aVal; int nVal = 0; /* Value */ + u8 *aVal = 0; int nVal = 0; /* Value */ int iTopic; u8 *aCell; int iPgPtr; @@ -5593,7 +5593,7 @@ static void infoCellDump( ){ u8 *aData; int nData; /* Page data */ u8 *aKey; int nKey = 0; /* Key */ - u8 *aVal; int nVal = 0; /* Value */ + u8 *aVal = 0; int nVal = 0; /* Value */ int eType; int iPgPtr; Page *pRef = 0; /* Pointer to page iRef */ @@ -5705,7 +5705,7 @@ static int infoPageDump( aData = fsPageData(pPg, &nData); nRec = pageGetNRec(aData, nData); - iPtr = pageGetPtr(aData, nData); + iPtr = (int)pageGetPtr(aData, nData); flags = pageGetFlags(aData, nData); lsmStringInit(&str, pDb->pEnv); diff --git a/ext/lsm1/lsm_tree.c b/ext/lsm1/lsm_tree.c index be6e276c3e..1a199fc1ce 100644 --- a/ext/lsm1/lsm_tree.c +++ b/ext/lsm1/lsm_tree.c @@ -278,8 +278,9 @@ static int treeKeycmp(void *p1, int n1, void *p2, int n2){ ** sub-tree of the node. */ static u32 getChildPtr(TreeNode *p, int iVersion, int iCell){ + assert( iVersion>=0 ); assert( iCell>=0 && iCell<=array_size(p->aiChildPtr) ); - if( p->iV2 && p->iV2<=iVersion && iCell==p->iV2Child ) return p->iV2Ptr; + if( p->iV2 && p->iV2<=(u32)iVersion && iCell==p->iV2Child ) return p->iV2Ptr; return p->aiChildPtr[iCell]; } @@ -300,7 +301,7 @@ static int treeOffsetToChunk(u32 iOff){ */ static void *treeShmptr(lsm_db *pDb, u32 iPtr){ - assert( (iPtr>>15)nShm ); + assert( (iPtr>>15)<(u32)pDb->nShm ); assert( pDb->apShm[iPtr>>15] ); return iPtr ? treeShmptrUnsafe(pDb, iPtr) : 0; @@ -519,7 +520,7 @@ void dump_node_contents( }else{ for(i=0; i<4 && nHeight>0; i++){ u32 iPtr = getChildPtr(pNode, pDb->treehdr.root.iTransId, i); - zPath[nPath] = i+'0'; + zPath[nPath] = (char)(i+'0'); zPath[nPath+1] = '/'; if( iPtr ){ @@ -644,7 +645,7 @@ static u32 treeShmalloc(lsm_db *pDb, int bAlign, int nByte, int *pRc){ assert( iWrite ); iChunk = treeOffsetToChunk(iWrite-1); iEof = (iChunk+1) * CHUNK_SIZE; - assert( iEof>=iWrite && (iEof-iWrite)=iWrite && (iEof-iWrite)<(u32)CHUNK_SIZE ); if( (iWrite+nByte)>iEof ){ ShmChunk *pHdr; /* Header of chunk just finished (iChunk) */ ShmChunk *pFirst; /* Header of chunk treehdr.iFirst */ @@ -757,7 +758,7 @@ static TreeKey *newTreeKey( iWrite = (pDb->treehdr.iWrite & (LSM_SHM_CHUNK_SIZE-1)); iWrite = LSM_MAX(iWrite, LSM_SHM_CHUNK_HDR); - nAlloc = LSM_MIN((LSM_SHM_CHUNK_SIZE-iWrite), nRem); + nAlloc = LSM_MIN((LSM_SHM_CHUNK_SIZE-iWrite), (u32)nRem); aAlloc = treeShmptr(pDb, treeShmalloc(pDb, 0, nAlloc, pRc)); if( aAlloc==0 ) break; @@ -1209,7 +1210,7 @@ static int treeCheckLinkedList(lsm_db *db){ nVisit++; } - if( rc==LSM_OK && nVisit!=db->treehdr.nChunk-1 ){ + if( rc==LSM_OK && (u32)nVisit!=db->treehdr.nChunk-1 ){ rc = LSM_CORRUPT_BKPT; } return rc; @@ -1259,7 +1260,7 @@ static int treeRepairList(lsm_db *db){ /* Iterate through all shm chunks. Find the smallest shm-id present in ** the shared-memory region. */ - for(i=1; rc==LSM_OK && itreehdr.nChunk; i++){ + for(i=1; rc==LSM_OK && (u32)itreehdr.nChunk; i++){ p = treeShmChunkRc(db, i, &rc); if( p && (pMin==0 || shm_sequence_ge(pMin->iShmid, p->iShmid)) ){ pMin = p; @@ -1279,7 +1280,7 @@ static int treeRepairList(lsm_db *db){ /* Allocate space for a merge sort. */ nSort = 1; - while( nSort < (db->treehdr.nChunk-1) ) nSort = nSort * 2; + while( (u32)nSort < (db->treehdr.nChunk-1) ) nSort = nSort * 2; nByte = sizeof(ShmChunkLoc) * nSort * 2; aSort = lsmMallocZeroRc(db->pEnv, nByte, &rc); iPrevShmid = pMin->iShmid; @@ -1287,11 +1288,11 @@ static int treeRepairList(lsm_db *db){ /* Fix all shm-ids, if required. */ if( rc==LSM_OK ){ iPrevShmid = pMin->iShmid-1; - for(i=1; itreehdr.nChunk; i++){ + for(i=1; (u32)itreehdr.nChunk; i++){ p = treeShmChunk(db, i); aSort[i-1].pShm = p; aSort[i-1].iLoc = i; - if( i!=db->treehdr.iFirst ){ + if( (u32)i!=db->treehdr.iFirst ){ if( shm_sequence_ge(p->iShmid, db->treehdr.iNextShmid) ){ p->iShmid = iPrevShmid--; } @@ -1375,7 +1376,7 @@ static void treeOverwriteKey(lsm_db *db, TreeCursor *pCsr, u32 iKey, int *pRc){ int iCell = pCsr->aiCell[pCsr->iNode]; /* Create a copy of this node */ - if( (pCsr->iNode>0 && pCsr->iNode==(p->nHeight-1)) ){ + if( (pCsr->iNode>0 && (u32)pCsr->iNode==(p->nHeight-1)) ){ pNew = copyTreeLeaf(db, (TreeLeaf *)pNode, &iNew, pRc); }else{ pNew = copyTreeNode(db, pNode, &iNew, pRc); @@ -1398,7 +1399,7 @@ static int treeNextIsEndDelete(lsm_db *db, TreeCursor *pCsr){ int iCell = pCsr->aiCell[iNode]+1; /* Cursor currently points to a leaf node. */ - assert( pCsr->iNode==(db->treehdr.root.nHeight-1) ); + assert( (u32)pCsr->iNode==(db->treehdr.root.nHeight-1) ); while( iNode>=0 ){ TreeNode *pNode = pCsr->apTreeNode[iNode]; @@ -1419,7 +1420,7 @@ static int treePrevIsStartDelete(lsm_db *db, TreeCursor *pCsr){ int iNode = pCsr->iNode; /* Cursor currently points to a leaf node. */ - assert( pCsr->iNode==(db->treehdr.root.nHeight-1) ); + assert( (u32)pCsr->iNode==(db->treehdr.root.nHeight-1) ); while( iNode>=0 ){ TreeNode *pNode = pCsr->apTreeNode[iNode]; @@ -1450,7 +1451,7 @@ static int treeInsertEntry( u32 iTreeKey; TreeRoot *p = &pDb->treehdr.root; TreeCursor csr; /* Cursor to seek to pKey/nKey */ - int res; /* Result of seek operation on csr */ + int res = 0; /* Result of seek operation on csr */ assert( nVal>=0 || pVal==0 ); assert_tree_looks_ok(LSM_OK, pTree); @@ -1597,9 +1598,9 @@ static int treeDeleteEntry(lsm_db *db, TreeCursor *pCsr, u32 iNewptr){ assert( pNode->aiKeyPtr[1] ); assert( pNode->aiKeyPtr[iSlot] ); assert( iSlot==0 || iSlot==1 || iSlot==2 ); - assert( (pCsr->iNode==(db->treehdr.root.nHeight-1))==(iNewptr==0) ); + assert( ((u32)pCsr->iNode==(db->treehdr.root.nHeight-1))==(iNewptr==0) ); - bLeaf = (pCsr->iNode==(p->nHeight-1) && p->nHeight>1); + bLeaf = ((u32)pCsr->iNode==(p->nHeight-1) && p->nHeight>1); if( pNode->aiKeyPtr[0] || pNode->aiKeyPtr[2] ){ /* There are currently at least 2 keys on this node. So just create @@ -1764,7 +1765,7 @@ static int treeDeleteEntry(lsm_db *db, TreeCursor *pCsr, u32 iNewptr){ iPSlot--; pNew1->aiKeyPtr[iKOut++] = pParent->aiKeyPtr[iPSlot]; if( bLeaf==0 ) pNew1->aiChildPtr[iPOut++] = iNewptr; - pCsr->aiCell[pCsr->iNode] = iPSlot; + pCsr->aiCell[pCsr->iNode] = (u8)iPSlot; } rc = treeDeleteEntry(db, pCsr, iNew1); @@ -1839,7 +1840,7 @@ int lsmTreeDelete( } if( bDone==0 ){ - if( csr.iNode==(p->nHeight-1) ){ + if( (u32)csr.iNode==(p->nHeight-1) ){ /* The element to delete already lies on a leaf node */ rc = treeDeleteEntry(db, &csr, 0); }else{ @@ -1854,7 +1855,7 @@ int lsmTreeDelete( TreeKey *pKey; int iNode = csr.iNode; lsmTreeCursorNext(&csr); - assert( csr.iNode==(p->nHeight-1) ); + assert( (u32)csr.iNode==(p->nHeight-1) ); iKey = csr.apTreeNode[csr.iNode]->aiKeyPtr[csr.aiCell[csr.iNode]]; lsmTreeCursorPrev(&csr); @@ -2028,19 +2029,19 @@ int lsmTreeCursorSeek(TreeCursor *pCsr, void *pKey, int nKey, int *pRes){ } res = treeKeycmp((void *)&pTreeKey[1], pTreeKey->nKey, pKey, nKey); if( res==0 ){ - pCsr->aiCell[iNode] = iTest; + pCsr->aiCell[iNode] = (u8)iTest; break; } }else{ iTest = 1; } - if( iNode<(pRoot->nHeight-1) ){ + if( (u32)iNode<(pRoot->nHeight-1) ){ iNodePtr = getChildPtr(pNode, pRoot->iTransId, iTest + (res<0)); }else{ iNodePtr = 0; } - pCsr->aiCell[iNode] = iTest + (iNodePtr && (res<0)); + pCsr->aiCell[iNode] = (u8)(iTest + (iNodePtr && (res<0))); } *pRes = res; @@ -2167,7 +2168,7 @@ int lsmTreeCursorPrev(TreeCursor *pCsr){ if( rc!=LSM_OK ) break; pCsr->apTreeNode[pCsr->iNode] = pNode; iCell = 1 + (pNode->aiKeyPtr[2]!=0) + (pCsr->iNode < iLeaf); - pCsr->aiCell[pCsr->iNode] = iCell; + pCsr->aiCell[pCsr->iNode] = (u8)iCell; }while( pCsr->iNode < iLeaf ); } @@ -2179,7 +2180,7 @@ int lsmTreeCursorPrev(TreeCursor *pCsr){ iCell = pCsr->aiCell[pCsr->iNode]-1; if( iCell>=0 && pCsr->apTreeNode[pCsr->iNode]->aiKeyPtr[iCell] ) break; }while( (--pCsr->iNode)>=0 ); - pCsr->aiCell[pCsr->iNode] = iCell; + pCsr->aiCell[pCsr->iNode] = (u8)iCell; } #ifndef NDEBUG @@ -2224,12 +2225,12 @@ int lsmTreeCursorEnd(TreeCursor *pCsr, int bLast){ pCsr->iNode++; pCsr->apTreeNode[pCsr->iNode] = pNode; - if( pCsr->iNodenHeight-1 ){ + if( (u32)pCsr->iNodenHeight-1 ){ iNodePtr = getChildPtr(pNode, pRoot->iTransId, iCell); }else{ iNodePtr = 0; } - pCsr->aiCell[pCsr->iNode] = iCell - (iNodePtr==0 && bLast); + pCsr->aiCell[pCsr->iNode] = (u8)(iCell - (iNodePtr==0 && bLast)); } return rc; diff --git a/ext/lsm1/lsm_varint.c b/ext/lsm1/lsm_varint.c index 0ef2fd5017..c550a6405d 100644 --- a/ext/lsm1/lsm_varint.c +++ b/ext/lsm1/lsm_varint.c @@ -176,7 +176,7 @@ int lsmVarintGet32(u8 *z, int *piVal){ } ret = lsmSqlite4GetVarint64(z, &i); - *piVal = i; + *piVal = (int)i; return ret; } diff --git a/ext/lsm1/lsm_vtab.c b/ext/lsm1/lsm_vtab.c index e17af345f2..0855621160 100644 --- a/ext/lsm1/lsm_vtab.c +++ b/ext/lsm1/lsm_vtab.c @@ -157,7 +157,7 @@ static int lsm1Close(sqlite3_vtab_cursor *cur){ */ static int lsm1Next(sqlite3_vtab_cursor *cur){ lsm1_cursor *pCur = (lsm1_cursor*)cur; - int rc; + int rc = LSM_OK; if( pCur->bUnique ){ pCur->atEof = 1; }else{ @@ -368,7 +368,7 @@ static int lsm1EncodeKey( pSpace = sqlite3_malloc( nVal+1 ); if( pSpace==0 ) return SQLITE_NOMEM; } - pSpace[0] = eType; + pSpace[0] = (unsigned char)eType; memcpy(&pSpace[1], pVal, nVal); *ppKey = pSpace; *pnKey = nVal+1; @@ -385,7 +385,7 @@ static int lsm1EncodeKey( uVal = iVal; eType = LSM1_TYPE_POSITIVE; } - pSpace[0] = eType; + pSpace[0] = (unsigned char)eType; *ppKey = pSpace; *pnKey = 1 + lsm1PutVarint64(&pSpace[1], uVal); } @@ -597,7 +597,7 @@ int lsm1Update( const void *pKey; int nKey; int eType; - int rc; + int rc = LSM_OK; sqlite3_value *pValue; const unsigned char *pVal; unsigned char *pData; @@ -654,7 +654,7 @@ int lsm1Update( if( pData==0 ){ rc = SQLITE_NOMEM; }else{ - pData[0] = eType; + pData[0] = (unsigned char)eType; memcpy(&pData[1], pVal, nVal); rc = lsm_insert(p->pDb, pKey, nKey, pData, nVal+1); sqlite3_free(pData); @@ -677,7 +677,7 @@ int lsm1Update( aVal[i] = x & 0xff; x >>= 8; } - aVal[i] = eType; + aVal[i] = (unsigned char)eType; rc = lsm_insert(p->pDb, pKey, nKey, &aVal[i], 9-i); break; } diff --git a/ext/lsm1/lsm_win32.c b/ext/lsm1/lsm_win32.c index f7a02612a7..6c5d06b4c8 100644 --- a/ext/lsm1/lsm_win32.c +++ b/ext/lsm1/lsm_win32.c @@ -648,7 +648,6 @@ static int lsmWin32OsShmMap(lsm_file *pFile, int iChunk, int sz, void **ppShm){ assert( sz>=0 ); assert( sz==LSM_SHM_CHUNK_SIZE ); if( iChunk>=pWin32File->nShm ){ - int i; LPHANDLE ahNew; LPVOID *apNew; LARGE_INTEGER fileSize; diff --git a/manifest b/manifest index c0ffe7578b..bd09b3743a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\ssupport\sfor\stab-completion\s(using\sthe\sext/misc/completion.c\svirtual\stable)\nto\sthe\scommand-line\sshell. -D 2017-07-11T13:59:07.400 +C Fix\sharmless\scompiler\swarnings\sseen\swith\sMSVC\sfor\slsm1. +D 2017-07-11T16:36:10.699 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba @@ -210,7 +210,7 @@ F ext/icu/README.txt d9fbbad0c2f647c3fdf715fc9fd64af53aedfc43 F ext/icu/icu.c 84900472a088a3a172c6c079f58a1d3a1952c332 F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37 F ext/lsm1/Makefile a2ea4975162be8932b5efa727080f4982715d34c32035d9eb7a015ae78404981 -F ext/lsm1/Makefile.msc b9227a1d308f1e408b25557b32ce722517bc22343bd7b728b3ab3979cf2c8a1d +F ext/lsm1/Makefile.msc f9b5f1f9f534231bf315d96364315928f9f06eae1a96435197c98c1f834e23b4 F ext/lsm1/lsm-test/README 87ea529d2abe615e856d4714bfe8bb185e6c2771b8612aa6298588b7b43e6f86 F ext/lsm1/lsm-test/lsmtest.h 5847594d4b43ec3412e1fd97104f7eb5fd770be55e691e6cb2e80929f86bebe3 F ext/lsm1/lsm-test/lsmtest1.c 33158978327f800e82b6a47c09b86ace809f56a9ff10b0162273ec1186cc3153 @@ -237,20 +237,20 @@ F ext/lsm1/lsm-test/lsmtest_util.c 241622db5a332a09c8e6e7606b617d288a37b557f7d3b F ext/lsm1/lsm-test/lsmtest_win32.c 5605aac3bf3852dcc2509fb1d097f5f11556418c1cc9cf0fdd09f9af53c97fb4 F ext/lsm1/lsm.h 0f6f64ff071471cb87bf98beb8386566f30ea001 F ext/lsm1/lsmInt.h 68945f00c4fc97a5c82bd285a15d0baacd0019cf2e0b7d535759f000459462e1 -F ext/lsm1/lsm_ckpt.c 6ab5f08f60f802601eef0d2bad968d8f3729b908f88131e72311b2c2deaa7734 -F ext/lsm1/lsm_file.c fc95548f8cf8e47fda4120215d2c1fc22dfa85e09294e5656a99a846dc80a62b -F ext/lsm1/lsm_log.c 8308714659b9fe4a995c239528520c57d26a03baf1d1c973967493a089a79cc6 +F ext/lsm1/lsm_ckpt.c 3f88c5b4f37f033636c13c71c89d02f8104a4a97284b525516718041dfb4e672 +F ext/lsm1/lsm_file.c 04049405abcd7cb9bec1c21c3a690a64e97d80362d37649733d3871aaab956d9 +F ext/lsm1/lsm_log.c a8bf334532109bba05b09a504ee45fc393828b0d034ca61ab45e3940709d9a7c F ext/lsm1/lsm_main.c 15e73ccdafdd44ddeefc29e332079d88ba8f00c12c797b3c2b63d3171b5afce8 F ext/lsm1/lsm_mem.c 4c51ea9fa285ee6e35301b33491642d071740a0a F ext/lsm1/lsm_mutex.c 378edf0a2b142b4f7640ee982df06d50b98788ea -F ext/lsm1/lsm_shared.c 54185ae27b7580a959127c700459b3358e39723afce12b6281f2dfe408cb0efd -F ext/lsm1/lsm_sorted.c 9bc5251a54a5cb24c2f003c10595fa81ffc7178c4f200c6b0f83d50a2272bb1d +F ext/lsm1/lsm_shared.c 6b903d1afce9e254b642be7898359b4760afde6fb5740623bae4affff5726ab8 +F ext/lsm1/lsm_sorted.c ad426f7ed930ff4bd0405fbf77e06b48cdaabd11673cc39870b4cf7e5d92109e F ext/lsm1/lsm_str.c 65e361b488c87b10bf3e5c0070b14ffc602cf84f094880bece77bbf6678bca82 -F ext/lsm1/lsm_tree.c 53b657439e0fcb1117b0559ad3567ac417f81f2ed0fff9bab79948a00ea3cacb +F ext/lsm1/lsm_tree.c 682679d7ef2b8b6f2fe77aeb532c8d29695bca671c220b0abac77069de5fb9fb F ext/lsm1/lsm_unix.c 57361bcf5b1a1a028f5d66571ee490e9064d2cfb145a2cc9e5ddade467bb551b -F ext/lsm1/lsm_varint.c b19ae9bd26b5a1e8402fb8a564b25d9542338a41 -F ext/lsm1/lsm_vtab.c 812b74a9a7539e8cab49761591ffddc1b3580735fac5d638826c8d2be95ff38b -F ext/lsm1/lsm_win32.c 515f8298982e0e8aa7c6677389ffc66c65a5ff294baf678eefa19b6e61c239c3 +F ext/lsm1/lsm_varint.c 43f954af668a66c7928b81597c14d6ad4be9fedbc276bbd80f52fa28a02fdb62 +F ext/lsm1/lsm_vtab.c e4afff67205741075b74d6c598f9f9967bbdec8eb306bdc7cc1dcd0c71bffbd9 +F ext/lsm1/lsm_win32.c 0a4acbd7e8d136dd3a5753f0a9e7a9802263a9d96cef3278cf120bcaa724db7c F ext/misc/README.md 8e008c8d2b02e09096b31dfba033253ac27c6c06a18aa5826e299fa7601d90b2 F ext/misc/amatch.c 6db4607cb17c54b853a2d7c7c36046d004853f65b9b733e6f019d543d5dfae87 F ext/misc/anycollseq.c 5ffdfde9829eeac52219136ad6aa7cd9a4edb3b15f4f2532de52f4a22525eddb @@ -1631,7 +1631,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 17e0bb12d82b510b86b6886b9fd0faf39b60b1374027344f89d7b89a32b842b9 -R 951f8f3a9284f3001be7f39a25c50055 -U drh -Z 55996074e61f063450435131cf82f298 +P 95cd1d9f8baa6be305c9a8bfa26fef2a403f2d5b3b5c9c55382ec04f0bc98d40 +R e5707d39e2420bcc7332884f2942bda4 +U mistachkin +Z 7cd7cb2156c8cf8d5e8c4a5374c20532 diff --git a/manifest.uuid b/manifest.uuid index 7a51d0481c..72636119a4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -95cd1d9f8baa6be305c9a8bfa26fef2a403f2d5b3b5c9c55382ec04f0bc98d40 \ No newline at end of file +cf6da4a52f7f9047e653ef2972e4c0910b29d7182d789a9e30225dc1849e8779 \ No newline at end of file From 36c68234d6126e4678b5a44863e5bb966f2e78b6 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Tue, 11 Jul 2017 16:46:41 +0000 Subject: [PATCH 51/64] Fix more harmless compiler warnings in lsm1, seen with MSVC 2015. FossilOrigin-Name: 0f1307f1f5638c1c4f1ce2b89cdef7ce8b76dc2a38685cd1ca152cde9e8727da --- ext/lsm1/lsm_ckpt.c | 6 +++--- ext/lsm1/lsm_file.c | 12 ++++++------ ext/lsm1/lsm_sorted.c | 44 +++++++++++++++++++++---------------------- manifest | 16 ++++++++-------- manifest.uuid | 2 +- 5 files changed, 40 insertions(+), 40 deletions(-) diff --git a/ext/lsm1/lsm_ckpt.c b/ext/lsm1/lsm_ckpt.c index 42fa41ee7b..cf4c55bf84 100644 --- a/ext/lsm1/lsm_ckpt.c +++ b/ext/lsm1/lsm_ckpt.c @@ -1017,9 +1017,9 @@ int lsmCheckpointDeserialize( pDb->pEnv, sizeof(FreelistEntry)*nFree, &rc ); if( rc==LSM_OK ){ - int i; - for(i=0; ifreelist.aEntry[i]; + int j; + for(j=0; jfreelist.aEntry[j]; p->iBlk = aCkpt[iIn++]; p->iId = ((i64)(aCkpt[iIn])<<32) + aCkpt[iIn+1]; iIn += 2; diff --git a/ext/lsm1/lsm_file.c b/ext/lsm1/lsm_file.c index 2248be2fa0..7b22051069 100644 --- a/ext/lsm1/lsm_file.c +++ b/ext/lsm1/lsm_file.c @@ -2116,10 +2116,10 @@ int lsmFsSortedAppend( if( iPrev==0 ){ iApp = findAppendPoint(pFS, pLvl); }else if( fsIsLast(pFS, iPrev) ){ - int iNext; - rc = fsBlockNext(pFS, 0, fsPageToBlock(pFS, iPrev), &iNext); + int iNext2; + rc = fsBlockNext(pFS, 0, fsPageToBlock(pFS, iPrev), &iNext2); if( rc!=LSM_OK ) return rc; - iApp = fsFirstPageOnBlock(pFS, iNext); + iApp = fsFirstPageOnBlock(pFS, iNext2); }else{ iApp = iPrev + 1; } @@ -3257,10 +3257,10 @@ int lsmFsIntegrityCheck(lsm_db *pDb){ } for(pLevel=pWorker->pLevel; pLevel; pLevel=pLevel->pNext){ - int i; + int j; checkBlocks(pFS, &pLevel->lhs, (pLevel->nRight!=0), nBlock, aUsed); - for(i=0; inRight; i++){ - checkBlocks(pFS, &pLevel->aRhs[i], 0, nBlock, aUsed); + for(j=0; jnRight; j++){ + checkBlocks(pFS, &pLevel->aRhs[j], 0, nBlock, aUsed); } } diff --git a/ext/lsm1/lsm_sorted.c b/ext/lsm1/lsm_sorted.c index 9c09237691..7fc3114b38 100644 --- a/ext/lsm1/lsm_sorted.c +++ b/ext/lsm1/lsm_sorted.c @@ -890,22 +890,22 @@ static int btreeCursorRestore( } do { - Page *pPg; - rc = lsmFsDbPageGet(pCsr->pFS, pSeg, iLoad, &pPg); - assert( rc==LSM_OK || pPg==0 ); + Page *pPg2; + rc = lsmFsDbPageGet(pCsr->pFS, pSeg, iLoad, &pPg2); + assert( rc==LSM_OK || pPg2==0 ); if( rc==LSM_OK ){ u8 *aData; /* Buffer containing page data */ int nData; /* Size of aData[] in bytes */ int iMin; int iMax; - int iCell; + int iCell2; - aData = fsPageData(pPg, &nData); + aData = fsPageData(pPg2, &nData); assert( (pageGetFlags(aData, nData) & SEGMENT_BTREE_FLAG) ); iLoad = (int)pageGetPtr(aData, nData); - iCell = pageGetNRec(aData, nData); - iMax = iCell-1; + iCell2 = pageGetNRec(aData, nData); + iMax = iCell2-1; iMin = 0; while( iMax>=iMin ){ @@ -916,7 +916,7 @@ static int btreeCursorRestore( int res; /* (pSeek - pKeyT) */ rc = pageGetBtreeKey( - pSeg, pPg, iTry, &iPtr, &iTopic, &pKey, &nKey, &blob + pSeg, pPg2, iTry, &iPtr, &iTopic, &pKey, &nKey, &blob ); if( rc!=LSM_OK ) break; @@ -927,15 +927,15 @@ static int btreeCursorRestore( if( res<0 ){ iLoad = (int)iPtr; - iCell = iTry; + iCell2 = iTry; iMax = iTry-1; }else{ iMin = iTry+1; } } - pCsr->aPg[iPg].pPage = pPg; - pCsr->aPg[iPg].iCell = iCell; + pCsr->aPg[iPg].pPage = pPg2; + pCsr->aPg[iPg].iCell = iCell2; iPg++; assert( iPg!=nDepth-1 || lsmFsRedirectPage(pCsr->pFS, pSeg->pRedirect, iLoad)==iLeaf @@ -2007,37 +2007,37 @@ static void multiCursorGetKey( if( pCsr->iFree < (nEntry*2) ){ FreelistEntry *aEntry = pWorker->freelist.aEntry; int i = nEntry - 1 - (pCsr->iFree / 2); - u32 iKey = 0; + u32 iKey2 = 0; if( (pCsr->iFree % 2) ){ eType = LSM_END_DELETE|LSM_SYSTEMKEY; - iKey = aEntry[i].iBlk-1; + iKey2 = aEntry[i].iBlk-1; }else if( aEntry[i].iId>=0 ){ eType = LSM_INSERT|LSM_SYSTEMKEY; - iKey = aEntry[i].iBlk; + iKey2 = aEntry[i].iBlk; /* If the in-memory entry immediately before this one was a ** DELETE, and the block number is one greater than the current ** block number, mark this entry as an "end-delete-range". */ - if( i<(nEntry-1) && aEntry[i+1].iBlk==iKey+1 && aEntry[i+1].iId<0 ){ + if( i<(nEntry-1) && aEntry[i+1].iBlk==iKey2+1 && aEntry[i+1].iId<0 ){ eType |= LSM_END_DELETE; } }else{ eType = LSM_START_DELETE|LSM_SYSTEMKEY; - iKey = aEntry[i].iBlk + 1; + iKey2 = aEntry[i].iBlk + 1; } /* If the in-memory entry immediately after this one is a ** DELETE, and the block number is one less than the current ** key, mark this entry as an "start-delete-range". */ - if( i>0 && aEntry[i-1].iBlk==iKey-1 && aEntry[i-1].iId<0 ){ + if( i>0 && aEntry[i-1].iBlk==iKey2-1 && aEntry[i-1].iId<0 ){ eType |= LSM_START_DELETE; } pKey = pCsr->pSystemVal; nKey = 4; - lsmPutU32(pKey, ~iKey); + lsmPutU32(pKey, ~iKey2); } } break; @@ -5699,20 +5699,20 @@ static int infoPageDump( LsmString str; int nRec; int iPtr; - int flags; + int flags2; int iCell; u8 *aData; int nData; /* Page data and size thereof */ aData = fsPageData(pPg, &nData); nRec = pageGetNRec(aData, nData); iPtr = (int)pageGetPtr(aData, nData); - flags = pageGetFlags(aData, nData); + flags2 = pageGetFlags(aData, nData); lsmStringInit(&str, pDb->pEnv); lsmStringAppendf(&str, "Page : %lld (%d bytes)\n", iPg, nData); lsmStringAppendf(&str, "nRec : %d\n", nRec); lsmStringAppendf(&str, "iPtr : %d\n", iPtr); - lsmStringAppendf(&str, "flags: %04x\n", flags); + lsmStringAppendf(&str, "flags: %04x\n", flags2); lsmStringAppendf(&str, "\n"); for(iCell=0; iCell Date: Tue, 11 Jul 2017 17:06:42 +0000 Subject: [PATCH 52/64] Fix a whitespace alignment issue in lsm1. FossilOrigin-Name: a8e651e0e52b016c3939df3ee23b4981f1a8841c7ddd2981c1ef391feb559a5e --- ext/lsm1/lsm_sorted.c | 2 +- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ext/lsm1/lsm_sorted.c b/ext/lsm1/lsm_sorted.c index 7fc3114b38..f479f4ce8c 100644 --- a/ext/lsm1/lsm_sorted.c +++ b/ext/lsm1/lsm_sorted.c @@ -4038,7 +4038,7 @@ static int mergeWorkerWrite( if( flags ) lsmPutU16(&aData[SEGMENT_FLAGS_OFFSET(nData)], (u16)flags); /* Write the entry header into the current page. */ - aData[iOff++] = (u8)eType; /* 1 */ + aData[iOff++] = (u8)eType; /* 1 */ iOff += lsmVarintPut32(&aData[iOff], iRPtr); /* 2 */ iOff += lsmVarintPut32(&aData[iOff], nKey); /* 3 */ if( rtIsWrite(eType) ) iOff += lsmVarintPut32(&aData[iOff], nVal); /* 4 */ diff --git a/manifest b/manifest index 181cfa6613..03a4449371 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\smore\sharmless\scompiler\swarnings\sin\slsm1,\sseen\swith\sMSVC\s2015. -D 2017-07-11T16:46:41.623 +C Fix\sa\swhitespace\salignment\sissue\sin\slsm1. +D 2017-07-11T17:06:42.710 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba @@ -244,7 +244,7 @@ F ext/lsm1/lsm_main.c 15e73ccdafdd44ddeefc29e332079d88ba8f00c12c797b3c2b63d3171b F ext/lsm1/lsm_mem.c 4c51ea9fa285ee6e35301b33491642d071740a0a F ext/lsm1/lsm_mutex.c 378edf0a2b142b4f7640ee982df06d50b98788ea F ext/lsm1/lsm_shared.c 6b903d1afce9e254b642be7898359b4760afde6fb5740623bae4affff5726ab8 -F ext/lsm1/lsm_sorted.c 1bdd5668c27e36253d164b180ee3e0c5cf75964786d4777f25ef45c0d37e53a8 +F ext/lsm1/lsm_sorted.c a04518dfbfff0171fafb152a46e9fe9f45e1edbf3570e4533dd58ddb6567f0c9 F ext/lsm1/lsm_str.c 65e361b488c87b10bf3e5c0070b14ffc602cf84f094880bece77bbf6678bca82 F ext/lsm1/lsm_tree.c 682679d7ef2b8b6f2fe77aeb532c8d29695bca671c220b0abac77069de5fb9fb F ext/lsm1/lsm_unix.c 57361bcf5b1a1a028f5d66571ee490e9064d2cfb145a2cc9e5ddade467bb551b @@ -1631,7 +1631,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P cf6da4a52f7f9047e653ef2972e4c0910b29d7182d789a9e30225dc1849e8779 -R e3b76a73346e93609e0049aa729badac +P 0f1307f1f5638c1c4f1ce2b89cdef7ce8b76dc2a38685cd1ca152cde9e8727da +R 7400a8b15efac04f7b2e05c59db9c23f U mistachkin -Z 43b08d17226cf77572e88a78b7952b8a +Z 8bfcb6b9870f5a07cd83371a25e25bb8 diff --git a/manifest.uuid b/manifest.uuid index 210133996e..b01cd2aa9b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0f1307f1f5638c1c4f1ce2b89cdef7ce8b76dc2a38685cd1ca152cde9e8727da \ No newline at end of file +a8e651e0e52b016c3939df3ee23b4981f1a8841c7ddd2981c1ef391feb559a5e \ No newline at end of file From db3e0456d28ae7d36a257a132aaaab55b72e329a Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 11 Jul 2017 17:28:27 +0000 Subject: [PATCH 53/64] Enabled the new sqlite3_prepare_v3() and sqlite3_prepare16_v3() interfaces for loadable extensions. FossilOrigin-Name: b9debd626a68c4bc0e5fdeb8d15a991cfe6f62f9586eda76c07a1c18e498e3c2 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/loadext.c | 5 ++++- src/sqlite3ext.h | 8 ++++++++ 4 files changed, 21 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 03a4449371..39556ed745 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\swhitespace\salignment\sissue\sin\slsm1. -D 2017-07-11T17:06:42.710 +C Enabled\sthe\snew\ssqlite3_prepare_v3()\sand\ssqlite3_prepare16_v3()\sinterfaces\nfor\sloadable\sextensions. +D 2017-07-11T17:28:27.462 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba @@ -413,7 +413,7 @@ F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c bb70abf32c7c926745eb550938db9132309584a667a44c2db0e5fa3207600391 F src/legacy.c 134ab3e3fae00a0f67a5187981d6935b24b337bcf0f4b3e5c9fa5763da95bf4e -F src/loadext.c a72909474dadce771d3669bf84bf689424f6f87d471fee898589c3ef9b2acfd9 +F src/loadext.c 83fc9858b19ffe4b7191f5d0bfa9111896af9d7dff55367edc92e6720511108e F src/main.c 20574bb9a0d7911efcd659ac252f2126dc4e3308bed3c8764ea3fb5a00f70420 F src/malloc.c e20bb2b48abec52d3faf01cce12e8b4f95973755fafec98d45162dfdab111978 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 @@ -454,7 +454,7 @@ F src/shell.c 19726a6f28f66aa0488f5e9c7aacc399f2bbcd934bffc3a92a5de6d365389eee F src/shell.c.in 18510e3fdd9216a6183ff93a48cac7d8d253d39f17750af597d90d3c5f27fc34 F src/sqlite.h.in 03a422ba13da1dfef7f1aaa1ba344acf18dc867112620b1fdb2a1426cabba634 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 -F src/sqlite3ext.h 58fd0676d3111d02e62e5a35992a7d3da5d3f88753acc174f2d37b774fbbdd28 +F src/sqlite3ext.h 5539ec41f3d81890d626d5a845b08c82bd0e946ddc5c1c341144b700bc56101e F src/sqliteInt.h 7a7cd6f682471cce4afe64216f71fd64c622712aeb9d947c33c38337a7cf19a9 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 @@ -1631,7 +1631,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0f1307f1f5638c1c4f1ce2b89cdef7ce8b76dc2a38685cd1ca152cde9e8727da -R 7400a8b15efac04f7b2e05c59db9c23f -U mistachkin -Z 8bfcb6b9870f5a07cd83371a25e25bb8 +P a8e651e0e52b016c3939df3ee23b4981f1a8841c7ddd2981c1ef391feb559a5e +R 203da47c07175d33b190b03dbc1a6851 +U drh +Z 26dac8927f38097219eaf56c6204ab1a diff --git a/manifest.uuid b/manifest.uuid index b01cd2aa9b..f21fe12e65 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a8e651e0e52b016c3939df3ee23b4981f1a8841c7ddd2981c1ef391feb559a5e \ No newline at end of file +b9debd626a68c4bc0e5fdeb8d15a991cfe6f62f9586eda76c07a1c18e498e3c2 \ No newline at end of file diff --git a/src/loadext.c b/src/loadext.c index 1fee4260ab..47efc11f0c 100644 --- a/src/loadext.c +++ b/src/loadext.c @@ -423,7 +423,10 @@ static const sqlite3_api_routines sqlite3Apis = { sqlite3_trace_v2, sqlite3_expanded_sql, /* Version 3.18.0 and later */ - sqlite3_set_last_insert_rowid + sqlite3_set_last_insert_rowid, + /* Version 3.20.0 and later */ + sqlite3_prepare_v3, + sqlite3_prepare16_v3 }; /* diff --git a/src/sqlite3ext.h b/src/sqlite3ext.h index f25084a1f5..06b5e5b71c 100644 --- a/src/sqlite3ext.h +++ b/src/sqlite3ext.h @@ -284,6 +284,11 @@ struct sqlite3_api_routines { char *(*expanded_sql)(sqlite3_stmt*); /* Version 3.18.0 and later */ void (*set_last_insert_rowid)(sqlite3*,sqlite3_int64); + /* Version 3.20.0 and later */ + int (*prepare_v3)(sqlite3*,const char*,int,unsigned int, + sqlite3_stmt**,const char**); + int (*prepare16_v3)(sqlite3*,const void*,int,unsigned int, + sqlite3_stmt**,const void**); }; /* @@ -544,6 +549,9 @@ typedef int (*sqlite3_loadext_entry)( #define sqlite3_expanded_sql sqlite3_api->expanded_sql /* Version 3.18.0 and later */ #define sqlite3_set_last_insert_rowid sqlite3_api->set_last_insert_rowid +/* Version 3.20.0 and later */ +#define sqlite3_prepare_v3 sqlite3_api->prepare_v3 +#define sqlite3_prepare16_v3 sqlite3_api->prepare16_v3 #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) From ba334bb20d6db22fcdbbeb1cca3dea2c55ba97c9 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Tue, 11 Jul 2017 17:54:27 +0000 Subject: [PATCH 54/64] Make win32GetTimeOfDay() in the lsm1 test code more portable. FossilOrigin-Name: 2fe3a84330063378ca9fc5bfc8efe486c52d50b5c40be4f402a4f2318be69436 --- ext/lsm1/lsm-test/lsmtest_win32.c | 16 ++++++++-------- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/ext/lsm1/lsm-test/lsmtest_win32.c b/ext/lsm1/lsm-test/lsmtest_win32.c index f2f112acb4..9472723368 100644 --- a/ext/lsm1/lsm-test/lsmtest_win32.c +++ b/ext/lsm1/lsm-test/lsmtest_win32.c @@ -12,19 +12,19 @@ int win32GetTimeOfDay( void *tzp ){ FILETIME fileTime; - ULARGE_INTEGER largeInteger; ULONGLONG ticks; + ULONGLONG unixTicks; unused_parameter(tzp); memset(&fileTime, 0, sizeof(FILETIME)); GetSystemTimeAsFileTime(&fileTime); - memset(&largeInteger, 0, sizeof(ULARGE_INTEGER)); - largeInteger.LowPart = fileTime.dwLowDateTime; - largeInteger.HighPart = fileTime.dwHighDateTime; - ticks = largeInteger.QuadPart - TICKS_UNIX_EPOCH; - tp->tv_sec = (long)(ticks / TICKS_PER_SECOND); - ticks -= ((ULONGLONG)tp->tv_sec * TICKS_PER_SECOND); - tp->tv_usec = (long)(ticks / TICKS_PER_MICROSECOND); + ticks = (ULONGLONG)fileTime.dwHighDateTime << 32; + ticks |= (ULONGLONG)fileTime.dwLowDateTime; + unixTicks = ticks - TICKS_UNIX_EPOCH; + tp->tv_sec = (long)(unixTicks / TICKS_PER_SECOND); + unixTicks -= ((ULONGLONG)tp->tv_sec * TICKS_PER_SECOND); + tp->tv_usec = (long)(unixTicks / TICKS_PER_MICROSECOND); + return 0; } #endif diff --git a/manifest b/manifest index 39556ed745..162add8085 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enabled\sthe\snew\ssqlite3_prepare_v3()\sand\ssqlite3_prepare16_v3()\sinterfaces\nfor\sloadable\sextensions. -D 2017-07-11T17:28:27.462 +C Make\swin32GetTimeOfDay()\sin\sthe\slsm1\stest\scode\smore\sportable. +D 2017-07-11T17:54:27.449 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba @@ -234,7 +234,7 @@ F ext/lsm1/lsm-test/lsmtest_tdb2.cc 99ea7f2dd9c7536c8fb9bdd329e4cfeb76899f3ddf6f F ext/lsm1/lsm-test/lsmtest_tdb3.c e44bf94e8bd724cd6ac161fd2cd44ffe43193932ad3a6bee1b07d80bb74012bb F ext/lsm1/lsm-test/lsmtest_tdb4.c 47e8bb5eba266472d690fb8264f1855ebdba0ae5a0e541e35fcda61ebf1d277f F ext/lsm1/lsm-test/lsmtest_util.c 241622db5a332a09c8e6e7606b617d288a37b557f7d3bce0bb97809f67cc2806 -F ext/lsm1/lsm-test/lsmtest_win32.c 5605aac3bf3852dcc2509fb1d097f5f11556418c1cc9cf0fdd09f9af53c97fb4 +F ext/lsm1/lsm-test/lsmtest_win32.c 0e0a224674c4d3170631c41b026b56c7e1672b151f5261e1b4cc19068641da2d F ext/lsm1/lsm.h 0f6f64ff071471cb87bf98beb8386566f30ea001 F ext/lsm1/lsmInt.h 68945f00c4fc97a5c82bd285a15d0baacd0019cf2e0b7d535759f000459462e1 F ext/lsm1/lsm_ckpt.c ac6fb4581983291c2e0be6fbb68f12b26f0c08d606835c05417be1323d0fdd03 @@ -1631,7 +1631,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a8e651e0e52b016c3939df3ee23b4981f1a8841c7ddd2981c1ef391feb559a5e -R 203da47c07175d33b190b03dbc1a6851 -U drh -Z 26dac8927f38097219eaf56c6204ab1a +P b9debd626a68c4bc0e5fdeb8d15a991cfe6f62f9586eda76c07a1c18e498e3c2 +R 8745ce1c706502301f89ec6738b13039 +U mistachkin +Z 63dd27d75b2c25ef4e26d8f81d95be48 diff --git a/manifest.uuid b/manifest.uuid index f21fe12e65..dba55a945d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b9debd626a68c4bc0e5fdeb8d15a991cfe6f62f9586eda76c07a1c18e498e3c2 \ No newline at end of file +2fe3a84330063378ca9fc5bfc8efe486c52d50b5c40be4f402a4f2318be69436 \ No newline at end of file From 8999798e6053b76955ae1d35182cb94832f846cc Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 11 Jul 2017 18:11:33 +0000 Subject: [PATCH 55/64] Fix harmless compiler warnings in the core. FossilOrigin-Name: 55e93f256018757e5e1cb3b10ef48abf5914e7687419eae58b00998a37061261 --- ext/misc/completion.c | 16 +++++++++++++++- ext/misc/fileio.c | 2 ++ manifest | 24 ++++++++++++------------ manifest.uuid | 2 +- src/btree.c | 37 +++++++++++++++++++------------------ src/shell.c | 22 +++++++++++++++++++--- src/shell.c.in | 4 ++-- src/sqliteInt.h | 2 ++ 8 files changed, 72 insertions(+), 37 deletions(-) diff --git a/ext/misc/completion.c b/ext/misc/completion.c index 8dc5d7dbaf..79f889abf1 100644 --- a/ext/misc/completion.c +++ b/ext/misc/completion.c @@ -106,6 +106,11 @@ static int completionConnect( completion_vtab *pNew; int rc; + (void)(pAux); /* Unused parameter */ + (void)(argc); /* Unused parameter */ + (void)(argv); /* Unused parameter */ + (void)(pzErr); /* Unused parameter */ + /* Column numbers */ #define COMPLETION_COLUMN_CANDIDATE 0 /* Suggested completion of the input */ #define COMPLETION_COLUMN_PREFIX 1 /* Prefix of the word to be completed */ @@ -192,6 +197,8 @@ static const char *completionKwrds[] = { "UPDATE", "USING", "VACUUM", "VALUES", "VIEW", "VIRTUAL", "WHEN", "WHERE", "WITH", "WITHOUT", }; +#define completionKwCount \ + (int)(sizeof(completionKwrds)/sizeof(completionKwrds[0])) /* ** Advance a completion_cursor to its next row of output. @@ -215,7 +222,7 @@ static int completionNext(sqlite3_vtab_cursor *cur){ while( pCur->ePhase!=COMPLETION_EOF ){ switch( pCur->ePhase ){ case COMPLETION_KEYWORDS: { - if( pCur->j >= sizeof(completionKwrds)/sizeof(completionKwrds[0]) ){ + if( pCur->j >= completionKwCount ){ pCur->zCurrentRow = 0; pCur->ePhase = COMPLETION_DATABASES; }else{ @@ -372,6 +379,8 @@ static int completionFilter( ){ completion_cursor *pCur = (completion_cursor *)pVtabCursor; int iArg = 0; + (void)(idxStr); /* Unused parameter */ + (void)(argc); /* Unused parameter */ completionCursorReset(pCur); if( idxNum & 1 ){ pCur->nPrefix = sqlite3_value_bytes(argv[iArg]); @@ -426,6 +435,7 @@ static int completionBestIndex( int nArg = 0; /* Number of arguments that completeFilter() expects */ const struct sqlite3_index_constraint *pConstraint; + (void)(tab); /* Unused parameter */ pConstraint = pIdxInfo->aConstraint; for(i=0; inConstraint; i++, pConstraint++){ if( pConstraint->usable==0 ) continue; @@ -480,6 +490,9 @@ static sqlite3_module completionModule = { 0, /* xRollback */ 0, /* xFindMethod */ 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0 /* xRollbackTo */ }; #endif /* SQLITE_OMIT_VIRTUALTABLE */ @@ -502,6 +515,7 @@ int sqlite3_completion_init( ){ int rc = SQLITE_OK; SQLITE_EXTENSION_INIT2(pApi); + (void)(pzErrMsg); /* Unused parameter */ #ifndef SQLITE_OMIT_VIRTUALTABLE rc = sqlite3CompletionVtabInit(db); #endif diff --git a/ext/misc/fileio.c b/ext/misc/fileio.c index fbe2d030c0..2c00ad971d 100644 --- a/ext/misc/fileio.c +++ b/ext/misc/fileio.c @@ -32,6 +32,7 @@ static void readfileFunc( long nIn; void *pBuf; + (void)(argc); /* Unused parameter */ zName = (const char*)sqlite3_value_text(argv[0]); if( zName==0 ) return; in = fopen(zName, "rb"); @@ -64,6 +65,7 @@ static void writefileFunc( sqlite3_int64 rc; const char *zFile; + (void)(argc); /* Unused parameter */ zFile = (const char*)sqlite3_value_text(argv[0]); if( zFile==0 ) return; out = fopen(zFile, "wb"); diff --git a/manifest b/manifest index 162add8085..270e42e442 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\swin32GetTimeOfDay()\sin\sthe\slsm1\stest\scode\smore\sportable. -D 2017-07-11T17:54:27.449 +C Fix\sharmless\scompiler\swarnings\sin\sthe\score. +D 2017-07-11T18:11:33.473 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba @@ -256,12 +256,12 @@ F ext/misc/amatch.c 6db4607cb17c54b853a2d7c7c36046d004853f65b9b733e6f019d543d5df F ext/misc/anycollseq.c 5ffdfde9829eeac52219136ad6aa7cd9a4edb3b15f4f2532de52f4a22525eddb F ext/misc/carray.c 40c27641010a4dc67e3690bdb7c9d36ca58b3c2d F ext/misc/closure.c 0d2a038df8fbae7f19de42e7c7d71f2e4dc88704 -F ext/misc/completion.c 821141b02a0313ce7dbe72f0260ef755f81d4b57eacb799864e4c40ad5ceb3f3 +F ext/misc/completion.c 52c3f01523e3e387eb321b4739a89d1fe47cbe6025aa1f2d8d3685e9e365df0f F ext/misc/compress.c 122faa92d25033d6c3f07c39231de074ab3d2e83 F ext/misc/csv.c d91c0388445b08f6e373dd0e8fc024d4551b1fcaf64e876a1c3f4fac8a63adc2 F ext/misc/dbdump.c 3509fa6b8932d04e932d6b6b827b6a82ca362781b8e8f3c77336f416793e215e F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2 -F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f +F ext/misc/fileio.c b1aa06c0f1dac277695d4529e5e976c65ab5678dcbb53a0304deaa8adc44b332 F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25 F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c F ext/misc/json1.c dbe086615b9546c156bf32b9378fc09383b58bd17513b866cfd24c1e15281984 @@ -392,7 +392,7 @@ F src/auth.c 79f96c6f33bf0e5da8d1c282cee5ebb1852bb8a6ccca3e485d7c459b035d9c3c F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca -F src/btree.c 79fb003347c47c74f8fda24f2fd332321da616771cd3d1b3258b739f569ec625 +F src/btree.c f55ea8f456d103328d61076be40fa39acbfea05eaa4eccfed275532a63c867c4 F src/btree.h 3edc5329bc59534d2d15b4f069a9f54b779a7e51289e98fa481ae3c0e526a5ca F src/btreeInt.h 97700795edf8a43245720414798b7b29d8e465aef46bf301ffacd431910c0da1 F src/build.c 74108007d286232fb4290464ee5452fa860c26215f8caa0e6c7cbf69a6fafe8f @@ -450,12 +450,12 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 6aa1fb1212e601f65b983ee1215d69a591986c8f97a3805c425c625a53839539 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 6aa7e8ee53dcb9d0b77b05670bb44a1076d6747bc9b2c1f12a365b553ab6c828 -F src/shell.c 19726a6f28f66aa0488f5e9c7aacc399f2bbcd934bffc3a92a5de6d365389eee -F src/shell.c.in 18510e3fdd9216a6183ff93a48cac7d8d253d39f17750af597d90d3c5f27fc34 +F src/shell.c 0401a716fc5343594b8ee60ce065d9a71373d3403f0b81f9fed684741e6401d1 +F src/shell.c.in 98bfdeeb0808418b37f59e6d380568a76e0733efe2494377096f434b39940cad F src/sqlite.h.in 03a422ba13da1dfef7f1aaa1ba344acf18dc867112620b1fdb2a1426cabba634 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 5539ec41f3d81890d626d5a845b08c82bd0e946ddc5c1c341144b700bc56101e -F src/sqliteInt.h 7a7cd6f682471cce4afe64216f71fd64c622712aeb9d947c33c38337a7cf19a9 +F src/sqliteInt.h c9cc829906fc9c95444c6c3b4a7dbf8eac39af15cde5582e869ae5c9b4eebef9 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -1631,7 +1631,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b9debd626a68c4bc0e5fdeb8d15a991cfe6f62f9586eda76c07a1c18e498e3c2 -R 8745ce1c706502301f89ec6738b13039 -U mistachkin -Z 63dd27d75b2c25ef4e26d8f81d95be48 +P 2fe3a84330063378ca9fc5bfc8efe486c52d50b5c40be4f402a4f2318be69436 +R 5233df6163d8e8ff9a79e293df00de6c +U drh +Z d9b035cf4c291f130c8cdbd2d8e35ec0 diff --git a/manifest.uuid b/manifest.uuid index dba55a945d..74c8ab24ec 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2fe3a84330063378ca9fc5bfc8efe486c52d50b5c40be4f402a4f2318be69436 \ No newline at end of file +55e93f256018757e5e1cb3b10ef48abf5914e7687419eae58b00998a37061261 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 406a2b4282..4d38315f30 100644 --- a/src/btree.c +++ b/src/btree.c @@ -5449,19 +5449,19 @@ i64 sqlite3BtreeRowCountEst(BtCursor *pCur){ ** routine is called when it is necessary to move to a different page or ** to restore the cursor. ** -** If bit 0x01 of the flags argument is 1, then the cursor corresponds to -** an SQL index and this routine could have been skipped if the SQL index -** had been a unique index. The flags argument is a hint to the implement. -** SQLite btree implementation does not use this hint, but COMDB2 does. +** If bit 0x01 of the F argument in sqlite3BtreeNext(C,F) is 1, then the +** cursor corresponds to an SQL index and this routine could have been +** skipped if the SQL index had been a unique index. The F argument +** is a hint to the implement. SQLite btree implementation does not use +** this hint, but COMDB2 does. */ -static SQLITE_NOINLINE int btreeNext(BtCursor *pCur, int flags){ +static SQLITE_NOINLINE int btreeNext(BtCursor *pCur){ int rc; int idx; MemPage *pPage; assert( cursorOwnsBtShared(pCur) ); assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID ); - assert( flags==0 ); if( pCur->eState!=CURSOR_VALID ){ assert( (pCur->curFlags & BTCF_ValidOvfl)==0 ); rc = restoreCursorPosition(pCur); @@ -5508,7 +5508,7 @@ static SQLITE_NOINLINE int btreeNext(BtCursor *pCur, int flags){ pPage = pCur->apPage[pCur->iPage]; }while( pCur->ix>=pPage->nCell ); if( pPage->intKey ){ - return sqlite3BtreeNext(pCur, flags); + return sqlite3BtreeNext(pCur, 0); }else{ return SQLITE_OK; } @@ -5521,16 +5521,17 @@ static SQLITE_NOINLINE int btreeNext(BtCursor *pCur, int flags){ } int sqlite3BtreeNext(BtCursor *pCur, int flags){ MemPage *pPage; + UNUSED_PARAMETER( flags ); /* Used in COMDB2 but not native SQLite */ assert( cursorOwnsBtShared(pCur) ); assert( flags==0 || flags==1 ); assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID ); pCur->info.nSize = 0; pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); - if( pCur->eState!=CURSOR_VALID ) return btreeNext(pCur, 0); + if( pCur->eState!=CURSOR_VALID ) return btreeNext(pCur); pPage = pCur->apPage[pCur->iPage]; if( (++pCur->ix)>=pPage->nCell ){ pCur->ix--; - return btreeNext(pCur, 0); + return btreeNext(pCur); } if( pPage->leaf ){ return SQLITE_OK; @@ -5553,18 +5554,17 @@ int sqlite3BtreeNext(BtCursor *pCur, int flags){ ** helper routine is called when it is necessary to move to a different page ** or to restore the cursor. ** -** -** If bit 0x01 of the flags argument is 1, then the cursor corresponds to -** an SQL index and this routine could have been skipped if the SQL index -** had been a unique index. The flags argument is a hint to the implement. -** SQLite btree implementation does not use this hint, but COMDB2 does. +** If bit 0x01 of the F argument to sqlite3BtreePrevious(C,F) is 1, then +** the cursor corresponds to an SQL index and this routine could have been +** skipped if the SQL index had been a unique index. The F argument is a +** hint to the implement. The native SQLite btree implementation does not +** use this hint, but COMDB2 does. */ -static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur, int flags){ +static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur){ int rc; MemPage *pPage; assert( cursorOwnsBtShared(pCur) ); - assert( flags==0 ); assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID ); assert( (pCur->curFlags & (BTCF_AtLast|BTCF_ValidOvfl|BTCF_ValidNKey))==0 ); assert( pCur->info.nSize==0 ); @@ -5608,7 +5608,7 @@ static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur, int flags){ pCur->ix--; pPage = pCur->apPage[pCur->iPage]; if( pPage->intKey && !pPage->leaf ){ - rc = sqlite3BtreePrevious(pCur, flags); + rc = sqlite3BtreePrevious(pCur, 0); }else{ rc = SQLITE_OK; } @@ -5619,13 +5619,14 @@ int sqlite3BtreePrevious(BtCursor *pCur, int flags){ assert( cursorOwnsBtShared(pCur) ); assert( flags==0 || flags==1 ); assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID ); + UNUSED_PARAMETER( flags ); /* Used in COMDB2 but not native SQLite */ pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidOvfl|BTCF_ValidNKey); pCur->info.nSize = 0; if( pCur->eState!=CURSOR_VALID || pCur->ix==0 || pCur->apPage[pCur->iPage]->leaf==0 ){ - return btreePrevious(pCur, 0); + return btreePrevious(pCur); } pCur->ix--; return SQLITE_OK; diff --git a/src/shell.c b/src/shell.c index 443304616c..4fe0fd3856 100644 --- a/src/shell.c +++ b/src/shell.c @@ -784,7 +784,7 @@ static void shellAddSchemaName( const char *zSchema = (const char*)sqlite3_value_text(apVal[1]); assert( nVal==2 ); if( zIn!=0 && strncmp(zIn, "CREATE ", 7)==0 ){ - for(i=0; iePhase!=COMPLETION_EOF ){ switch( pCur->ePhase ){ case COMPLETION_KEYWORDS: { - if( pCur->j >= sizeof(completionKwrds)/sizeof(completionKwrds[0]) ){ + if( pCur->j >= completionKwCount ){ pCur->zCurrentRow = 0; pCur->ePhase = COMPLETION_DATABASES; }else{ @@ -2003,6 +2012,8 @@ static int completionFilter( ){ completion_cursor *pCur = (completion_cursor *)pVtabCursor; int iArg = 0; + (void)(idxStr); /* Unused parameter */ + (void)(argc); /* Unused parameter */ completionCursorReset(pCur); if( idxNum & 1 ){ pCur->nPrefix = sqlite3_value_bytes(argv[iArg]); @@ -2057,6 +2068,7 @@ static int completionBestIndex( int nArg = 0; /* Number of arguments that completeFilter() expects */ const struct sqlite3_index_constraint *pConstraint; + (void)(tab); /* Unused parameter */ pConstraint = pIdxInfo->aConstraint; for(i=0; inConstraint; i++, pConstraint++){ if( pConstraint->usable==0 ) continue; @@ -2111,6 +2123,9 @@ static sqlite3_module completionModule = { 0, /* xRollback */ 0, /* xFindMethod */ 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0 /* xRollbackTo */ }; #endif /* SQLITE_OMIT_VIRTUALTABLE */ @@ -2133,6 +2148,7 @@ int sqlite3_completion_init( ){ int rc = SQLITE_OK; SQLITE_EXTENSION_INIT2(pApi); + (void)(pzErrMsg); /* Unused parameter */ #ifndef SQLITE_OMIT_VIRTUALTABLE rc = sqlite3CompletionVtabInit(db); #endif diff --git a/src/shell.c.in b/src/shell.c.in index 72d07799ba..3c57772767 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -766,7 +766,7 @@ static void shellAddSchemaName( const char *zSchema = (const char*)sqlite3_value_text(apVal[1]); assert( nVal==2 ); if( zIn!=0 && strncmp(zIn, "CREATE ", 7)==0 ){ - for(i=0; i Date: Tue, 11 Jul 2017 19:55:38 +0000 Subject: [PATCH 56/64] Simplify the way in which the database file is truncated when the last connection disconnects. Also ignore the error code from the xTruncate call - as truncating a database file is always optional. FossilOrigin-Name: b0a49d90fc91acca1306cf6145adc83acd368686768b7eb4a3b27515b3237396 --- ext/lsm1/lsmInt.h | 2 +- ext/lsm1/lsm_shared.c | 12 ++++-------- manifest | 16 ++++++++-------- manifest.uuid | 2 +- 4 files changed, 14 insertions(+), 18 deletions(-) diff --git a/ext/lsm1/lsmInt.h b/ext/lsm1/lsmInt.h index 9190c7d796..8e956dbb4c 100644 --- a/ext/lsm1/lsmInt.h +++ b/ext/lsm1/lsmInt.h @@ -589,7 +589,7 @@ struct Snapshot { /* ** Functions from file "lsm_ckpt.c". */ -int lsmCheckpointWrite(lsm_db *, int, u32 *); +int lsmCheckpointWrite(lsm_db *, u32 *); int lsmCheckpointLevels(lsm_db *, int, void **, int *); int lsmCheckpointLoadLevels(lsm_db *pDb, void *pVal, int nVal); diff --git a/ext/lsm1/lsm_shared.c b/ext/lsm1/lsm_shared.c index 6b41c1dc39..111b0ddbe7 100644 --- a/ext/lsm1/lsm_shared.c +++ b/ext/lsm1/lsm_shared.c @@ -230,7 +230,7 @@ static int dbTruncateFile(lsm_db *pDb){ /* If the last block that contains data is not already the last block in ** the database file, truncate the database file so that it is. */ - if( rc==LSM_OK && ctx.nBlock!=pDb->pWorker->nBlock ){ + if( rc==LSM_OK ){ rc = lsmFsTruncateDb( pDb->pFS, (i64)ctx.nBlock*lsmFsBlockSize(pDb->pFS) ); @@ -293,7 +293,7 @@ static void doDbDisconnect(lsm_db *pDb){ /* Write a checkpoint to disk. */ if( rc==LSM_OK ){ - rc = lsmCheckpointWrite(pDb, (bReadonly==0), 0); + rc = lsmCheckpointWrite(pDb, 0); } /* If the checkpoint was written successfully, delete the log file @@ -914,7 +914,7 @@ int lsmBlockRefree(lsm_db *pDb, int iBlk){ ** not be held that long (in case it is required by a client flushing an ** in-memory tree to disk). */ -int lsmCheckpointWrite(lsm_db *pDb, int bTruncate, u32 *pnWrite){ +int lsmCheckpointWrite(lsm_db *pDb, u32 *pnWrite){ int rc; /* Return Code */ u32 nWrite = 0; @@ -969,10 +969,6 @@ int lsmCheckpointWrite(lsm_db *pDb, int bTruncate, u32 *pnWrite){ ); #endif } - - if( rc==LSM_OK && bTruncate && nBlock>0 ){ - rc = lsmFsTruncateDb(pDb->pFS, (i64)nBlock*lsmFsBlockSize(pDb->pFS)); - } } lsmShmLock(pDb, LSM_LOCK_CHECKPOINTER, LSM_LOCK_UNLOCK, 0); @@ -1966,7 +1962,7 @@ int lsm_checkpoint(lsm_db *pDb, int *pnKB){ /* Attempt the checkpoint. If successful, nWrite is set to the number of ** pages written between this and the previous checkpoint. */ - rc = lsmCheckpointWrite(pDb, 0, &nWrite); + rc = lsmCheckpointWrite(pDb, &nWrite); /* If required, calculate the output variable (KB of data checkpointed). ** Set it to zero if an error occured. */ diff --git a/manifest b/manifest index 270e42e442..da2b01d60f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings\sin\sthe\score. -D 2017-07-11T18:11:33.473 +C Simplify\sthe\sway\sin\swhich\sthe\sdatabase\sfile\sis\struncated\swhen\sthe\slast\nconnection\sdisconnects.\sAlso\signore\sthe\serror\scode\sfrom\sthe\sxTruncate\scall\s-\nas\struncating\sa\sdatabase\sfile\sis\salways\soptional. +D 2017-07-11T19:55:38.241 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba @@ -236,14 +236,14 @@ F ext/lsm1/lsm-test/lsmtest_tdb4.c 47e8bb5eba266472d690fb8264f1855ebdba0ae5a0e54 F ext/lsm1/lsm-test/lsmtest_util.c 241622db5a332a09c8e6e7606b617d288a37b557f7d3bce0bb97809f67cc2806 F ext/lsm1/lsm-test/lsmtest_win32.c 0e0a224674c4d3170631c41b026b56c7e1672b151f5261e1b4cc19068641da2d F ext/lsm1/lsm.h 0f6f64ff071471cb87bf98beb8386566f30ea001 -F ext/lsm1/lsmInt.h 68945f00c4fc97a5c82bd285a15d0baacd0019cf2e0b7d535759f000459462e1 +F ext/lsm1/lsmInt.h bfa516dca9884de255c6adcb0fc07316770a724d4a52ea6fd54af82a416246b8 F ext/lsm1/lsm_ckpt.c ac6fb4581983291c2e0be6fbb68f12b26f0c08d606835c05417be1323d0fdd03 F ext/lsm1/lsm_file.c d4aee18aeb97d2e91ce30a4b46fa4c7006bca1d5e9f9bb2b7897e30ba8bdf002 F ext/lsm1/lsm_log.c a8bf334532109bba05b09a504ee45fc393828b0d034ca61ab45e3940709d9a7c F ext/lsm1/lsm_main.c 15e73ccdafdd44ddeefc29e332079d88ba8f00c12c797b3c2b63d3171b5afce8 F ext/lsm1/lsm_mem.c 4c51ea9fa285ee6e35301b33491642d071740a0a F ext/lsm1/lsm_mutex.c 378edf0a2b142b4f7640ee982df06d50b98788ea -F ext/lsm1/lsm_shared.c 6b903d1afce9e254b642be7898359b4760afde6fb5740623bae4affff5726ab8 +F ext/lsm1/lsm_shared.c 341c3649575b94a6b1520d50acd540a3ff4036049ee73fbec4e33143ad37f990 F ext/lsm1/lsm_sorted.c a04518dfbfff0171fafb152a46e9fe9f45e1edbf3570e4533dd58ddb6567f0c9 F ext/lsm1/lsm_str.c 65e361b488c87b10bf3e5c0070b14ffc602cf84f094880bece77bbf6678bca82 F ext/lsm1/lsm_tree.c 682679d7ef2b8b6f2fe77aeb532c8d29695bca671c220b0abac77069de5fb9fb @@ -1631,7 +1631,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2fe3a84330063378ca9fc5bfc8efe486c52d50b5c40be4f402a4f2318be69436 -R 5233df6163d8e8ff9a79e293df00de6c -U drh -Z d9b035cf4c291f130c8cdbd2d8e35ec0 +P 55e93f256018757e5e1cb3b10ef48abf5914e7687419eae58b00998a37061261 +R 7c3852771a4c807385128ef5313db6ce +U dan +Z aa49b66b4f30401e0222268e506f5e2a diff --git a/manifest.uuid b/manifest.uuid index 74c8ab24ec..542c6c0865 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -55e93f256018757e5e1cb3b10ef48abf5914e7687419eae58b00998a37061261 \ No newline at end of file +b0a49d90fc91acca1306cf6145adc83acd368686768b7eb4a3b27515b3237396 \ No newline at end of file From 1cd523cf0f5fc0f73adaf84035c3358d4f6eb8d0 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 11 Jul 2017 20:36:35 +0000 Subject: [PATCH 57/64] In lsm, attempt to unmap the database file before truncating it when disconnecting. A mapped file may not be truncated on win32. FossilOrigin-Name: 39069941e98605bc8c7c736819781761760ee2b83363471ceb6f19e5eb06b13a --- ext/lsm1/lsmInt.h | 2 ++ ext/lsm1/lsm_file.c | 11 +++++++++++ ext/lsm1/lsm_shared.c | 2 ++ manifest | 16 ++++++++-------- manifest.uuid | 2 +- 5 files changed, 24 insertions(+), 9 deletions(-) diff --git a/ext/lsm1/lsmInt.h b/ext/lsm1/lsmInt.h index 8e956dbb4c..b346d8dded 100644 --- a/ext/lsm1/lsmInt.h +++ b/ext/lsm1/lsmInt.h @@ -696,6 +696,8 @@ int lsmFsOpenLog(lsm_db *, int *); void lsmFsCloseLog(lsm_db *); void lsmFsClose(FileSystem *); +int lsmFsUnmap(FileSystem *); + int lsmFsConfigure(lsm_db *db); int lsmFsBlockSize(FileSystem *); diff --git a/ext/lsm1/lsm_file.c b/ext/lsm1/lsm_file.c index 7b22051069..3283c023dd 100644 --- a/ext/lsm1/lsm_file.c +++ b/ext/lsm1/lsm_file.c @@ -1150,6 +1150,17 @@ static void fsGrowMapping( } } +/* +** If it is mapped, unmap the database file. +*/ +int lsmFsUnmap(FileSystem *pFS){ + int rc = LSM_OK; + if( pFS ){ + rc = lsmEnvRemap(pFS->pEnv, pFS->fdDb, -1, &pFS->pMap, &pFS->nMap); + } + return rc; +} + /* ** fsync() the database file. */ diff --git a/ext/lsm1/lsm_shared.c b/ext/lsm1/lsm_shared.c index 111b0ddbe7..83e44b4705 100644 --- a/ext/lsm1/lsm_shared.c +++ b/ext/lsm1/lsm_shared.c @@ -312,6 +312,7 @@ static void doDbDisconnect(lsm_db *pDb){ /* The database may only be truncated if there exist no read-only ** clients - either connected or running rotrans transactions. */ if( bReadonly==0 && bRotrans==0 ){ + lsmFsUnmap(pDb->pFS); dbTruncateFile(pDb); if( p->pFile && p->bMultiProc ){ lsmEnvShmUnmap(pDb->pEnv, p->pFile, 1); @@ -568,6 +569,7 @@ void lsmDbDatabaseRelease(lsm_db *pDb){ doDbDisconnect(pDb); } + lsmFsUnmap(pDb->pFS); lsmMutexEnter(pDb->pEnv, p->pClientMutex); for(ppDb=&p->pConn; *ppDb!=pDb; ppDb=&((*ppDb)->pNext)); *ppDb = pDb->pNext; diff --git a/manifest b/manifest index da2b01d60f..0ae649bd1e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplify\sthe\sway\sin\swhich\sthe\sdatabase\sfile\sis\struncated\swhen\sthe\slast\nconnection\sdisconnects.\sAlso\signore\sthe\serror\scode\sfrom\sthe\sxTruncate\scall\s-\nas\struncating\sa\sdatabase\sfile\sis\salways\soptional. -D 2017-07-11T19:55:38.241 +C In\slsm,\sattempt\sto\sunmap\sthe\sdatabase\sfile\sbefore\struncating\sit\swhen\ndisconnecting.\sA\smapped\sfile\smay\snot\sbe\struncated\son\swin32. +D 2017-07-11T20:36:35.268 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba @@ -236,14 +236,14 @@ F ext/lsm1/lsm-test/lsmtest_tdb4.c 47e8bb5eba266472d690fb8264f1855ebdba0ae5a0e54 F ext/lsm1/lsm-test/lsmtest_util.c 241622db5a332a09c8e6e7606b617d288a37b557f7d3bce0bb97809f67cc2806 F ext/lsm1/lsm-test/lsmtest_win32.c 0e0a224674c4d3170631c41b026b56c7e1672b151f5261e1b4cc19068641da2d F ext/lsm1/lsm.h 0f6f64ff071471cb87bf98beb8386566f30ea001 -F ext/lsm1/lsmInt.h bfa516dca9884de255c6adcb0fc07316770a724d4a52ea6fd54af82a416246b8 +F ext/lsm1/lsmInt.h e9e5c5f08e35a104086102b3def94ee69cbc0d39002f6596f5c80a640439628e F ext/lsm1/lsm_ckpt.c ac6fb4581983291c2e0be6fbb68f12b26f0c08d606835c05417be1323d0fdd03 -F ext/lsm1/lsm_file.c d4aee18aeb97d2e91ce30a4b46fa4c7006bca1d5e9f9bb2b7897e30ba8bdf002 +F ext/lsm1/lsm_file.c e50f0e15427513dca4507110d0107268544bcaebb0ff0599a822da1f8d0da9eb F ext/lsm1/lsm_log.c a8bf334532109bba05b09a504ee45fc393828b0d034ca61ab45e3940709d9a7c F ext/lsm1/lsm_main.c 15e73ccdafdd44ddeefc29e332079d88ba8f00c12c797b3c2b63d3171b5afce8 F ext/lsm1/lsm_mem.c 4c51ea9fa285ee6e35301b33491642d071740a0a F ext/lsm1/lsm_mutex.c 378edf0a2b142b4f7640ee982df06d50b98788ea -F ext/lsm1/lsm_shared.c 341c3649575b94a6b1520d50acd540a3ff4036049ee73fbec4e33143ad37f990 +F ext/lsm1/lsm_shared.c 5bc37768e558492f60d7196735ddd54843cd239bd66c1af6eb205a6348ca5e46 F ext/lsm1/lsm_sorted.c a04518dfbfff0171fafb152a46e9fe9f45e1edbf3570e4533dd58ddb6567f0c9 F ext/lsm1/lsm_str.c 65e361b488c87b10bf3e5c0070b14ffc602cf84f094880bece77bbf6678bca82 F ext/lsm1/lsm_tree.c 682679d7ef2b8b6f2fe77aeb532c8d29695bca671c220b0abac77069de5fb9fb @@ -1631,7 +1631,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 55e93f256018757e5e1cb3b10ef48abf5914e7687419eae58b00998a37061261 -R 7c3852771a4c807385128ef5313db6ce +P b0a49d90fc91acca1306cf6145adc83acd368686768b7eb4a3b27515b3237396 +R 02e2bf78e78459dd3983b787a92c6553 U dan -Z aa49b66b4f30401e0222268e506f5e2a +Z 35b0c5fdca1937f85545a9243c607cf9 diff --git a/manifest.uuid b/manifest.uuid index 542c6c0865..6f618d90a4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b0a49d90fc91acca1306cf6145adc83acd368686768b7eb4a3b27515b3237396 \ No newline at end of file +39069941e98605bc8c7c736819781761760ee2b83363471ceb6f19e5eb06b13a \ No newline at end of file From f0f44b79c90682a35621baad331468443dcf7134 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 12 Jul 2017 12:19:33 +0000 Subject: [PATCH 58/64] Compile cleanly with SQLITE_OMIT_UTF16. FossilOrigin-Name: 783100b801703577e35ec12fe7623e1797e49699f3b8deb0694ef061a142b844 --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/loadext.c | 1 + src/sqliteInt.h | 4 ++++ src/utf.c | 2 ++ src/vdbeInt.h | 6 ++++-- 6 files changed, 22 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 0ae649bd1e..0c065d61a1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\slsm,\sattempt\sto\sunmap\sthe\sdatabase\sfile\sbefore\struncating\sit\swhen\ndisconnecting.\sA\smapped\sfile\smay\snot\sbe\struncated\son\swin32. -D 2017-07-11T20:36:35.268 +C Compile\scleanly\swith\sSQLITE_OMIT_UTF16. +D 2017-07-12T12:19:33.990 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba @@ -413,7 +413,7 @@ F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c bb70abf32c7c926745eb550938db9132309584a667a44c2db0e5fa3207600391 F src/legacy.c 134ab3e3fae00a0f67a5187981d6935b24b337bcf0f4b3e5c9fa5763da95bf4e -F src/loadext.c 83fc9858b19ffe4b7191f5d0bfa9111896af9d7dff55367edc92e6720511108e +F src/loadext.c 15e458a122bccef49850cc1d6b69802040ea3f9022e564a125faf599354fe050 F src/main.c 20574bb9a0d7911efcd659ac252f2126dc4e3308bed3c8764ea3fb5a00f70420 F src/malloc.c e20bb2b48abec52d3faf01cce12e8b4f95973755fafec98d45162dfdab111978 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 @@ -455,7 +455,7 @@ F src/shell.c.in 98bfdeeb0808418b37f59e6d380568a76e0733efe2494377096f434b39940ca F src/sqlite.h.in 03a422ba13da1dfef7f1aaa1ba344acf18dc867112620b1fdb2a1426cabba634 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 5539ec41f3d81890d626d5a845b08c82bd0e946ddc5c1c341144b700bc56101e -F src/sqliteInt.h c9cc829906fc9c95444c6c3b4a7dbf8eac39af15cde5582e869ae5c9b4eebef9 +F src/sqliteInt.h 23e96647425bcda6afeeed945d1c706a8424098ba1c1d37976228ede0a60af53 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -514,12 +514,12 @@ F src/tokenize.c 1003d6d90c6783206c711f0a9397656fa5b055209f4d092caa43bb3bf5215db F src/treeview.c 2ee4a5dada213d5ab08a742af5c876cee6f1aaae65f10a61923f3fb63846afef F src/trigger.c d1cae560bfacc8bfb3a072d73658245c1714c0389097da69b4cb23877a082d7e F src/update.c c443935c652af9365e033f756550b5032d02e1b06eb2cb890ed7511ae0c051dc -F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c +F src/utf.c 810fbfebe12359f10bc2a011520a6e10879ab2a163bcb26c74768eab82ea62a5 F src/util.c fc081ec6f63448dcd80d3dfad35baecfa104823254a815b081a4d9fe76e1db23 F src/vacuum.c 874c0f2f15ab2908748297d587d22d485ea96d55aaec91d4775dddb2e24d2ecf F src/vdbe.c adc8a378710ec2376101483cc8a5f499539ee9bbebfb2a784f3370704d5d44ad F src/vdbe.h dde459b1e8a02b8445ecfd5959f38cd5ebb6b0ad392d491d8b159ac8193d231a -F src/vdbeInt.h 8dd7548d86a98b77b6ed910d8014d0e9e0666356b56f3d16ab7063aad4f102f5 +F src/vdbeInt.h c8b3d97001a7bab5cdf71927fc813869d95263160e67ba2ef78a32d7538f159d F src/vdbeapi.c 899d8f021c89ab348708b3a9b00b855f5ecc3c0f949a75359a61a3c621021281 F src/vdbeaux.c 6f01fe8a49b801cc7734ccfc61d1b782131ee3bb7ee28e336f3c73474800f8f9 F src/vdbeblob.c 359891617358deefc85bef7bcf787fa6b77facb9 @@ -1631,7 +1631,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b0a49d90fc91acca1306cf6145adc83acd368686768b7eb4a3b27515b3237396 -R 02e2bf78e78459dd3983b787a92c6553 -U dan -Z 35b0c5fdca1937f85545a9243c607cf9 +P 39069941e98605bc8c7c736819781761760ee2b83363471ceb6f19e5eb06b13a +R 6c08473ae2deed66303e72a4ddd28537 +U drh +Z 1abdfc4df47c311bf1af13a17928c267 diff --git a/manifest.uuid b/manifest.uuid index 6f618d90a4..2cf2753188 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -39069941e98605bc8c7c736819781761760ee2b83363471ceb6f19e5eb06b13a \ No newline at end of file +783100b801703577e35ec12fe7623e1797e49699f3b8deb0694ef061a142b844 \ No newline at end of file diff --git a/src/loadext.c b/src/loadext.c index 47efc11f0c..b1f1b03e35 100644 --- a/src/loadext.c +++ b/src/loadext.c @@ -51,6 +51,7 @@ # define sqlite3_open16 0 # define sqlite3_prepare16 0 # define sqlite3_prepare16_v2 0 +# define sqlite3_prepare16_v3 0 # define sqlite3_result_error16 0 # define sqlite3_result_text16 0 # define sqlite3_result_text16be 0 diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 2e18b8cc93..5f7ad50cc4 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3925,7 +3925,9 @@ int sqlite3FixTriggerStep(DbFixer*, TriggerStep*); int sqlite3AtoF(const char *z, double*, int, u8); int sqlite3GetInt32(const char *, int*); int sqlite3Atoi(const char*); +#ifndef SQLITE_OMIT_UTF16 int sqlite3Utf16ByteLen(const void *pData, int nChar); +#endif int sqlite3Utf8CharLen(const char *pData, int nByte); u32 sqlite3Utf8Read(const u8**); LogEst sqlite3LogEst(u64); @@ -4014,7 +4016,9 @@ void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, void sqlite3ValueSetNull(sqlite3_value*); void sqlite3ValueFree(sqlite3_value*); sqlite3_value *sqlite3ValueNew(sqlite3 *); +#ifndef SQLITE_OMIT_UTF16 char *sqlite3Utf16to8(sqlite3 *, const void*, int, u8); +#endif int sqlite3ValueFromExpr(sqlite3 *, Expr *, u8, u8, sqlite3_value **); void sqlite3ValueApplyAffinity(sqlite3_value *, u8, u8); #ifndef SQLITE_AMALGAMATION diff --git a/src/utf.c b/src/utf.c index 7801306cb4..4b04c9e282 100644 --- a/src/utf.c +++ b/src/utf.c @@ -332,7 +332,9 @@ translate_out: #endif return SQLITE_OK; } +#endif /* SQLITE_OMIT_UTF16 */ +#ifndef SQLITE_OMIT_UTF16 /* ** This routine checks for a byte-order mark at the beginning of the ** UTF-16 string stored in *pMem. If one is present, it is removed and diff --git a/src/vdbeInt.h b/src/vdbeInt.h index d8e899b0af..1789c83227 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -534,12 +534,14 @@ int sqlite3VdbeCheckFk(Vdbe *, int); # define sqlite3VdbeCheckFk(p,i) 0 #endif -int sqlite3VdbeMemTranslate(Mem*, u8); #ifdef SQLITE_DEBUG void sqlite3VdbePrintSql(Vdbe*); void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf); #endif -int sqlite3VdbeMemHandleBom(Mem *pMem); +#ifndef SQLITE_OMIT_UTF16 + int sqlite3VdbeMemTranslate(Mem*, u8); + int sqlite3VdbeMemHandleBom(Mem *pMem); +#endif #ifndef SQLITE_OMIT_INCRBLOB int sqlite3VdbeMemExpandBlob(Mem *); From 47ebd4caddfe9745289d051e57348c7bebf7a1a5 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 12 Jul 2017 14:03:13 +0000 Subject: [PATCH 59/64] Fix a problem in an lsmtest test case caused by writing data in "text" mode instead of "binary". FossilOrigin-Name: 3e56a79ad8754e6da3181883154fa1c8b227a8d16c9b2a3eba925371595ae1f9 --- ext/lsm1/lsm-test/lsmtest8.c | 82 ++++++++++++++++++------------------ manifest | 14 +++--- manifest.uuid | 2 +- 3 files changed, 50 insertions(+), 48 deletions(-) diff --git a/ext/lsm1/lsm-test/lsmtest8.c b/ext/lsm1/lsm-test/lsmtest8.c index dfc4cae069..f734ac6aba 100644 --- a/ext/lsm1/lsm-test/lsmtest8.c +++ b/ext/lsm1/lsm-test/lsmtest8.c @@ -85,7 +85,7 @@ static void setupDatabase1(TestDb *pDb, Datasource **ppData){ void testReadFile(const char *zFile, int iOff, void *pOut, int nByte, int *pRc){ if( *pRc==0 ){ FILE *fd; - fd = fopen(zFile, "r"); + fd = fopen(zFile, "rb"); if( fd==0 ){ *pRc = 1; }else{ @@ -111,7 +111,7 @@ void testWriteFile( ){ if( *pRc==0 ){ FILE *fd; - fd = fopen(zFile, "r+"); + fd = fopen(zFile, "r+b"); if( fd==0 ){ *pRc = 1; }else{ @@ -157,50 +157,52 @@ static ShmHeader *getShmHeader(const char *zDb){ ** 5) Check once more that the checksum is still zCksum. */ static void doLiveRecovery(const char *zDb, const char *zCksum, int *pRc){ - const DatasourceDefn defn = {TEST_DATASOURCE_RANDOM, 20, 25, 100, 500}; - Datasource *pData; - const char *zCopy = "testcopy.lsm"; - char zCksum2[TEST_CKSUM_BYTES]; - TestDb *pDb = 0; - int rc; + if( *pRc==LSM_OK ){ + const DatasourceDefn defn = {TEST_DATASOURCE_RANDOM, 20, 25, 100, 500}; + Datasource *pData; + const char *zCopy = "testcopy.lsm"; + char zCksum2[TEST_CKSUM_BYTES]; + TestDb *pDb = 0; + int rc; - pData = testDatasourceNew(&defn); - - testCopyLsmdb(zDb, zCopy); - rc = tdb_lsm_open("test_no_recovery=1", zCopy, 0, &pDb); - if( rc==0 ){ - ShmHeader *pHdr; - lsm_db *db; - testCksumDatabase(pDb, zCksum2); - testCompareStr(zCksum, zCksum2, &rc); - - testWriteDatasourceRange(pDb, pData, 1, 10, &rc); - testDeleteDatasourceRange(pDb, pData, 1, 10, &rc); - - /* Test that the two tree-headers are now consistent. */ - pHdr = getShmHeader(zCopy); - if( rc==0 && memcmp(&pHdr->hdr1, &pHdr->hdr2, sizeof(pHdr->hdr1)) ){ - rc = 1; - } - testFree(pHdr); + pData = testDatasourceNew(&defn); + testCopyLsmdb(zDb, zCopy); + rc = tdb_lsm_open("test_no_recovery=1", zCopy, 0, &pDb); if( rc==0 ){ - int nBuf = 64; - db = tdb_lsm(pDb); - lsm_config(db, LSM_CONFIG_AUTOFLUSH, &nBuf); - lsm_begin(db, 1); - lsm_commit(db, 0); - rc = lsm_work(db, 0, 0, 0); + ShmHeader *pHdr; + lsm_db *db; + testCksumDatabase(pDb, zCksum2); + testCompareStr(zCksum, zCksum2, &rc); + + testWriteDatasourceRange(pDb, pData, 1, 10, &rc); + testDeleteDatasourceRange(pDb, pData, 1, 10, &rc); + + /* Test that the two tree-headers are now consistent. */ + pHdr = getShmHeader(zCopy); + if( rc==0 && memcmp(&pHdr->hdr1, &pHdr->hdr2, sizeof(pHdr->hdr1)) ){ + rc = 1; + } + testFree(pHdr); + + if( rc==0 ){ + int nBuf = 64; + db = tdb_lsm(pDb); + lsm_config(db, LSM_CONFIG_AUTOFLUSH, &nBuf); + lsm_begin(db, 1); + lsm_commit(db, 0); + rc = lsm_work(db, 0, 0, 0); + } + + testCksumDatabase(pDb, zCksum2); + testCompareStr(zCksum, zCksum2, &rc); } - testCksumDatabase(pDb, zCksum2); - testCompareStr(zCksum, zCksum2, &rc); + testDatasourceFree(pData); + testClose(&pDb); + testDeleteLsmdb(zCopy); + *pRc = rc; } - - testDatasourceFree(pData); - testClose(&pDb); - testDeleteLsmdb(zCopy); - *pRc = rc; } static void doWriterCrash1(int *pRc){ diff --git a/manifest b/manifest index 0c065d61a1..4b1e3ec1f8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Compile\scleanly\swith\sSQLITE_OMIT_UTF16. -D 2017-07-12T12:19:33.990 +C Fix\sa\sproblem\sin\san\slsmtest\stest\scase\scaused\sby\swriting\sdata\sin\s"text"\smode\ninstead\sof\s"binary". +D 2017-07-12T14:03:13.542 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba @@ -220,7 +220,7 @@ F ext/lsm1/lsm-test/lsmtest4.c d258d6a245db5d8eaede096e2368d23f859c5e92c80ab9122 F ext/lsm1/lsm-test/lsmtest5.c 8d5242a0f870d65eeada191c8945781fed9cb8ece3886573790ebd373b62dac5 F ext/lsm1/lsm-test/lsmtest6.c 869cb4a172cd07d1a75b3aeaecd61d0a477787b3b8668bad0d3ff0f43b642b7c F ext/lsm1/lsm-test/lsmtest7.c 7a917455a0f956a8ed3f44f5c9387ec0ea6627714874464cc3fa5c5a9cabb2f2 -F ext/lsm1/lsm-test/lsmtest8.c ab8c30c08540c7cd21e32b678e6c7090ae138c00faf84fdd0ba517361b710861 +F ext/lsm1/lsm-test/lsmtest8.c 589b68c44531a0f04d5e879bb1e211be5f7100f48eed7e8631e07ed5cbd68f94 F ext/lsm1/lsm-test/lsmtest9.c dd1a0ebf41134933a744d1e00e60429a2a21fc50d587ae7dd6bdb6e96d805bdc F ext/lsm1/lsm-test/lsmtest_bt.c d70d9a9be5eef9360af1251dd083948d74fd30137a08f61bef995f7ac04e037f F ext/lsm1/lsm-test/lsmtest_datasource.c 5d770be191d0ca51315926723009b2c25c0b4b8136840494ef710ac324aa916c @@ -1631,7 +1631,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 39069941e98605bc8c7c736819781761760ee2b83363471ceb6f19e5eb06b13a -R 6c08473ae2deed66303e72a4ddd28537 -U drh -Z 1abdfc4df47c311bf1af13a17928c267 +P 783100b801703577e35ec12fe7623e1797e49699f3b8deb0694ef061a142b844 +R ab6ba7417c8ef7732b2a8b211358e460 +U dan +Z df42a5b7a8146f5aa8e5ac6a01bf086c diff --git a/manifest.uuid b/manifest.uuid index 2cf2753188..def91d9740 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -783100b801703577e35ec12fe7623e1797e49699f3b8deb0694ef061a142b844 \ No newline at end of file +3e56a79ad8754e6da3181883154fa1c8b227a8d16c9b2a3eba925371595ae1f9 \ No newline at end of file From ec360a8d01bb445fd6bdad301bf636982e1180a3 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 12 Jul 2017 14:10:19 +0000 Subject: [PATCH 60/64] Clarification and simplification and result column naming logic. FossilOrigin-Name: 68824a439b76a4cca05609a02de7abdc42bd1d26afbfcd047b90001c610d3c56 --- manifest | 14 +++++----- manifest.uuid | 2 +- src/select.c | 71 ++++++++++++++++++++++++++++++++++++--------------- 3 files changed, 59 insertions(+), 28 deletions(-) diff --git a/manifest b/manifest index 4b1e3ec1f8..30988f4ae9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\sin\san\slsmtest\stest\scase\scaused\sby\swriting\sdata\sin\s"text"\smode\ninstead\sof\s"binary". -D 2017-07-12T14:03:13.542 +C Clarification\sand\ssimplification\sand\sresult\scolumn\snaming\slogic. +D 2017-07-12T14:10:19.869 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba @@ -449,7 +449,7 @@ F src/printf.c 8757834f1b54dae512fb25eb1acc8e94a0d15dd2290b58f2563f65973265adb2 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 6aa1fb1212e601f65b983ee1215d69a591986c8f97a3805c425c625a53839539 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac -F src/select.c 6aa7e8ee53dcb9d0b77b05670bb44a1076d6747bc9b2c1f12a365b553ab6c828 +F src/select.c 95659b7990e390f9bd8dc30b8975c675fcd1d46e569bc4f5a14e22a8d03e3d14 F src/shell.c 0401a716fc5343594b8ee60ce065d9a71373d3403f0b81f9fed684741e6401d1 F src/shell.c.in 98bfdeeb0808418b37f59e6d380568a76e0733efe2494377096f434b39940cad F src/sqlite.h.in 03a422ba13da1dfef7f1aaa1ba344acf18dc867112620b1fdb2a1426cabba634 @@ -1631,7 +1631,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 783100b801703577e35ec12fe7623e1797e49699f3b8deb0694ef061a142b844 -R ab6ba7417c8ef7732b2a8b211358e460 -U dan -Z df42a5b7a8146f5aa8e5ac6a01bf086c +P 3e56a79ad8754e6da3181883154fa1c8b227a8d16c9b2a3eba925371595ae1f9 +R 262c8bdac1ac6c4d0dad5be8958ad15e +U drh +Z 4894df80f0f6930b7360c2bd22600907 diff --git a/manifest.uuid b/manifest.uuid index def91d9740..e1c60e2626 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3e56a79ad8754e6da3181883154fa1c8b227a8d16c9b2a3eba925371595ae1f9 \ No newline at end of file +68824a439b76a4cca05609a02de7abdc42bd1d26afbfcd047b90001c610d3c56 \ No newline at end of file diff --git a/src/select.c b/src/select.c index bb6f68221b..b9afc46537 100644 --- a/src/select.c +++ b/src/select.c @@ -1568,20 +1568,46 @@ static Table *tableWithCursor(SrcList *pList, int iCursor){ /* -** Generate code that will tell the VDBE the names of columns -** in the result set. This information is used to provide the -** azCol[] values in the callback. +** Compute the column names for a SELECT statement. +** +** The only guarantee that SQLite makes about column names is that if the +** column has an AS clause assigning it a name, that will be the name used. +** That is the only documented guarantee. However, countless applications +** developed over the years have made baseless assumptions about column names +** and will break if those assumptions changes. Hence, use extreme caution +** when modifying this routine to avoid breaking legacy. +** +** See Also: sqlite3ColumnsFromExprList() +** +** The PRAGMA short_column_names and PRAGMA full_column_names settings are +** deprecated. The default setting is short=ON, full=OFF. 99.9% of all +** applications should operate this way. Nevertheless, we need to support the +** other modes for legacy: +** +** short=OFF, full=OFF: Column name is the text of the expression has it +** originally appears in the SELECT statement. In +** other words, the zSpan of the result expression. +** +** short=ON, full=OFF: (This is the default setting). If the result +** refers directly to a table column, then the result +** column name is just the table column name: COLUMN. +** Otherwise use zSpan. +** +** full=ON, short=ANY: If the result refers directly to a table column, +** then the result column name with the table name +** prefix, ex: TABLE.COLUMN. Otherwise use zSpan. */ static void generateColumnNames( Parse *pParse, /* Parser context */ - SrcList *pTabList, /* List of tables */ + SrcList *pTabList, /* The FROM clause of the SELECT */ ExprList *pEList /* Expressions defining the result set */ ){ Vdbe *v = pParse->pVdbe; int i; Table *pTab; sqlite3 *db = pParse->db; - int fullNames, shortNames; + int fullName; /* TABLE.COLUMN if no AS clause and is a direct table ref */ + int srcName; /* COLUMN or TABLE.COLUMN if no AS clause and is direct */ #ifndef SQLITE_OMIT_EXPLAIN /* If this is an EXPLAIN, skip this step */ @@ -1594,17 +1620,19 @@ static void generateColumnNames( assert( v!=0 ); assert( pTabList!=0 ); pParse->colNamesSet = 1; - fullNames = (db->flags & SQLITE_FullColNames)!=0; - shortNames = (db->flags & SQLITE_ShortColNames)!=0; + fullName = (db->flags & SQLITE_FullColNames)!=0; + srcName = (db->flags & SQLITE_ShortColNames)!=0 || fullName; sqlite3VdbeSetNumCols(v, pEList->nExpr); for(i=0; inExpr; i++){ - Expr *p; - p = pEList->a[i].pExpr; - if( NEVER(p==0) ) continue; + Expr *p = pEList->a[i].pExpr; + + assert( p!=0 ); if( pEList->a[i].zName ){ + /* An AS clause always takes first priority */ char *zName = pEList->a[i].zName; sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_TRANSIENT); - }else if( (p->op==TK_COLUMN || p->op==TK_AGG_COLUMN) + }else if( srcName + && (p->op==TK_COLUMN || p->op==TK_AGG_COLUMN) && (pTab = tableWithCursor(pTabList, p->iTable))!=0 ){ char *zCol; @@ -1616,10 +1644,7 @@ static void generateColumnNames( }else{ zCol = pTab->aCol[iCol].zName; } - if( !shortNames && !fullNames ){ - sqlite3VdbeSetColName(v, i, COLNAME_NAME, - sqlite3DbStrDup(db, pEList->a[i].zSpan), SQLITE_DYNAMIC); - }else if( fullNames ){ + if( fullName ){ char *zName = 0; zName = sqlite3MPrintf(db, "%s.%s", pTab->zName, zCol); sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_DYNAMIC); @@ -1647,6 +1672,15 @@ static void generateColumnNames( ** ** Return SQLITE_OK on success. If a memory allocation error occurs, ** store NULL in *paCol and 0 in *pnCol and return SQLITE_NOMEM. +** +** The only guarantee that SQLite makes about column names is that if the +** column has an AS clause assigning it a name, that will be the name used. +** That is the only documented guarantee. However, countless applications +** developed over the years have made baseless assumptions about column names +** and will break if those assumptions changes. Hence, use extreme caution +** when modifying this routine to avoid breaking legacy. +** +** See Also: generateColumnNames() */ int sqlite3ColumnsFromExprList( Parse *pParse, /* Parsing context */ @@ -1659,7 +1693,6 @@ int sqlite3ColumnsFromExprList( u32 cnt; /* Index added to make the name unique */ Column *aCol, *pCol; /* For looping over result columns */ int nCol; /* Number of columns in the result set */ - Expr *p; /* Expression for a single result column */ char *zName; /* Column name */ int nName; /* Size of name in zName[] */ Hash ht; /* Hash table of column names */ @@ -1680,12 +1713,10 @@ int sqlite3ColumnsFromExprList( for(i=0, pCol=aCol; imallocFailed; i++, pCol++){ /* Get an appropriate name for the column */ - p = sqlite3ExprSkipCollate(pEList->a[i].pExpr); if( (zName = pEList->a[i].zName)!=0 ){ /* If the column contains an "AS " phrase, use as the name */ }else{ - Expr *pColExpr = p; /* The expression that is the result column name */ - Table *pTab; /* Table associated with this expression */ + Expr *pColExpr = sqlite3ExprSkipCollate(pEList->a[i].pExpr); while( pColExpr->op==TK_DOT ){ pColExpr = pColExpr->pRight; assert( pColExpr!=0 ); @@ -1693,7 +1724,7 @@ int sqlite3ColumnsFromExprList( if( pColExpr->op==TK_COLUMN && pColExpr->pTab!=0 ){ /* For columns use the column name name */ int iCol = pColExpr->iColumn; - pTab = pColExpr->pTab; + Table *pTab = pColExpr->pTab; if( iCol<0 ) iCol = pTab->iPKey; zName = iCol>=0 ? pTab->aCol[iCol].zName : "rowid"; }else if( pColExpr->op==TK_ID ){ From 971ecd7eaa1d3fe923b4dea45a896224f2169a1d Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 12 Jul 2017 17:08:24 +0000 Subject: [PATCH 61/64] The EP_Resolved flag on the Expr object is not required for correctness nor performance, so remove it. FossilOrigin-Name: 54f55d3b7973e326541a81bfb2e752a2f6618e4fec9a3631b95f28e12e9c6e34 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/parse.y | 2 +- src/resolve.c | 3 --- src/sqliteInt.h | 2 +- 5 files changed, 11 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 30988f4ae9..bc847efddf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Clarification\sand\ssimplification\sand\sresult\scolumn\snaming\slogic. -D 2017-07-12T14:10:19.869 +C The\sEP_Resolved\sflag\son\sthe\sExpr\sobject\sis\snot\srequired\sfor\scorrectness\snor\nperformance,\sso\sremove\sit. +D 2017-07-12T17:08:24.323 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba @@ -438,7 +438,7 @@ F src/os_win.c 2a6c73eef01c51a048cc4ddccd57f981afbec18a F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c 14f6982c470c05b8e85575c69e9c1712010602e20400f8670d8699e21283e0e4 F src/pager.h f2a99646c5533ffe11afa43e9e0bea74054e4efa -F src/parse.y 71bf06b02f567232deabe258641b03e833e93c4dee61a120765ad74c13e7faec +F src/parse.y 213fda2ad805126eed9b960f2acc68580776f897f54b0db488b7f1d2f79589a8 F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870 F src/pcache.h 521bb9610d38ef17a3cc9b5ddafd4546c2ea67fa3d0e464823d73c2a28d50e11 F src/pcache1.c 1195a21fe28e223e024f900b2011e80df53793f0356a24caace4188b098540dc @@ -447,7 +447,7 @@ F src/pragma.h bb83728944b42f6d409c77f5838a8edbdb0fe83046c5496ffc9602b40340a324 F src/prepare.c 4b84ae7458febe1df3e04ae62ba56abc851f771340e460d14426e6802c5615f4 F src/printf.c 8757834f1b54dae512fb25eb1acc8e94a0d15dd2290b58f2563f65973265adb2 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 -F src/resolve.c 6aa1fb1212e601f65b983ee1215d69a591986c8f97a3805c425c625a53839539 +F src/resolve.c 4324a94573b1e29286f8121e4881db59eaedc014afeb274c8d3e07ed282e0e20 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c 95659b7990e390f9bd8dc30b8975c675fcd1d46e569bc4f5a14e22a8d03e3d14 F src/shell.c 0401a716fc5343594b8ee60ce065d9a71373d3403f0b81f9fed684741e6401d1 @@ -455,7 +455,7 @@ F src/shell.c.in 98bfdeeb0808418b37f59e6d380568a76e0733efe2494377096f434b39940ca F src/sqlite.h.in 03a422ba13da1dfef7f1aaa1ba344acf18dc867112620b1fdb2a1426cabba634 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 5539ec41f3d81890d626d5a845b08c82bd0e946ddc5c1c341144b700bc56101e -F src/sqliteInt.h 23e96647425bcda6afeeed945d1c706a8424098ba1c1d37976228ede0a60af53 +F src/sqliteInt.h 0ba730cdc8afa723a5642380712f8bb33abd6a69218571c18b94acf3562de22a F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -1631,7 +1631,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3e56a79ad8754e6da3181883154fa1c8b227a8d16c9b2a3eba925371595ae1f9 -R 262c8bdac1ac6c4d0dad5be8958ad15e +P 68824a439b76a4cca05609a02de7abdc42bd1d26afbfcd047b90001c610d3c56 +R 7be666c6b54b174db8f6783afda432a3 U drh -Z 4894df80f0f6930b7360c2bd22600907 +Z 215d37529409d33306bee9f0e8fb9f75 diff --git a/manifest.uuid b/manifest.uuid index e1c60e2626..8fa13dc9c2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -68824a439b76a4cca05609a02de7abdc42bd1d26afbfcd047b90001c610d3c56 \ No newline at end of file +54f55d3b7973e326541a81bfb2e752a2f6618e4fec9a3631b95f28e12e9c6e34 \ No newline at end of file diff --git a/src/parse.y b/src/parse.y index dc8cff84be..52bc87f22f 100644 --- a/src/parse.y +++ b/src/parse.y @@ -898,7 +898,7 @@ term(A) ::= INTEGER(X). { A.pExpr = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &X, 1); A.zStart = X.z; A.zEnd = X.z + X.n; - if( A.pExpr ) A.pExpr->flags |= EP_Leaf|EP_Resolved; + if( A.pExpr ) A.pExpr->flags |= EP_Leaf; } expr(A) ::= VARIABLE(X). { if( !(X.z[0]=='#' && sqlite3Isdigit(X.z[1])) ){ diff --git a/src/resolve.c b/src/resolve.c index b13786f4df..78f37512a2 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -517,7 +517,6 @@ Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSrc, int iCol){ testcase( iCol==BMS-1 ); pItem->colUsed |= ((Bitmask)1)<<(iCol>=BMS ? BMS-1 : iCol); } - ExprSetProperty(p, EP_Resolved); } return p; } @@ -577,8 +576,6 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ pParse = pNC->pParse; assert( pParse==pWalker->pParse ); - if( ExprHasProperty(pExpr, EP_Resolved) ) return WRC_Prune; - ExprSetProperty(pExpr, EP_Resolved); #ifndef NDEBUG if( pNC->pSrcList && pNC->pSrcList->nAlloc>0 ){ SrcList *pSrcList = pNC->pSrcList; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 5f7ad50cc4..e0c569825b 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2372,7 +2372,7 @@ struct Expr { */ #define EP_FromJoin 0x000001 /* Originates in ON/USING clause of outer join */ #define EP_Agg 0x000002 /* Contains one or more aggregate functions */ -#define EP_Resolved 0x000004 /* IDs have been resolved to COLUMNs */ + /* 0x000004 // available for use */ /* 0x000008 // available for use */ #define EP_Distinct 0x000010 /* Aggregate function with DISTINCT keyword */ #define EP_VarSelect 0x000020 /* pSelect is correlated, not constant */ From 980a89e630dc01043a9e855ffc81e69ca3410f73 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 12 Jul 2017 17:26:44 +0000 Subject: [PATCH 62/64] Remove unnecessary EP_Leaf settings on the Expr object. FossilOrigin-Name: f951c8b71b2369da62a329c792af5e3d3087bbe020f38c68ca1d0a594b904c08 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/parse.y | 6 ++---- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index bc847efddf..dc1582b064 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\sEP_Resolved\sflag\son\sthe\sExpr\sobject\sis\snot\srequired\sfor\scorrectness\snor\nperformance,\sso\sremove\sit. -D 2017-07-12T17:08:24.323 +C Remove\sunnecessary\sEP_Leaf\ssettings\son\sthe\sExpr\sobject. +D 2017-07-12T17:26:44.723 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba @@ -438,7 +438,7 @@ F src/os_win.c 2a6c73eef01c51a048cc4ddccd57f981afbec18a F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c 14f6982c470c05b8e85575c69e9c1712010602e20400f8670d8699e21283e0e4 F src/pager.h f2a99646c5533ffe11afa43e9e0bea74054e4efa -F src/parse.y 213fda2ad805126eed9b960f2acc68580776f897f54b0db488b7f1d2f79589a8 +F src/parse.y e384cb73f99e1b074085c974b37f4d830e885359e4b60837e30f7d67c16ba65b F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870 F src/pcache.h 521bb9610d38ef17a3cc9b5ddafd4546c2ea67fa3d0e464823d73c2a28d50e11 F src/pcache1.c 1195a21fe28e223e024f900b2011e80df53793f0356a24caace4188b098540dc @@ -1631,7 +1631,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 68824a439b76a4cca05609a02de7abdc42bd1d26afbfcd047b90001c610d3c56 -R 7be666c6b54b174db8f6783afda432a3 +P 54f55d3b7973e326541a81bfb2e752a2f6618e4fec9a3631b95f28e12e9c6e34 +R 10e100e27df0df45b8129ca115b68f3d U drh -Z 215d37529409d33306bee9f0e8fb9f75 +Z e95f877e9262c0f435291a075b3e65bf diff --git a/manifest.uuid b/manifest.uuid index 8fa13dc9c2..c8a97e3513 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -54f55d3b7973e326541a81bfb2e752a2f6618e4fec9a3631b95f28e12e9c6e34 \ No newline at end of file +f951c8b71b2369da62a329c792af5e3d3087bbe020f38c68ca1d0a594b904c08 \ No newline at end of file diff --git a/src/parse.y b/src/parse.y index 52bc87f22f..129686ad57 100644 --- a/src/parse.y +++ b/src/parse.y @@ -875,7 +875,6 @@ idlist(A) ::= nm(Y). expr(A) ::= term(A). expr(A) ::= LP(B) expr(X) RP(E). {spanSet(&A,&B,&E); /*A-overwrites-B*/ A.pExpr = X.pExpr;} -term(A) ::= NULL(X). {spanExpr(&A,pParse,@X,X);/*A-overwrites-X*/} expr(A) ::= id(X). {spanExpr(&A,pParse,TK_ID,X); /*A-overwrites-X*/} expr(A) ::= JOIN_KW(X). {spanExpr(&A,pParse,TK_ID,X); /*A-overwrites-X*/} expr(A) ::= nm(X) DOT nm(Y). { @@ -892,13 +891,12 @@ expr(A) ::= nm(X) DOT nm(Y) DOT nm(Z). { spanSet(&A,&X,&Z); /*A-overwrites-X*/ A.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp4); } -term(A) ::= FLOAT|BLOB(X). {spanExpr(&A,pParse,@X,X);/*A-overwrites-X*/} -term(A) ::= STRING(X). {spanExpr(&A,pParse,@X,X);/*A-overwrites-X*/} +term(A) ::= NULL|FLOAT|BLOB(X). {spanExpr(&A,pParse,@X,X); /*A-overwrites-X*/} +term(A) ::= STRING(X). {spanExpr(&A,pParse,@X,X); /*A-overwrites-X*/} term(A) ::= INTEGER(X). { A.pExpr = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &X, 1); A.zStart = X.z; A.zEnd = X.z + X.n; - if( A.pExpr ) A.pExpr->flags |= EP_Leaf; } expr(A) ::= VARIABLE(X). { if( !(X.z[0]=='#' && sqlite3Isdigit(X.z[1])) ){ From 7ccf95dbab421130f0b10de267798c96ed472018 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 12 Jul 2017 18:05:54 +0000 Subject: [PATCH 63/64] Fix harmless compiler warnings about incomplete structure initializers. FossilOrigin-Name: 604c11d1a39f09e47b6fcee0f8b1c1054f9dbbc7b2c1cf93312aeaa4b7095018 --- ext/misc/stmt.c | 3 +++ manifest | 14 +++++++------- manifest.uuid | 2 +- src/dbstat.c | 3 +++ 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/ext/misc/stmt.c b/ext/misc/stmt.c index a74e6b877c..b06191e938 100644 --- a/ext/misc/stmt.c +++ b/ext/misc/stmt.c @@ -285,6 +285,9 @@ static sqlite3_module stmtModule = { 0, /* xRollback */ 0, /* xFindMethod */ 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ }; #endif /* SQLITE_OMIT_VIRTUALTABLE */ diff --git a/manifest b/manifest index dc1582b064..cddf48e329 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sunnecessary\sEP_Leaf\ssettings\son\sthe\sExpr\sobject. -D 2017-07-12T17:26:44.723 +C Fix\sharmless\scompiler\swarnings\sabout\sincomplete\sstructure\sinitializers. +D 2017-07-12T18:05:54.577 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba @@ -277,7 +277,7 @@ F ext/misc/sha1.c 0b9e9b855354910d3ca467bf39099d570e73db56 F ext/misc/shathree.c fa185d7aee0ad0aca5e091b4a2db7baff11796170e5793b5de99e511a13af448 F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 F ext/misc/spellfix.c a4723b6aff748a417b5091b68a46443265c40f0d -F ext/misc/stmt.c e517a1e3e0075e17f3bb274544439db91f121e714da4a0f19f7c9693c20c3fcf +F ext/misc/stmt.c de7f8e172b319f9f708bd31b15a048e31dc4f73639454fe23a6b31bf8a7ea1d6 F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512 F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95 F ext/misc/vfsstat.c bf10ef0bc51e1ad6756629e1edb142f7a8db1178 @@ -400,7 +400,7 @@ F src/callback.c 8e14b60d1ed1c87c02cb5f121ecda99224f2aea6524a77ee6f72c9b5c7110f8 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 928954802b1397d9fb1378c7eb702c94b4735bbab1d5793e21b6a77734f56a1b F src/date.c cc42a41c7422389860d40419a5e3bce5eaf6e7835c3ba2677751dc653550a5c7 -F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d +F src/dbstat.c 7a4ba8518b6369ef3600c49cf9c918ad979acba610b2aebef1b656d649b96720 F src/delete.c 3213547e97b676c6fa79948b7a9ede4801ea04a01a2043241deafedf132ecf5d F src/expr.c f3f0f7a1a8f91e980244152e9e0263144a9db862e715a80c70422faa2fde4f2f F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 @@ -1631,7 +1631,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 54f55d3b7973e326541a81bfb2e752a2f6618e4fec9a3631b95f28e12e9c6e34 -R 10e100e27df0df45b8129ca115b68f3d +P f951c8b71b2369da62a329c792af5e3d3087bbe020f38c68ca1d0a594b904c08 +R 72a6efcd125b0c95596513fdcf1cc1c1 U drh -Z e95f877e9262c0f435291a075b3e65bf +Z c72f75e91dfa4521c812f9addaece596 diff --git a/manifest.uuid b/manifest.uuid index c8a97e3513..9dce22f0a7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f951c8b71b2369da62a329c792af5e3d3087bbe020f38c68ca1d0a594b904c08 \ No newline at end of file +604c11d1a39f09e47b6fcee0f8b1c1054f9dbbc7b2c1cf93312aeaa4b7095018 \ No newline at end of file diff --git a/src/dbstat.c b/src/dbstat.c index 13974bb979..c9f0fa83bf 100644 --- a/src/dbstat.c +++ b/src/dbstat.c @@ -694,6 +694,9 @@ int sqlite3DbstatRegister(sqlite3 *db){ 0, /* xRollback */ 0, /* xFindMethod */ 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ }; return sqlite3_create_module(db, "dbstat", &dbstat_module, 0); } From 0c2433003dcbb725c8e44eaa5fc7a6aa0816cbdf Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 12 Jul 2017 20:43:23 +0000 Subject: [PATCH 64/64] Smaller and faster implementation for vdbeFreeOpArray() and freeP4(). FossilOrigin-Name: 0c80593520d30958231be41fc443209eb39e0b3ee0e66308c3ef3a0f4cb8ea66 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbe.h | 38 ++++++++++++++++++++------------------ src/vdbeaux.c | 2 +- 4 files changed, 29 insertions(+), 27 deletions(-) diff --git a/manifest b/manifest index cddf48e329..1519f185fc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings\sabout\sincomplete\sstructure\sinitializers. -D 2017-07-12T18:05:54.577 +C Smaller\sand\sfaster\simplementation\sfor\svdbeFreeOpArray()\sand\sfreeP4(). +D 2017-07-12T20:43:23.436 F Makefile.in 081e48dfe7f995d57ce1a88ddf4d2917b4349158648a6cd45b42beae30de3a12 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba @@ -518,10 +518,10 @@ F src/utf.c 810fbfebe12359f10bc2a011520a6e10879ab2a163bcb26c74768eab82ea62a5 F src/util.c fc081ec6f63448dcd80d3dfad35baecfa104823254a815b081a4d9fe76e1db23 F src/vacuum.c 874c0f2f15ab2908748297d587d22d485ea96d55aaec91d4775dddb2e24d2ecf F src/vdbe.c adc8a378710ec2376101483cc8a5f499539ee9bbebfb2a784f3370704d5d44ad -F src/vdbe.h dde459b1e8a02b8445ecfd5959f38cd5ebb6b0ad392d491d8b159ac8193d231a +F src/vdbe.h 7bf719031782823b915aff2c1f93d1944c1c6b300770a15339b7dbc9610b802e F src/vdbeInt.h c8b3d97001a7bab5cdf71927fc813869d95263160e67ba2ef78a32d7538f159d F src/vdbeapi.c 899d8f021c89ab348708b3a9b00b855f5ecc3c0f949a75359a61a3c621021281 -F src/vdbeaux.c 6f01fe8a49b801cc7734ccfc61d1b782131ee3bb7ee28e336f3c73474800f8f9 +F src/vdbeaux.c 518d1cf6728ecb591390541c58b14902e8d61735ef574426b9971624c54d2c4b F src/vdbeblob.c 359891617358deefc85bef7bcf787fa6b77facb9 F src/vdbemem.c 8d78df62becfd2dce3c317f64b32a94ecaff8346d814bc8b0b877b38a1ad3718 F src/vdbesort.c f512c68d0bf7e0105316a5594c4329358c8ee9cae3b25138df041d97516c0372 @@ -1631,7 +1631,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f951c8b71b2369da62a329c792af5e3d3087bbe020f38c68ca1d0a594b904c08 -R 72a6efcd125b0c95596513fdcf1cc1c1 +P 604c11d1a39f09e47b6fcee0f8b1c1054f9dbbc7b2c1cf93312aeaa4b7095018 +R 549dc263ced9c697f9b1d9eb2b003b47 U drh -Z c72f75e91dfa4521c812f9addaece596 +Z 774a79b024a9ed7218e88c0cd802cdf5 diff --git a/manifest.uuid b/manifest.uuid index 9dce22f0a7..f6526cbfec 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -604c11d1a39f09e47b6fcee0f8b1c1054f9dbbc7b2c1cf93312aeaa4b7095018 \ No newline at end of file +0c80593520d30958231be41fc443209eb39e0b3ee0e66308c3ef3a0f4cb8ea66 \ No newline at end of file diff --git a/src/vdbe.h b/src/vdbe.h index 9640607a54..7de95c2e90 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -107,24 +107,26 @@ typedef struct VdbeOpList VdbeOpList; /* ** Allowed values of VdbeOp.p4type */ -#define P4_NOTUSED 0 /* The P4 parameter is not used */ -#define P4_DYNAMIC (-1) /* Pointer to a string obtained from sqliteMalloc() */ -#define P4_STATIC (-2) /* Pointer to a static string */ -#define P4_COLLSEQ (-3) /* P4 is a pointer to a CollSeq structure */ -#define P4_FUNCDEF (-4) /* P4 is a pointer to a FuncDef structure */ -#define P4_KEYINFO (-5) /* P4 is a pointer to a KeyInfo structure */ -#define P4_EXPR (-6) /* P4 is a pointer to an Expr tree */ -#define P4_MEM (-7) /* P4 is a pointer to a Mem* structure */ -#define P4_TRANSIENT 0 /* P4 is a pointer to a transient string */ -#define P4_VTAB (-8) /* P4 is a pointer to an sqlite3_vtab structure */ -#define P4_REAL (-9) /* P4 is a 64-bit floating point value */ -#define P4_INT64 (-10) /* P4 is a 64-bit signed integer */ -#define P4_INT32 (-11) /* P4 is a 32-bit signed integer */ -#define P4_INTARRAY (-12) /* P4 is a vector of 32-bit integers */ -#define P4_SUBPROGRAM (-13) /* P4 is a pointer to a SubProgram structure */ -#define P4_ADVANCE (-14) /* P4 is a pointer to BtreeNext() or BtreePrev() */ -#define P4_TABLE (-15) /* P4 is a pointer to a Table structure */ -#define P4_FUNCCTX (-16) /* P4 is a pointer to an sqlite3_context object */ +#define P4_NOTUSED 0 /* The P4 parameter is not used */ +#define P4_TRANSIENT 0 /* P4 is a pointer to a transient string */ +#define P4_STATIC (-1) /* Pointer to a static string */ +#define P4_COLLSEQ (-2) /* P4 is a pointer to a CollSeq structure */ +#define P4_INT32 (-3) /* P4 is a 32-bit signed integer */ +#define P4_SUBPROGRAM (-4) /* P4 is a pointer to a SubProgram structure */ +#define P4_ADVANCE (-5) /* P4 is a pointer to BtreeNext() or BtreePrev() */ +#define P4_TABLE (-6) /* P4 is a pointer to a Table structure */ +/* Above do not own any resources. Must free those below */ +#define P4_FREE_IF_LE (-7) +#define P4_DYNAMIC (-7) /* Pointer to memory from sqliteMalloc() */ +#define P4_FUNCDEF (-8) /* P4 is a pointer to a FuncDef structure */ +#define P4_KEYINFO (-9) /* P4 is a pointer to a KeyInfo structure */ +#define P4_EXPR (-10) /* P4 is a pointer to an Expr tree */ +#define P4_MEM (-11) /* P4 is a pointer to a Mem* structure */ +#define P4_VTAB (-12) /* P4 is a pointer to an sqlite3_vtab structure */ +#define P4_REAL (-13) /* P4 is a 64-bit floating point value */ +#define P4_INT64 (-14) /* P4 is a 64-bit signed integer */ +#define P4_INTARRAY (-15) /* P4 is a vector of 32-bit integers */ +#define P4_FUNCCTX (-16) /* P4 is a pointer to an sqlite3_context object */ /* Error message codes for OP_Halt */ #define P5_ConstraintNotNull 1 diff --git a/src/vdbeaux.c b/src/vdbeaux.c index ef5420e233..66b2951247 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -886,7 +886,7 @@ static void vdbeFreeOpArray(sqlite3 *db, Op *aOp, int nOp){ if( aOp ){ Op *pOp; for(pOp=&aOp[nOp-1]; pOp>=aOp; pOp--){ - if( pOp->p4type ) freeP4(db, pOp->p4type, pOp->p4.p); + if( pOp->p4type <= P4_FREE_IF_LE ) freeP4(db, pOp->p4type, pOp->p4.p); #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS sqlite3DbFree(db, pOp->zComment); #endif