From f97dad8849a1b64a817a0a5f4182b5cb838b79d8 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 26 May 2014 20:06:45 +0000 Subject: [PATCH 01/18] Enable the OR optimization for WITHOUT ROWID tables. Use a temp table instead of the RowSet object to track the rows that have already been included in the result set. FossilOrigin-Name: 2c7e277bbebd5c93dec53d381d9737909d40d846 --- manifest | 16 +++++++---- manifest.uuid | 2 +- src/where.c | 64 +++++++++++++++++++++++++++++++++++------ test/whereI.test | 74 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 140 insertions(+), 16 deletions(-) create mode 100644 test/whereI.test diff --git a/manifest b/manifest index f1b1389523..3aa8bdc554 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\sin\sthe\sshell\swhen\simporting\sCSV\sfiles.\sIf\sthe\sleftmost\sfield\sof\sthe\sfirst\srow\sin\sthe\sCSV\sfile\swas\sboth\szero\sbytes\sin\ssize\sand\sunquoted,\sno\sdata\swas\simported. -D 2014-05-26T18:27:12.472 +C Enable\sthe\sOR\soptimization\sfor\sWITHOUT\sROWID\stables.\sUse\sa\stemp\stable\sinstead\sof\sthe\sRowSet\sobject\sto\strack\sthe\srows\sthat\shave\salready\sbeen\sincluded\sin\sthe\sresult\sset. +D 2014-05-26T20:06:45.481 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in dd2b1aba364ff9b05de41086f74407f285c57670 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -294,7 +294,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 76e7fc6de229bea8b30bb2539110f03a494dc3a8 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45 -F src/where.c 9d351a5ecefdcc104d0bb7d9b5631dce4d60757c +F src/where.c a911a484ed86fc4a3d52219c8adb64b19f7afeb7 F src/whereInt.h 6804c2e5010378568c2bb1350477537755296a46 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1106,6 +1106,7 @@ F test/whereE.test b3a055eef928c992b0a33198a7b8dc10eea5ad2f F test/whereF.test 5b2ba0dbe8074aa13e416b37c753991f0a2492d7 F test/whereG.test 0ac23e5e8311b69d87245f4a85112de321031658 F test/whereH.test e4b07f7a3c2f5d31195cd33710054c78667573b2 +F test/whereI.test 6cc613df883a17ca3df36021c6d6e514f5f3bd23 F test/wherelimit.test 5e9fd41e79bb2b2d588ed999d641d9c965619b31 F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c @@ -1172,7 +1173,10 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P d90c4964fcf46b0b043dbfd58267098582267001 -R 4f49cf43bba70559a864b8b79fde7303 +P 856d44a206d82e96265103556dedda39ca3602b1 +R 9e568de169ca65397feb1345691b1a68 +T *branch * without-rowid-or-opt +T *sym-without-rowid-or-opt * +T -sym-trunk * U dan -Z b7657af7a09e4e39091c8340eac623cc +Z 2a22ab55186c5c60531d14f3d4d18429 diff --git a/manifest.uuid b/manifest.uuid index daf356e5f4..6244887898 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -856d44a206d82e96265103556dedda39ca3602b1 \ No newline at end of file +2c7e277bbebd5c93dec53d381d9737909d40d846 \ No newline at end of file diff --git a/src/where.c b/src/where.c index b9385a5ecd..d52aed834f 100644 --- a/src/where.c +++ b/src/where.c @@ -3307,6 +3307,7 @@ static Bitmask codeOneLoopStart( int untestedTerms = 0; /* Some terms not completely tested */ int ii; /* Loop counter */ Expr *pAndExpr = 0; /* An ".. AND (...)" expression */ + Table *pTab = pTabItem->pTab; pTerm = pLoop->aLTerm[0]; assert( pTerm!=0 ); @@ -3350,9 +3351,16 @@ static Bitmask codeOneLoopStart( ** called on an uninitialized cursor. */ if( (pWInfo->wctrlFlags & WHERE_DUPLICATES_OK)==0 ){ - regRowset = ++pParse->nMem; + if( HasRowid(pTab) ){ + regRowset = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Null, 0, regRowset); + }else{ + Index *pPk = sqlite3PrimaryKeyIndex(pTab); + regRowset = pParse->nTab++; + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, regRowset, pPk->nKeyCol); + sqlite3VdbeSetP4KeyInfo(pParse, pPk); + } regRowid = ++pParse->nMem; - sqlite3VdbeAddOp2(v, OP_Null, 0, regRowset); } iRetInit = sqlite3VdbeAddOp2(v, OP_Integer, 0, regReturn); @@ -3408,13 +3416,52 @@ static Bitmask codeOneLoopStart( pParse, pOrTab, &pSubWInfo->a[0], iLevel, pLevel->iFrom, 0 ); if( (pWInfo->wctrlFlags & WHERE_DUPLICATES_OK)==0 ){ - int iSet = ((ii==pOrWc->nTerm-1)?-1:ii); int r; - r = sqlite3ExprCodeGetColumn(pParse, pTabItem->pTab, -1, iCur, - regRowid, 0); - sqlite3VdbeAddOp4Int(v, OP_RowSetTest, regRowset, - sqlite3VdbeCurrentAddr(v)+2, r, iSet); - VdbeCoverage(v); + int addr; /* Address just past Gosub coded below */ + int iSet = ((ii==pOrWc->nTerm-1)?-1:ii); + if( HasRowid(pTab) ){ + r = sqlite3ExprCodeGetColumn(pParse, pTab, -1, iCur, regRowid, 0); + addr = sqlite3VdbeCurrentAddr(v)+2; + sqlite3VdbeAddOp4Int(v, OP_RowSetTest, regRowset, addr, r, iSet); + VdbeCoverage(v); + }else{ + Index *pPk = sqlite3PrimaryKeyIndex(pTab); + int nPk = pPk->nKeyCol; + int iPk; + + /* Read the PK into an array of temp registers. */ + r = sqlite3GetTempRange(pParse, nPk); + for(iPk=0; iPkaiColumn[iPk]; + sqlite3ExprCodeGetColumn(pParse, pTab, iCol, iCur, r+iPk, 0); + } + + /* Check if the temp table already contains this key. If so, + ** the row has already been included in the result set and + ** can be ignored (by jumping past the Gosub below). Otherwise, + ** insert the key into the temp table and proceed with processing + ** the row. + ** + ** Use some of the same optimizations as OP_RowSetTest: If iSet + ** is zero, assume that the key cannot already be present in + ** the temp table. And if iSet is -1, assume that there is no + ** need to insert the key into the temp table, as it will never + ** be tested for. */ + if( iSet ){ + addr = sqlite3VdbeCurrentAddr(v) + 2 + ((iSet>0) ? 2 : 0); + sqlite3VdbeAddOp4Int(v, OP_Found, regRowset, addr, r, nPk); + } + if( iSet>=0 ){ + sqlite3VdbeAddOp3(v, OP_MakeRecord, r, nPk, regRowid); + sqlite3VdbeAddOp3(v, OP_IdxInsert, regRowset, regRowid, 0); + if( iSet ) sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); + } + + /* Release the array of temp registers */ + sqlite3ReleaseTempRange(pParse, r, nPk); + } + assert( db->mallocFailed + || iSet==0 || addr==(sqlite3VdbeCurrentAddr(v)+1) ); } sqlite3VdbeAddOp2(v, OP_Gosub, regReturn, iLoopBody); @@ -4766,7 +4813,6 @@ static int whereLoopAddOr(WhereLoopBuilder *pBuilder, Bitmask mExtra){ pNew = pBuilder->pNew; memset(&sSum, 0, sizeof(sSum)); pItem = pWInfo->pTabList->a + pNew->iTab; - if( !HasRowid(pItem->pTab) ) return SQLITE_OK; iCur = pItem->iCursor; for(pTerm=pWC->a; pTerm Date: Mon, 26 May 2014 20:25:34 +0000 Subject: [PATCH 02/18] Add a missing VdbeCoverage() macro on an OP_Found opcode added in the previous check-in. FossilOrigin-Name: b4980a07e287480beddb2c6633c733520e05d074 --- manifest | 17 +++++++---------- manifest.uuid | 2 +- src/where.c | 1 + 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 3aa8bdc554..4c806d5a59 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enable\sthe\sOR\soptimization\sfor\sWITHOUT\sROWID\stables.\sUse\sa\stemp\stable\sinstead\sof\sthe\sRowSet\sobject\sto\strack\sthe\srows\sthat\shave\salready\sbeen\sincluded\sin\sthe\sresult\sset. -D 2014-05-26T20:06:45.481 +C Add\sa\smissing\sVdbeCoverage()\smacro\son\san\sOP_Found\sopcode\sadded\sin\sthe\sprevious\ncheck-in. +D 2014-05-26T20:25:34.589 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in dd2b1aba364ff9b05de41086f74407f285c57670 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -294,7 +294,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 76e7fc6de229bea8b30bb2539110f03a494dc3a8 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45 -F src/where.c a911a484ed86fc4a3d52219c8adb64b19f7afeb7 +F src/where.c d46d73c76f48ede86e0e5bb112b2bcc91947bfaa F src/whereInt.h 6804c2e5010378568c2bb1350477537755296a46 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1173,10 +1173,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 856d44a206d82e96265103556dedda39ca3602b1 -R 9e568de169ca65397feb1345691b1a68 -T *branch * without-rowid-or-opt -T *sym-without-rowid-or-opt * -T -sym-trunk * -U dan -Z 2a22ab55186c5c60531d14f3d4d18429 +P 2c7e277bbebd5c93dec53d381d9737909d40d846 +R 3707fb894adfd77b824ab9f7bdc17e79 +U drh +Z 370b7f2e785b22f24333c303cca00bc0 diff --git a/manifest.uuid b/manifest.uuid index 6244887898..e04960c2e5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2c7e277bbebd5c93dec53d381d9737909d40d846 \ No newline at end of file +b4980a07e287480beddb2c6633c733520e05d074 \ No newline at end of file diff --git a/src/where.c b/src/where.c index d52aed834f..bf81ed8ffd 100644 --- a/src/where.c +++ b/src/where.c @@ -3450,6 +3450,7 @@ static Bitmask codeOneLoopStart( if( iSet ){ addr = sqlite3VdbeCurrentAddr(v) + 2 + ((iSet>0) ? 2 : 0); sqlite3VdbeAddOp4Int(v, OP_Found, regRowset, addr, r, nPk); + VdbeCoverage(v); } if( iSet>=0 ){ sqlite3VdbeAddOp3(v, OP_MakeRecord, r, nPk, regRowid); From 5609baf35e668ca24f0c80430f0923ca6448a3e6 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 26 May 2014 22:01:00 +0000 Subject: [PATCH 03/18] Minor enhancements to comments and clarification of the code. FossilOrigin-Name: cbec30d0c49a3f618c3df3ae0ca3d651b48841c2 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/where.c | 18 ++++++++++-------- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 4c806d5a59..fb7eecbb03 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\smissing\sVdbeCoverage()\smacro\son\san\sOP_Found\sopcode\sadded\sin\sthe\sprevious\ncheck-in. -D 2014-05-26T20:25:34.589 +C Minor\senhancements\sto\scomments\sand\sclarification\sof\sthe\scode. +D 2014-05-26T22:01:00.008 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in dd2b1aba364ff9b05de41086f74407f285c57670 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -294,7 +294,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 76e7fc6de229bea8b30bb2539110f03a494dc3a8 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45 -F src/where.c d46d73c76f48ede86e0e5bb112b2bcc91947bfaa +F src/where.c b5719b11c414874826c676cf8c8455cb2939a30c F src/whereInt.h 6804c2e5010378568c2bb1350477537755296a46 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1173,7 +1173,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 2c7e277bbebd5c93dec53d381d9737909d40d846 -R 3707fb894adfd77b824ab9f7bdc17e79 +P b4980a07e287480beddb2c6633c733520e05d074 +R 8f53ac145522e21d9a1c5059c77f2db7 U drh -Z 370b7f2e785b22f24333c303cca00bc0 +Z ad528aef359e7c77cf0a017e9208591c diff --git a/manifest.uuid b/manifest.uuid index e04960c2e5..2940deda79 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b4980a07e287480beddb2c6633c733520e05d074 \ No newline at end of file +cbec30d0c49a3f618c3df3ae0ca3d651b48841c2 \ No newline at end of file diff --git a/src/where.c b/src/where.c index bf81ed8ffd..b74f44987d 100644 --- a/src/where.c +++ b/src/where.c @@ -3293,6 +3293,10 @@ static Bitmask codeOneLoopStart( ** ** B: ** + ** Added 2014-05-26: If the table is a WITHOUT ROWID table, then + ** use an ephermeral index instead of a RowSet to record the primary + ** keys of the rows we have already seen. + ** */ WhereClause *pOrWc; /* The OR-clause broken out into subterms */ SrcList *pOrTab; /* Shortened table list or OR-clause generation */ @@ -3340,7 +3344,8 @@ static Bitmask codeOneLoopStart( } /* Initialize the rowset register to contain NULL. An SQL NULL is - ** equivalent to an empty rowset. + ** equivalent to an empty rowset. Or, create an ephermeral index + ** capable of holding primary keys in the case of a WITHOUT ROWID. ** ** Also initialize regReturn to contain the address of the instruction ** immediately following the OP_Return at the bottom of the loop. This @@ -3401,6 +3406,7 @@ static Bitmask codeOneLoopStart( if( pOrTerm->leftCursor==iCur || (pOrTerm->eOperator & WO_AND)!=0 ){ WhereInfo *pSubWInfo; /* Info for single OR-term scan */ Expr *pOrExpr = pOrTerm->pExpr; + int j1 = 0; /* Address of jump operation */ if( pAndExpr && !ExprHasProperty(pOrExpr, EP_FromJoin) ){ pAndExpr->pLeft = pOrExpr; pOrExpr = pAndExpr; @@ -3417,12 +3423,10 @@ static Bitmask codeOneLoopStart( ); if( (pWInfo->wctrlFlags & WHERE_DUPLICATES_OK)==0 ){ int r; - int addr; /* Address just past Gosub coded below */ int iSet = ((ii==pOrWc->nTerm-1)?-1:ii); if( HasRowid(pTab) ){ r = sqlite3ExprCodeGetColumn(pParse, pTab, -1, iCur, regRowid, 0); - addr = sqlite3VdbeCurrentAddr(v)+2; - sqlite3VdbeAddOp4Int(v, OP_RowSetTest, regRowset, addr, r, iSet); + j1 = sqlite3VdbeAddOp4Int(v, OP_RowSetTest, regRowset, 0, r,iSet); VdbeCoverage(v); }else{ Index *pPk = sqlite3PrimaryKeyIndex(pTab); @@ -3448,8 +3452,7 @@ static Bitmask codeOneLoopStart( ** need to insert the key into the temp table, as it will never ** be tested for. */ if( iSet ){ - addr = sqlite3VdbeCurrentAddr(v) + 2 + ((iSet>0) ? 2 : 0); - sqlite3VdbeAddOp4Int(v, OP_Found, regRowset, addr, r, nPk); + j1 = sqlite3VdbeAddOp4Int(v, OP_Found, regRowset, 0, r, nPk); VdbeCoverage(v); } if( iSet>=0 ){ @@ -3461,10 +3464,9 @@ static Bitmask codeOneLoopStart( /* Release the array of temp registers */ sqlite3ReleaseTempRange(pParse, r, nPk); } - assert( db->mallocFailed - || iSet==0 || addr==(sqlite3VdbeCurrentAddr(v)+1) ); } sqlite3VdbeAddOp2(v, OP_Gosub, regReturn, iLoopBody); + if( j1 ) sqlite3VdbeJumpHere(v, j1); /* The pSubWInfo->untestedTerms flag means that this OR term ** contained one or more AND term from a notReady table. The From 15299080014edc7493c57340c84206c778dd013b Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 27 May 2014 10:57:37 +0000 Subject: [PATCH 04/18] Fix for (unsupported) SQLITE_USE_FCNTL_TRACE code. FossilOrigin-Name: 994b2b7a591f08609140eb504253c141aec6206a --- manifest | 13 ++++++------- manifest.uuid | 2 +- src/vdbe.c | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 56c3d49f6b..2e8de519be 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sOR-optimization\sto\sWITHOUT\sROWID\stables. -D 2014-05-26T22:05:46.794 +C Fix\sfor\s(unsupported)\sSQLITE_USE_FCNTL_TRACE\scode. +D 2014-05-27T10:57:37.938 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in dd2b1aba364ff9b05de41086f74407f285c57670 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -281,7 +281,7 @@ F src/update.c 5b3e74a03b3811e586b4f2b4cbd7c49f01c93115 F src/utf.c 6dc9ec9f1b3db43ae8ba0365377f11df1ee4c01c F src/util.c 049fe1d3c0e2209c1bee107aec2fcff6285f909f F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c 3ebcbe6a83198045b0411956fc6005b9f4a6991c +F src/vdbe.c 9bfe6becfc094382ae213656fbe511055ad83a54 F src/vdbe.h 394464909ed682334aa3d5831aae0c2fe2abef94 F src/vdbeInt.h e6d83e5bfd62fc6685ba1ed6153f7099f82de9f7 F src/vdbeapi.c 0ed6053f947edd0b30f64ce5aeb811872a3450a4 @@ -1173,8 +1173,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 856d44a206d82e96265103556dedda39ca3602b1 cbec30d0c49a3f618c3df3ae0ca3d651b48841c2 -R 8f53ac145522e21d9a1c5059c77f2db7 -T +closed cbec30d0c49a3f618c3df3ae0ca3d651b48841c2 +P 06a23b8b32f0439b22936dc4107890481e4a1327 +R 1ea67ea23f6d65217b1fa5e6a1cb1745 U drh -Z 4f60de2d6ef2869c107540511682c313 +Z 5395f720c06a5e5e2e7f0dd6ed7719cf diff --git a/manifest.uuid b/manifest.uuid index 0d4ac611af..b257a713e1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -06a23b8b32f0439b22936dc4107890481e4a1327 \ No newline at end of file +994b2b7a591f08609140eb504253c141aec6206a \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index f5b159ca4a..11aa035026 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -6281,7 +6281,7 @@ case OP_Init: { /* jump */ if( zTrace ){ int i; for(i=0; inDb; i++){ - if( MASKBIT(i) & p->btreeMask)==0 ) continue; + if( (MASKBIT(i) & p->btreeMask)==0 ) continue; sqlite3_file_control(db, db->aDb[i].zName, SQLITE_FCNTL_TRACE, zTrace); } } From c2070c7d96975f0a150b5de9b47737ba2d36c10b Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 27 May 2014 11:42:23 +0000 Subject: [PATCH 05/18] Add a test to whereI.test that uses a multi-column PK. FossilOrigin-Name: aa183e60929bdbbcea3c436dd8cc674fc44ad09a --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/whereI.test | 20 +++++++++++++++++++- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 2e8de519be..b1c7e36cfe 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sfor\s(unsupported)\sSQLITE_USE_FCNTL_TRACE\scode. -D 2014-05-27T10:57:37.938 +C Add\sa\stest\sto\swhereI.test\sthat\suses\sa\smulti-column\sPK. +D 2014-05-27T11:42:23.800 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in dd2b1aba364ff9b05de41086f74407f285c57670 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -1106,7 +1106,7 @@ F test/whereE.test b3a055eef928c992b0a33198a7b8dc10eea5ad2f F test/whereF.test 5b2ba0dbe8074aa13e416b37c753991f0a2492d7 F test/whereG.test 0ac23e5e8311b69d87245f4a85112de321031658 F test/whereH.test e4b07f7a3c2f5d31195cd33710054c78667573b2 -F test/whereI.test 6cc613df883a17ca3df36021c6d6e514f5f3bd23 +F test/whereI.test 1d89199697919d4930be05a71e7fe620f114e622 F test/wherelimit.test 5e9fd41e79bb2b2d588ed999d641d9c965619b31 F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c @@ -1173,7 +1173,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 06a23b8b32f0439b22936dc4107890481e4a1327 -R 1ea67ea23f6d65217b1fa5e6a1cb1745 -U drh -Z 5395f720c06a5e5e2e7f0dd6ed7719cf +P 994b2b7a591f08609140eb504253c141aec6206a +R 9f5fb115adc3bda89f20bf959aa72d38 +U dan +Z 82d2f3f55de0a896d1573b7f67dc993e diff --git a/manifest.uuid b/manifest.uuid index b257a713e1..2b88626017 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -994b2b7a591f08609140eb504253c141aec6206a \ No newline at end of file +aa183e60929bdbbcea3c436dd8cc674fc44ad09a \ No newline at end of file diff --git a/test/whereI.test b/test/whereI.test index 23ca57ca68..452e7f8f19 100644 --- a/test/whereI.test +++ b/test/whereI.test @@ -69,6 +69,24 @@ do_execsql_test 2.3 { SELECT a FROM t2 WHERE b='a' OR c='z' } {i} +#---------------------------------------------------------------------- +# On a table with a multi-column PK. +# +do_execsql_test 3.0 { + CREATE TABLE t3(a, b, c, d, PRIMARY KEY(c, b)) WITHOUT ROWID; + + INSERT INTO t3 VALUES('f', 1, 1, 'o'); + INSERT INTO t3 VALUES('o', 2, 1, 't'); + INSERT INTO t3 VALUES('t', 1, 2, 't'); + INSERT INTO t3 VALUES('t', 2, 2, 'f'); + + CREATE INDEX t3i1 ON t3(d); + CREATE INDEX t3i2 ON t3(a); + + SELECT c||'.'||b FROM t3 WHERE a='t' OR d='t' +} { + 2.1 2.2 1.2 +} + finish_test - From b7231a8cf06356a2219accdd29a37872f107cb8d Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 27 May 2014 11:54:48 +0000 Subject: [PATCH 06/18] Fix a harmless compiler warning in the FTS4 logic. FossilOrigin-Name: 64a869ad2388d9d62601b93d5139f2dc57f260f7 --- ext/fts3/fts3_expr.c | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/ext/fts3/fts3_expr.c b/ext/fts3/fts3_expr.c index 95a9b1aada..f5d28cbfcc 100644 --- a/ext/fts3/fts3_expr.c +++ b/ext/fts3/fts3_expr.c @@ -502,7 +502,7 @@ static int getNextNode( return rc; }else if( *zInput==')' ){ pParse->nNest--; - *pnConsumed = (zInput - z) + 1; + *pnConsumed = (int)((zInput - z) + 1); *ppExpr = 0; return SQLITE_DONE; } diff --git a/manifest b/manifest index b1c7e36cfe..d56281d090 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\stest\sto\swhereI.test\sthat\suses\sa\smulti-column\sPK. -D 2014-05-27T11:42:23.800 +C Fix\sa\sharmless\scompiler\swarning\sin\sthe\sFTS4\slogic. +D 2014-05-27T11:54:48.854 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in dd2b1aba364ff9b05de41086f74407f285c57670 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -82,7 +82,7 @@ F ext/fts3/fts3.c 0a9813c01ce7cc33d63680725ea30755d77c7b39 F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe F ext/fts3/fts3Int.h 16cddf2d7b0e5f3681615ae1d8ca0e45fca44918 F ext/fts3/fts3_aux.c 5c211e17a64885faeb16b9ba7772f9d5445c2365 -F ext/fts3/fts3_expr.c 2ac35bda474f00c14c19608e49a02c8c7ceb9970 +F ext/fts3/fts3_expr.c 351395fad6fcb16ecfc61db0861008a70101330c F ext/fts3/fts3_hash.c 29b986e43f4e9dd40110eafa377dc0d63c422c60 F ext/fts3/fts3_hash.h 39cf6874dc239d6b4e30479b1975fe5b22a3caaf F ext/fts3/fts3_icu.c e319e108661147bcca8dd511cd562f33a1ba81b5 @@ -1173,7 +1173,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 994b2b7a591f08609140eb504253c141aec6206a -R 9f5fb115adc3bda89f20bf959aa72d38 -U dan -Z 82d2f3f55de0a896d1573b7f67dc993e +P aa183e60929bdbbcea3c436dd8cc674fc44ad09a +R dc3220081ccb63ed0a892f7c8cb59b2d +U drh +Z f463b60fc8d319117d5bb0fe1cac3b72 diff --git a/manifest.uuid b/manifest.uuid index 2b88626017..5de733e73d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -aa183e60929bdbbcea3c436dd8cc674fc44ad09a \ No newline at end of file +64a869ad2388d9d62601b93d5139f2dc57f260f7 \ No newline at end of file From f53b4ad0f9f7e4fcef932461ae6cb5519f1675c6 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 27 May 2014 15:21:42 +0000 Subject: [PATCH 07/18] Remove unused code (previously #ifdef-ed out) from btree.c. FossilOrigin-Name: 8bc9737112e2700f337ff377cda040c8ba9d729f --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 6 ------ 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index d56281d090..ee6c2106b8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sharmless\scompiler\swarning\sin\sthe\sFTS4\slogic. -D 2014-05-27T11:54:48.854 +C Remove\sunused\scode\s(previously\s#ifdef-ed\sout)\sfrom\sbtree.c. +D 2014-05-27T15:21:42.410 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in dd2b1aba364ff9b05de41086f74407f285c57670 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -165,7 +165,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c a729e63cf5cd1829507cb7b8e89f99b95141bb53 F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c e29fc07a968f8d1bbe38b5736d71db59959f545c +F src/btree.c 70c60a3807b2072982f184d9614e020d2953f89c F src/btree.h 4245a349bfe09611d7ff887dbc3a80cee8b7955a F src/btreeInt.h cf180d86b2e9e418f638d65baa425c4c69c0e0e3 F src/build.c 92539f47043ac9c48921450a9b2162da672bda4a @@ -1173,7 +1173,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P aa183e60929bdbbcea3c436dd8cc674fc44ad09a -R dc3220081ccb63ed0a892f7c8cb59b2d +P 64a869ad2388d9d62601b93d5139f2dc57f260f7 +R ce6739b7102ff2fcf5c416b0ad7372b3 U drh -Z f463b60fc8d319117d5bb0fe1cac3b72 +Z 7d981ef6a78ea000e412f69d3d0c7cf8 diff --git a/manifest.uuid b/manifest.uuid index 5de733e73d..ece315d4f2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -64a869ad2388d9d62601b93d5139f2dc57f260f7 \ No newline at end of file +8bc9737112e2700f337ff377cda040c8ba9d729f \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index e843a946b0..9032a9304c 100644 --- a/src/btree.c +++ b/src/btree.c @@ -4218,12 +4218,6 @@ static const void *fetchPayload( assert( cursorHoldsMutex(pCur) ); assert( pCur->aiIdx[pCur->iPage]apPage[pCur->iPage]->nCell ); assert( pCur->info.nSize>0 ); -#if 0 - if( pCur->info.nSize==0 ){ - btreeParseCell(pCur->apPage[pCur->iPage], pCur->aiIdx[pCur->iPage], - &pCur->info); - } -#endif *pAmt = pCur->info.nLocal; return (void*)(pCur->info.pCell + pCur->info.nHeader); } From 3fb6730699f24f7ec2cecc88fba7deb356a27f52 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 27 May 2014 16:41:39 +0000 Subject: [PATCH 08/18] Improved comments on the OR-optimization logic in the query planner. FossilOrigin-Name: 77fef5a3987fc16f84a8e755283ca6ec1363013c --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/where.c | 20 +++++++++++++++++--- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index ee6c2106b8..04ddaf44ca 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sunused\scode\s(previously\s#ifdef-ed\sout)\sfrom\sbtree.c. -D 2014-05-27T15:21:42.410 +C Improved\scomments\son\sthe\sOR-optimization\slogic\sin\sthe\squery\splanner. +D 2014-05-27T16:41:39.846 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in dd2b1aba364ff9b05de41086f74407f285c57670 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -294,7 +294,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 76e7fc6de229bea8b30bb2539110f03a494dc3a8 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45 -F src/where.c b5719b11c414874826c676cf8c8455cb2939a30c +F src/where.c c0d3d347448ce49cce09f6d9c9c77b2e50cb04e8 F src/whereInt.h 6804c2e5010378568c2bb1350477537755296a46 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1173,7 +1173,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 64a869ad2388d9d62601b93d5139f2dc57f260f7 -R ce6739b7102ff2fcf5c416b0ad7372b3 +P 8bc9737112e2700f337ff377cda040c8ba9d729f +R c7cb76eccf21aa84ad851897e7d321d9 U drh -Z 7d981ef6a78ea000e412f69d3d0c7cf8 +Z 007914f5e44aaaab8e86bcf739f9064c diff --git a/manifest.uuid b/manifest.uuid index ece315d4f2..7426ad2ba1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8bc9737112e2700f337ff377cda040c8ba9d729f \ No newline at end of file +77fef5a3987fc16f84a8e755283ca6ec1363013c \ No newline at end of file diff --git a/src/where.c b/src/where.c index b74f44987d..e03f94ba1a 100644 --- a/src/where.c +++ b/src/where.c @@ -3401,12 +3401,16 @@ static Bitmask codeOneLoopStart( } } + /* Run a separate WHERE clause for each term of the OR clause. After + ** eliminating duplicates from other WHERE clauses, the action for each + ** sub-WHERE clause is to to invoke the main loop body as a subroutine. + */ for(ii=0; iinTerm; ii++){ WhereTerm *pOrTerm = &pOrWc->a[ii]; if( pOrTerm->leftCursor==iCur || (pOrTerm->eOperator & WO_AND)!=0 ){ - WhereInfo *pSubWInfo; /* Info for single OR-term scan */ - Expr *pOrExpr = pOrTerm->pExpr; - int j1 = 0; /* Address of jump operation */ + WhereInfo *pSubWInfo; /* Info for single OR-term scan */ + Expr *pOrExpr = pOrTerm->pExpr; /* Current OR clause term */ + int j1 = 0; /* Address of jump operation */ if( pAndExpr && !ExprHasProperty(pOrExpr, EP_FromJoin) ){ pAndExpr->pLeft = pOrExpr; pOrExpr = pAndExpr; @@ -3421,6 +3425,11 @@ static Bitmask codeOneLoopStart( explainOneScan( pParse, pOrTab, &pSubWInfo->a[0], iLevel, pLevel->iFrom, 0 ); + /* This is the sub-WHERE clause body. First skip over + ** duplicate rows from prior sub-WHERE clauses, and record the + ** rowid (or PRIMARY KEY) for the current row so that the same + ** row will be skipped in subsequent sub-WHERE clauses. + */ if( (pWInfo->wctrlFlags & WHERE_DUPLICATES_OK)==0 ){ int r; int iSet = ((ii==pOrWc->nTerm-1)?-1:ii); @@ -3465,7 +3474,12 @@ static Bitmask codeOneLoopStart( sqlite3ReleaseTempRange(pParse, r, nPk); } } + + /* Invoke the main loop body as a subroutine */ sqlite3VdbeAddOp2(v, OP_Gosub, regReturn, iLoopBody); + + /* Jump here (skipping the main loop body subroutine) if the + ** current sub-WHERE row is a duplicate from prior sub-WHEREs. */ if( j1 ) sqlite3VdbeJumpHere(v, j1); /* The pSubWInfo->untestedTerms flag means that this OR term From a3bc66a3f588f1db8ed410b461cf0bce63059400 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 27 May 2014 17:57:32 +0000 Subject: [PATCH 09/18] Avoid unnecessary cursor opens and seeks when running the OR-optimization on a WITHOUT ROWID table. FossilOrigin-Name: 9c785c58327e08dad94a278a643a5443f94aec36 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/where.c | 20 +++++++++++++++----- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 04ddaf44ca..23fbeabdb4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\scomments\son\sthe\sOR-optimization\slogic\sin\sthe\squery\splanner. -D 2014-05-27T16:41:39.846 +C Avoid\sunnecessary\scursor\sopens\sand\sseeks\swhen\srunning\sthe\sOR-optimization\non\sa\sWITHOUT\sROWID\stable. +D 2014-05-27T17:57:32.885 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in dd2b1aba364ff9b05de41086f74407f285c57670 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -294,7 +294,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 76e7fc6de229bea8b30bb2539110f03a494dc3a8 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45 -F src/where.c c0d3d347448ce49cce09f6d9c9c77b2e50cb04e8 +F src/where.c a2dba34bd878afd6266f21c72858cede8fd015b3 F src/whereInt.h 6804c2e5010378568c2bb1350477537755296a46 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1173,7 +1173,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 8bc9737112e2700f337ff377cda040c8ba9d729f -R c7cb76eccf21aa84ad851897e7d321d9 +P 77fef5a3987fc16f84a8e755283ca6ec1363013c +R 9c15bb60113056d77932f80a5eec6f19 U drh -Z 007914f5e44aaaab8e86bcf739f9064c +Z 4fb05aa38d1f916817ea122f0841369f diff --git a/manifest.uuid b/manifest.uuid index 7426ad2ba1..24937ad719 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -77fef5a3987fc16f84a8e755283ca6ec1363013c \ No newline at end of file +9c785c58327e08dad94a278a643a5443f94aec36 \ No newline at end of file diff --git a/src/where.c b/src/where.c index e03f94ba1a..ff94822ebe 100644 --- a/src/where.c +++ b/src/where.c @@ -3223,7 +3223,7 @@ static Bitmask codeOneLoopStart( sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, iRowidReg); sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg); sqlite3VdbeAddOp2(v, OP_Seek, iCur, iRowidReg); /* Deferred seek */ - }else{ + }else if( iCur!=iIdxCur ){ Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable); iRowidReg = sqlite3GetTempRange(pParse, pPk->nKeyCol); for(j=0; jnKeyCol; j++){ @@ -3505,6 +3505,7 @@ static Bitmask codeOneLoopStart( assert( (pSubLoop->wsFlags & WHERE_AUTO_INDEX)==0 ); if( (pSubLoop->wsFlags & WHERE_INDEXED)!=0 && (ii==0 || pSubLoop->u.btree.pIndex==pCov) + && (HasRowid(pTab) || pSubLoop->u.btree.pIndex->autoIndex!=2) ){ assert( pSubWInfo->a[0].iIdxCur==iCovCur ); pCov = pSubLoop->u.btree.pIndex; @@ -6078,7 +6079,14 @@ WhereInfo *sqlite3WhereBegin( int op = OP_OpenRead; /* iIdxCur is always set if to a positive value if ONEPASS is possible */ assert( iIdxCur!=0 || (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 ); - if( pWInfo->okOnePass ){ + if( !HasRowid(pTab) && pIx->autoIndex==2 + && (wctrlFlags & WHERE_ONETABLE_ONLY)!=0 + ){ + /* This is one term of an OR-optimization using the PRIMARY KEY of a + ** WITHOUT ROWID table. No need for a separate index */ + iIndexCur = pLevel->iTabCur; + op = 0; + }else if( pWInfo->okOnePass ){ Index *pJ = pTabItem->pTab->pIndex; iIndexCur = iIdxCur; assert( wctrlFlags & WHERE_ONEPASS_DESIRED ); @@ -6096,9 +6104,11 @@ WhereInfo *sqlite3WhereBegin( pLevel->iIdxCur = iIndexCur; assert( pIx->pSchema==pTab->pSchema ); assert( iIndexCur>=0 ); - sqlite3VdbeAddOp3(v, op, iIndexCur, pIx->tnum, iDb); - sqlite3VdbeSetP4KeyInfo(pParse, pIx); - VdbeComment((v, "%s", pIx->zName)); + if( op ){ + sqlite3VdbeAddOp3(v, op, iIndexCur, pIx->tnum, iDb); + sqlite3VdbeSetP4KeyInfo(pParse, pIx); + VdbeComment((v, "%s", pIx->zName)); + } } if( iDb>=0 ) sqlite3CodeVerifySchema(pParse, iDb); notReady &= ~getMask(&pWInfo->sMaskSet, pTabItem->iCursor); From 48dd1d8e281238bb2844e03732d3e919429ee0e7 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 27 May 2014 18:18:58 +0000 Subject: [PATCH 10/18] Change the name of the Index.autoIndex field to Index.idxType and provide symbolic names for the various values of that field rather than using magic numbers. FossilOrigin-Name: d16e575dacc811de0f7b58a0d1cd243678dce6c5 --- manifest | 26 +++++++++++++------------- manifest.uuid | 2 +- src/analyze.c | 2 +- src/build.c | 19 ++++++++++--------- src/fkey.c | 4 ++-- src/insert.c | 6 +++--- src/select.c | 2 +- src/sqliteInt.h | 12 +++++++++++- src/update.c | 2 +- src/where.c | 6 +++--- 10 files changed, 46 insertions(+), 35 deletions(-) diff --git a/manifest b/manifest index 23fbeabdb4..0de865b6a4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sunnecessary\scursor\sopens\sand\sseeks\swhen\srunning\sthe\sOR-optimization\non\sa\sWITHOUT\sROWID\stable. -D 2014-05-27T17:57:32.885 +C Change\sthe\sname\sof\sthe\sIndex.autoIndex\sfield\sto\sIndex.idxType\sand\sprovide\nsymbolic\snames\sfor\sthe\svarious\svalues\sof\sthat\sfield\srather\sthan\susing\nmagic\snumbers. +D 2014-05-27T18:18:58.025 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in dd2b1aba364ff9b05de41086f74407f285c57670 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -159,7 +159,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 3d8b83c91651f53472ca17599dae3457b8b89494 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c b00900877f766f116f9e16116f1ccacdc21d82f1 -F src/analyze.c 3596f863bb80126fe56ba217df5932749271efc8 +F src/analyze.c e8c8a9d20beb2ad156321330e8f4fea002d8deee F src/attach.c 3801129015ef59d76bf23c95ef9b0069d18a0c52 F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c a729e63cf5cd1829507cb7b8e89f99b95141bb53 @@ -168,7 +168,7 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btree.c 70c60a3807b2072982f184d9614e020d2953f89c F src/btree.h 4245a349bfe09611d7ff887dbc3a80cee8b7955a F src/btreeInt.h cf180d86b2e9e418f638d65baa425c4c69c0e0e3 -F src/build.c 92539f47043ac9c48921450a9b2162da672bda4a +F src/build.c 927e39b6aaf872c7b28f154f6acfeb9a05a72442 F src/callback.c 174e3c8656bc29f91d710ab61550d16eea34be98 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 0231df905e2c4abba4483ee18ffc05adc321df2a @@ -176,13 +176,13 @@ F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 F src/delete.c bcf8f72126cea80fc3d5bc5494cf19b3f8935aaf F src/expr.c 4f9e497c66e2f25a4d139357a778c84d5713207c F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb -F src/fkey.c 5269ef07b100763134f71b889327c333bd0989cf +F src/fkey.c a549cff9fe8b736cdae21650ea0af6de29b77619 F src/func.c 2e16316ec3a6365a0dc3e553c586f91b20f7f6c8 F src/global.c 1e4bd956dc2f608f87d2a929abc4a20db65f30e4 F src/hash.c d139319967164f139c8d1bb8a11b14db9c4ba3cd F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c ac1a00ca5952555ad54911666762ee5d59cb63cd +F src/insert.c a038daeadfb818aaadafa854f40f5623b6929d84 F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b @@ -220,12 +220,12 @@ F src/printf.c e5a0005f8b3de21f85da6a709d2fbee76775bf4b F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 273d5f47c4e2c05b2d3d2bffeda939551ab59e66 F src/rowset.c a9c9aae3234b44a6d7c6f5a3cadf90dce1e627be -F src/select.c a6e8fe35d2929911448fe29fc9194eec73c6c0a5 +F src/select.c 7df17ec5506c2427576d412bee0e6ea740e12563 F src/shell.c bfac06fb15f3cd0d447e2e72ab3a283fac301813 F src/sqlite.h.in 564fc23db33870b5096b20d72df7491ce0b8b74f F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h 1977f44283be0d3b40da315fb4fd9e21c79fadcc +F src/sqliteInt.h fccdc735c27b3dc12322fec7cdad8bc76be8d00b F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -277,7 +277,7 @@ F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/tokenize.c 6da2de6e12218ccb0aea5184b56727d011f4bee7 F src/trigger.c 66f3470b03b52b395e839155786966e3e037fddb -F src/update.c 5b3e74a03b3811e586b4f2b4cbd7c49f01c93115 +F src/update.c 01564b3c430f6c7b0a35afaf7aba7987206fa3a5 F src/utf.c 6dc9ec9f1b3db43ae8ba0365377f11df1ee4c01c F src/util.c 049fe1d3c0e2209c1bee107aec2fcff6285f909f F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 @@ -294,7 +294,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 76e7fc6de229bea8b30bb2539110f03a494dc3a8 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45 -F src/where.c a2dba34bd878afd6266f21c72858cede8fd015b3 +F src/where.c b3be5eb4193b6327c4a02fe91411df503fe770e8 F src/whereInt.h 6804c2e5010378568c2bb1350477537755296a46 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1173,7 +1173,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 77fef5a3987fc16f84a8e755283ca6ec1363013c -R 9c15bb60113056d77932f80a5eec6f19 +P 9c785c58327e08dad94a278a643a5443f94aec36 +R 58924fd70359b2c52e2bf8678fd7d495 U drh -Z 4fb05aa38d1f916817ea122f0841369f +Z 5d9af4bfdc2c3042e69c13bc9e203142 diff --git a/manifest.uuid b/manifest.uuid index 24937ad719..49de0b7405 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9c785c58327e08dad94a278a643a5443f94aec36 \ No newline at end of file +d16e575dacc811de0f7b58a0d1cd243678dce6c5 \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index 2952b364c3..4dcd7e8b8f 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -1002,7 +1002,7 @@ static void analyzeOneTable( if( aGotoChng==0 ) continue; /* Populate the register containing the index name. */ - if( pIdx->autoIndex==2 && !HasRowid(pTab) ){ + if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){ zIdxName = pTab->zName; }else{ zIdxName = pIdx->zName; diff --git a/src/build.c b/src/build.c index 8615fe76d4..677ba326c6 100644 --- a/src/build.c +++ b/src/build.c @@ -757,7 +757,7 @@ int sqlite3CheckObjectName(Parse *pParse, const char *zName){ */ Index *sqlite3PrimaryKeyIndex(Table *pTab){ Index *p; - for(p=pTab->pIndex; p && p->autoIndex!=2; p=p->pNext){} + for(p=pTab->pIndex; p && !IsPrimaryKeyIndex(p); p=p->pNext){} return p; } @@ -1286,7 +1286,7 @@ void sqlite3AddPrimaryKey( p = sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0, 0, sortOrder, 0); if( p ){ - p->autoIndex = 2; + p->idxType = SQLITE_IDXTYPE_PRIMARYKEY; if( v ) sqlite3VdbeJumpHere(v, pParse->addrSkipPK); } pList = 0; @@ -1661,7 +1661,7 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ assert( pParse->pNewTable==pTab ); pPk = sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0); if( pPk==0 ) return; - pPk->autoIndex = 2; + pPk->idxType = SQLITE_IDXTYPE_PRIMARYKEY; pTab->iPKey = -1; }else{ pPk = sqlite3PrimaryKeyIndex(pTab); @@ -1684,7 +1684,7 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ */ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ int n; - if( pIdx->autoIndex==2 ) continue; + if( IsPrimaryKeyIndex(pIdx) ) continue; for(i=n=0; iaiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) ) n++; } @@ -2764,7 +2764,7 @@ Index *sqlite3AllocateIndexObject( ** ** If the index is created successfully, return a pointer to the new Index ** structure. This is used by sqlite3AddPrimaryKey() to mark the index -** as the tables primary key (Index.autoIndex==2). +** as the tables primary key (Index.idxType==SQLITE_IDXTYPE_PRIMARYKEY) */ Index *sqlite3CreateIndex( Parse *pParse, /* All information about this parse */ @@ -2979,7 +2979,7 @@ Index *sqlite3CreateIndex( pIndex->pTable = pTab; pIndex->onError = (u8)onError; pIndex->uniqNotNull = onError!=OE_None; - pIndex->autoIndex = (u8)(pName==0); + pIndex->idxType = pName ? SQLITE_IDXTYPE_APPDEF : SQLITE_IDXTYPE_UNIQUE; pIndex->pSchema = db->aDb[iDb].pSchema; pIndex->nKeyCol = pList->nExpr; if( pPIWhere ){ @@ -3091,7 +3091,7 @@ Index *sqlite3CreateIndex( for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ int k; assert( pIdx->onError!=OE_None ); - assert( pIdx->autoIndex ); + assert( pIdx->idxType!=SQLITE_IDXTYPE_APPDEF ); assert( pIndex->onError!=OE_None ); if( pIdx->nKeyCol!=pIndex->nKeyCol ) continue; @@ -3314,7 +3314,7 @@ void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists){ pParse->checkSchema = 1; goto exit_drop_index; } - if( pIndex->autoIndex ){ + if( pIndex->idxType!=SQLITE_IDXTYPE_APPDEF ){ sqlite3ErrorMsg(pParse, "index associated with UNIQUE " "or PRIMARY KEY constraint cannot be dropped", 0); goto exit_drop_index; @@ -3973,7 +3973,8 @@ void sqlite3UniqueConstraint( } zErr = sqlite3StrAccumFinish(&errMsg); sqlite3HaltConstraint(pParse, - (pIdx->autoIndex==2)?SQLITE_CONSTRAINT_PRIMARYKEY:SQLITE_CONSTRAINT_UNIQUE, + IsPrimaryKeyIndex(pIdx) ? SQLITE_CONSTRAINT_PRIMARYKEY + : SQLITE_CONSTRAINT_UNIQUE, onError, zErr, P4_DYNAMIC, P5_ConstraintUnique); } diff --git a/src/fkey.c b/src/fkey.c index 336256e0f3..c3cac276a9 100644 --- a/src/fkey.c +++ b/src/fkey.c @@ -233,8 +233,8 @@ int sqlite3FkLocateIndex( if( zKey==0 ){ /* If zKey is NULL, then this foreign key is implicitly mapped to ** the PRIMARY KEY of table pParent. The PRIMARY KEY index may be - ** identified by the test (Index.autoIndex==2). */ - if( pIdx->autoIndex==2 ){ + ** identified by the test. */ + if( IsPrimaryKeyIndex(pIdx) ){ if( aiCol ){ int i; for(i=0; iaCol[i].iFrom; diff --git a/src/insert.c b/src/insert.c index 9f588d9063..7b427d1eb6 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1463,7 +1463,7 @@ void sqlite3GenerateConstraintChecks( ** KEY values of this row before the update. */ int addrJump = sqlite3VdbeCurrentAddr(v)+pPk->nKeyCol; int op = OP_Ne; - int regCmp = (pIdx->autoIndex==2 ? regIdx : regR); + int regCmp = (IsPrimaryKeyIndex(pIdx) ? regIdx : regR); for(i=0; inKeyCol; i++){ char *p4 = (char*)sqlite3LocateCollSeq(pParse, pPk->azColl[i]); @@ -1564,7 +1564,7 @@ void sqlite3CompleteInsertion( sqlite3VdbeAddOp2(v, OP_IdxInsert, iIdxCur+i, aRegIdx[i]); pik_flags = 0; if( useSeekResult ) pik_flags = OPFLAG_USESEEKRESULT; - if( pIdx->autoIndex==2 && !HasRowid(pTab) ){ + if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){ assert( pParse->nested==0 ); pik_flags |= OPFLAG_NCHANGE; } @@ -1650,7 +1650,7 @@ int sqlite3OpenTableAndIndices( for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ int iIdxCur = iBase++; assert( pIdx->pSchema==pTab->pSchema ); - if( pIdx->autoIndex==2 && !HasRowid(pTab) && piDataCur ){ + if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) && piDataCur ){ *piDataCur = iIdxCur; } if( aToOpen==0 || aToOpen[i+1] ){ diff --git a/src/select.c b/src/select.c index b3939ba643..ba6f6551af 100644 --- a/src/select.c +++ b/src/select.c @@ -4498,7 +4498,7 @@ static void explainSimpleCount( Index *pIdx /* Index used to optimize scan, or NULL */ ){ if( pParse->explain==2 ){ - int bCover = (pIdx!=0 && (HasRowid(pTab) || pIdx->autoIndex!=2)); + int bCover = (pIdx!=0 && (HasRowid(pTab) || !IsPrimaryKeyIndex(pIdx))); char *zEqp = sqlite3MPrintf(pParse->db, "SCAN TABLE %s%s%s", pTab->zName, bCover ? " USING COVERING INDEX " : "", diff --git a/src/sqliteInt.h b/src/sqliteInt.h index bb8763ccbb..cc3a030510 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1694,7 +1694,7 @@ struct Index { u16 nKeyCol; /* Number of columns forming the key */ u16 nColumn; /* Number of columns stored in the index */ u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ - unsigned autoIndex:2; /* 1==UNIQUE, 2==PRIMARY KEY, 0==CREATE INDEX */ + unsigned idxType:2; /* 1==UNIQUE, 2==PRIMARY KEY, 0==CREATE INDEX */ unsigned bUnordered:1; /* Use this index for == or IN queries only */ unsigned uniqNotNull:1; /* True if UNIQUE and NOT NULL for all columns */ unsigned isResized:1; /* True if resizeIndexObject() has been called */ @@ -1707,6 +1707,16 @@ struct Index { #endif }; +/* +** Allowed values for Index.idxType +*/ +#define SQLITE_IDXTYPE_APPDEF 0 /* Created using CREATE INDEX */ +#define SQLITE_IDXTYPE_UNIQUE 1 /* Implements a UNIQUE constraint */ +#define SQLITE_IDXTYPE_PRIMARYKEY 2 /* Is the PRIMARY KEY for the table */ + +/* Return true if index X is a PRIMARY KEY index */ +#define IsPrimaryKeyIndex(X) ((X)->idxType==SQLITE_IDXTYPE_PRIMARYKEY) + /* ** Each sample stored in the sqlite_stat3 table is represented in memory ** using a structure of this type. See documentation at the top of the diff --git a/src/update.c b/src/update.c index 4138749f80..3e04e00316 100644 --- a/src/update.c +++ b/src/update.c @@ -187,7 +187,7 @@ void sqlite3Update( iIdxCur = iDataCur+1; pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab); for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ - if( pIdx->autoIndex==2 && pPk!=0 ){ + if( IsPrimaryKeyIndex(pIdx) && pPk!=0 ){ iDataCur = pParse->nTab; pTabList->a[0].iCursor = iDataCur; } diff --git a/src/where.c b/src/where.c index ff94822ebe..25c1c04148 100644 --- a/src/where.c +++ b/src/where.c @@ -2722,7 +2722,7 @@ static void explainOneScan( Index *pIdx = pLoop->u.btree.pIndex; char *zWhere = explainIndexRange(db, pLoop, pItem->pTab); assert( !(flags&WHERE_AUTO_INDEX) || (flags&WHERE_IDX_ONLY) ); - if( !HasRowid(pItem->pTab) && pIdx->autoIndex==2 ){ + if( !HasRowid(pItem->pTab) && IsPrimaryKeyIndex(pIdx) ){ zFmt = zWhere ? "%s USING PRIMARY KEY%.0s%s" : "%s%.0s%s"; }else if( flags & WHERE_AUTO_INDEX ){ zFmt = "%s USING AUTOMATIC COVERING INDEX%.0s%s"; @@ -3505,7 +3505,7 @@ static Bitmask codeOneLoopStart( assert( (pSubLoop->wsFlags & WHERE_AUTO_INDEX)==0 ); if( (pSubLoop->wsFlags & WHERE_INDEXED)!=0 && (ii==0 || pSubLoop->u.btree.pIndex==pCov) - && (HasRowid(pTab) || pSubLoop->u.btree.pIndex->autoIndex!=2) + && (HasRowid(pTab) || !IsPrimaryKeyIndex(pSubLoop->u.btree.pIndex)) ){ assert( pSubWInfo->a[0].iIdxCur==iCovCur ); pCov = pSubLoop->u.btree.pIndex; @@ -6079,7 +6079,7 @@ WhereInfo *sqlite3WhereBegin( int op = OP_OpenRead; /* iIdxCur is always set if to a positive value if ONEPASS is possible */ assert( iIdxCur!=0 || (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 ); - if( !HasRowid(pTab) && pIx->autoIndex==2 + if( !HasRowid(pTab) && IsPrimaryKeyIndex(pIx) && (wctrlFlags & WHERE_ONETABLE_ONLY)!=0 ){ /* This is one term of an OR-optimization using the PRIMARY KEY of a From 3c559a8d3cc3a39a5fb5e2bd46726c52623d69cb Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 27 May 2014 19:18:36 +0000 Subject: [PATCH 11/18] Fix harmless compiler warnings. FossilOrigin-Name: 20b75460c0661b5dc071177b4a0791aceccda029 --- ext/fts3/fts3.c | 2 +- ext/fts3/fts3_write.c | 4 ++-- manifest | 16 ++++++++-------- manifest.uuid | 2 +- tool/warnings.sh | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/ext/fts3/fts3.c b/ext/fts3/fts3.c index 318a927087..1676fd41e1 100644 --- a/ext/fts3/fts3.c +++ b/ext/fts3/fts3.c @@ -1376,7 +1376,7 @@ static int fts3InitVtab( int n = (int)strlen(p->azColumn[iCol]); for(i=0; iazColumn[iCol], zNot, n) ){ p->abNotindexed[iCol] = 1; diff --git a/ext/fts3/fts3_write.c b/ext/fts3/fts3_write.c index ea3c08802a..72df64f26b 100644 --- a/ext/fts3/fts3_write.c +++ b/ext/fts3/fts3_write.c @@ -3065,7 +3065,7 @@ static int fts3PromoteSegments( sqlite3_bind_int64(pRange, 1, iAbsLevel+1); sqlite3_bind_int64(pRange, 2, iLast); while( SQLITE_ROW==sqlite3_step(pRange) ){ - i64 nSize, dummy; + i64 nSize = 0, dummy; fts3ReadEndBlockField(pRange, 2, &dummy, &nSize); if( nSize<=0 || nSize>nLimit ){ /* If nSize==0, then the %_segdir.end_block field does not not @@ -4870,7 +4870,7 @@ int sqlite3Fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){ rc = fts3IncrmergeOutputIdx(p, iAbsLevel, &iIdx); assert( bUseHint==1 || bUseHint==0 ); if( iIdx==0 || (bUseHint && iIdx==1) ){ - int bIgnore; + int bIgnore = 0; rc = fts3SegmentIsMaxLevel(p, iAbsLevel+1, &bIgnore); if( bIgnore ){ pFilter->flags |= FTS3_SEGMENT_IGNORE_EMPTY; diff --git a/manifest b/manifest index 0de865b6a4..937dcd7369 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\sname\sof\sthe\sIndex.autoIndex\sfield\sto\sIndex.idxType\sand\sprovide\nsymbolic\snames\sfor\sthe\svarious\svalues\sof\sthat\sfield\srather\sthan\susing\nmagic\snumbers. -D 2014-05-27T18:18:58.025 +C Fix\sharmless\scompiler\swarnings. +D 2014-05-27T19:18:36.162 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in dd2b1aba364ff9b05de41086f74407f285c57670 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -78,7 +78,7 @@ F ext/fts3/README.content fdc666a70d5257a64fee209f97cf89e0e6e32b51 F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a F ext/fts3/README.tokenizers e0a8b81383ea60d0334d274fadf305ea14a8c314 F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d -F ext/fts3/fts3.c 0a9813c01ce7cc33d63680725ea30755d77c7b39 +F ext/fts3/fts3.c 20bc65862cfcea0a39bb64a819f8fe92a8e144c1 F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe F ext/fts3/fts3Int.h 16cddf2d7b0e5f3681615ae1d8ca0e45fca44918 F ext/fts3/fts3_aux.c 5c211e17a64885faeb16b9ba7772f9d5445c2365 @@ -96,7 +96,7 @@ F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3 F ext/fts3/fts3_tokenizer1.c 5c98225a53705e5ee34824087478cf477bdb7004 F ext/fts3/fts3_unicode.c 92391b4b4fb043564c6539ea9b8661e3bcba47b9 F ext/fts3/fts3_unicode2.c 0113d3acf13429e6dc38e0647d1bc71211c31a4d -F ext/fts3/fts3_write.c 9e4e8579ad26cff3ee7743aaf5c3fe937fc441b4 +F ext/fts3/fts3_write.c 5ee9d894da74a5d15a3c317414fb8c84f1694fa4 F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9 F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100 F ext/fts3/tool/fts3view.c 6cfc5b67a5f0e09c0d698f9fd012c784bfaa9197 @@ -1171,9 +1171,9 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 -F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 +F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 9c785c58327e08dad94a278a643a5443f94aec36 -R 58924fd70359b2c52e2bf8678fd7d495 +P d16e575dacc811de0f7b58a0d1cd243678dce6c5 +R b87af21bb1b8599ff9f8b8b0d9487163 U drh -Z 5d9af4bfdc2c3042e69c13bc9e203142 +Z 6454dd72a172141a989aefb8a68747be diff --git a/manifest.uuid b/manifest.uuid index 49de0b7405..626f68ec67 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d16e575dacc811de0f7b58a0d1cd243678dce6c5 \ No newline at end of file +20b75460c0661b5dc071177b4a0791aceccda029 \ No newline at end of file diff --git a/tool/warnings.sh b/tool/warnings.sh index 246bccbe23..5d71361138 100644 --- a/tool/warnings.sh +++ b/tool/warnings.sh @@ -4,7 +4,7 @@ # compiler warnings in SQLite. # rm -f sqlite3.c -make sqlite3.c-debug +make sqlite3.c echo '********** No optimizations. Includes FTS4 and RTREE *********' gcc -c -Wshadow -Wall -Wextra -pedantic-errors -Wno-long-long -std=c89 \ -ansi -DHAVE_STDINT_H -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_RTREE \ From e9afc3f27984cfe73716ba7e589fdf70d33373e3 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 27 May 2014 20:19:06 +0000 Subject: [PATCH 12/18] Remove an incorrect assert() in the sorter. FossilOrigin-Name: b8b66103de8c554cb87df40bf040760ec29f2ae1 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbesort.c | 1 - 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 937dcd7369..c071341fc7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings. -D 2014-05-27T19:18:36.162 +C Remove\san\sincorrect\sassert()\sin\sthe\ssorter. +D 2014-05-27T20:19:06.293 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in dd2b1aba364ff9b05de41086f74407f285c57670 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -288,7 +288,7 @@ F src/vdbeapi.c 0ed6053f947edd0b30f64ce5aeb811872a3450a4 F src/vdbeaux.c e493f38758c4b8f4ca2007cf6a700bd405d192f3 F src/vdbeblob.c 9205ce9d3b064d9600f8418a897fc88b5687d9ac F src/vdbemem.c 6fc77594c60f6155404f3f8d71bf36d1fdeb4447 -F src/vdbesort.c 4abb7c0f8f19b7d7d82f4558d5da1a30fdf9ea38 +F src/vdbesort.c 44441d73b08b3a638dcdb725afffb87c6574ad27 F src/vdbetrace.c 6f52bc0c51e144b7efdcfb2a8f771167a8816767 F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 76e7fc6de229bea8b30bb2539110f03a494dc3a8 @@ -1173,7 +1173,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P d16e575dacc811de0f7b58a0d1cd243678dce6c5 -R b87af21bb1b8599ff9f8b8b0d9487163 +P 20b75460c0661b5dc071177b4a0791aceccda029 +R d313f2f9d0d10f0cab7c1f3623a16b09 U drh -Z 6454dd72a172141a989aefb8a68747be +Z b3d89b92529dc184b6d7c7b851a6fe5b diff --git a/manifest.uuid b/manifest.uuid index 626f68ec67..dcd05b62b0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -20b75460c0661b5dc071177b4a0791aceccda029 \ No newline at end of file +b8b66103de8c554cb87df40bf040760ec29f2ae1 \ No newline at end of file diff --git a/src/vdbesort.c b/src/vdbesort.c index d1b726b727..d3690244c4 100644 --- a/src/vdbesort.c +++ b/src/vdbesort.c @@ -350,7 +350,6 @@ static int vdbeSorterIterInit( rc = sqlite3OsRead( pSorter->pTemp1, &pIter->aBuffer[iBuf], nRead, iStart ); - assert( rc!=SQLITE_IOERR_SHORT_READ ); } if( rc==SQLITE_OK ){ From ff0bc8f9f776fca7f6288b7e725f9bc0cc5468ac Mon Sep 17 00:00:00 2001 From: mistachkin Date: Wed, 28 May 2014 03:23:55 +0000 Subject: [PATCH 13/18] Revise how OSTRACE reports logically boolean results in the Win32 VFS. FossilOrigin-Name: c405f971cf03e29110019ff863cbfb026d97e1e6 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/os_win.c | 24 ++++++++++++------------ 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/manifest b/manifest index c071341fc7..faef47fa27 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sincorrect\sassert()\sin\sthe\ssorter. -D 2014-05-27T20:19:06.293 +C Revise\show\sOSTRACE\sreports\slogically\sboolean\sresults\sin\sthe\sWin32\sVFS. +D 2014-05-28T03:23:55.937 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in dd2b1aba364ff9b05de41086f74407f285c57670 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -206,7 +206,7 @@ F src/os.h 60d419395e32a8029fa380a80a3da2e9030f635e F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c ae4b5240af4619d711301d7992396e182585269f -F src/os_win.c 485d06a93965f306c7281fca0937829292367234 +F src/os_win.c 648f842876e25391b7c454c8e49f7db1fd981d65 F src/os_win.h 057344a6720b4c8405d9bd98f58cb37a6ee46c25 F src/pager.c f6bb1fa6cdf2062f2d8aec3e64db302bca519ab8 F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428 @@ -1173,7 +1173,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 20b75460c0661b5dc071177b4a0791aceccda029 -R d313f2f9d0d10f0cab7c1f3623a16b09 -U drh -Z b3d89b92529dc184b6d7c7b851a6fe5b +P b8b66103de8c554cb87df40bf040760ec29f2ae1 +R fb2228bf340b8e64476c0b547456f447 +U mistachkin +Z 33db4268ebdb5368353cf9e380a10aca diff --git a/manifest.uuid b/manifest.uuid index dcd05b62b0..a5c805d0f6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b8b66103de8c554cb87df40bf040760ec29f2ae1 \ No newline at end of file +c405f971cf03e29110019ff863cbfb026d97e1e6 \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index fcac665dff..21f633e486 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -2825,7 +2825,7 @@ static int winGetReadLock(winFile *pFile){ pFile->lastErrno = osGetLastError(); /* No need to log a failure to lock */ } - OSTRACE(("READ-LOCK file=%p, rc=%s\n", pFile->h, sqlite3ErrName(res))); + OSTRACE(("READ-LOCK file=%p, result=%d\n", pFile->h, res)); return res; } @@ -2849,7 +2849,7 @@ static int winUnlockReadLock(winFile *pFile){ winLogError(SQLITE_IOERR_UNLOCK, pFile->lastErrno, "winUnlockReadLock", pFile->zPath); } - OSTRACE(("READ-UNLOCK file=%p, rc=%s\n", pFile->h, sqlite3ErrName(res))); + OSTRACE(("READ-UNLOCK file=%p, result=%d\n", pFile->h, res)); return res; } @@ -2924,8 +2924,8 @@ static int winLock(sqlite3_file *id, int locktype){ ** If you are using this code as a model for alternative VFSes, do not ** copy this retry logic. It is a hack intended for Windows only. */ - OSTRACE(("LOCK-PENDING-FAIL file=%p, count=%d, rc=%s\n", - pFile->h, cnt, sqlite3ErrName(res))); + OSTRACE(("LOCK-PENDING-FAIL file=%p, count=%d, result=%d\n", + pFile->h, cnt, res)); if( cnt ) sqlite3_win32_sleep(1); } gotPendingLock = res; @@ -3010,7 +3010,7 @@ static int winLock(sqlite3_file *id, int locktype){ ** non-zero, otherwise zero. */ static int winCheckReservedLock(sqlite3_file *id, int *pResOut){ - int rc; + int res; winFile *pFile = (winFile*)id; SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); @@ -3018,17 +3018,17 @@ static int winCheckReservedLock(sqlite3_file *id, int *pResOut){ assert( id!=0 ); if( pFile->locktype>=RESERVED_LOCK ){ - rc = 1; - OSTRACE(("TEST-WR-LOCK file=%p, rc=%d (local)\n", pFile->h, rc)); + res = 1; + OSTRACE(("TEST-WR-LOCK file=%p, result=%d (local)\n", pFile->h, res)); }else{ - rc = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS,RESERVED_BYTE, 0, 1, 0); - if( rc ){ + res = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS,RESERVED_BYTE, 0, 1, 0); + if( res ){ winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0); } - rc = !rc; - OSTRACE(("TEST-WR-LOCK file=%p, rc=%d (remote)\n", pFile->h, rc)); + res = !res; + OSTRACE(("TEST-WR-LOCK file=%p, result=%d (remote)\n", pFile->h, res)); } - *pResOut = rc; + *pResOut = res; OSTRACE(("TEST-WR-LOCK file=%p, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n", pFile->h, pResOut, *pResOut)); return SQLITE_OK; From 3b21f6d62d781d2621d4057e019711145b147412 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 28 May 2014 10:00:38 +0000 Subject: [PATCH 14/18] Add an extra test to verify that the FTS notindexed option is working. FossilOrigin-Name: c461c0fe051d33cc8b4fede4eca13cd71f28126a --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/fts4noti.test | 17 +++++++++++++++++ 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index faef47fa27..4747c006d3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Revise\show\sOSTRACE\sreports\slogically\sboolean\sresults\sin\sthe\sWin32\sVFS. -D 2014-05-28T03:23:55.937 +C Add\san\sextra\stest\sto\sverify\sthat\sthe\sFTS\snotindexed\soption\sis\sworking. +D 2014-05-28T10:00:38.278 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in dd2b1aba364ff9b05de41086f74407f285c57670 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -578,7 +578,7 @@ F test/fts4merge.test c424309743fdd203f8e56a1f1cd7872cd66cc0ee F test/fts4merge2.test 5faa558d1b672f82b847d2a337465fa745e46891 F test/fts4merge3.test aab02a09f50fe6baaddc2e159c3eabc116d45fc7 F test/fts4merge4.test d895b1057a7798b67e03455d0fa50e9ea836c47b -F test/fts4noti.test 9695c7c6c32480ea9fc20a2b38ed1de0640bcaec +F test/fts4noti.test 524807f0c36d49deea7920cdd4cd687408b58849 F test/fts4unicode.test 01ec3fe2a7c3cfff3b4c0581b83caa11b33efa36 F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d F test/func.test ae97561957aba6ca9e3a7b8a13aac41830d701ef @@ -1173,7 +1173,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P b8b66103de8c554cb87df40bf040760ec29f2ae1 -R fb2228bf340b8e64476c0b547456f447 -U mistachkin -Z 33db4268ebdb5368353cf9e380a10aca +P c405f971cf03e29110019ff863cbfb026d97e1e6 +R e5a9e845a94856ba3834be3d275aa741 +U dan +Z 682e816d8cc7267dd27dd1b8bd8b3242 diff --git a/manifest.uuid b/manifest.uuid index a5c805d0f6..d400b38cb0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c405f971cf03e29110019ff863cbfb026d97e1e6 \ No newline at end of file +c461c0fe051d33cc8b4fede4eca13cd71f28126a \ No newline at end of file diff --git a/test/fts4noti.test b/test/fts4noti.test index 1b39a73950..c90999b4fa 100644 --- a/test/fts4noti.test +++ b/test/fts4noti.test @@ -210,6 +210,23 @@ do_execsql_test 6.2.5 { SELECT * FROM t1 WHERE t1 MATCH '60*'; } { Restaurant 6021 } +do_execsql_test 6.3.1 { + DROP TABLE t1; + CREATE VIRTUAL TABLE t1 USING fts4(abc, ab, a, notindexed=abc); + CREATE VIRTUAL TABLE t2 USING fts4(a, ab, abc, notindexed=abc); + + INSERT INTO t1 VALUES('no', 'yes', 'yep'); + INSERT INTO t2 VALUES('yep', 'yes', 'no'); + + SELECT count(*) FROM t1 WHERE t1 MATCH 'no'; + SELECT count(*) FROM t1 WHERE t1 MATCH 'yes'; + SELECT count(*) FROM t1 WHERE t1 MATCH 'yep'; + + SELECT count(*) FROM t2 WHERE t2 MATCH 'no'; + SELECT count(*) FROM t2 WHERE t2 MATCH 'yes'; + SELECT count(*) FROM t2 WHERE t2 MATCH 'yep'; +} {0 1 1 0 1 1} + finish_test From 62cdde539c92ec60907d862125f2280e605514a5 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 28 May 2014 20:22:28 +0000 Subject: [PATCH 15/18] Add the ".shell" and the ".system" commands (aliases for the same thing) to the command-line shell. FossilOrigin-Name: d018a34a05cec6adda61ed225d084c587343f2a6 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c | 19 ++++++++++++++++++- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 4747c006d3..593d435c92 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\san\sextra\stest\sto\sverify\sthat\sthe\sFTS\snotindexed\soption\sis\sworking. -D 2014-05-28T10:00:38.278 +C Add\sthe\s".shell"\sand\sthe\s".system"\scommands\s(aliases\sfor\sthe\ssame\sthing)\nto\sthe\scommand-line\sshell. +D 2014-05-28T20:22:28.746 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in dd2b1aba364ff9b05de41086f74407f285c57670 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -221,7 +221,7 @@ F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 273d5f47c4e2c05b2d3d2bffeda939551ab59e66 F src/rowset.c a9c9aae3234b44a6d7c6f5a3cadf90dce1e627be F src/select.c 7df17ec5506c2427576d412bee0e6ea740e12563 -F src/shell.c bfac06fb15f3cd0d447e2e72ab3a283fac301813 +F src/shell.c 8a0f8f4cd354a1b9f8181d747943c86c678dccfc F src/sqlite.h.in 564fc23db33870b5096b20d72df7491ce0b8b74f F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc @@ -1173,7 +1173,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P c405f971cf03e29110019ff863cbfb026d97e1e6 -R e5a9e845a94856ba3834be3d275aa741 -U dan -Z 682e816d8cc7267dd27dd1b8bd8b3242 +P c461c0fe051d33cc8b4fede4eca13cd71f28126a +R fb95d3a0c98ad15d709d47a9c08467f3 +U drh +Z 7af2c566de91be5522e4d89625d0c4dc diff --git a/manifest.uuid b/manifest.uuid index d400b38cb0..e9e567d457 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c461c0fe051d33cc8b4fede4eca13cd71f28126a \ No newline at end of file +d018a34a05cec6adda61ed225d084c587343f2a6 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 08ed195449..ddda4fd63f 100644 --- a/src/shell.c +++ b/src/shell.c @@ -1580,7 +1580,7 @@ static char zHelp[] = ".exit Exit this program\n" ".explain ?ON|OFF? Turn output mode suitable for EXPLAIN on or off.\n" " With no args, it turns EXPLAIN on.\n" - ".header(s) ON|OFF Turn display of headers on or off\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" ".indices ?TABLE? Show names of all indices\n" @@ -1616,8 +1616,10 @@ static char zHelp[] = " If TABLE specified, only show tables matching\n" " LIKE pattern TABLE.\n" ".separator STRING Change separator used by output mode and .import\n" + ".shell CMD ARGS... Run CMD ARGS... in a system shell\n" ".show Show the current values for various settings\n" ".stats ON|OFF 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" @@ -1625,6 +1627,7 @@ static char zHelp[] = ".trace FILE|off Output each SQL statement as it is run\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" ; static char zTimerHelp[] = @@ -2900,6 +2903,20 @@ static int do_meta_command(char *zLine, struct callback_data *p){ "%.*s", (int)sizeof(p->separator)-1, azArg[1]); }else + if( c=='s' + && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0) + && nArg>=2 + ){ + char *zCmd; + int i; + zCmd = sqlite3_mprintf("\"%s\"", azArg[1]); + for(i=2; iout,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off"); From dcb3e3d62c72d45aa0ff1868f18303f2583e58b3 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 29 May 2014 03:17:29 +0000 Subject: [PATCH 16/18] Only quote the arguments to the ".shell" and ".system" commands if they contain spaces. FossilOrigin-Name: e58f4bd39d51c4c1a28684dab6427de81173d564 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c | 5 +++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 593d435c92..0d3e2478c4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s".shell"\sand\sthe\s".system"\scommands\s(aliases\sfor\sthe\ssame\sthing)\nto\sthe\scommand-line\sshell. -D 2014-05-28T20:22:28.746 +C Only\squote\sthe\sarguments\sto\sthe\s".shell"\sand\s".system"\scommands\sif\sthey\ncontain\sspaces. +D 2014-05-29T03:17:29.412 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in dd2b1aba364ff9b05de41086f74407f285c57670 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -221,7 +221,7 @@ F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 273d5f47c4e2c05b2d3d2bffeda939551ab59e66 F src/rowset.c a9c9aae3234b44a6d7c6f5a3cadf90dce1e627be F src/select.c 7df17ec5506c2427576d412bee0e6ea740e12563 -F src/shell.c 8a0f8f4cd354a1b9f8181d747943c86c678dccfc +F src/shell.c f389c2bcae6192daad01b46169e63538456427fa F src/sqlite.h.in 564fc23db33870b5096b20d72df7491ce0b8b74f F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc @@ -1173,7 +1173,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P c461c0fe051d33cc8b4fede4eca13cd71f28126a -R fb95d3a0c98ad15d709d47a9c08467f3 +P d018a34a05cec6adda61ed225d084c587343f2a6 +R c32df26ea35dc6668db5bcd28814662e U drh -Z 7af2c566de91be5522e4d89625d0c4dc +Z a04310abc4a1ec4cc8144d03b2ee32a5 diff --git a/manifest.uuid b/manifest.uuid index e9e567d457..944a28888f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d018a34a05cec6adda61ed225d084c587343f2a6 \ No newline at end of file +e58f4bd39d51c4c1a28684dab6427de81173d564 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index ddda4fd63f..f51ce9a164 100644 --- a/src/shell.c +++ b/src/shell.c @@ -2909,9 +2909,10 @@ static int do_meta_command(char *zLine, struct callback_data *p){ ){ char *zCmd; int i; - zCmd = sqlite3_mprintf("\"%s\"", azArg[1]); + zCmd = sqlite3_mprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]); for(i=2; i Date: Thu, 29 May 2014 12:36:14 +0000 Subject: [PATCH 17/18] Improvements to error messages for errors in the dot-commands of the command-line shell. Add the ".once" command. The output of ".help" now goes to the designated output channel. FossilOrigin-Name: 48dce821a07ac29da6ce05e92cf3f6e52b6eb388 --- manifest | 18 +-- manifest.uuid | 2 +- src/shell.c | 337 +++++++++++++++++++++++++++++++---------------- test/shell1.test | 90 ++++++------- test/shell4.test | 4 +- test/shell5.test | 16 +-- 6 files changed, 291 insertions(+), 176 deletions(-) diff --git a/manifest b/manifest index 0d3e2478c4..fb3c92c2cf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Only\squote\sthe\sarguments\sto\sthe\s".shell"\sand\s".system"\scommands\sif\sthey\ncontain\sspaces. -D 2014-05-29T03:17:29.412 +C Improvements\sto\serror\smessages\sfor\serrors\sin\sthe\sdot-commands\sof\sthe\ncommand-line\sshell.\s\sAdd\sthe\s".once"\scommand.\s\sThe\soutput\sof\s".help"\nnow\sgoes\sto\sthe\sdesignated\soutput\schannel. +D 2014-05-29T12:36:14.908 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in dd2b1aba364ff9b05de41086f74407f285c57670 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -221,7 +221,7 @@ F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 273d5f47c4e2c05b2d3d2bffeda939551ab59e66 F src/rowset.c a9c9aae3234b44a6d7c6f5a3cadf90dce1e627be F src/select.c 7df17ec5506c2427576d412bee0e6ea740e12563 -F src/shell.c f389c2bcae6192daad01b46169e63538456427fa +F src/shell.c a94689054bc0a66608f3d75b3ced2b886c3d7f50 F src/sqlite.h.in 564fc23db33870b5096b20d72df7491ce0b8b74f F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc @@ -813,11 +813,11 @@ F test/shared9.test 5f2a8f79b4d6c7d107a01ffa1ed05ae7e6333e21 F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5 F test/shared_err.test 0079c05c97d88cfa03989b7c20a8b266983087aa F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304 -F test/shell1.test f2a1d471e5cd2b42f7a65b166dc1ace2b8d11583 +F test/shell1.test fb080d67c81e8a80a79ea04b36f127209b5bd112 F test/shell2.test c57da3a381c099b02c813ba156298d5c2f5c93a3 F test/shell3.test 5e8545ec72c4413a0e8d4c6be56496e3c257ca29 -F test/shell4.test aa4eef8118b412d1a01477a53426ece169ea86a9 -F test/shell5.test fa5583230c0aea5c9ff33f0ac1e26b1e3f03d153 +F test/shell4.test 8a9c08976291e6c6c808b4d718f4a8b299f339f5 +F test/shell5.test 6b1a53c49a4ff5c3bd0bad17a85ecba505608278 F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3 F test/show_speedtest1_rtree.tcl 32e6c5f073d7426148a6936a0408f4b5b169aba5 F test/shrink.test 8c70f62b6e8eb4d54533de6d65bd06b1b9a17868 @@ -1173,7 +1173,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P d018a34a05cec6adda61ed225d084c587343f2a6 -R c32df26ea35dc6668db5bcd28814662e +P e58f4bd39d51c4c1a28684dab6427de81173d564 +R 7215154feb44506111be05bd24ee86a7 U drh -Z a04310abc4a1ec4cc8144d03b2ee32a5 +Z cfc4096d1968e16f0aae201a0082ea68 diff --git a/manifest.uuid b/manifest.uuid index 944a28888f..9fb4a9df39 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e58f4bd39d51c4c1a28684dab6427de81173d564 \ No newline at end of file +48dce821a07ac29da6ce05e92cf3f6e52b6eb388 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index f51ce9a164..e2748911e6 100644 --- a/src/shell.c +++ b/src/shell.c @@ -446,8 +446,9 @@ struct previous_mode_data { struct callback_data { sqlite3 *db; /* The database */ int echoOn; /* True to echo input commands */ - int autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL statement */ + int autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */ int statsOn; /* True to display memory stats before each finalize */ + int outCount; /* Revert to stdout when reaching zero */ int cnt; /* Number of records displayed so far */ FILE *out; /* Write results here */ FILE *traceOut; /* Output for sqlite3_trace() */ @@ -878,7 +879,8 @@ static int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int }else if( aiType && aiType[i]==SQLITE_TEXT ){ if( zSep[0] ) fprintf(p->out,"%s",zSep); output_quoted_string(p->out, azArg[i]); - }else if( aiType && (aiType[i]==SQLITE_INTEGER || aiType[i]==SQLITE_FLOAT) ){ + }else if( aiType && (aiType[i]==SQLITE_INTEGER + || aiType[i]==SQLITE_FLOAT) ){ fprintf(p->out,"%s%s",zSep, azArg[i]); }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){ const void *pBlob = sqlite3_column_blob(p->pStmt, i); @@ -1570,17 +1572,17 @@ static int run_schema_dump_query( */ static char zHelp[] = ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n" - ".bail ON|OFF Stop after hitting an error. Default OFF\n" + ".bail on|off Stop after hitting an error. Default OFF\n" ".clone NEWDB Clone data into NEWDB from the existing database\n" ".databases List names and files of attached databases\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" + ".echo on|off Turn command echo on or off\n" ".exit Exit this program\n" - ".explain ?ON|OFF? Turn output mode suitable for EXPLAIN on or off.\n" + ".explain ?on|off? Turn output mode suitable for EXPLAIN on or off.\n" " With no args, it turns EXPLAIN on.\n" - ".headers ON|OFF Turn display of headers on or off\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" ".indices ?TABLE? Show names of all indices\n" @@ -1603,9 +1605,9 @@ static char zHelp[] = " 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 ?FILENAME? Close existing database and reopen FILENAME\n" - ".output FILENAME Send output to FILENAME\n" - ".output stdout Send output to the screen\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" @@ -1618,22 +1620,19 @@ static char zHelp[] = ".separator STRING Change separator used by output mode and .import\n" ".shell CMD ARGS... Run CMD ARGS... in a system shell\n" ".show Show the current values for various settings\n" - ".stats ON|OFF Turn stats on or off\n" + ".stats on|off 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" ".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" ".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" ; -static char zTimerHelp[] = - ".timer ON|OFF Turn the CPU timer measurement on or off\n" -; - /* Forward reference */ static int process_input(struct callback_data *p, FILE *in); @@ -1675,6 +1674,7 @@ static void open_db(struct callback_data *p, int keepAlive){ 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=='\\' ){ c = z[++i]; @@ -1700,7 +1700,7 @@ static void resolve_backslashes(char *z){ } z[j] = c; } - z[j] = 0; + if( joutfile[0]=='|' ){ + pclose(p->out); + }else{ + output_file_close(p->out); + } + p->outfile[0] = 0; + p->out = stdout; +} + /* ** If an input line begins with "." then invoke this routine to ** process that line. @@ -2242,8 +2255,13 @@ static int do_meta_command(char *zLine, struct callback_data *p){ sqlite3_close(pDest); }else - if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 && nArg>1 && nArg<3 ){ - bail_on_error = booleanValue(azArg[1]); + if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){ + if( nArg==2 ){ + bail_on_error = booleanValue(azArg[1]); + }else{ + fprintf(stderr, "Usage: .bail on|off\n"); + rc = 1; + } }else /* The undocumented ".breakpoint" command causes a call to the no-op @@ -2253,11 +2271,16 @@ static int do_meta_command(char *zLine, struct callback_data *p){ test_breakpoint(); }else - if( c=='c' && strncmp(azArg[0], "clone", n)==0 && nArg>1 && nArg<3 ){ - tryToClone(p, azArg[1]); + if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){ + if( nArg==2 ){ + tryToClone(p, azArg[1]); + }else{ + fprintf(stderr, "Usage: .clone FILENAME\n"); + rc = 1; + } }else - if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 && nArg==1 ){ + if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){ struct callback_data data; char *zErrMsg = 0; open_db(p, 0); @@ -2276,11 +2299,16 @@ static int do_meta_command(char *zLine, struct callback_data *p){ } }else - if( c=='d' && strncmp(azArg[0], "dump", n)==0 && nArg<3 ){ + if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){ open_db(p, 0); /* When playing back a "dump", the content might appear in an order ** which causes immediate foreign key constraints to be violated. ** So disable foreign-key constraint enforcement to prevent problems. */ + if( nArg!=1 && nArg!=2 ){ + fprintf(stderr, "Usage: .dump ?LIKE-PATTERN?\n"); + rc = 1; + goto meta_command_exit; + } fprintf(p->out, "PRAGMA foreign_keys=OFF;\n"); fprintf(p->out, "BEGIN TRANSACTION;\n"); p->writableSchema = 0; @@ -2325,12 +2353,22 @@ static int do_meta_command(char *zLine, struct callback_data *p){ fprintf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n"); }else - if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 && nArg<3 ){ - p->echoOn = booleanValue(azArg[1]); + if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){ + if( nArg==2 ){ + p->echoOn = booleanValue(azArg[1]); + }else{ + fprintf(stderr, "Usage: .echo on|off\n"); + rc = 1; + } }else - if( c=='e' && strncmp(azArg[0], "eqp", n)==0 && nArg>1 && nArg<3 ){ - p->autoEQP = booleanValue(azArg[1]); + if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){ + if( nArg==2 ){ + p->autoEQP = booleanValue(azArg[1]); + }else{ + fprintf(stderr, "Usage: .eqp on|off\n"); + rc = 1; + } }else if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){ @@ -2338,7 +2376,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){ rc = 2; }else - if( c=='e' && strncmp(azArg[0], "explain", n)==0 && nArg<3 ){ + if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){ int val = nArg>=2 ? booleanValue(azArg[1]) : 1; if(val == 1) { if(!p->explainPrev.valid) { @@ -2373,19 +2411,20 @@ static int do_meta_command(char *zLine, struct callback_data *p){ } }else - if( c=='h' && (strncmp(azArg[0], "header", n)==0 || - strncmp(azArg[0], "headers", n)==0) && nArg>1 && nArg<3 ){ - p->showHeader = booleanValue(azArg[1]); - }else - - if( c=='h' && strncmp(azArg[0], "help", n)==0 ){ - fprintf(stderr,"%s",zHelp); - if( HAS_TIMER ){ - fprintf(stderr,"%s",zTimerHelp); + if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){ + if( nArg==2 ){ + p->showHeader = booleanValue(azArg[1]); + }else{ + fprintf(stderr, "Usage: .headers on|off\n"); + rc = 1; } }else - if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg==3 ){ + if( c=='h' && strncmp(azArg[0], "help", n)==0 ){ + fprintf(p->out, "%s", zHelp); + }else + + if( c=='i' && strncmp(azArg[0], "import", n)==0 ){ char *zTable = azArg[2]; /* Insert data into this table */ char *zFile = azArg[1]; /* Name of file to extra content from */ sqlite3_stmt *pStmt = NULL; /* A statement */ @@ -2398,6 +2437,10 @@ static int do_meta_command(char *zLine, struct callback_data *p){ CSVReader sCsv; /* Reader context */ int (*xCloser)(FILE*); /* Procedure to close th3 connection */ + if( nArg!=3 ){ + fprintf(stderr, "Usage: .import FILE TABLE\n"); + goto meta_command_exit; + } seenInterrupt = 0; memset(&sCsv, 0, sizeof(sCsv)); open_db(p, 0); @@ -2536,7 +2579,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){ if( needCommit ) sqlite3_exec(db, "COMMIT", 0, 0, 0); }else - if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg<3 ){ + if( c=='i' && strncmp(azArg[0], "indices", n)==0 ){ struct callback_data data; char *zErrMsg = 0; open_db(p, 0); @@ -2553,7 +2596,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){ "ORDER BY 1", callback, &data, &zErrMsg ); - }else{ + }else if( nArg==2 ){ zShellStatic = azArg[1]; rc = sqlite3_exec(p->db, "SELECT name FROM sqlite_master " @@ -2565,6 +2608,10 @@ static int do_meta_command(char *zLine, struct callback_data *p){ callback, &data, &zErrMsg ); zShellStatic = 0; + }else{ + fprintf(stderr, "Usage: .indices ?LIKE-PATTERN?\n"); + rc = 1; + goto meta_command_exit; } if( zErrMsg ){ fprintf(stderr,"Error: %s\n", zErrMsg); @@ -2600,9 +2647,14 @@ static int do_meta_command(char *zLine, struct callback_data *p){ #endif #ifndef SQLITE_OMIT_LOAD_EXTENSION - if( c=='l' && strncmp(azArg[0], "load", n)==0 && nArg>=2 ){ + if( c=='l' && strncmp(azArg[0], "load", n)==0 ){ const char *zFile, *zProc; char *zErrMsg = 0; + if( nArg<2 ){ + fprintf(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); @@ -2615,38 +2667,41 @@ static int do_meta_command(char *zLine, struct callback_data *p){ }else #endif - if( c=='l' && strncmp(azArg[0], "log", n)==0 && nArg>=2 ){ - const char *zFile = azArg[1]; - output_file_close(p->pLog); - p->pLog = output_file_open(zFile); + if( c=='l' && strncmp(azArg[0], "log", n)==0 ){ + if( nArg!=2 ){ + fprintf(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 && nArg==2 ){ - int n2 = strlen30(azArg[1]); - if( (n2==4 && strncmp(azArg[1],"line",n2)==0) - || - (n2==5 && strncmp(azArg[1],"lines",n2)==0) ){ + 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; - }else if( (n2==6 && strncmp(azArg[1],"column",n2)==0) - || - (n2==7 && strncmp(azArg[1],"columns",n2)==0) ){ + }else if( c2=='c' && strncmp(azArg[1],"columns",n2)==0 ){ p->mode = MODE_Column; - }else if( n2==4 && strncmp(azArg[1],"list",n2)==0 ){ + }else if( c2=='l' && n2>2 && strncmp(azArg[1],"list",n2)==0 ){ p->mode = MODE_List; - }else if( n2==4 && strncmp(azArg[1],"html",n2)==0 ){ + }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){ p->mode = MODE_Html; - }else if( n2==3 && strncmp(azArg[1],"tcl",n2)==0 ){ + }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){ p->mode = MODE_Tcl; sqlite3_snprintf(sizeof(p->separator), p->separator, " "); - }else if( n2==3 && strncmp(azArg[1],"csv",n2)==0 ){ + }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){ p->mode = MODE_Csv; sqlite3_snprintf(sizeof(p->separator), p->separator, ","); - }else if( n2==4 && strncmp(azArg[1],"tabs",n2)==0 ){ + }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){ p->mode = MODE_List; sqlite3_snprintf(sizeof(p->separator), p->separator, "\t"); - }else if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){ + }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){ p->mode = MODE_Insert; - set_table_name(p, "table"); + set_table_name(p, nArg>=3 ? azArg[2] : "table"); }else { fprintf(stderr,"Error: mode should be one of: " "column csv html insert line list tabs tcl\n"); @@ -2654,23 +2709,16 @@ static int do_meta_command(char *zLine, struct callback_data *p){ } }else - if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==3 ){ - int n2 = strlen30(azArg[1]); - if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){ - p->mode = MODE_Insert; - set_table_name(p, azArg[2]); - }else { - fprintf(stderr, "Error: invalid arguments: " - " \"%s\". Enter \".help\" for help\n", azArg[2]); + 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{ + fprintf(stderr, "Usage: .nullvalue STRING\n"); rc = 1; } }else - if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) { - sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue, - "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]); - }else - if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){ sqlite3 *savedDb = p->db; const char *zSavedFilename = p->zDbFilename; @@ -2691,32 +2739,45 @@ static int do_meta_command(char *zLine, struct callback_data *p){ } }else - if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){ - if( p->outfile[0]=='|' ){ - pclose(p->out); - }else{ - output_file_close(p->out); + 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 ){ + fprintf(stderr, "Usage: .%s FILE\n", azArg[0]); + rc = 1; + goto meta_command_exit; } - p->outfile[0] = 0; - if( azArg[1][0]=='|' ){ - p->out = popen(&azArg[1][1], "w"); + if( n>1 && strncmp(azArg[0], "once", n)==0 ){ + if( nArg<2 ){ + fprintf(stderr, "Usage: .once FILE\n"); + rc = 1; + goto meta_command_exit; + } + p->outCount = 2; + }else{ + p->outCount = 0; + } + output_reset(p); + if( zFile[0]=='|' ){ + p->out = popen(zFile + 1, "w"); if( p->out==0 ){ - fprintf(stderr,"Error: cannot open pipe \"%s\"\n", &azArg[1][1]); + fprintf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1); p->out = stdout; rc = 1; }else{ - sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]); + sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile); } }else{ - p->out = output_file_open(azArg[1]); + p->out = output_file_open(zFile); if( p->out==0 ){ - if( strcmp(azArg[1],"off")!=0 ){ - fprintf(stderr,"Error: cannot write to \"%s\"\n", azArg[1]); + if( strcmp(zFile,"off")!=0 ){ + fprintf(stderr,"Error: cannot write to \"%s\"\n", zFile); } p->out = stdout; rc = 1; } else { - sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]); + sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile); } } }else @@ -2730,7 +2791,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){ fprintf(p->out, "\n"); }else - if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){ + if( c=='p' && strncmp(azArg[0], "prompt", n)==0 ){ if( nArg >= 2) { strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1); } @@ -2739,12 +2800,18 @@ static int do_meta_command(char *zLine, struct callback_data *p){ } }else - if( c=='q' && strncmp(azArg[0], "quit", n)==0 && nArg==1 ){ + if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){ rc = 2; }else - if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 && nArg==2 ){ - FILE *alt = fopen(azArg[1], "rb"); + if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){ + FILE *alt; + if( nArg!=2 ){ + fprintf(stderr, "Usage: .read FILE\n"); + rc = 1; + goto meta_command_exit; + } + alt = fopen(azArg[1], "rb"); if( alt==0 ){ fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]); rc = 1; @@ -2754,7 +2821,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){ } }else - if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 && nArg>1 && nArg<4){ + if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){ const char *zSrcFile; const char *zDb; sqlite3 *pSrc; @@ -2764,9 +2831,13 @@ static int do_meta_command(char *zLine, struct callback_data *p){ if( nArg==2 ){ zSrcFile = azArg[1]; zDb = "main"; - }else{ + }else if( nArg==3 ){ zSrcFile = azArg[2]; zDb = azArg[1]; + }else{ + fprintf(stderr, "Usage: .restore ?DB? FILE\n"); + rc = 1; + goto meta_command_exit; } rc = sqlite3_open(zSrcFile, &pSrc); if( rc!=SQLITE_OK ){ @@ -2801,14 +2872,14 @@ static int do_meta_command(char *zLine, struct callback_data *p){ sqlite3_close(pSrc); }else - if( c=='s' && strncmp(azArg[0], "schema", n)==0 && nArg<3 ){ + if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){ struct callback_data data; char *zErrMsg = 0; open_db(p, 0); memcpy(&data, p, sizeof(data)); data.showHeader = 0; data.mode = MODE_Semi; - if( nArg>1 ){ + if( nArg==2 ){ int i; for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]); if( strcmp(azArg[1],"sqlite_master")==0 ){ @@ -2852,7 +2923,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){ callback, &data, &zErrMsg); zShellStatic = 0; } - }else{ + }else if( nArg==1 ){ rc = sqlite3_exec(p->db, "SELECT sql FROM " " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x" @@ -2862,6 +2933,10 @@ static int do_meta_command(char *zLine, struct callback_data *p){ "ORDER BY rowid", callback, &data, &zErrMsg ); + }else{ + fprintf(stderr, "Usage: .schema ?LIKE-PATTERN?\n"); + rc = 1; + goto meta_command_exit; } if( zErrMsg ){ fprintf(stderr,"Error: %s\n", zErrMsg); @@ -2891,24 +2966,33 @@ static int do_meta_command(char *zLine, struct callback_data *p){ for(i=1; iout, "%s", zBuf); } } }else #endif - if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){ - sqlite3_snprintf(sizeof(p->separator), p->separator, - "%.*s", (int)sizeof(p->separator)-1, azArg[1]); + if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){ + if( nArg==2 ){ + sqlite3_snprintf(sizeof(p->separator), p->separator, + "%.*s", (int)sizeof(p->separator)-1, azArg[1]); + }else{ + fprintf(stderr, "Usage: .separator STRING\n"); + rc = 1; + } }else if( c=='s' && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0) - && nArg>=2 ){ char *zCmd; int i; + if( nArg<2 ){ + fprintf(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,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off"); fprintf(p->out,"%9.9s: %s\n","eqp", p->autoEQP ? "on" : "off"); fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off"); @@ -2941,11 +3030,16 @@ static int do_meta_command(char *zLine, struct callback_data *p){ fprintf(p->out,"\n"); }else - if( c=='s' && strncmp(azArg[0], "stats", n)==0 && nArg>1 && nArg<3 ){ - p->statsOn = booleanValue(azArg[1]); + if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){ + if( nArg==2 ){ + p->statsOn = booleanValue(azArg[1]); + }else{ + fprintf(stderr, "Usage: .stats on|off\n"); + rc = 1; + } }else - if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 && nArg<3 ){ + if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){ sqlite3_stmt *pStmt; char **azResult; int nRow, nAlloc; @@ -3151,20 +3245,32 @@ static int do_meta_command(char *zLine, struct callback_data *p){ } }else - if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 && nArg==2 ){ + if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 ){ open_db(p, 0); - sqlite3_busy_timeout(p->db, (int)integerValue(azArg[1])); + sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0); }else - if( HAS_TIMER && c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 - && nArg==2 - ){ - enableTimer = booleanValue(azArg[1]); + if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 ){ + if( nArg==2 ){ + enableTimer = booleanValue(azArg[1]); + if( enableTimer && !HAS_TIMER ){ + fprintf(stderr, "Error: timer not available on this system.\n"); + enableTimer = 0; + } + }else{ + fprintf(stderr, "Usage: .timer on|off\n"); + rc = 1; + } }else - if( c=='t' && strncmp(azArg[0], "trace", n)==0 && nArg>1 ){ + if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){ open_db(p, 0); output_file_close(p->traceOut); + if( nArg!=2 ){ + fprintf(stderr, "Usage: .trace FILE|off\n"); + rc = 1; + goto meta_command_exit; + } p->traceOut = output_file_open(azArg[1]); #if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) if( p->traceOut==0 ){ @@ -3195,11 +3301,11 @@ static int do_meta_command(char *zLine, struct callback_data *p){ #if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE) if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){ extern int sqlite3WhereTrace; - sqlite3WhereTrace = booleanValue(azArg[1]); + sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff; }else #endif - if( c=='w' && strncmp(azArg[0], "width", n)==0 && nArg>1 ){ + if( c=='w' && strncmp(azArg[0], "width", n)==0 ){ int j; assert( nArg<=ArraySize(azArg) ); for(j=1; jcolWidth); j++){ @@ -3213,6 +3319,11 @@ static int do_meta_command(char *zLine, struct callback_data *p){ rc = 1; } +meta_command_exit: + if( p->outCount ){ + p->outCount--; + if( p->outCount==0 ) output_reset(p); + } return rc; } @@ -3380,6 +3491,10 @@ static int process_input(struct callback_data *p, FILE *in){ errCnt++; } nSql = 0; + if( p->outCount ){ + output_reset(p); + p->outCount = 0; + } }else if( nSql && _all_whitespace(zSql) ){ if( p->echoOn ) printf("%s\n", zSql); nSql = 0; diff --git a/test/shell1.test b/test/shell1.test index 6ea4f4a82c..e6fb0c28d2 100644 --- a/test/shell1.test +++ b/test/shell1.test @@ -268,7 +268,7 @@ do_test shell1-3.1.4 { # .bail ON|OFF Stop after hitting an error. Default OFF do_test shell1-3.2.1 { catchcmd "test.db" ".bail" -} {1 {Error: unknown command or invalid arguments: "bail". Enter ".help" for help}} +} {1 {Usage: .bail on|off}} do_test shell1-3.2.2 { catchcmd "test.db" ".bail ON" } {0 {}} @@ -278,16 +278,16 @@ do_test shell1-3.2.3 { do_test shell1-3.2.4 { # too many arguments catchcmd "test.db" ".bail OFF BAD" -} {1 {Error: unknown command or invalid arguments: "bail". Enter ".help" for help}} +} {1 {Usage: .bail on|off}} # .databases List names and files of attached databases do_test shell1-3.3.1 { catchcmd "-csv test.db" ".databases" } "/0 +.*main +[string map {/ .} [string range [get_pwd] 0 10]].*/" do_test shell1-3.3.2 { - # too many arguments + # extra arguments ignored catchcmd "test.db" ".databases BAD" -} {1 {Error: unknown command or invalid arguments: "databases". Enter ".help" for help}} +} "/0 +.*main +[string map {/ .} [string range [get_pwd] 0 10]].*/" # .dump ?TABLE? ... Dump the database in an SQL text format # If TABLE specified, only dump tables matching @@ -305,12 +305,12 @@ do_test shell1-3.4.2 { do_test shell1-3.4.3 { # too many arguments catchcmd "test.db" ".dump FOO BAD" -} {1 {Error: unknown command or invalid arguments: "dump". Enter ".help" for help}} +} {1 {Usage: .dump ?LIKE-PATTERN?}} # .echo ON|OFF Turn command echo on or off do_test shell1-3.5.1 { catchcmd "test.db" ".echo" -} {1 {Error: unknown command or invalid arguments: "echo". Enter ".help" for help}} +} {1 {Usage: .echo on|off}} do_test shell1-3.5.2 { catchcmd "test.db" ".echo ON" } {0 {}} @@ -320,7 +320,7 @@ do_test shell1-3.5.3 { do_test shell1-3.5.4 { # too many arguments catchcmd "test.db" ".echo OFF BAD" -} {1 {Error: unknown command or invalid arguments: "echo". Enter ".help" for help}} +} {1 {Usage: .echo on|off}} # .exit Exit this program do_test shell1-3.6.1 { @@ -339,15 +339,15 @@ do_test shell1-3.7.3 { catchcmd "test.db" ".explain OFF" } {0 {}} do_test shell1-3.7.4 { - # too many arguments + # extra arguments ignored catchcmd "test.db" ".explain OFF BAD" -} {1 {Error: unknown command or invalid arguments: "explain". Enter ".help" for help}} +} {0 {}} # .header(s) ON|OFF Turn display of headers on or off do_test shell1-3.9.1 { catchcmd "test.db" ".header" -} {1 {Error: unknown command or invalid arguments: "header". Enter ".help" for help}} +} {1 {Usage: .headers on|off}} do_test shell1-3.9.2 { catchcmd "test.db" ".header ON" } {0 {}} @@ -357,11 +357,11 @@ do_test shell1-3.9.3 { do_test shell1-3.9.4 { # too many arguments catchcmd "test.db" ".header OFF BAD" -} {1 {Error: unknown command or invalid arguments: "header". Enter ".help" for help}} +} {1 {Usage: .headers on|off}} do_test shell1-3.9.5 { catchcmd "test.db" ".headers" -} {1 {Error: unknown command or invalid arguments: "headers". Enter ".help" for help}} +} {1 {Usage: .headers on|off}} do_test shell1-3.9.6 { catchcmd "test.db" ".headers ON" } {0 {}} @@ -371,7 +371,7 @@ do_test shell1-3.9.7 { do_test shell1-3.9.8 { # too many arguments catchcmd "test.db" ".headers OFF BAD" -} {1 {Error: unknown command or invalid arguments: "headers". Enter ".help" for help}} +} {1 {Usage: .headers on|off}} # .help Show this message do_test shell1-3.10.1 { @@ -393,17 +393,17 @@ do_test shell1-3.10.2 { # .import FILE TABLE Import data from FILE into TABLE do_test shell1-3.11.1 { catchcmd "test.db" ".import" -} {1 {Error: unknown command or invalid arguments: "import". Enter ".help" for help}} +} {1 {Usage: .import FILE TABLE}} do_test shell1-3.11.2 { catchcmd "test.db" ".import FOO" -} {1 {Error: unknown command or invalid arguments: "import". Enter ".help" for help}} +} {1 {Usage: .import FILE TABLE}} #do_test shell1-3.11.2 { # catchcmd "test.db" ".import FOO BAR" #} {1 {Error: no such table: BAR}} do_test shell1-3.11.3 { # too many arguments catchcmd "test.db" ".import FOO BAR BAD" -} {1 {Error: unknown command or invalid arguments: "import". Enter ".help" for help}} +} {1 {Usage: .import FILE TABLE}} # .indices ?TABLE? Show names of all indices # If TABLE specified, only show indices for tables @@ -417,7 +417,7 @@ do_test shell1-3.12.2 { do_test shell1-3.12.3 { # too many arguments catchcmd "test.db" ".indices FOO BAD" -} {1 {Error: unknown command or invalid arguments: "indices". Enter ".help" for help}} +} {1 {Usage: .indices ?LIKE-PATTERN?}} # .mode MODE ?TABLE? Set output mode where MODE is one of: # csv Comma-separated values @@ -430,7 +430,7 @@ do_test shell1-3.12.3 { # tcl TCL list elements do_test shell1-3.13.1 { catchcmd "test.db" ".mode" -} {1 {Error: unknown command or invalid arguments: "mode". Enter ".help" for help}} +} {1 {Error: mode should be one of: column csv html insert line list tabs tcl}} do_test shell1-3.13.2 { catchcmd "test.db" ".mode FOO" } {1 {Error: mode should be one of: column csv html insert line list tabs tcl}} @@ -459,9 +459,9 @@ do_test shell1-3.13.10 { catchcmd "test.db" ".mode tcl" } {0 {}} do_test shell1-3.13.11 { - # too many arguments + # extra arguments ignored catchcmd "test.db" ".mode tcl BAD" -} {1 {Error: invalid arguments: "BAD". Enter ".help" for help}} +} {0 {}} # don't allow partial mode type matches do_test shell1-3.13.12 { @@ -472,31 +472,31 @@ do_test shell1-3.13.13 { } {1 {Error: mode should be one of: column csv html insert line list tabs tcl}} do_test shell1-3.13.14 { catchcmd "test.db" ".mode lin" -} {1 {Error: mode should be one of: column csv html insert line list tabs tcl}} +} {0 {}} # .nullvalue STRING Print STRING in place of NULL values do_test shell1-3.14.1 { catchcmd "test.db" ".nullvalue" -} {1 {Error: unknown command or invalid arguments: "nullvalue". Enter ".help" for help}} +} {1 {Usage: .nullvalue STRING}} do_test shell1-3.14.2 { catchcmd "test.db" ".nullvalue FOO" } {0 {}} do_test shell1-3.14.3 { # too many arguments catchcmd "test.db" ".nullvalue FOO BAD" -} {1 {Error: unknown command or invalid arguments: "nullvalue". Enter ".help" for help}} +} {1 {Usage: .nullvalue STRING}} # .output FILENAME Send output to FILENAME do_test shell1-3.15.1 { catchcmd "test.db" ".output" -} {1 {Error: unknown command or invalid arguments: "output". Enter ".help" for help}} +} {0 {}} do_test shell1-3.15.2 { catchcmd "test.db" ".output FOO" } {0 {}} do_test shell1-3.15.3 { # too many arguments catchcmd "test.db" ".output FOO BAD" -} {1 {Error: unknown command or invalid arguments: "output". Enter ".help" for help}} +} {1 {Usage: .output FILE}} # .output stdout Send output to the screen do_test shell1-3.16.1 { @@ -505,12 +505,12 @@ do_test shell1-3.16.1 { do_test shell1-3.16.2 { # too many arguments catchcmd "test.db" ".output stdout BAD" -} {1 {Error: unknown command or invalid arguments: "output". Enter ".help" for help}} +} {1 {Usage: .output FILE}} # .prompt MAIN CONTINUE Replace the standard prompts do_test shell1-3.17.1 { catchcmd "test.db" ".prompt" -} {1 {Error: unknown command or invalid arguments: "prompt". Enter ".help" for help}} +} {0 {}} do_test shell1-3.17.2 { catchcmd "test.db" ".prompt FOO" } {0 {}} @@ -520,7 +520,7 @@ do_test shell1-3.17.3 { do_test shell1-3.17.4 { # too many arguments catchcmd "test.db" ".prompt FOO BAR BAD" -} {1 {Error: unknown command or invalid arguments: "prompt". Enter ".help" for help}} +} {0 {}} # .quit Exit this program do_test shell1-3.18.1 { @@ -529,12 +529,12 @@ do_test shell1-3.18.1 { do_test shell1-3.18.2 { # too many arguments catchcmd "test.db" ".quit BAD" -} {1 {Error: unknown command or invalid arguments: "quit". Enter ".help" for help}} +} {0 {}} # .read FILENAME Execute SQL in FILENAME do_test shell1-3.19.1 { catchcmd "test.db" ".read" -} {1 {Error: unknown command or invalid arguments: "read". Enter ".help" for help}} +} {1 {Usage: .read FILE}} do_test shell1-3.19.2 { forcedelete FOO catchcmd "test.db" ".read FOO" @@ -542,12 +542,12 @@ do_test shell1-3.19.2 { do_test shell1-3.19.3 { # too many arguments catchcmd "test.db" ".read FOO BAD" -} {1 {Error: unknown command or invalid arguments: "read". Enter ".help" for help}} +} {1 {Usage: .read FILE}} # .restore ?DB? FILE Restore content of DB (default "main") from FILE do_test shell1-3.20.1 { catchcmd "test.db" ".restore" -} {1 {Error: unknown command or invalid arguments: "restore". Enter ".help" for help}} +} {1 {Usage: .restore ?DB? FILE}} do_test shell1-3.20.2 { catchcmd "test.db" ".restore FOO" } {0 {}} @@ -557,7 +557,7 @@ do_test shell1-3.20.3 { do_test shell1-3.20.4 { # too many arguments catchcmd "test.db" ".restore FOO BAR BAD" -} {1 {Error: unknown command or invalid arguments: "restore". Enter ".help" for help}} +} {1 {Usage: .restore ?DB? FILE}} # .schema ?TABLE? Show the CREATE statements # If TABLE specified, only show tables matching @@ -571,7 +571,7 @@ do_test shell1-3.21.2 { do_test shell1-3.21.3 { # too many arguments catchcmd "test.db" ".schema FOO BAD" -} {1 {Error: unknown command or invalid arguments: "schema". Enter ".help" for help}} +} {1 {Usage: .schema ?LIKE-PATTERN?}} do_test shell1-3.21.4 { catchcmd "test.db" { @@ -588,14 +588,14 @@ db eval {DROP VIEW v1; DROP VIEW v2; DROP TABLE t1;} # .separator STRING Change separator used by output mode and .import do_test shell1-3.22.1 { catchcmd "test.db" ".separator" -} {1 {Error: unknown command or invalid arguments: "separator". Enter ".help" for help}} +} {1 {Usage: .separator STRING}} do_test shell1-3.22.2 { catchcmd "test.db" ".separator FOO" } {0 {}} do_test shell1-3.22.3 { # too many arguments catchcmd "test.db" ".separator FOO BAD" -} {1 {Error: unknown command or invalid arguments: "separator". Enter ".help" for help}} +} {1 {Usage: .separator STRING}} # .show Show the current values for various settings do_test shell1-3.23.1 { @@ -613,12 +613,12 @@ do_test shell1-3.23.1 { do_test shell1-3.23.2 { # too many arguments catchcmd "test.db" ".show BAD" -} {1 {Error: unknown command or invalid arguments: "show". Enter ".help" for help}} +} {1 {Usage: .show}} # .stats ON|OFF Turn stats on or off do_test shell1-3.23b.1 { catchcmd "test.db" ".stats" -} {1 {Error: unknown command or invalid arguments: "stats". Enter ".help" for help}} +} {1 {Usage: .stats on|off}} do_test shell1-3.23b.2 { catchcmd "test.db" ".stats ON" } {0 {}} @@ -628,7 +628,7 @@ do_test shell1-3.23b.3 { do_test shell1-3.23b.4 { # too many arguments catchcmd "test.db" ".stats OFF BAD" -} {1 {Error: unknown command or invalid arguments: "stats". Enter ".help" for help}} +} {1 {Usage: .stats on|off}} # .tables ?TABLE? List names of tables # If TABLE specified, only list tables matching @@ -642,12 +642,12 @@ do_test shell1-3.24.2 { do_test shell1-3.24.3 { # too many arguments catchcmd "test.db" ".tables FOO BAD" -} {1 {Error: unknown command or invalid arguments: "tables". Enter ".help" for help}} +} {0 {}} # .timeout MS Try opening locked tables for MS milliseconds do_test shell1-3.25.1 { catchcmd "test.db" ".timeout" -} {1 {Error: unknown command or invalid arguments: "timeout". Enter ".help" for help}} +} {0 {}} do_test shell1-3.25.2 { catchcmd "test.db" ".timeout zzz" # this should be treated the same as a '0' timeout @@ -658,12 +658,12 @@ do_test shell1-3.25.3 { do_test shell1-3.25.4 { # too many arguments catchcmd "test.db" ".timeout 1 BAD" -} {1 {Error: unknown command or invalid arguments: "timeout". Enter ".help" for help}} +} {0 {}} # .width NUM NUM ... Set column widths for "column" mode do_test shell1-3.26.1 { catchcmd "test.db" ".width" -} {1 {Error: unknown command or invalid arguments: "width". Enter ".help" for help}} +} {0 {}} do_test shell1-3.26.2 { catchcmd "test.db" ".width xxx" # this should be treated the same as a '0' width for col 1 @@ -689,7 +689,7 @@ do_test shell1-3.26.6 { # .timer ON|OFF Turn the CPU timer measurement on or off do_test shell1-3.27.1 { catchcmd "test.db" ".timer" -} {1 {Error: unknown command or invalid arguments: "timer". Enter ".help" for help}} +} {1 {Usage: .timer on|off}} do_test shell1-3.27.2 { catchcmd "test.db" ".timer ON" } {0 {}} @@ -699,7 +699,7 @@ do_test shell1-3.27.3 { do_test shell1-3.27.4 { # too many arguments catchcmd "test.db" ".timer OFF BAD" -} {1 {Error: unknown command or invalid arguments: "timer". Enter ".help" for help}} +} {1 {Usage: .timer on|off}} do_test shell1-3-28.1 { catchcmd test.db \ diff --git a/test/shell4.test b/test/shell4.test index 5af44c8fd7..c29faf00cf 100644 --- a/test/shell4.test +++ b/test/shell4.test @@ -63,7 +63,7 @@ do_test shell4-1.2.2 { # .stats ON|OFF Turn stats on or off do_test shell4-1.3.1 { catchcmd "test.db" ".stats" -} {1 {Error: unknown command or invalid arguments: "stats". Enter ".help" for help}} +} {1 {Usage: .stats on|off}} do_test shell4-1.3.2 { catchcmd "test.db" ".stats ON" } {0 {}} @@ -73,7 +73,7 @@ do_test shell4-1.3.3 { do_test shell4-1.3.4 { # too many arguments catchcmd "test.db" ".stats OFF BAD" -} {1 {Error: unknown command or invalid arguments: "stats". Enter ".help" for help}} +} {1 {Usage: .stats on|off}} # NB. whitespace is important do_test shell4-1.4.1 { diff --git a/test/shell5.test b/test/shell5.test index a14c84a48c..734833f6fc 100644 --- a/test/shell5.test +++ b/test/shell5.test @@ -40,29 +40,29 @@ forcedelete test.db test.db-journal test.db-wal # .import FILE TABLE Import data from FILE into TABLE do_test shell5-1.1.1 { catchcmd "test.db" ".import" -} {1 {Error: unknown command or invalid arguments: "import". Enter ".help" for help}} +} {1 {Usage: .import FILE TABLE}} do_test shell5-1.1.2 { catchcmd "test.db" ".import FOO" -} {1 {Error: unknown command or invalid arguments: "import". Enter ".help" for help}} +} {1 {Usage: .import FILE TABLE}} #do_test shell5-1.1.2 { # catchcmd "test.db" ".import FOO BAR" #} {1 {Error: no such table: BAR}} do_test shell5-1.1.3 { # too many arguments catchcmd "test.db" ".import FOO BAR BAD" -} {1 {Error: unknown command or invalid arguments: "import". Enter ".help" for help}} +} {1 {Usage: .import FILE TABLE}} # .separator STRING Change separator used by output mode and .import -do_test shell1-1.2.1 { +do_test shell5-1.2.1 { catchcmd "test.db" ".separator" -} {1 {Error: unknown command or invalid arguments: "separator". Enter ".help" for help}} -do_test shell1-1.2.2 { +} {1 {Usage: .separator STRING}} +do_test shell5-1.2.2 { catchcmd "test.db" ".separator FOO" } {0 {}} -do_test shell1-1.2.3 { +do_test shell5-1.2.3 { # too many arguments catchcmd "test.db" ".separator FOO BAD" -} {1 {Error: unknown command or invalid arguments: "separator". Enter ".help" for help}} +} {1 {Usage: .separator STRING}} # separator should default to "|" do_test shell5-1.3.1 { From b463fef3fda4d233ba634d81bfc9c3bf001f0513 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 29 May 2014 20:17:57 +0000 Subject: [PATCH 18/18] Fix to the EXPLAIN indentation logic in the command-line shell. FossilOrigin-Name: 8f916ed1e185ac728e00624d90e1d7bd2dda4469 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index fb3c92c2cf..5ca3da5016 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvements\sto\serror\smessages\sfor\serrors\sin\sthe\sdot-commands\sof\sthe\ncommand-line\sshell.\s\sAdd\sthe\s".once"\scommand.\s\sThe\soutput\sof\s".help"\nnow\sgoes\sto\sthe\sdesignated\soutput\schannel. -D 2014-05-29T12:36:14.908 +C Fix\sto\sthe\sEXPLAIN\sindentation\slogic\sin\sthe\scommand-line\sshell. +D 2014-05-29T20:17:57.027 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in dd2b1aba364ff9b05de41086f74407f285c57670 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -221,7 +221,7 @@ F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 273d5f47c4e2c05b2d3d2bffeda939551ab59e66 F src/rowset.c a9c9aae3234b44a6d7c6f5a3cadf90dce1e627be F src/select.c 7df17ec5506c2427576d412bee0e6ea740e12563 -F src/shell.c a94689054bc0a66608f3d75b3ced2b886c3d7f50 +F src/shell.c 33f6c0bc0e32eae099f7c2b79cfa7515b4b4702c F src/sqlite.h.in 564fc23db33870b5096b20d72df7491ce0b8b74f F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc @@ -1173,7 +1173,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P e58f4bd39d51c4c1a28684dab6427de81173d564 -R 7215154feb44506111be05bd24ee86a7 +P 48dce821a07ac29da6ce05e92cf3f6e52b6eb388 +R f3f6ddac33e05ba165213ff981b802f2 U drh -Z cfc4096d1968e16f0aae201a0082ea68 +Z 830218d29106127a2f4cf14b2b59a5e2 diff --git a/manifest.uuid b/manifest.uuid index 9fb4a9df39..16ffe06ff6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -48dce821a07ac29da6ce05e92cf3f6e52b6eb388 \ No newline at end of file +8f916ed1e185ac728e00624d90e1d7bd2dda4469 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index e2748911e6..9b45a20592 100644 --- a/src/shell.c +++ b/src/shell.c @@ -1200,7 +1200,7 @@ static void explain_data_prepare(struct callback_data *p, sqlite3_stmt *pSql){ const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext", "NextIfOpen", "PrevIfOpen", 0 }; - const char *azYield[] = { "Yield", "SeekLt", "SeekGt", "RowSetRead", "Rewind", 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