From 7977fa3ab291bd0ec6bdbb21c93ef8c37f7fed4b Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 20 Nov 2015 13:17:29 +0000 Subject: [PATCH 01/53] Enhancements to a comment in sqliteInt.h. No changes to code. FossilOrigin-Name: 5446ae64d7f92444ca40aae2108015d1d77bc03f --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqliteInt.h | 3 ++- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index d831f3f7cd..bffe612950 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sproblems\swith\sthe\sway\sthe\sIsHiddenColumn()\smacro\sis\sdefined. -D 2015-11-19T18:11:20.451 +C Enhancements\sto\sa\scomment\sin\ssqliteInt.h.\s\sNo\schanges\sto\scode. +D 2015-11-20T13:17:29.368 F Makefile.in d828db6afa6c1fa060d01e33e4674408df1942a1 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e928e68168df69b353300ac87c10105206653a03 @@ -344,7 +344,7 @@ F src/shell.c f0f59ea60ad297f671b7ae0fb957a736ad17c92c F src/sqlite.h.in fa62718f73553f06b2f2e362fd09ccb4e1cbb626 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h 4b66e3e3435da4b4c8c83696d0349f0c503b3924 -F src/sqliteInt.h 25d0792e6d355a27975dc7c49c4514b3f6eb2294 +F src/sqliteInt.h 64256d193a16a147d9f6317cc4e095fdd3e0a2e9 F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e @@ -1404,7 +1404,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 13995756ad8b80568aa2f74387788a8cab1123ef -R 7d5fbb49b212de9edfd34eb075dc8992 +P 126b998cf163dcdd5a222634f1e929f04db3c700 +R 039797124bfe4b260998bebf04e01b11 U drh -Z bc25bafe8827ab2ba48c52405ca8c198 +Z 94dd81621cb18a68b28885d578a9299b diff --git a/manifest.uuid b/manifest.uuid index 3e5e242be0..a8efd6adfb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -126b998cf163dcdd5a222634f1e929f04db3c700 \ No newline at end of file +5446ae64d7f92444ca40aae2108015d1d77bc03f \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 2e1adb82e6..338a573253 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1382,7 +1382,8 @@ struct FuncDestructor { /* ** Possible values for FuncDef.flags. Note that the _LENGTH and _TYPEOF -** values must correspond to OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG. There +** values must correspond to OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG. And +** SQLITE_FUNC_CONSTANT must be the same as SQLITE_DETERMINISTIC. There ** are assert() statements in the code to verify this. */ #define SQLITE_FUNC_ENCMASK 0x0003 /* SQLITE_UTF8, SQLITE_UTF16BE or UTF16LE */ From 5f7dacb443434559c2e5eee22cb451cec6aa60f4 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 20 Nov 2015 13:33:56 +0000 Subject: [PATCH 02/53] In the OP_Column opcode, only test the btree payload size for exceeding the string length limit if the payload does not fit on a single page. FossilOrigin-Name: 35c7f6cba6febf2480de01fca9d61b8065bf1c12 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 5 ++--- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index bffe612950..8a550a6fb5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhancements\sto\sa\scomment\sin\ssqliteInt.h.\s\sNo\schanges\sto\scode. -D 2015-11-20T13:17:29.368 +C In\sthe\sOP_Column\sopcode,\sonly\stest\sthe\sbtree\spayload\ssize\sfor\sexceeding\sthe\nstring\slength\slimit\sif\sthe\spayload\sdoes\snot\sfit\son\sa\ssingle\spage. +D 2015-11-20T13:33:56.212 F Makefile.in d828db6afa6c1fa060d01e33e4674408df1942a1 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e928e68168df69b353300ac87c10105206653a03 @@ -402,7 +402,7 @@ F src/update.c 40e51cd0883cb5bfd6abb7d8a7cd8aa47fab2945 F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c F src/util.c fc612367108b74573c5fd13a85d0a23027f438bd F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701 -F src/vdbe.c 7a9b18027414368d800716e6319e2acd699c70db +F src/vdbe.c 7a4efb964a050fd3cd733b051ce2ef1c8d609f53 F src/vdbe.h efb7a8c1459e31f3ea4377824c6a7e4cb5068637 F src/vdbeInt.h 33403622c6a8feaaac5f0f3f17f5d1bf6df42286 F src/vdbeapi.c 020681b943e77766b32ae1cddf86d7831b7374ca @@ -1404,7 +1404,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 126b998cf163dcdd5a222634f1e929f04db3c700 -R 039797124bfe4b260998bebf04e01b11 +P 5446ae64d7f92444ca40aae2108015d1d77bc03f +R a5098759debd354cc66c1a03fdae8b41 U drh -Z 94dd81621cb18a68b28885d578a9299b +Z f951ff158d10f4e00f2e4ba144c0ce20 diff --git a/manifest.uuid b/manifest.uuid index a8efd6adfb..704f765b40 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5446ae64d7f92444ca40aae2108015d1d77bc03f \ No newline at end of file +35c7f6cba6febf2480de01fca9d61b8065bf1c12 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index d13655d9c1..5be906c677 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2427,12 +2427,11 @@ case OP_Column: { assert( avail<=65536 ); /* Maximum page size is 64KiB */ if( pC->payloadSize <= (u32)avail ){ pC->szRow = pC->payloadSize; + }else if( pC->payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ + goto too_big; }else{ pC->szRow = avail; } - if( pC->payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ - goto too_big; - } } pC->cacheStatus = p->cacheCtr; pC->iHdrOffset = getVarint32(pC->aRow, offset); From c960dcbacef43fff0c5f58c292e43c639b7b9dd4 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 20 Nov 2015 19:22:01 +0000 Subject: [PATCH 03/53] Refactor the VdbeCursor object. It is now slightly smaller and faster and is easier to understand. FossilOrigin-Name: 9b1d174d862500a627840008ffac4c8419dc97e2 --- manifest | 20 ++--- manifest.uuid | 2 +- src/vdbe.c | 212 ++++++++++++++++++++++++++----------------------- src/vdbeInt.h | 52 ++++++------ src/vdbeaux.c | 72 ++++++++++------- src/vdbeblob.c | 2 +- src/vdbesort.c | 36 ++++++--- 7 files changed, 225 insertions(+), 171 deletions(-) diff --git a/manifest b/manifest index 8a550a6fb5..d22ad18b8d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\sOP_Column\sopcode,\sonly\stest\sthe\sbtree\spayload\ssize\sfor\sexceeding\sthe\nstring\slength\slimit\sif\sthe\spayload\sdoes\snot\sfit\son\sa\ssingle\spage. -D 2015-11-20T13:33:56.212 +C Refactor\sthe\sVdbeCursor\sobject.\s\sIt\sis\snow\sslightly\ssmaller\sand\sfaster\sand\sis\neasier\sto\sunderstand. +D 2015-11-20T19:22:01.706 F Makefile.in d828db6afa6c1fa060d01e33e4674408df1942a1 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e928e68168df69b353300ac87c10105206653a03 @@ -402,14 +402,14 @@ F src/update.c 40e51cd0883cb5bfd6abb7d8a7cd8aa47fab2945 F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c F src/util.c fc612367108b74573c5fd13a85d0a23027f438bd F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701 -F src/vdbe.c 7a4efb964a050fd3cd733b051ce2ef1c8d609f53 +F src/vdbe.c 9ef1b1701e133d1cdb7dc66598863993b925b069 F src/vdbe.h efb7a8c1459e31f3ea4377824c6a7e4cb5068637 -F src/vdbeInt.h 33403622c6a8feaaac5f0f3f17f5d1bf6df42286 +F src/vdbeInt.h 75c2e82ee3357e9210c06474f8d9bdf12c81105d F src/vdbeapi.c 020681b943e77766b32ae1cddf86d7831b7374ca -F src/vdbeaux.c da9eddc62e025148e30267600a6fe3882d5e912f -F src/vdbeblob.c 565fabd302f5fca3bdf3d56cac330483616a39b6 +F src/vdbeaux.c b660c995256e3d3e2cb47ccd20b82a1c342fa093 +F src/vdbeblob.c fdc4a81605ae7a35ae94a55bd768b66d6be16f15 F src/vdbemem.c fdd1578e47bea61390d472de53c565781d81e045 -F src/vdbesort.c 8b23930a1289526f6d2a3a9f2e965bcc963e4a68 +F src/vdbesort.c a7ec02da4494c59dfd071126dd3726be5a11459d F src/vdbetrace.c 8befe829faff6d9e6f6e4dee5a7d3f85cc85f1a0 F src/vtab.c 2a8b44aa372c33f6154208e7a7f6c44254549806 F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb @@ -1404,7 +1404,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 5446ae64d7f92444ca40aae2108015d1d77bc03f -R a5098759debd354cc66c1a03fdae8b41 +P 35c7f6cba6febf2480de01fca9d61b8065bf1c12 +R ae691eb0177fe2d5adc77d9ff2c7f6f3 U drh -Z f951ff158d10f4e00f2e4ba144c0ce20 +Z 018ade43e937d593f3f9dd76ba8e9c12 diff --git a/manifest.uuid b/manifest.uuid index 704f765b40..86e0a6e699 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -35c7f6cba6febf2480de01fca9d61b8065bf1c12 \ No newline at end of file +9b1d174d862500a627840008ffac4c8419dc97e2 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 5be906c677..7428d5f607 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -165,7 +165,7 @@ int sqlite3_found_count = 0; && sqlite3VdbeMemMakeWriteable(P) ){ goto no_mem;} /* Return true if the cursor was opened using the OP_OpenSorter opcode. */ -#define isSorter(x) ((x)->pSorter!=0) +#define isSorter(x) ((x)->eCurType==CURTYPE_SORTER) /* ** Allocate VdbeCursor number iCur. Return a pointer to it. Return NULL @@ -176,7 +176,7 @@ static VdbeCursor *allocateCursor( int iCur, /* Index of the new VdbeCursor */ int nField, /* Number of fields in the table or index */ int iDb, /* Database the cursor belongs to, or -1 */ - int isBtreeCursor /* True for B-Tree. False for pseudo-table or vtab */ + u8 eCurType /* Type of the new cursor */ ){ /* Find the memory cell that will be used to store the blob of memory ** required for this VdbeCursor structure. It is convenient to use a @@ -202,7 +202,7 @@ static VdbeCursor *allocateCursor( VdbeCursor *pCx = 0; nByte = ROUND8(sizeof(VdbeCursor)) + 2*sizeof(u32)*nField + - (isBtreeCursor?sqlite3BtreeCursorSize():0); + (eCurType==CURTYPE_BTREE?sqlite3BtreeCursorSize():0); assert( iCurnCursor ); if( p->apCsr[iCur] ){ @@ -212,13 +212,14 @@ static VdbeCursor *allocateCursor( if( SQLITE_OK==sqlite3VdbeMemClearAndResize(pMem, nByte) ){ p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->z; memset(pCx, 0, sizeof(VdbeCursor)); + pCx->eCurType = eCurType; pCx->iDb = iDb; pCx->nField = nField; pCx->aOffset = &pCx->aType[nField]; - if( isBtreeCursor ){ - pCx->pCursor = (BtCursor*) + if( eCurType==CURTYPE_BTREE ){ + pCx->uc.pCursor = (BtCursor*) &pMem->z[ROUND8(sizeof(VdbeCursor))+2*sizeof(u32)*nField]; - sqlite3BtreeCursorZero(pCx->pCursor); + sqlite3BtreeCursorZero(pCx->uc.pCursor); } } return pCx; @@ -2383,21 +2384,19 @@ case OP_Column: { assert( pC!=0 ); assert( p2nField ); aOffset = pC->aOffset; -#ifndef SQLITE_OMIT_VIRTUALTABLE - assert( pC->pVtabCursor==0 ); /* OP_Column never called on virtual table */ -#endif - pCrsr = pC->pCursor; - assert( pCrsr!=0 || pC->pseudoTableReg>0 ); /* pCrsr NULL on PseudoTables */ - assert( pCrsr!=0 || pC->nullRow ); /* pC->nullRow on PseudoTables */ + assert( pC->eCurType!=CURTYPE_VTAB ); /* OP_Column never called on virtual table */ + assert( pC->eCurType!=CURTYPE_PSEUDO || pC->nullRow ); + assert( pC->eCurType!=CURTYPE_SORTER ); + pCrsr = pC->uc.pCursor; /* If the cursor cache is stale, bring it up-to-date */ rc = sqlite3VdbeCursorMoveto(pC); if( rc ) goto abort_due_to_error; if( pC->cacheStatus!=p->cacheCtr ){ if( pC->nullRow ){ - if( pCrsr==0 ){ - assert( pC->pseudoTableReg>0 ); - pReg = &aMem[pC->pseudoTableReg]; + if( pC->eCurType==CURTYPE_PSEUDO ){ + assert( pC->uc.pseudoTableReg>0 ); + pReg = &aMem[pC->uc.pseudoTableReg]; assert( pReg->flags & MEM_Blob ); assert( memIsValid(pReg) ); pC->payloadSize = pC->szRow = avail = pReg->n; @@ -2407,6 +2406,7 @@ case OP_Column: { goto op_column_out; } }else{ + assert( pC->eCurType==CURTYPE_BTREE ); assert( pCrsr ); if( pC->isTable==0 ){ assert( sqlite3BtreeCursorIsValid(pCrsr) ); @@ -2795,7 +2795,8 @@ case OP_Count: { /* out2 */ i64 nEntry; BtCursor *pCrsr; - pCrsr = p->apCsr[pOp->p1]->pCursor; + assert( p->apCsr[pOp->p1]->eCurType==CURTYPE_BTREE ); + pCrsr = p->apCsr[pOp->p1]->uc.pCursor; assert( pCrsr ); nEntry = 0; /* Not needed. Only used to silence a warning. */ rc = sqlite3BtreeCount(pCrsr, &nEntry); @@ -3380,12 +3381,12 @@ case OP_OpenWrite: assert( pOp->p1>=0 ); assert( nField>=0 ); testcase( nField==0 ); /* Table with INTEGER PRIMARY KEY and nothing else */ - pCur = allocateCursor(p, pOp->p1, nField, iDb, 1); + pCur = allocateCursor(p, pOp->p1, nField, iDb, CURTYPE_BTREE); if( pCur==0 ) goto no_mem; pCur->nullRow = 1; pCur->isOrdered = 1; pCur->pgnoRoot = p2; - rc = sqlite3BtreeCursor(pX, p2, wrFlag, pKeyInfo, pCur->pCursor); + rc = sqlite3BtreeCursor(pX, p2, wrFlag, pKeyInfo, pCur->uc.pCursor); pCur->pKeyInfo = pKeyInfo; /* Set the VdbeCursor.isTable variable. Previous versions of ** SQLite used to check if the root-page flags were sane at this point @@ -3400,7 +3401,7 @@ open_cursor_set_hints: #ifdef SQLITE_ENABLE_CURSOR_HINT testcase( pOp->p2 & OPFLAG_SEEKEQ ); #endif - sqlite3BtreeCursorHintFlags(pCur->pCursor, + sqlite3BtreeCursorHintFlags(pCur->uc.pCursor, (pOp->p5 & (OPFLAG_BULKCSR|OPFLAG_SEEKEQ))); break; } @@ -3444,7 +3445,7 @@ case OP_OpenEphemeral: { SQLITE_OPEN_TRANSIENT_DB; assert( pOp->p1>=0 ); assert( pOp->p2>=0 ); - pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1); + pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, CURTYPE_BTREE); if( pCx==0 ) goto no_mem; pCx->nullRow = 1; pCx->isEphemeral = 1; @@ -3468,11 +3469,11 @@ case OP_OpenEphemeral: { assert( pKeyInfo->db==db ); assert( pKeyInfo->enc==ENC(db) ); pCx->pKeyInfo = pKeyInfo; - rc = sqlite3BtreeCursor(pCx->pBt, pgno, BTREE_WRCSR, pKeyInfo, pCx->pCursor); + rc = sqlite3BtreeCursor(pCx->pBt, pgno, BTREE_WRCSR, pKeyInfo, pCx->uc.pCursor); } pCx->isTable = 0; }else{ - rc = sqlite3BtreeCursor(pCx->pBt, MASTER_ROOT, BTREE_WRCSR, 0, pCx->pCursor); + rc = sqlite3BtreeCursor(pCx->pBt, MASTER_ROOT, BTREE_WRCSR, 0, pCx->uc.pCursor); pCx->isTable = 1; } } @@ -3495,7 +3496,7 @@ case OP_SorterOpen: { assert( pOp->p1>=0 ); assert( pOp->p2>=0 ); - pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1); + pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, CURTYPE_SORTER); if( pCx==0 ) goto no_mem; pCx->pKeyInfo = pOp->p4.pKeyInfo; assert( pCx->pKeyInfo->db==db ); @@ -3515,7 +3516,7 @@ case OP_SequenceTest: { VdbeCursor *pC; assert( pOp->p1>=0 && pOp->p1nCursor ); pC = p->apCsr[pOp->p1]; - assert( pC->pSorter ); + assert( isSorter(pC) ); if( (pC->seqCount++)==0 ){ goto jump_to_p2; } @@ -3543,10 +3544,10 @@ case OP_OpenPseudo: { assert( pOp->p1>=0 ); assert( pOp->p3>=0 ); - pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, 0); + pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, CURTYPE_PSEUDO); if( pCx==0 ) goto no_mem; pCx->nullRow = 1; - pCx->pseudoTableReg = pOp->p2; + pCx->uc.pseudoTableReg = pOp->p2; pCx->isTable = 1; assert( pOp->p5==0 ); break; @@ -3578,7 +3579,7 @@ case OP_Close: { case OP_ColumnsUsed: { VdbeCursor *pC; pC = p->apCsr[pOp->p1]; - assert( pC->pCursor ); + assert( pC->eCurType==CURTYPE_BTREE ); pC->maskUsed = *(u64*)pOp->p4.pI64; break; } @@ -3686,12 +3687,12 @@ case OP_SeekGT: { /* jump, in3 */ assert( pOp->p2!=0 ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); - assert( pC->pseudoTableReg==0 ); + assert( pC->eCurType==CURTYPE_BTREE ); assert( OP_SeekLE == OP_SeekLT+1 ); assert( OP_SeekGE == OP_SeekLT+2 ); assert( OP_SeekGT == OP_SeekLT+3 ); assert( pC->isOrdered ); - assert( pC->pCursor!=0 ); + assert( pC->uc.pCursor!=0 ); oc = pOp->opcode; eqOnly = 0; pC->nullRow = 0; @@ -3701,7 +3702,7 @@ case OP_SeekGT: { /* jump, in3 */ if( pC->isTable ){ /* The BTREE_SEEK_EQ flag is only set on index cursors */ - assert( sqlite3BtreeCursorHasHint(pC->pCursor, BTREE_SEEK_EQ)==0 ); + assert( sqlite3BtreeCursorHasHint(pC->uc.pCursor, BTREE_SEEK_EQ)==0 ); /* The input value in P3 might be of any type: integer, real, string, ** blob, or NULL. But it needs to be an integer before we can do @@ -3745,7 +3746,7 @@ case OP_SeekGT: { /* jump, in3 */ if( (oc & 0x0001)==(OP_SeekLT & 0x0001) ) oc++; } } - rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)iKey, 0, &res); + rc = sqlite3BtreeMovetoUnpacked(pC->uc.pCursor, 0, (u64)iKey, 0, &res); pC->movetoTarget = iKey; /* Used by OP_Delete */ if( rc!=SQLITE_OK ){ goto abort_due_to_error; @@ -3755,7 +3756,7 @@ case OP_SeekGT: { /* jump, in3 */ ** OP_SeekLE opcodes are allowed, and these must be immediately followed ** by an OP_IdxGT or OP_IdxLT opcode, respectively, with the same key. */ - if( sqlite3BtreeCursorHasHint(pC->pCursor, BTREE_SEEK_EQ) ){ + if( sqlite3BtreeCursorHasHint(pC->uc.pCursor, BTREE_SEEK_EQ) ){ eqOnly = 1; assert( pOp->opcode==OP_SeekGE || pOp->opcode==OP_SeekLE ); assert( pOp[1].opcode==OP_IdxLT || pOp[1].opcode==OP_IdxGT ); @@ -3790,7 +3791,7 @@ case OP_SeekGT: { /* jump, in3 */ #endif ExpandBlob(r.aMem); r.eqSeen = 0; - rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, &r, 0, 0, &res); + rc = sqlite3BtreeMovetoUnpacked(pC->uc.pCursor, &r, 0, 0, &res); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } @@ -3807,7 +3808,7 @@ case OP_SeekGT: { /* jump, in3 */ if( oc>=OP_SeekGE ){ assert( oc==OP_SeekGE || oc==OP_SeekGT ); if( res<0 || (res==0 && oc==OP_SeekGT) ){ res = 0; - rc = sqlite3BtreeNext(pC->pCursor, &res); + rc = sqlite3BtreeNext(pC->uc.pCursor, &res); if( rc!=SQLITE_OK ) goto abort_due_to_error; }else{ res = 0; @@ -3816,13 +3817,13 @@ case OP_SeekGT: { /* jump, in3 */ assert( oc==OP_SeekLT || oc==OP_SeekLE ); if( res>0 || (res==0 && oc==OP_SeekLT) ){ res = 0; - rc = sqlite3BtreePrevious(pC->pCursor, &res); + rc = sqlite3BtreePrevious(pC->uc.pCursor, &res); if( rc!=SQLITE_OK ) goto abort_due_to_error; }else{ /* res might be negative because the table is empty. Check to ** see if this is the case. */ - res = sqlite3BtreeEof(pC->pCursor); + res = sqlite3BtreeEof(pC->uc.pCursor); } } seek_not_found: @@ -3853,7 +3854,8 @@ case OP_Seek: { /* in2 */ assert( pOp->p1>=0 && pOp->p1nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); - assert( pC->pCursor!=0 ); + assert( pC->eCurType==CURTYPE_BTREE ); + assert( pC->uc.pCursor!=0 ); assert( pC->isTable ); pC->nullRow = 0; pIn2 = &aMem[pOp->p2]; @@ -3947,7 +3949,8 @@ case OP_Found: { /* jump, in3 */ pC->seekOp = pOp->opcode; #endif pIn3 = &aMem[pOp->p3]; - assert( pC->pCursor!=0 ); + assert( pC->eCurType==CURTYPE_BTREE ); + assert( pC->uc.pCursor!=0 ); assert( pC->isTable==0 ); pFree = 0; if( pOp->p4.i>0 ){ @@ -3984,7 +3987,7 @@ case OP_Found: { /* jump, in3 */ } } } - rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, pIdxKey, 0, 0, &res); + rc = sqlite3BtreeMovetoUnpacked(pC->uc.pCursor, pIdxKey, 0, 0, &res); sqlite3DbFree(db, pFree); if( rc!=SQLITE_OK ){ break; @@ -4038,8 +4041,8 @@ case OP_NotExists: { /* jump, in3 */ pC->seekOp = 0; #endif assert( pC->isTable ); - assert( pC->pseudoTableReg==0 ); - pCrsr = pC->pCursor; + assert( pC->eCurType==CURTYPE_BTREE ); + pCrsr = pC->uc.pCursor; assert( pCrsr!=0 ); res = 0; iKey = pIn3->u.i; @@ -4073,6 +4076,7 @@ case OP_NotExists: { /* jump, in3 */ case OP_Sequence: { /* out2 */ assert( pOp->p1>=0 && pOp->p1nCursor ); assert( p->apCsr[pOp->p1]!=0 ); + assert( p->apCsr[pOp->p1]->eCurType!=CURTYPE_VTAB ); pOut = out2Prerelease(p, pOp); pOut->u.i = p->apCsr[pOp->p1]->seqCount++; break; @@ -4108,7 +4112,8 @@ case OP_NewRowid: { /* out2 */ assert( pOp->p1>=0 && pOp->p1nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); - assert( pC->pCursor!=0 ); + assert( pC->eCurType==CURTYPE_BTREE ); + assert( pC->uc.pCursor!=0 ); { /* The next rowid or record number (different terms for the same ** thing) is obtained in a two-step algorithm. @@ -4136,15 +4141,15 @@ case OP_NewRowid: { /* out2 */ #endif if( !pC->useRandomRowid ){ - rc = sqlite3BtreeLast(pC->pCursor, &res); + rc = sqlite3BtreeLast(pC->uc.pCursor, &res); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } if( res ){ v = 1; /* IMP: R-61914-48074 */ }else{ - assert( sqlite3BtreeCursorIsValid(pC->pCursor) ); - rc = sqlite3BtreeKeySize(pC->pCursor, &v); + assert( sqlite3BtreeCursorIsValid(pC->uc.pCursor) ); + rc = sqlite3BtreeKeySize(pC->uc.pCursor, &v); assert( rc==SQLITE_OK ); /* Cannot fail following BtreeLast() */ if( v>=MAX_ROWID ){ pC->useRandomRowid = 1; @@ -4195,7 +4200,7 @@ case OP_NewRowid: { /* out2 */ do{ sqlite3_randomness(sizeof(v), &v); v &= (MAX_ROWID>>1); v++; /* Ensure that v is greater than zero */ - }while( ((rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)v, + }while( ((rc = sqlite3BtreeMovetoUnpacked(pC->uc.pCursor, 0, (u64)v, 0, &res))==SQLITE_OK) && (res==0) && (++cnt<100)); @@ -4275,8 +4280,8 @@ case OP_InsertInt: { assert( memIsValid(pData) ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); - assert( pC->pCursor!=0 ); - assert( pC->pseudoTableReg==0 ); + assert( pC->eCurType==CURTYPE_BTREE ); + assert( pC->uc.pCursor!=0 ); assert( pC->isTable ); REGISTER_TRACE(pOp->p2, pData); @@ -4305,7 +4310,7 @@ case OP_InsertInt: { }else{ nZero = 0; } - rc = sqlite3BtreeInsert(pC->pCursor, 0, iKey, + rc = sqlite3BtreeInsert(pC->uc.pCursor, 0, iKey, pData->z, pData->n, nZero, (pOp->p5 & OPFLAG_APPEND)!=0, seekResult ); @@ -4352,12 +4357,13 @@ case OP_Delete: { assert( pOp->p1>=0 && pOp->p1nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); - assert( pC->pCursor!=0 ); /* Only valid for real tables, no pseudotables */ + assert( pC->eCurType==CURTYPE_BTREE ); + assert( pC->uc.pCursor!=0 ); assert( pC->deferredMoveto==0 ); hasUpdateCallback = db->xUpdateCallback && pOp->p4.z && pC->isTable; if( pOp->p5 && hasUpdateCallback ){ - sqlite3BtreeKeySize(pC->pCursor, &pC->movetoTarget); + sqlite3BtreeKeySize(pC->uc.pCursor, &pC->movetoTarget); } #ifdef SQLITE_DEBUG @@ -4366,12 +4372,12 @@ case OP_Delete: { ** is being deleted */ if( pOp->p4.z && pC->isTable && pOp->p5==0 ){ i64 iKey = 0; - sqlite3BtreeKeySize(pC->pCursor, &iKey); + sqlite3BtreeKeySize(pC->uc.pCursor, &iKey); assert( pC->movetoTarget==iKey ); } #endif - rc = sqlite3BtreeDelete(pC->pCursor, pOp->p5); + rc = sqlite3BtreeDelete(pC->uc.pCursor, pOp->p5); pC->cacheStatus = CACHE_STALE; /* Invoke the update-hook if required. */ @@ -4488,14 +4494,14 @@ case OP_RowData: { /* Note that RowKey and RowData are really exactly the same instruction */ assert( pOp->p1>=0 && pOp->p1nCursor ); pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( pC->eCurType==CURTYPE_BTREE ); assert( isSorter(pC)==0 ); assert( pC->isTable || pOp->opcode!=OP_RowData ); assert( pC->isTable==0 || pOp->opcode==OP_RowData ); - assert( pC!=0 ); assert( pC->nullRow==0 ); - assert( pC->pseudoTableReg==0 ); - assert( pC->pCursor!=0 ); - pCrsr = pC->pCursor; + assert( pC->uc.pCursor!=0 ); + pCrsr = pC->uc.pCursor; /* The OP_RowKey and OP_RowData opcodes always follow OP_NotExists or ** OP_Rewind/Op_Next with no intervening instructions that might invalidate @@ -4563,29 +4569,31 @@ case OP_Rowid: { /* out2 */ assert( pOp->p1>=0 && pOp->p1nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); - assert( pC->pseudoTableReg==0 || pC->nullRow ); + assert( pC->eCurType!=CURTYPE_PSEUDO || pC->nullRow ); if( pC->nullRow ){ pOut->flags = MEM_Null; break; }else if( pC->deferredMoveto ){ v = pC->movetoTarget; #ifndef SQLITE_OMIT_VIRTUALTABLE - }else if( pC->pVtabCursor ){ - pVtab = pC->pVtabCursor->pVtab; + }else if( pC->eCurType==CURTYPE_VTAB ){ + assert( pC->uc.pVCur!=0 ); + pVtab = pC->uc.pVCur->pVtab; pModule = pVtab->pModule; assert( pModule->xRowid ); - rc = pModule->xRowid(pC->pVtabCursor, &v); + rc = pModule->xRowid(pC->uc.pVCur, &v); sqlite3VtabImportErrmsg(p, pVtab); #endif /* SQLITE_OMIT_VIRTUALTABLE */ }else{ - assert( pC->pCursor!=0 ); + assert( pC->eCurType==CURTYPE_BTREE ); + assert( pC->uc.pCursor!=0 ); rc = sqlite3VdbeCursorRestore(pC); if( rc ) goto abort_due_to_error; if( pC->nullRow ){ pOut->flags = MEM_Null; break; } - rc = sqlite3BtreeKeySize(pC->pCursor, &v); + rc = sqlite3BtreeKeySize(pC->uc.pCursor, &v); assert( rc==SQLITE_OK ); /* Always so because of CursorRestore() above */ } pOut->u.i = v; @@ -4606,8 +4614,9 @@ case OP_NullRow: { assert( pC!=0 ); pC->nullRow = 1; pC->cacheStatus = CACHE_STALE; - if( pC->pCursor ){ - sqlite3BtreeClearCursor(pC->pCursor); + if( pC->eCurType==CURTYPE_BTREE ){ + assert( pC->uc.pCursor!=0 ); + sqlite3BtreeClearCursor(pC->uc.pCursor); } break; } @@ -4632,7 +4641,8 @@ case OP_Last: { /* jump */ assert( pOp->p1>=0 && pOp->p1nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); - pCrsr = pC->pCursor; + assert( pC->eCurType==CURTYPE_BTREE ); + pCrsr = pC->uc.pCursor; res = 0; assert( pCrsr!=0 ); rc = sqlite3BtreeLast(pCrsr, &res); @@ -4700,7 +4710,8 @@ case OP_Rewind: { /* jump */ if( isSorter(pC) ){ rc = sqlite3VdbeSorterRewind(pC, &res); }else{ - pCrsr = pC->pCursor; + assert( pC->eCurType==CURTYPE_BTREE ); + pCrsr = pC->uc.pCursor; assert( pCrsr ); rc = sqlite3BtreeFirst(pCrsr, &res); pC->deferredMoveto = 0; @@ -4797,7 +4808,7 @@ case OP_Next: /* jump */ res = pOp->p3; assert( pC!=0 ); assert( pC->deferredMoveto==0 ); - assert( pC->pCursor ); + assert( pC->eCurType==CURTYPE_BTREE ); assert( res==0 || (res==1 && pC->isTable==0) ); testcase( res==1 ); assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext ); @@ -4814,7 +4825,7 @@ case OP_Next: /* jump */ || pC->seekOp==OP_SeekLT || pC->seekOp==OP_SeekLE || pC->seekOp==OP_Last ); - rc = pOp->p4.xAdvance(pC->pCursor, &res); + rc = pOp->p4.xAdvance(pC->uc.pCursor, &res); next_tail: pC->cacheStatus = CACHE_STALE; VdbeBranchTaken(res==0,2); @@ -4865,7 +4876,7 @@ case OP_IdxInsert: { /* in2 */ pIn2 = &aMem[pOp->p2]; assert( pIn2->flags & MEM_Blob ); if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++; - assert( pC->pCursor!=0 ); + assert( pC->eCurType==CURTYPE_BTREE || pOp->opcode==OP_SorterInsert ); assert( pC->isTable==0 ); rc = ExpandBlob(pIn2); if( rc==SQLITE_OK ){ @@ -4874,7 +4885,7 @@ case OP_IdxInsert: { /* in2 */ }else{ nKey = pIn2->n; zKey = pIn2->z; - rc = sqlite3BtreeInsert(pC->pCursor, zKey, nKey, "", 0, 0, pOp->p3, + rc = sqlite3BtreeInsert(pC->uc.pCursor, zKey, nKey, "", 0, 0, pOp->p3, ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0) ); assert( pC->deferredMoveto==0 ); @@ -4902,7 +4913,8 @@ case OP_IdxDelete: { assert( pOp->p1>=0 && pOp->p1nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); - pCrsr = pC->pCursor; + assert( pC->eCurType==CURTYPE_BTREE ); + pCrsr = pC->uc.pCursor; assert( pCrsr!=0 ); assert( pOp->p5==0 ); r.pKeyInfo = pC->pKeyInfo; @@ -4939,7 +4951,8 @@ case OP_IdxRowid: { /* out2 */ assert( pOp->p1>=0 && pOp->p1nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); - pCrsr = pC->pCursor; + assert( pC->eCurType==CURTYPE_BTREE ); + pCrsr = pC->uc.pCursor; assert( pCrsr!=0 ); pOut->flags = MEM_Null; assert( pC->isTable==0 ); @@ -5020,7 +5033,8 @@ case OP_IdxGE: { /* jump */ pC = p->apCsr[pOp->p1]; assert( pC!=0 ); assert( pC->isOrdered ); - assert( pC->pCursor!=0); + assert( pC->eCurType==CURTYPE_BTREE ); + assert( pC->uc.pCursor!=0); assert( pC->deferredMoveto==0 ); assert( pOp->p5==0 || pOp->p5==1 ); assert( pOp->p4type==P4_INT32 ); @@ -5153,11 +5167,12 @@ case OP_ResetSorter: { assert( pOp->p1>=0 && pOp->p1nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); - if( pC->pSorter ){ - sqlite3VdbeSorterReset(db, pC->pSorter); + if( isSorter(pC) ){ + sqlite3VdbeSorterReset(db, pC->uc.pSorter); }else{ + assert( pC->eCurType==CURTYPE_BTREE ); assert( pC->isEphemeral ); - rc = sqlite3BtreeClearTableOfCursor(pC->pCursor); + rc = sqlite3BtreeClearTableOfCursor(pC->uc.pCursor); } break; } @@ -6231,33 +6246,33 @@ case OP_VDestroy: { */ case OP_VOpen: { VdbeCursor *pCur; - sqlite3_vtab_cursor *pVtabCursor; + sqlite3_vtab_cursor *pVCur; sqlite3_vtab *pVtab; const sqlite3_module *pModule; assert( p->bIsReader ); pCur = 0; - pVtabCursor = 0; + pVCur = 0; pVtab = pOp->p4.pVtab->pVtab; if( pVtab==0 || NEVER(pVtab->pModule==0) ){ rc = SQLITE_LOCKED; break; } pModule = pVtab->pModule; - rc = pModule->xOpen(pVtab, &pVtabCursor); + rc = pModule->xOpen(pVtab, &pVCur); sqlite3VtabImportErrmsg(p, pVtab); if( SQLITE_OK==rc ){ /* Initialize sqlite3_vtab_cursor base class */ - pVtabCursor->pVtab = pVtab; + pVCur->pVtab = pVtab; /* Initialize vdbe cursor object */ - pCur = allocateCursor(p, pOp->p1, 0, -1, 0); + pCur = allocateCursor(p, pOp->p1, 0, -1, CURTYPE_VTAB); if( pCur ){ - pCur->pVtabCursor = pVtabCursor; + pCur->uc.pVCur = pVCur; pVtab->nRef++; }else{ assert( db->mallocFailed ); - pModule->xClose(pVtabCursor); + pModule->xClose(pVCur); goto no_mem; } } @@ -6291,7 +6306,7 @@ case OP_VFilter: { /* jump */ const sqlite3_module *pModule; Mem *pQuery; Mem *pArgc; - sqlite3_vtab_cursor *pVtabCursor; + sqlite3_vtab_cursor *pVCur; sqlite3_vtab *pVtab; VdbeCursor *pCur; int res; @@ -6303,9 +6318,9 @@ case OP_VFilter: { /* jump */ pCur = p->apCsr[pOp->p1]; assert( memIsValid(pQuery) ); REGISTER_TRACE(pOp->p3, pQuery); - assert( pCur->pVtabCursor ); - pVtabCursor = pCur->pVtabCursor; - pVtab = pVtabCursor->pVtab; + assert( pCur->eCurType==CURTYPE_VTAB ); + pVCur = pCur->uc.pVCur; + pVtab = pVCur->pVtab; pModule = pVtab->pModule; /* Grab the index number and argc parameters */ @@ -6319,10 +6334,10 @@ case OP_VFilter: { /* jump */ for(i = 0; ixFilter(pVtabCursor, iQuery, pOp->p4.z, nArg, apArg); + rc = pModule->xFilter(pVCur, iQuery, pOp->p4.z, nArg, apArg); sqlite3VtabImportErrmsg(p, pVtab); if( rc==SQLITE_OK ){ - res = pModule->xEof(pVtabCursor); + res = pModule->xEof(pVCur); } pCur->nullRow = 0; VdbeBranchTaken(res!=0,2); @@ -6346,7 +6361,7 @@ case OP_VColumn: { sqlite3_context sContext; VdbeCursor *pCur = p->apCsr[pOp->p1]; - assert( pCur->pVtabCursor ); + assert( pCur->eCurType==CURTYPE_VTAB ); assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); pDest = &aMem[pOp->p3]; memAboutToChange(p, pDest); @@ -6354,13 +6369,13 @@ case OP_VColumn: { sqlite3VdbeMemSetNull(pDest); break; } - pVtab = pCur->pVtabCursor->pVtab; + pVtab = pCur->uc.pVCur->pVtab; pModule = pVtab->pModule; assert( pModule->xColumn ); memset(&sContext, 0, sizeof(sContext)); sContext.pOut = pDest; MemSetTypeFlag(pDest, MEM_Null); - rc = pModule->xColumn(pCur->pVtabCursor, &sContext, pOp->p2); + rc = pModule->xColumn(pCur->uc.pVCur, &sContext, pOp->p2); sqlite3VtabImportErrmsg(p, pVtab); if( sContext.isError ){ rc = sContext.isError; @@ -6391,11 +6406,11 @@ case OP_VNext: { /* jump */ res = 0; pCur = p->apCsr[pOp->p1]; - assert( pCur->pVtabCursor ); + assert( pCur->eCurType==CURTYPE_VTAB ); if( pCur->nullRow ){ break; } - pVtab = pCur->pVtabCursor->pVtab; + pVtab = pCur->uc.pVCur->pVtab; pModule = pVtab->pModule; assert( pModule->xNext ); @@ -6405,10 +6420,10 @@ case OP_VNext: { /* jump */ ** data is available) and the error code returned when xColumn or ** some other method is next invoked on the save virtual table cursor. */ - rc = pModule->xNext(pCur->pVtabCursor); + rc = pModule->xNext(pCur->uc.pVCur); sqlite3VtabImportErrmsg(p, pVtab); if( rc==SQLITE_OK ){ - res = pModule->xEof(pCur->pVtabCursor); + res = pModule->xEof(pCur->uc.pVCur); } VdbeBranchTaken(!res,2); if( !res ){ @@ -6632,7 +6647,8 @@ case OP_CursorHint: { assert( pOp->p4type==P4_EXPR ); pC = p->apCsr[pOp->p1]; if( pC ){ - sqlite3BtreeCursorHint(pC->pCursor, BTREE_HINT_RANGE, pOp->p4.pExpr, aMem); + assert( pC->eCurType==CURTYPE_BTREE ); + sqlite3BtreeCursorHint(pC->uc.pCursor, BTREE_HINT_RANGE, pOp->p4.pExpr, aMem); } break; } diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 729304bd8d..d1de55eb1c 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -58,42 +58,48 @@ typedef struct Explain Explain; /* Elements of the linked list at Vdbe.pAuxData */ typedef struct AuxData AuxData; +/* Types of VDBE cursors */ +#define CURTYPE_BTREE 0 +#define CURTYPE_SORTER 1 +#define CURTYPE_VTAB 2 +#define CURTYPE_PSEUDO 3 + /* -** A cursor is a pointer into a single BTree within a database file. -** The cursor can seek to a BTree entry with a particular key, or -** loop over all entries of the Btree. You can also insert new BTree -** entries or retrieve the key or data from the entry that the cursor -** is currently pointing to. +** A VdbeCursor is an superclass (a wrapper) for various cursor objects: ** -** Cursors can also point to virtual tables, sorters, or "pseudo-tables". -** A pseudo-table is a single-row table implemented by registers. -** -** Every cursor that the virtual machine has open is represented by an -** instance of the following structure. +** * A b-tree cursor +** - In the main database or in an ephemeral database +** - On either an index or a table +** * A sorter +** * A virtual table +** * A one-row "pseudotable" stored in a single register */ struct VdbeCursor { - BtCursor *pCursor; /* The cursor structure of the backend */ - Btree *pBt; /* Separate file holding temporary table */ - KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */ - int seekResult; /* Result of previous sqlite3BtreeMoveto() */ - int pseudoTableReg; /* Register holding pseudotable content. */ - i16 nField; /* Number of fields in the header */ - u16 nHdrParsed; /* Number of header fields parsed so far */ -#ifdef SQLITE_DEBUG - u8 seekOp; /* Most recent seek operation on this cursor */ -#endif + u8 eCurType; /* One of the CURTYPE_* values above */ i8 iDb; /* Index of cursor database in db->aDb[] (or -1) */ u8 nullRow; /* True if pointing to a row with no data */ u8 deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */ + u8 isTable; /* True for rowid tables. False for indexes */ +#ifdef SQLITE_DEBUG + u8 seekOp; /* Most recent seek operation on this cursor */ +#endif Bool isEphemeral:1; /* True for an ephemeral table */ Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */ - Bool isTable:1; /* True if a table requiring integer keys */ Bool isOrdered:1; /* True if the underlying table is BTREE_UNORDERED */ Pgno pgnoRoot; /* Root page of the open btree cursor */ - sqlite3_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */ + i16 nField; /* Number of fields in the header */ + u16 nHdrParsed; /* Number of header fields parsed so far */ + union { + BtCursor *pCursor; /* CURTYPE_BTREE. Btree cursor */ + sqlite3_vtab_cursor *pVCur; /* CURTYPE_VTAB. Vtab cursor */ + int pseudoTableReg; /* CURTYPE_PSEUDO. Reg holding content. */ + VdbeSorter *pSorter; /* CURTYPE_SORTER. Sorter object */ + } uc; + Btree *pBt; /* Separate file holding temporary table */ + KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */ + int seekResult; /* Result of previous sqlite3BtreeMoveto() */ i64 seqCount; /* Sequence counter */ i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */ - VdbeSorter *pSorter; /* Sorter object for OP_SorterOpen cursors */ #ifdef SQLITE_ENABLE_COLUMN_USED_MASK u64 maskUsed; /* Mask of columns used by this cursor */ #endif diff --git a/src/vdbeaux.c b/src/vdbeaux.c index a5bc0b71a2..9ced9480b7 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1930,23 +1930,34 @@ void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){ if( pCx==0 ){ return; } - sqlite3VdbeSorterClose(p->db, pCx); - if( pCx->pBt ){ - sqlite3BtreeClose(pCx->pBt); - /* The pCx->pCursor will be close automatically, if it exists, by - ** the call above. */ - }else if( pCx->pCursor ){ - sqlite3BtreeCloseCursor(pCx->pCursor); - } + assert( pCx->pBt==0 || pCx->eCurType==CURTYPE_BTREE ); + switch( pCx->eCurType ){ + case CURTYPE_SORTER: { + sqlite3VdbeSorterClose(p->db, pCx); + break; + } + case CURTYPE_BTREE: { + if( pCx->pBt ){ + sqlite3BtreeClose(pCx->pBt); + /* The pCx->pCursor will be close automatically, if it exists, by + ** the call above. */ + }else{ + assert( pCx->uc.pCursor!=0 ); + sqlite3BtreeCloseCursor(pCx->uc.pCursor); + } + break; + } #ifndef SQLITE_OMIT_VIRTUALTABLE - else if( pCx->pVtabCursor ){ - sqlite3_vtab_cursor *pVtabCursor = pCx->pVtabCursor; - const sqlite3_module *pModule = pVtabCursor->pVtab->pModule; - assert( pVtabCursor->pVtab->nRef>0 ); - pVtabCursor->pVtab->nRef--; - pModule->xClose(pVtabCursor); - } + case CURTYPE_VTAB: { + sqlite3_vtab_cursor *pVCur = pCx->uc.pVCur; + const sqlite3_module *pModule = pVCur->pVtab->pModule; + assert( pVCur->pVtab->nRef>0 ); + pVCur->pVtab->nRef--; + pModule->xClose(pVCur); + break; + } #endif + } } /* @@ -2933,7 +2944,8 @@ static int SQLITE_NOINLINE handleDeferredMoveto(VdbeCursor *p){ #endif assert( p->deferredMoveto ); assert( p->isTable ); - rc = sqlite3BtreeMovetoUnpacked(p->pCursor, 0, p->movetoTarget, 0, &res); + assert( p->eCurType==CURTYPE_BTREE ); + rc = sqlite3BtreeMovetoUnpacked(p->uc.pCursor, 0, p->movetoTarget, 0, &res); if( rc ) return rc; if( res!=0 ) return SQLITE_CORRUPT_BKPT; #ifdef SQLITE_TEST @@ -2953,9 +2965,10 @@ static int SQLITE_NOINLINE handleDeferredMoveto(VdbeCursor *p){ */ static int SQLITE_NOINLINE handleMovedCursor(VdbeCursor *p){ int isDifferentRow, rc; - assert( p->pCursor!=0 ); - assert( sqlite3BtreeCursorHasMoved(p->pCursor) ); - rc = sqlite3BtreeCursorRestore(p->pCursor, &isDifferentRow); + assert( p->eCurType==CURTYPE_BTREE ); + assert( p->uc.pCursor!=0 ); + assert( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ); + rc = sqlite3BtreeCursorRestore(p->uc.pCursor, &isDifferentRow); p->cacheStatus = CACHE_STALE; if( isDifferentRow ) p->nullRow = 1; return rc; @@ -2966,7 +2979,8 @@ static int SQLITE_NOINLINE handleMovedCursor(VdbeCursor *p){ ** if need be. Return any I/O error from the restore operation. */ int sqlite3VdbeCursorRestore(VdbeCursor *p){ - if( sqlite3BtreeCursorHasMoved(p->pCursor) ){ + assert( p->eCurType==CURTYPE_BTREE ); + if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){ return handleMovedCursor(p); } return SQLITE_OK; @@ -2986,11 +3000,13 @@ int sqlite3VdbeCursorRestore(VdbeCursor *p){ ** not been deleted out from under the cursor, then this routine is a no-op. */ int sqlite3VdbeCursorMoveto(VdbeCursor *p){ - if( p->deferredMoveto ){ - return handleDeferredMoveto(p); - } - if( p->pCursor && sqlite3BtreeCursorHasMoved(p->pCursor) ){ - return handleMovedCursor(p); + if( p->eCurType==CURTYPE_BTREE ){ + if( p->deferredMoveto ){ + return handleDeferredMoveto(p); + } + if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){ + return handleMovedCursor(p); + } } return SQLITE_OK; } @@ -4303,9 +4319,11 @@ int sqlite3VdbeIdxKeyCompare( ){ i64 nCellKey = 0; int rc; - BtCursor *pCur = pC->pCursor; + BtCursor *pCur; Mem m; + assert( pC->eCurType==CURTYPE_BTREE ); + pCur = pC->uc.pCursor; assert( sqlite3BtreeCursorIsValid(pCur) ); VVA_ONLY(rc =) sqlite3BtreeKeySize(pCur, &nCellKey); assert( rc==SQLITE_OK ); /* pCur is always valid so KeySize cannot fail */ @@ -4316,7 +4334,7 @@ int sqlite3VdbeIdxKeyCompare( return SQLITE_CORRUPT_BKPT; } sqlite3VdbeMemInit(&m, db, 0); - rc = sqlite3VdbeMemFromBtree(pC->pCursor, 0, (u32)nCellKey, 1, &m); + rc = sqlite3VdbeMemFromBtree(pCur, 0, (u32)nCellKey, 1, &m); if( rc ){ return rc; } diff --git a/src/vdbeblob.c b/src/vdbeblob.c index 30a329189e..a4718efacc 100644 --- a/src/vdbeblob.c +++ b/src/vdbeblob.c @@ -76,7 +76,7 @@ static int blobSeekToRow(Incrblob *p, sqlite3_int64 iRow, char **pzErr){ }else{ p->iOffset = pC->aType[p->iCol + pC->nField]; p->nByte = sqlite3VdbeSerialTypeLen(type); - p->pCsr = pC->pCursor; + p->pCsr = pC->uc.pCursor; sqlite3BtreeIncrblobCursor(p->pCsr); } } diff --git a/src/vdbesort.c b/src/vdbesort.c index 9840bed315..54e538fd50 100644 --- a/src/vdbesort.c +++ b/src/vdbesort.c @@ -961,11 +961,12 @@ int sqlite3VdbeSorterInit( #endif assert( pCsr->pKeyInfo && pCsr->pBt==0 ); + assert( pCsr->eCurType==CURTYPE_SORTER ); szKeyInfo = sizeof(KeyInfo) + (pCsr->pKeyInfo->nField-1)*sizeof(CollSeq*); sz = sizeof(VdbeSorter) + nWorker * sizeof(SortSubtask); pSorter = (VdbeSorter*)sqlite3DbMallocZero(db, sz + szKeyInfo); - pCsr->pSorter = pSorter; + pCsr->uc.pSorter = pSorter; if( pSorter==0 ){ rc = SQLITE_NOMEM; }else{ @@ -1249,12 +1250,14 @@ void sqlite3VdbeSorterReset(sqlite3 *db, VdbeSorter *pSorter){ ** Free any cursor components allocated by sqlite3VdbeSorterXXX routines. */ void sqlite3VdbeSorterClose(sqlite3 *db, VdbeCursor *pCsr){ - VdbeSorter *pSorter = pCsr->pSorter; + VdbeSorter *pSorter; + assert( pCsr->eCurType==CURTYPE_SORTER ); + pSorter = pCsr->uc.pSorter; if( pSorter ){ sqlite3VdbeSorterReset(db, pSorter); sqlite3_free(pSorter->list.aMemory); sqlite3DbFree(db, pSorter); - pCsr->pSorter = 0; + pCsr->uc.pSorter = 0; } } @@ -1752,15 +1755,16 @@ int sqlite3VdbeSorterWrite( const VdbeCursor *pCsr, /* Sorter cursor */ Mem *pVal /* Memory cell containing record */ ){ - VdbeSorter *pSorter = pCsr->pSorter; + VdbeSorter *pSorter; int rc = SQLITE_OK; /* Return Code */ SorterRecord *pNew; /* New list element */ - int bFlush; /* True to flush contents of memory to PMA */ int nReq; /* Bytes of memory required */ int nPMA; /* Bytes of PMA space required */ int t; /* serial type of first record field */ + assert( pCsr->eCurType==CURTYPE_SORTER ); + pSorter = pCsr->uc.pSorter; getVarint32((const u8*)&pVal->z[1], t); if( t>0 && t<10 && t!=7 ){ pSorter->typeMask &= SORTER_TYPE_INTEGER; @@ -2552,9 +2556,11 @@ static int vdbeSorterSetupMerge(VdbeSorter *pSorter){ ** in sorted order. */ int sqlite3VdbeSorterRewind(const VdbeCursor *pCsr, int *pbEof){ - VdbeSorter *pSorter = pCsr->pSorter; + VdbeSorter *pSorter; int rc = SQLITE_OK; /* Return code */ + assert( pCsr->eCurType==CURTYPE_SORTER ); + pSorter = pCsr->uc.pSorter; assert( pSorter ); /* If no data has been written to disk, then do not do so now. Instead, @@ -2598,9 +2604,11 @@ int sqlite3VdbeSorterRewind(const VdbeCursor *pCsr, int *pbEof){ ** Advance to the next element in the sorter. */ int sqlite3VdbeSorterNext(sqlite3 *db, const VdbeCursor *pCsr, int *pbEof){ - VdbeSorter *pSorter = pCsr->pSorter; + VdbeSorter *pSorter; int rc; /* Return code */ + assert( pCsr->eCurType==CURTYPE_SORTER ); + pSorter = pCsr->uc.pSorter; assert( pSorter->bUsePMA || (pSorter->pReader==0 && pSorter->pMerger==0) ); if( pSorter->bUsePMA ){ assert( pSorter->pReader==0 || pSorter->pMerger==0 ); @@ -2660,9 +2668,11 @@ static void *vdbeSorterRowkey( ** Copy the current sorter key into the memory cell pOut. */ int sqlite3VdbeSorterRowkey(const VdbeCursor *pCsr, Mem *pOut){ - VdbeSorter *pSorter = pCsr->pSorter; + VdbeSorter *pSorter; void *pKey; int nKey; /* Sorter key to copy into pOut */ + assert( pCsr->eCurType==CURTYPE_SORTER ); + pSorter = pCsr->uc.pSorter; pKey = vdbeSorterRowkey(pSorter, &nKey); if( sqlite3VdbeMemClearAndResize(pOut, nKey) ){ return SQLITE_NOMEM; @@ -2696,12 +2706,16 @@ int sqlite3VdbeSorterCompare( int nKeyCol, /* Compare this many columns */ int *pRes /* OUT: Result of comparison */ ){ - VdbeSorter *pSorter = pCsr->pSorter; - UnpackedRecord *r2 = pSorter->pUnpacked; - KeyInfo *pKeyInfo = pCsr->pKeyInfo; + VdbeSorter *pSorter; + UnpackedRecord *r2; + KeyInfo *pKeyInfo; int i; void *pKey; int nKey; /* Sorter key to compare pVal with */ + assert( pCsr->eCurType==CURTYPE_SORTER ); + pSorter = pCsr->uc.pSorter; + r2 = pSorter->pUnpacked; + pKeyInfo = pCsr->pKeyInfo; if( r2==0 ){ char *p; r2 = pSorter->pUnpacked = sqlite3VdbeAllocUnpackedRecord(pKeyInfo,0,0,&p); From 202923107d97496744deb553836558e00d7fd108 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 21 Nov 2015 13:24:46 +0000 Subject: [PATCH 04/53] Do not allow table-valued function syntax on ordinary tables and views as those objects are not table-valued functions. Fix for ticket [73eba7ba5c7c0fc]. FossilOrigin-Name: ff5716b89f99d9c4568a39f1f52524528a631623 --- manifest | 22 +++++++++++----------- manifest.uuid | 2 +- src/build.c | 2 +- src/resolve.c | 7 ++++--- src/select.c | 24 +++++++++++++++++++----- src/whereexpr.c | 2 +- test/misc1.test | 2 +- test/tabfunc01.test | 22 ++++++++++++++++++++-- 8 files changed, 58 insertions(+), 25 deletions(-) diff --git a/manifest b/manifest index d22ad18b8d..360f4ee9aa 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Refactor\sthe\sVdbeCursor\sobject.\s\sIt\sis\snow\sslightly\ssmaller\sand\sfaster\sand\sis\neasier\sto\sunderstand. -D 2015-11-20T19:22:01.706 +C Do\snot\sallow\stable-valued\sfunction\ssyntax\son\sordinary\stables\sand\sviews\sas\sthose\nobjects\sare\snot\stable-valued\sfunctions.\nFix\sfor\sticket\s[73eba7ba5c7c0fc]. +D 2015-11-21T13:24:46.175 F Makefile.in d828db6afa6c1fa060d01e33e4674408df1942a1 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e928e68168df69b353300ac87c10105206653a03 @@ -285,7 +285,7 @@ F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79 F src/btree.c d3bdd8462a86492e2ebc9aca4a0168429017de25 F src/btree.h 2d76dee44704c47eed323356a758662724b674a0 F src/btreeInt.h 3ab435ed27adea54d040584b0bcc488ee7db1e38 -F src/build.c 5a3b71786e2b96d2bb92d40f190eb1fe736f25ca +F src/build.c 19f7585c9747d5043dae64bc82f9cac759f69700 F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0 F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f F src/ctime.c 509ef9c64d1321f42448f111da86400b1799218a @@ -337,9 +337,9 @@ F src/pragma.h 3d94aebbebd2089899fecc01909bf2608b39507d F src/prepare.c 82e5db1013846a819f198336fed72c44c974e7b1 F src/printf.c f8fc8f04e75b1e983ef2793c27ec7a43b287e94a F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 -F src/resolve.c 1954a0f01bf65d78d7d559aea3d5c67f33376d91 +F src/resolve.c f4c897ca76ca6d5e0b3f0499c627392ffe657c8e F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e -F src/select.c 2376d320907a5c28c55290f18fd94aa3400bf97c +F src/select.c 0495e86f8377026fbd529a1a5bf62046cbb6eec5 F src/shell.c f0f59ea60ad297f671b7ae0fb957a736ad17c92c F src/sqlite.h.in fa62718f73553f06b2f2e362fd09ccb4e1cbb626 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad @@ -419,7 +419,7 @@ F src/walker.c 2e14d17f592d176b6dc879c33fbdec4fbccaa2ba F src/where.c 6aceb72cc58dc06922a9e1604d559c8ca4c3e728 F src/whereInt.h 7892bb54cf9ca0ae5c7e6094491b94c9286dc647 F src/wherecode.c 4c96182e7b25e4be54008dee2da5b9c2f8480b9b -F src/whereexpr.c e63244ca06c503e5f3c5b7f3c9aea0db826089ed +F src/whereexpr.c fa36d793a96dfdec5260085baf59ee3cc39be9d5 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -876,7 +876,7 @@ F test/minmax.test 42fbad0e81afaa6e0de41c960329f2b2c3526efd F test/minmax2.test b44bae787fc7b227597b01b0ca5575c7cb54d3bc F test/minmax3.test cc1e8b010136db0d01a6f2a29ba5a9f321034354 F test/minmax4.test 936941484ebdceb8adec7c86b6cd9b6e5e897c1f -F test/misc1.test d614a334b777b1aded6873d76a3560329b819fea +F test/misc1.test 48ebfb5b22a6a058f7b7e1df211226dd1d21409c F test/misc2.test 00d7de54eda90e237fc9a38b9e5ccc769ebf6d4d F test/misc3.test cf3dda47d5dda3e53fc5804a100d3c82be736c9d F test/misc4.test 0d8be3466adf123a7791a66ba2bc8e8d229e87f3 @@ -1053,7 +1053,7 @@ F test/symlink.test 2513f7c030df0f435c6415687ba8b739f3d312df F test/sync.test a34cd43e98b7fb84eabbf38f7ed8f7349b3f3d85 F test/syscall.test fba9ebdc6905d05bba6a835e691f20ed9ea2cc88 F test/sysfault.test fa776e60bf46bdd3ae69f0b73e46ee3977a58ae6 -F test/tabfunc01.test 03c4ad422c6ab596cff6dcaf86dd061a9f039525 +F test/tabfunc01.test cc33684f9480fcf1fd5ce287ac28d22971cad1cc F test/table.test b708f3e5fa2542fa51dfab21fc07b36ea445cb2f F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126 F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930 @@ -1404,7 +1404,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 35c7f6cba6febf2480de01fca9d61b8065bf1c12 -R ae691eb0177fe2d5adc77d9ff2c7f6f3 +P 9b1d174d862500a627840008ffac4c8419dc97e2 +R 8fd11c528c94e9e37286e19e744014c6 U drh -Z 018ade43e937d593f3f9dd76ba8e9c12 +Z b8d6aae555aa179b5937cf64dce6701d diff --git a/manifest.uuid b/manifest.uuid index 86e0a6e699..a19be2c4ca 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9b1d174d862500a627840008ffac4c8419dc97e2 \ No newline at end of file +ff5716b89f99d9c4568a39f1f52524528a631623 \ No newline at end of file diff --git a/src/build.c b/src/build.c index f928ba3075..5f2dc28235 100644 --- a/src/build.c +++ b/src/build.c @@ -3876,7 +3876,7 @@ void sqlite3SrcListIndexedBy(Parse *pParse, SrcList *p, Token *pIndexedBy){ ** table-valued-function. */ void sqlite3SrcListFuncArgs(Parse *pParse, SrcList *p, ExprList *pList){ - if( p && pList ){ + if( p ){ struct SrcList_item *pItem = &p->a[p->nSrc-1]; assert( pItem->fg.notIndexed==0 ); assert( pItem->fg.isIndexedBy==0 ); diff --git a/src/resolve.c b/src/resolve.c index ac1706b595..b3e887778d 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -1423,9 +1423,10 @@ int sqlite3ResolveExprListNames( ExprList *pList /* The expression list to be analyzed. */ ){ int i; - assert( pList!=0 ); - for(i=0; inExpr; i++){ - if( sqlite3ResolveExprNames(pNC, pList->a[i].pExpr) ) return WRC_Abort; + if( pList ){ + for(i=0; inExpr; i++){ + if( sqlite3ResolveExprNames(pNC, pList->a[i].pExpr) ) return WRC_Abort; + } } return WRC_Continue; } diff --git a/src/select.c b/src/select.c index 3d69dfb03a..dc8443e8b5 100644 --- a/src/select.c +++ b/src/select.c @@ -3623,6 +3623,7 @@ static int flattenSubquery( */ for(i=0; ia[i+iFrom].pUsing); + assert( pSrc->a[i+iFrom].fg.isTabFunc==0 ); pSrc->a[i+iFrom] = pSubSrc->a[i]; memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i])); } @@ -3957,6 +3958,19 @@ static int convertCompoundSelectToSubquery(Walker *pWalker, Select *p){ return WRC_Continue; } +/* +** Check to see if the FROM clause term pFrom has table-valued function +** arguments. If it does, leave an error message in pParse and return +** non-zero, since pFrom is not allowed to be a table-valued function. +*/ +static int cannotBeFunction(Parse *pParse, struct SrcList_item *pFrom){ + if( pFrom->fg.isTabFunc ){ + sqlite3ErrorMsg(pParse, "'%s' is not a function", pFrom->zName); + return 1; + } + return 0; +} + #ifndef SQLITE_OMIT_CTE /* ** Argument pWith (which may be NULL) points to a linked list of nested @@ -4052,6 +4066,7 @@ static int withExpand( sqlite3ErrorMsg(pParse, pCte->zCteErr, pCte->zName); return SQLITE_ERROR; } + if( cannotBeFunction(pParse, pFrom) ) return SQLITE_ERROR; assert( pFrom->pTab==0 ); pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table)); @@ -4245,15 +4260,14 @@ static int selectExpander(Walker *pWalker, Select *p){ return WRC_Abort; } pTab->nRef++; + if( !IsVirtual(pTab) && cannotBeFunction(pParse, pFrom) ){ + return WRC_Abort; + } #if !defined(SQLITE_OMIT_VIEW) || !defined (SQLITE_OMIT_VIRTUALTABLE) - if( pTab->pSelect || IsVirtual(pTab) ){ + if( IsVirtual(pTab) || pTab->pSelect ){ i16 nCol; if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort; assert( pFrom->pSelect==0 ); - if( pFrom->fg.isTabFunc && !IsVirtual(pTab) ){ - sqlite3ErrorMsg(pParse, "'%s' is not a function", pTab->zName); - return WRC_Abort; - } pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0); sqlite3SelectSetName(pFrom->pSelect, pTab->zName); nCol = pTab->nCol; diff --git a/src/whereexpr.c b/src/whereexpr.c index fadde79010..aa64f93e49 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -1316,7 +1316,7 @@ void sqlite3WhereTabFuncArgs( pTab = pItem->pTab; assert( pTab!=0 ); pArgs = pItem->u1.pFuncArg; - assert( pArgs!=0 ); + if( pArgs==0 ) return; for(j=k=0; jnExpr; j++){ while( knCol && (pTab->aCol[k].colFlags & COLFLAG_HIDDEN)==0 ){ k++; } if( k>=pTab->nCol ){ diff --git a/test/misc1.test b/test/misc1.test index 6e0abcd108..400a4517b4 100644 --- a/test/misc1.test +++ b/test/misc1.test @@ -707,7 +707,7 @@ do_test misc1-24.0 { do_catchsql_test misc1-25.0 { SELECT-1 UNION SELECT 5 UNION SELECT 0 UNION SElECT*from(SELECT-5) UNION SELECT*from(SELECT-0) UNION SELECT:SELECT-0 UNION SELECT-1 UNION SELECT 1 UNION SELECT 1 ORDER BY S in(WITH K AS(WITH K AS(select'CREINDERcharREADEVIRTUL5TABLECONFLICT !1 USIN'' MFtOR(b38q,eWITH K AS(selectCREATe TABLE t0(a,b,c,d,e, PRIMARY KEY(a,b,c,d,c,a,b,b,c,d,c,a,b,c,e,c,d,c,a,b,b,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,a,b,c,e,c,d,c,a,b,b,c,d,c,d,c,a,b,c,e,d,d,c,a,b,b,c,c,a,b,b,c,d,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,a,b,c,e,c,d,c,a,b,b,c,a,b,b,c,d,c,a,c,d,c,d,c,e,d,d,c,a,b,b,c,c,a,b,b,E,d,c,d,c,b,c,d,c,d,c,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,a,b,c,e,c,d,c,a,b,b,c,a,b,c,e,d,d,c,a,b,b,c,d,d,c,a,b,c,e,d,c,d,c,a,b,c,e,c,d,c,a,b,b,c,d,c,a,b,c,e,d,d,c,a,b,b,b,c,e,d,d,c,a,b,b,c,c,a,b,b,c,d,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,a,b,c,e,c,d,c,a,b,b,c,d,c,d,c,e,d,d,c,a,b,b,c,c,a,b,b,E,d,c,d,c,b,c,d,c,d,c,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,a,b,c,e,c,d'CEIl,k'',ab, g, a,b,o11b, i'nEX/charREDE IVT LR!VABLt5SG',N ,N in rement,l_vacuum,M&U,'te3(''5l' a,bB,b,l*e)SELECT:SELECT, *,*,*from(( SELECT $group,:conc ap0,1)fro,(select"",:PBAG,c,a,b,b,c,a,b,c,e,d,d,c,a,b,b,c,d,d,c,a,b,c,e,d,c,d,c,a,b,c,e,c,d,c,d,c,a,b,b,c,d,c,a,b,c,e,c,d,c,a,b,b,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,a,b,c,e,c,d,c,a,b,b,c,d,c,d,c,a,b,c,e,d,d,c,a,b,b,c,c,a,b,b,c,d,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,a,b,c,e,d,c,d,c,a,b,c,e,c,d,c,a,b,b,c,d,c,a,b,c,e,d,d,c,a,b,b,b,c,e,d,d,c,a,b,b,c,c,a,b,b,c,d,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,a,b,c,e,c,d,c,a,b,b,c,d,c,d,c,e,d,d,c,a,b,b,c,c,a,b,b,E,d,c,d,c,b,c,d,c,d,c,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,a,b,c,e,c,d,c,a,b,b,c,a,b,c,e,d,d,c,a,b,b,c,d,d,c,a,b,c,e,d,c,d,c,a,b,c,e,c,d,c,d,c,a,b,b,c,d,c,a,b,c,e,c,d,c,a,b,b,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,a,b,c,e,c,d,c,a,b,b,c,d,c,d,c,a,b,c,e,d,d,c,a,b,b,c,c,a,b,b,c,d,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,a,b,c,e,c,d,c,a,b,b,c,d,c,d,c,e,d,d,c,a,b,b,c,c,a,b,b,E,d,c,d,c,b,c,d,c,d,c,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,a,b,c,e,c,d,c,a,b,b,c,a,b,c,e,d,d,c,a,b,b,c,d,d,c,a,b,c,e,d,c,d,c,a,b,c,e,c,d,c,a,b,b,c,c,d,c,c,a,a,b,d,d,c,a,b,b,c,d,c,a,b,e,e,d,b,c,d,c,a,b,b,c,d,c,a,b,c,e,c,d,c,a,b,b,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,a,b,c,e,c,d,c,a,b,b,c,d,c,d,c,a,b,c,e,d,d,c,a,b,b,c,c,a,b,b,c,d,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,a,b,c,e,c,d,c,a,b,b,c,d, foreign_keysc,d,c,e,d,d,c,a,b,b,c,c,a,b,b,E,d,c,d,c,b,c,d,c,d,c,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,a,a,b,d,d,c,a,b,b,c,d,c,a,b,e,e,d,b,c,d,c,a,b,b,c,d,c,a,b,c,e,c,d,c,a,b,b,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,a,b,c,e,c,d,c,a,b,b,c,d,c,d,c,a,b,c,d,c,a,b,c,e,c,d,c,a,b,b,c,d,c,d,c,e,d,d,c,a,b,b,c,c,a,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,a,b,c,e,c,d,c,a,b,b,c,d,c,d,c,a,b,c,d,c,a,b,c,e,c,d,c,a,b,b,c,d,c,d,c,e,d,d,c,a,b,b,c,c,a,b,b,E,d,c,d,c,b,c,d,c,d,c,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,a,b,c,e,c,d,c,a,b,b,c,a,b,c,e,d,d,c,a,b,b,c,d,d,c,a,b,c,e,d,c,d,c,a,b,c,e,c,d,c,a,b,b,c,c,d,c,a,b,d,d,c,a,a,b,d,d,c,a,b,b,c,d,c,a,b,e,e,d,b,c,d,c,a,b,b,c,d,c,a,b,c,e,c,d,c,a,b,b,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,a,b,c,e,c,d,c,a,b,b,c,d,c,d,c,a,b,c,e,d,d,c,a,b,b,c,c,a,b,b,c,d,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,a,b,c,e,c,d,c,a,b,b,c,d,c,d,c,e,d,d,c,a,b,b,c,c,a,b,b,E,d,c,d,c,b,c,d,c,d,c,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,a,a,b,d,d,c,a,b,b,c,d,c,a,b,e,e,d,b,c,d,c,a,b,b,c,d,c,a,b,c,e,c,d,c,a,b,b,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,a,b,c,e,c,d,c,a,b,b,c,d,c,d,c,a,b,c,e,d,d,c,a,b,b,c,c,a,b,b,c,d,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,a,b,c,e,c,d,c,a,b,b,c,d,c,d,c,e,d,d,c,a,b,b,c,c,a,b,b,E,d,c,d,c,b,c,d,c,d,c,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,a,b,c,e,c,d,c,a,b,b,c,a,bb,b,E,d,c,d,c,b,c,d,c,d,c,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,a,b,c,e,c,d,c,a,b,b,c,a,b,c,e,d,d,c,a,b,b,c,d,d,c,a,b,c,e,d,c,d,c,a,b,c,e,c,d,c,a,b,b,c,c,d,c,a,b,d,d,c,a,a,b,d,d,c,a,b,b,c,d,c,a,b,e,e,d,b,c,d,c,a,b,b,c,d,c,a,b,c,e,c,d,c,a,b,b,c,d,c,a,b,c,e,d,d,c,a,b,b,c,d,c,d,c,a,b,c,e,c,d,c,a,b,b,c,d,MAato_aecSELEC,+?b," "O,"i","a",""b ,5 ))KEY)SELECT*FROM((k()reaC,k,K) eA,k '' )t ,K M); -} {1 {too many columns in result set}} +} {1 {'k' is not a function}} finish_test diff --git a/test/tabfunc01.test b/test/tabfunc01.test index 47af39606e..d85cb20ff5 100644 --- a/test/tabfunc01.test +++ b/test/tabfunc01.test @@ -59,16 +59,34 @@ do_execsql_test tabfunc01-1.20 { CREATE VIEW v1(a,b) AS VALUES(1,2),(3,4); SELECT * FROM v1; } {1 2 3 4} -do_catchsql_test tabfunc01-1.21 { +do_catchsql_test tabfunc01-1.21.1 { SELECT * FROM v1(55); } {1 {'v1' is not a function}} +do_catchsql_test tabfunc01-1.21.2 { + SELECT * FROM v1(); +} {1 {'v1' is not a function}} do_execsql_test tabfunc01-1.22 { CREATE VIEW v2(x) AS SELECT value FROM generate_series(1,5); SELECT * FROM v2; } {1 2 3 4 5} -do_catchsql_test tabfunc01-1.23 { +do_catchsql_test tabfunc01-1.23.1 { SELECT * FROM v2(55); } {1 {'v2' is not a function}} +do_catchsql_test tabfunc01-1.23.2 { + SELECT * FROM v2(); +} {1 {'v2' is not a function}} +do_execsql_test tabfunc01-1.24 { + CREATE TABLE t0(x); + INSERT INTO t0(x) VALUES(123),(456),(789); + SELECT * FROM t0 ORDER BY x; +} {123 456 789} +do_catchsql_test tabfunc01-1.25 { + SELECT * FROM t0(55) ORDER BY x; +} {1 {'t0' is not a function}} +do_catchsql_test tabfunc01-1.26 { + WITH w0 AS (SELECT * FROM t0) + INSERT INTO t0(x) SELECT * FROM w0() +} {1 {'w0' is not a function}} do_execsql_test tabfunc01-2.1 { CREATE TABLE t1(x); From 62aaa6ca885067b241c88cf24a6c40c26df2a9ca Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 21 Nov 2015 17:27:42 +0000 Subject: [PATCH 05/53] Fix over-length source code lines. No logic changes. FossilOrigin-Name: 198d191b2f5ef7d63ac0093c701955c9052fd734 --- manifest | 28 ++++++++++++++-------------- manifest.uuid | 2 +- src/bitvec.c | 3 ++- src/expr.c | 7 ++++--- src/mem5.c | 2 +- src/mutex_unix.c | 2 +- src/os_unix.c | 2 +- src/os_win.c | 2 +- src/util.c | 6 ++++-- src/vdbe.c | 11 +++++++---- src/whereexpr.c | 5 +++-- 11 files changed, 39 insertions(+), 31 deletions(-) diff --git a/manifest b/manifest index 360f4ee9aa..48ad5f5d35 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\sallow\stable-valued\sfunction\ssyntax\son\sordinary\stables\sand\sviews\sas\sthose\nobjects\sare\snot\stable-valued\sfunctions.\nFix\sfor\sticket\s[73eba7ba5c7c0fc]. -D 2015-11-21T13:24:46.175 +C Fix\sover-length\ssource\scode\slines.\s\sNo\slogic\schanges. +D 2015-11-21T17:27:42.127 F Makefile.in d828db6afa6c1fa060d01e33e4674408df1942a1 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e928e68168df69b353300ac87c10105206653a03 @@ -280,7 +280,7 @@ F src/analyze.c 4c308880cf53c558070cb8513bdff4ffb1a38a77 F src/attach.c e944d0052b577703b9b83aac1638452ff42a8395 F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c 2869a76c03eb393ee795416e2387005553df72bc -F src/bitvec.c d1f21d7d91690747881f03940584f4cc548c9d3d +F src/bitvec.c 1a78d450a17c5016710eec900bedfc5729bf9bdf F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79 F src/btree.c d3bdd8462a86492e2ebc9aca4a0168429017de25 F src/btree.h 2d76dee44704c47eed323356a758662724b674a0 @@ -292,7 +292,7 @@ F src/ctime.c 509ef9c64d1321f42448f111da86400b1799218a F src/date.c fb1c99172017dcc8e237339132c91a21a0788584 F src/dbstat.c ffd63fc8ba7541476ced189b95e95d7f2bc63f78 F src/delete.c 00af9f08a15ddc5cba5962d3d3e5bf2d67b2e7da -F src/expr.c 0080c0f12806eca91e75a23a121a68918e9da357 +F src/expr.c dfccb439a2a981d71970ce3d15effeb59b258798 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 31900763094a3736a5fc887469202eb579fef2d0 F src/func.c ecdd69ec6a1e406f04cc73324be2ebbf6354197f @@ -310,21 +310,21 @@ F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3 F src/mem3.c 8768ac94694f31ffaf8b4d0ea5dc08af7010a35a -F src/mem5.c c1ab1153bd6443bdf6f71e4213c6fb31221b9eb7 +F src/mem5.c 5c267678ba9f745a2ee58102a9f482d64a58577a F src/memjournal.c 3eb2c0b51adbd869cb6a44780323f05fa904dc85 F src/msvc.h d9ba56c6851227ab44b3f228a35f3f5772296495 F src/mutex.c 8e45800ee78e0cd1f1f3fe8e398853307f4a085c F src/mutex.h 779d588e3b7756ec3ecf7d78cde1d84aba414f85 F src/mutex_noop.c 9d4309c075ba9cc7249e19412d3d62f7f94839c4 -F src/mutex_unix.c a94b46f3f7beba307dde1b298b0f99f9c3677a93 +F src/mutex_unix.c fc54f25b2a750d53b32512a4a728cec28039ae2a F src/mutex_w32.c 5e6fe1c298fb5a8a15aaed4161d5759311431c17 F src/notify.c 9711a7575036f0d3040ba61bc6e217f13a9888e7 F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8 F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf F src/os_common.h abdb9a191a367793268fe553d25bab894e986a0e F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa -F src/os_unix.c eb24e0340fbe3cfd0eabfb15a71476953e54fa73 -F src/os_win.c 2d77dab5c555a18c0aff379c6a692fc3499044d9 +F src/os_unix.c bddde71dc024574ace03ffee859abb99d152fd4a +F src/os_win.c 386fba30419e8458b13209781c2af5590eab2811 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c 18341e2b759b447cbc82fb9215d08d9c5864e92e F src/pager.h 87c4118a71ba3965184148b379a6d93179071091 @@ -400,9 +400,9 @@ F src/treeview.c 78842e90c1f71269e7a73a1d4221b6fe360bab66 F src/trigger.c 322f23aad694e8f31d384dcfa386d52a48d3c52f F src/update.c 40e51cd0883cb5bfd6abb7d8a7cd8aa47fab2945 F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c -F src/util.c fc612367108b74573c5fd13a85d0a23027f438bd +F src/util.c e802e8e311a0d6c48cd1b3e89db164f6f0248d70 F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701 -F src/vdbe.c 9ef1b1701e133d1cdb7dc66598863993b925b069 +F src/vdbe.c b56b2fc9b2f2d0a99d1dbd02d47efaacec253a4c F src/vdbe.h efb7a8c1459e31f3ea4377824c6a7e4cb5068637 F src/vdbeInt.h 75c2e82ee3357e9210c06474f8d9bdf12c81105d F src/vdbeapi.c 020681b943e77766b32ae1cddf86d7831b7374ca @@ -419,7 +419,7 @@ F src/walker.c 2e14d17f592d176b6dc879c33fbdec4fbccaa2ba F src/where.c 6aceb72cc58dc06922a9e1604d559c8ca4c3e728 F src/whereInt.h 7892bb54cf9ca0ae5c7e6094491b94c9286dc647 F src/wherecode.c 4c96182e7b25e4be54008dee2da5b9c2f8480b9b -F src/whereexpr.c fa36d793a96dfdec5260085baf59ee3cc39be9d5 +F src/whereexpr.c bd4877cd4dd11f6ab551ef0054535ca3c6224950 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1404,7 +1404,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 9b1d174d862500a627840008ffac4c8419dc97e2 -R 8fd11c528c94e9e37286e19e744014c6 +P ff5716b89f99d9c4568a39f1f52524528a631623 +R 558d15295cc22b403e8d5cb8c3ebd48a U drh -Z b8d6aae555aa179b5937cf64dce6701d +Z 0a3988f827c1f289bd36fdbbf324f548 diff --git a/manifest.uuid b/manifest.uuid index a19be2c4ca..48582621bb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ff5716b89f99d9c4568a39f1f52524528a631623 \ No newline at end of file +198d191b2f5ef7d63ac0093c701955c9052fd734 \ No newline at end of file diff --git a/src/bitvec.c b/src/bitvec.c index fd908f791b..f7f544cff7 100644 --- a/src/bitvec.c +++ b/src/bitvec.c @@ -41,7 +41,8 @@ /* Round the union size down to the nearest pointer boundary, since that's how ** it will be aligned within the Bitvec struct. */ -#define BITVEC_USIZE (((BITVEC_SZ-(3*sizeof(u32)))/sizeof(Bitvec*))*sizeof(Bitvec*)) +#define BITVEC_USIZE \ + (((BITVEC_SZ-(3*sizeof(u32)))/sizeof(Bitvec*))*sizeof(Bitvec*)) /* Type of the array "element" for the bitmap representation. ** Should be a power of 2, and ideally, evenly divide into BITVEC_USIZE. diff --git a/src/expr.c b/src/expr.c index 6371e15ca7..0255d6902f 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1889,9 +1889,10 @@ int sqlite3CodeSubselect( #ifndef SQLITE_OMIT_EXPLAIN if( pParse->explain==2 ){ - char *zMsg = sqlite3MPrintf( - pParse->db, "EXECUTE %s%s SUBQUERY %d", jmpIfDynamic>=0?"":"CORRELATED ", - pExpr->op==TK_IN?"LIST":"SCALAR", pParse->iNextSelectId + char *zMsg = sqlite3MPrintf(pParse->db, "EXECUTE %s%s SUBQUERY %d", + jmpIfDynamic>=0?"":"CORRELATED ", + pExpr->op==TK_IN?"LIST":"SCALAR", + pParse->iNextSelectId ); sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC); } diff --git a/src/mem5.c b/src/mem5.c index 6bb24e5449..b34a04e8b6 100644 --- a/src/mem5.c +++ b/src/mem5.c @@ -241,7 +241,7 @@ static void *memsys5MallocUnsafe(int nByte){ } /* Round nByte up to the next valid power of two */ - for(iFullSz=mem5.szAtom, iLogsize=0; iFullSzh, res)); }else{ - res = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS,RESERVED_BYTE, 0, 1, 0); + res = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS,RESERVED_BYTE,0,1,0); if( res ){ winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0); } diff --git a/src/util.c b/src/util.c index f218bb7941..b4c5e62bb3 100644 --- a/src/util.c +++ b/src/util.c @@ -555,7 +555,8 @@ int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){ testcase( i==18 ); testcase( i==19 ); testcase( i==20 ); - if( (c!=0 && &zNum[i]19*incr || nonNum ){ + if( (c!=0 && &zNum[i]19*incr || nonNum ){ /* zNum is empty or contains non-numeric text or is longer ** than 19 digits (thus guaranteeing that it is too large) */ return 1; @@ -844,7 +845,8 @@ u8 sqlite3GetVarint(const unsigned char *p, u64 *v){ /* a: p0<<28 | p2<<14 | p4 (unmasked) */ if (!(a&0x80)) { - /* we can skip these cause they were (effectively) done above in calc'ing s */ + /* we can skip these cause they were (effectively) done above + ** while calculating s */ /* a &= (0x7f<<28)|(0x7f<<14)|(0x7f); */ /* b &= (0x7f<<14)|(0x7f); */ b = b<<7; diff --git a/src/vdbe.c b/src/vdbe.c index 7428d5f607..66b507b285 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2384,7 +2384,7 @@ case OP_Column: { assert( pC!=0 ); assert( p2nField ); aOffset = pC->aOffset; - assert( pC->eCurType!=CURTYPE_VTAB ); /* OP_Column never called on virtual table */ + assert( pC->eCurType!=CURTYPE_VTAB ); assert( pC->eCurType!=CURTYPE_PSEUDO || pC->nullRow ); assert( pC->eCurType!=CURTYPE_SORTER ); pCrsr = pC->uc.pCursor; @@ -3469,11 +3469,13 @@ case OP_OpenEphemeral: { assert( pKeyInfo->db==db ); assert( pKeyInfo->enc==ENC(db) ); pCx->pKeyInfo = pKeyInfo; - rc = sqlite3BtreeCursor(pCx->pBt, pgno, BTREE_WRCSR, pKeyInfo, pCx->uc.pCursor); + rc = sqlite3BtreeCursor(pCx->pBt, pgno, BTREE_WRCSR, + pKeyInfo, pCx->uc.pCursor); } pCx->isTable = 0; }else{ - rc = sqlite3BtreeCursor(pCx->pBt, MASTER_ROOT, BTREE_WRCSR, 0, pCx->uc.pCursor); + rc = sqlite3BtreeCursor(pCx->pBt, MASTER_ROOT, BTREE_WRCSR, + 0, pCx->uc.pCursor); pCx->isTable = 1; } } @@ -6648,7 +6650,8 @@ case OP_CursorHint: { pC = p->apCsr[pOp->p1]; if( pC ){ assert( pC->eCurType==CURTYPE_BTREE ); - sqlite3BtreeCursorHint(pC->uc.pCursor, BTREE_HINT_RANGE, pOp->p4.pExpr, aMem); + sqlite3BtreeCursorHint(pC->uc.pCursor, BTREE_HINT_RANGE, + pOp->p4.pExpr, aMem); } break; } diff --git a/src/whereexpr.c b/src/whereexpr.c index aa64f93e49..21301ac046 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -1222,7 +1222,8 @@ void sqlite3WhereClauseInit( /* ** Deallocate a WhereClause structure. The WhereClause structure -** itself is not freed. This routine is the inverse of sqlite3WhereClauseInit(). +** itself is not freed. This routine is the inverse of +** sqlite3WhereClauseInit(). */ void sqlite3WhereClauseClear(WhereClause *pWC){ int i; @@ -1318,7 +1319,7 @@ void sqlite3WhereTabFuncArgs( pArgs = pItem->u1.pFuncArg; if( pArgs==0 ) return; for(j=k=0; jnExpr; j++){ - while( knCol && (pTab->aCol[k].colFlags & COLFLAG_HIDDEN)==0 ){ k++; } + while( knCol && (pTab->aCol[k].colFlags & COLFLAG_HIDDEN)==0 ){k++;} if( k>=pTab->nCol ){ sqlite3ErrorMsg(pParse, "too many arguments on %s() - max %d", pTab->zName, j); From 8836cbbcb4924f5b78f5749dffc9857acf9b684f Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 21 Nov 2015 19:43:29 +0000 Subject: [PATCH 06/53] Fix an obscure memory leak found by libfuzzer that may occur under some circumstances if expanding a "*" expression causes a SELECT to return more than 32767 columns. FossilOrigin-Name: 60de5f23424552c98aa760ac89149a3d51f895be --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/select.c | 2 ++ test/sqllimits1.test | 11 +++++++++++ 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 48ad5f5d35..1ed1813193 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sover-length\ssource\scode\slines.\s\sNo\slogic\schanges. -D 2015-11-21T17:27:42.127 +C Fix\san\sobscure\smemory\sleak\sfound\sby\slibfuzzer\sthat\smay\soccur\sunder\ssome\scircumstances\sif\sexpanding\sa\s"*"\sexpression\scauses\sa\sSELECT\sto\sreturn\smore\sthan\s32767\scolumns. +D 2015-11-21T19:43:29.760 F Makefile.in d828db6afa6c1fa060d01e33e4674408df1942a1 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e928e68168df69b353300ac87c10105206653a03 @@ -339,7 +339,7 @@ F src/printf.c f8fc8f04e75b1e983ef2793c27ec7a43b287e94a F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c f4c897ca76ca6d5e0b3f0499c627392ffe657c8e F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e -F src/select.c 0495e86f8377026fbd529a1a5bf62046cbb6eec5 +F src/select.c e10586c750d87211caa8f4b239e2bfa6a2049e5b F src/shell.c f0f59ea60ad297f671b7ae0fb957a736ad17c92c F src/sqlite.h.in fa62718f73553f06b2f2e362fd09ccb4e1cbb626 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad @@ -1038,7 +1038,7 @@ F test/speedtest1.c f8bf04214e7b5f745feea99f7bde68b1c4870666 F test/spellfix.test 0597065ff57042df1f138e6a2611ae19c2698135 F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3 F test/sqldiff1.test 8f6bc7c6a5b3585d350d779c6078869ba402f8f5 -F test/sqllimits1.test 89b3d5aad05b99f707ee3786bdd4416dccf83304 +F test/sqllimits1.test a74ee2a3740b9f9c2437c246d8fb77354862a142 F test/sqllog.test a8faa2df39610a037dd372ed872d124260d32953 F test/stat.test 8de91498c99f5298b303f70f1d1f3b9557af91bf F test/statfault.test f525a7bf633e50afd027700e9a486090684b1ac1 @@ -1404,7 +1404,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P ff5716b89f99d9c4568a39f1f52524528a631623 -R 558d15295cc22b403e8d5cb8c3ebd48a -U drh -Z 0a3988f827c1f289bd36fdbbf324f548 +P 198d191b2f5ef7d63ac0093c701955c9052fd734 +R 8ed8d9e954ea81e19ae35a6836359b00 +U dan +Z f96d100152be981f85597b50bc9a8134 diff --git a/manifest.uuid b/manifest.uuid index 48582621bb..90fb983695 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -198d191b2f5ef7d63ac0093c701955c9052fd734 \ No newline at end of file +60de5f23424552c98aa760ac89149a3d51f895be \ No newline at end of file diff --git a/src/select.c b/src/select.c index dc8443e8b5..cf486e5b85 100644 --- a/src/select.c +++ b/src/select.c @@ -1613,6 +1613,7 @@ int sqlite3ColumnsFromExprList( nCol = 0; aCol = 0; } + assert( nCol==(i16)nCol ); *pnCol = nCol; *paCol = aCol; @@ -4455,6 +4456,7 @@ static int selectExpander(Walker *pWalker, Select *p){ #if SQLITE_MAX_COLUMN if( p->pEList && p->pEList->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){ sqlite3ErrorMsg(pParse, "too many columns in result set"); + return WRC_Abort; } #endif return WRC_Continue; diff --git a/test/sqllimits1.test b/test/sqllimits1.test index ec72723ebe..9508b5233d 100644 --- a/test/sqllimits1.test +++ b/test/sqllimits1.test @@ -874,6 +874,17 @@ do_test sqllimits1-16.2 { } } {1 {string or blob too big}} +do_catchsql_test sqllimits1.17.0 { + SELECT *,*,*,*,*,*,*,* FROM ( + SELECT *,*,*,*,*,*,*,* FROM ( + SELECT *,*,*,*,*,*,*,* FROM ( + SELECT *,*,*,*,*,*,*,* FROM ( + SELECT *,*,*,*,*,*,*,* FROM ( + SELECT 1,2,3,4,5,6,7,8,9,10 + ) + )))) +} "1 {too many columns in result set}" + foreach {key value} [array get saved] { catch {set $key $value} From 07bdba86d55b298c44cacdf92f164c1a5953504c Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 23 Nov 2015 21:09:54 +0000 Subject: [PATCH 07/53] Add experimental support for LIKE, GLOB and REGEXP to the virtual table interface. FossilOrigin-Name: 277a5b4027d4c2caba8143228a4f7d6df899dbb4 --- manifest | 26 +++++++++++++++----------- manifest.uuid | 2 +- src/sqlite.h.in | 15 +++++++++------ src/test8.c | 6 ++++++ src/where.c | 3 +++ src/whereInt.h | 1 + src/whereexpr.c | 28 ++++++++++++++++++++++------ test/vtab1.test | 8 ++++---- test/vtabH.test | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 110 insertions(+), 28 deletions(-) create mode 100644 test/vtabH.test diff --git a/manifest b/manifest index 1ed1813193..77ed28994e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sobscure\smemory\sleak\sfound\sby\slibfuzzer\sthat\smay\soccur\sunder\ssome\scircumstances\sif\sexpanding\sa\s"*"\sexpression\scauses\sa\sSELECT\sto\sreturn\smore\sthan\s32767\scolumns. -D 2015-11-21T19:43:29.760 +C Add\sexperimental\ssupport\sfor\sLIKE,\sGLOB\sand\sREGEXP\sto\sthe\svirtual\stable\sinterface. +D 2015-11-23T21:09:54.478 F Makefile.in d828db6afa6c1fa060d01e33e4674408df1942a1 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e928e68168df69b353300ac87c10105206653a03 @@ -341,7 +341,7 @@ F src/resolve.c f4c897ca76ca6d5e0b3f0499c627392ffe657c8e F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e F src/select.c e10586c750d87211caa8f4b239e2bfa6a2049e5b F src/shell.c f0f59ea60ad297f671b7ae0fb957a736ad17c92c -F src/sqlite.h.in fa62718f73553f06b2f2e362fd09ccb4e1cbb626 +F src/sqlite.h.in a71226fe80bded2af3b99c5aed7363ef486962e1 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h 4b66e3e3435da4b4c8c83696d0349f0c503b3924 F src/sqliteInt.h 64256d193a16a147d9f6317cc4e095fdd3e0a2e9 @@ -356,7 +356,7 @@ F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e F src/test5.c 5a34feec76d9b3a86aab30fd4f6cc9c48cbab4c1 F src/test6.c 41cacf3b0dd180823919bf9e1fbab287c9266723 F src/test7.c 9c89a4f1ed6bb13af0ed805b8d782bd83fcd57e3 -F src/test8.c 610e3d523018ca63b08081795e76794a2121ec38 +F src/test8.c 59d91e1ff19aa91603aa409d4f41568cab1b9a2d F src/test9.c bea1e8cf52aa93695487badedd6e1886c321ea60 F src/test_async.c 21e11293a2f72080eda70e1124e9102044531cd8 F src/test_autoext.c dea8a01a7153b9adc97bd26161e4226329546e12 @@ -416,10 +416,10 @@ F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb F src/wal.c 18b0ed49830cf04fe2d68224b41838a73ac6cd24 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 2e14d17f592d176b6dc879c33fbdec4fbccaa2ba -F src/where.c 6aceb72cc58dc06922a9e1604d559c8ca4c3e728 -F src/whereInt.h 7892bb54cf9ca0ae5c7e6094491b94c9286dc647 +F src/where.c 6687fb2675d9c1c1936ceca77529e2f21fb3a769 +F src/whereInt.h 6afc0d70cf6213e58e8fbe10b6e50d1aa16f122f F src/wherecode.c 4c96182e7b25e4be54008dee2da5b9c2f8480b9b -F src/whereexpr.c bd4877cd4dd11f6ab551ef0054535ca3c6224950 +F src/whereexpr.c 12c6fa7576674d24bf0116364a39885925c89188 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1259,7 +1259,7 @@ F test/vacuum4.test d3f8ecff345f166911568f397d2432c16d2867d9 F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102 F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661 F test/view.test f6c3a39e0c819891265e1d0754e99960d81ef6c9 -F test/vtab1.test 6210e076997f176bedc300a87ad6404651b601dd +F test/vtab1.test ec5cb767277d7e0eff34d3a02824c1dd959a5959 F test/vtab2.test f8cd1bb9aba7143eba97812d9617880a36d247ad F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e F test/vtab4.test 942f8b8280b3ea8a41dae20e7822d065ca1cb275 @@ -1274,6 +1274,7 @@ F test/vtabC.test 4528f459a13136f982e75614d120aef165f17292 F test/vtabD.test 05b3f1d77117271671089e48719524b676842e96 F test/vtabE.test 7c4693638d7797ce2eda17af74292b97e705cc61 F test/vtabF.test fd5ad376f5a34fe0891df1f3cddb4fe7c3eb077e +F test/vtabH.test 15e137d2af9b0b81fedca6697518eb8834c013f4 F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5 F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8 F test/vtab_shared.test ea8778d5b0df200adef2ca7c00c3c37d4375f772 @@ -1404,7 +1405,10 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 198d191b2f5ef7d63ac0093c701955c9052fd734 -R 8ed8d9e954ea81e19ae35a6836359b00 +P 60de5f23424552c98aa760ac89149a3d51f895be +R b6557d1407b51115ef511b97d0fc16c1 +T *branch * vtab-like-operator +T *sym-vtab-like-operator * +T -sym-trunk * U dan -Z f96d100152be981f85597b50bc9a8134 +Z 249ced27266ff2c4ebd31fcaec9b55b5 diff --git a/manifest.uuid b/manifest.uuid index 90fb983695..eee0121605 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -60de5f23424552c98aa760ac89149a3d51f895be \ No newline at end of file +277a5b4027d4c2caba8143228a4f7d6df899dbb4 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 13c97d8d4a..42652061fb 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -5709,12 +5709,15 @@ struct sqlite3_index_info { ** an operator that is part of a constraint term in the wHERE clause of ** a query that uses a [virtual table]. */ -#define SQLITE_INDEX_CONSTRAINT_EQ 2 -#define SQLITE_INDEX_CONSTRAINT_GT 4 -#define SQLITE_INDEX_CONSTRAINT_LE 8 -#define SQLITE_INDEX_CONSTRAINT_LT 16 -#define SQLITE_INDEX_CONSTRAINT_GE 32 -#define SQLITE_INDEX_CONSTRAINT_MATCH 64 +#define SQLITE_INDEX_CONSTRAINT_EQ 2 +#define SQLITE_INDEX_CONSTRAINT_GT 4 +#define SQLITE_INDEX_CONSTRAINT_LE 8 +#define SQLITE_INDEX_CONSTRAINT_LT 16 +#define SQLITE_INDEX_CONSTRAINT_GE 32 +#define SQLITE_INDEX_CONSTRAINT_MATCH 64 +#define SQLITE_INDEX_CONSTRAINT_LIKE 65 +#define SQLITE_INDEX_CONSTRAINT_GLOB 66 +#define SQLITE_INDEX_CONSTRAINT_REGEXP 67 /* ** CAPI3REF: Register A Virtual Table Implementation diff --git a/src/test8.c b/src/test8.c index 2107710a99..6d70c3042b 100644 --- a/src/test8.c +++ b/src/test8.c @@ -849,6 +849,12 @@ static int echoBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ zOp = ">="; break; case SQLITE_INDEX_CONSTRAINT_MATCH: zOp = "LIKE"; break; + case SQLITE_INDEX_CONSTRAINT_LIKE: + zOp = "like"; break; + case SQLITE_INDEX_CONSTRAINT_GLOB: + zOp = "glob"; break; + case SQLITE_INDEX_CONSTRAINT_REGEXP: + zOp = "regexp"; break; } if( zOp[0]=='L' ){ zNew = sqlite3_mprintf(" %s %s LIKE (SELECT '%%'||?||'%%')", diff --git a/src/where.c b/src/where.c index 1c87706ea2..737bfc4e6f 100644 --- a/src/where.c +++ b/src/where.c @@ -893,6 +893,9 @@ static sqlite3_index_info *allocateIndexInfo( pIdxCons[j].iTermOffset = i; op = (u8)pTerm->eOperator & WO_ALL; if( op==WO_IN ) op = WO_EQ; + if( op==WO_MATCH ){ + op = pTerm->eMatchOp; + } pIdxCons[j].op = op; /* The direct assignment in the previous line is possible only because ** the WO_ and SQLITE_INDEX_CONSTRAINT_ codes are identical. The diff --git a/src/whereInt.h b/src/whereInt.h index cae09acc82..86164d8c1f 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -253,6 +253,7 @@ struct WhereTerm { u16 eOperator; /* A WO_xx value describing */ u16 wtFlags; /* TERM_xxx bit flags. See below */ u8 nChild; /* Number of children that must disable us */ + u8 eMatchOp; /* Op for vtab MATCH/LIKE/GLOB/REGEXP terms */ WhereClause *pWC; /* The clause this term is part of */ Bitmask prereqRight; /* Bitmask of tables used by pExpr->pRight */ Bitmask prereqAll; /* Bitmask of tables referenced by pExpr */ diff --git a/src/whereexpr.c b/src/whereexpr.c index 21301ac046..0cc2fd7209 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -282,16 +282,24 @@ static int isLikeOrGlob( ** If it is then return TRUE. If not, return FALSE. */ static int isMatchOfColumn( - Expr *pExpr /* Test this expression */ + Expr *pExpr, /* Test this expression */ + unsigned char *peOp2 /* OUT: 0 for MATCH, or else an op2 value */ ){ + struct Op2 { + const char *zOp; + unsigned char eOp2; + } aOp[] = { + { "match", SQLITE_INDEX_CONSTRAINT_MATCH }, + { "glob", SQLITE_INDEX_CONSTRAINT_GLOB }, + { "like", SQLITE_INDEX_CONSTRAINT_LIKE }, + { "regex", SQLITE_INDEX_CONSTRAINT_REGEXP } + }; ExprList *pList; + int i; if( pExpr->op!=TK_FUNCTION ){ return 0; } - if( sqlite3StrICmp(pExpr->u.zToken,"match")!=0 ){ - return 0; - } pList = pExpr->x.pList; if( pList->nExpr!=2 ){ return 0; @@ -299,7 +307,13 @@ static int isMatchOfColumn( if( pList->a[1].pExpr->op != TK_COLUMN ){ return 0; } - return 1; + for(i=0; iu.zToken, aOp[i].zOp)==0 ){ + *peOp2 = aOp[i].eOp2; + return 1; + } + } + return 0; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ @@ -876,6 +890,7 @@ static void exprAnalyze( int op; /* Top-level operator. pExpr->op */ Parse *pParse = pWInfo->pParse; /* Parsing context */ sqlite3 *db = pParse->db; /* Database connection */ + unsigned char eOp2; /* op2 value for LIKE/REGEXP/GLOB */ if( db->mallocFailed ){ return; @@ -1099,7 +1114,7 @@ static void exprAnalyze( ** virtual tables. The native query optimizer does not attempt ** to do anything with MATCH functions. */ - if( isMatchOfColumn(pExpr) ){ + if( isMatchOfColumn(pExpr, &eOp2) ){ int idxNew; Expr *pRight, *pLeft; WhereTerm *pNewTerm; @@ -1120,6 +1135,7 @@ static void exprAnalyze( pNewTerm->leftCursor = pLeft->iTable; pNewTerm->u.leftColumn = pLeft->iColumn; pNewTerm->eOperator = WO_MATCH; + pNewTerm->eMatchOp = eOp2; markTermAsChild(pWC, idxNew, idxTerm); pTerm = &pWC->a[idxTerm]; pTerm->wtFlags |= TERM_COPIED; diff --git a/test/vtab1.test b/test/vtab1.test index 84de4cffa5..d5fae941af 100644 --- a/test/vtab1.test +++ b/test/vtab1.test @@ -1306,10 +1306,10 @@ foreach {tn sql res filter} { {xFilter {SELECT rowid, * FROM 't6' WHERE b >= ? AND b < ?} J K} 1.3 "SELECT a FROM e6 WHERE b LIKE 'J%'" {3 4} - {xFilter {SELECT rowid, * FROM 't6'}} + {xFilter {SELECT rowid, * FROM 't6' WHERE b like ?} J%} 1.4 "SELECT a FROM e6 WHERE b LIKE 'j%'" {3 4} - {xFilter {SELECT rowid, * FROM 't6'}} + {xFilter {SELECT rowid, * FROM 't6' WHERE b like ?} j%} } { set echo_module {} do_execsql_test 18.$tn.1 $sql $res @@ -1319,10 +1319,10 @@ foreach {tn sql res filter} { do_execsql_test 18.2.0 { PRAGMA case_sensitive_like = ON } foreach {tn sql res filter} { 2.1 "SELECT a FROM e6 WHERE b LIKE 'J%'" {3 4} - {xFilter {SELECT rowid, * FROM 't6'}} + {xFilter {SELECT rowid, * FROM 't6' WHERE b like ?} J%} 2.2 "SELECT a FROM e6 WHERE b LIKE 'j%'" {} - {xFilter {SELECT rowid, * FROM 't6'}} + {xFilter {SELECT rowid, * FROM 't6' WHERE b like ?} j%} } { set echo_module {} do_execsql_test 18.$tn.1 $sql $res diff --git a/test/vtabH.test b/test/vtabH.test new file mode 100644 index 0000000000..b0577eccab --- /dev/null +++ b/test/vtabH.test @@ -0,0 +1,49 @@ +# 2015 Nov 24 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix vtabH + +ifcapable !vtab { + finish_test + return +} + +register_echo_module db + +do_execsql_test 1.0 { + CREATE TABLE t6(a, b TEXT); + CREATE INDEX i6 ON t6(b, a); + CREATE VIRTUAL TABLE e6 USING echo(t6); +} + +foreach {tn sql expect} { + 1 "SELECT * FROM e6 WHERE b LIKE 'abc'" { + xBestIndex {SELECT rowid, * FROM 't6' WHERE b like ?} + xFilter {SELECT rowid, * FROM 't6' WHERE b like ?} abc + } + + 2 "SELECT * FROM e6 WHERE b GLOB 'abc'" { + xBestIndex {SELECT rowid, * FROM 't6' WHERE b glob ?} + xFilter {SELECT rowid, * FROM 't6' WHERE b glob ?} abc + } +} { + do_test 1.$tn { + set echo_module {} + execsql $sql + set ::echo_module + } [list {*}$expect] +} + +finish_test From 3d4143a38a374e092ff6e41b99549f05b5d6dcf0 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 24 Nov 2015 00:49:44 +0000 Subject: [PATCH 08/53] Do not try to eliminate No-ops at the end of VDBE program as this can cause problems for some DISTINCT handling algorithms, and does not improve performance. This also fixes an assertion fault found by libFuzzer. FossilOrigin-Name: 19d9f9ce691963310fa73ac5ff728ea8dea9d2b2 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbeaux.c | 1 - 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 1ed1813193..164471ab97 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sobscure\smemory\sleak\sfound\sby\slibfuzzer\sthat\smay\soccur\sunder\ssome\scircumstances\sif\sexpanding\sa\s"*"\sexpression\scauses\sa\sSELECT\sto\sreturn\smore\sthan\s32767\scolumns. -D 2015-11-21T19:43:29.760 +C Do\snot\stry\sto\seliminate\sNo-ops\sat\sthe\send\sof\sVDBE\sprogram\sas\sthis\scan\scause\nproblems\sfor\ssome\sDISTINCT\shandling\salgorithms,\sand\sdoes\snot\simprove\nperformance.\s\sThis\salso\sfixes\san\sassertion\sfault\sfound\sby\slibFuzzer. +D 2015-11-24T00:49:44.712 F Makefile.in d828db6afa6c1fa060d01e33e4674408df1942a1 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e928e68168df69b353300ac87c10105206653a03 @@ -406,7 +406,7 @@ F src/vdbe.c b56b2fc9b2f2d0a99d1dbd02d47efaacec253a4c F src/vdbe.h efb7a8c1459e31f3ea4377824c6a7e4cb5068637 F src/vdbeInt.h 75c2e82ee3357e9210c06474f8d9bdf12c81105d F src/vdbeapi.c 020681b943e77766b32ae1cddf86d7831b7374ca -F src/vdbeaux.c b660c995256e3d3e2cb47ccd20b82a1c342fa093 +F src/vdbeaux.c 9a234c9aaab4ad725daf94667cfed441a437c52d F src/vdbeblob.c fdc4a81605ae7a35ae94a55bd768b66d6be16f15 F src/vdbemem.c fdd1578e47bea61390d472de53c565781d81e045 F src/vdbesort.c a7ec02da4494c59dfd071126dd3726be5a11459d @@ -1404,7 +1404,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 198d191b2f5ef7d63ac0093c701955c9052fd734 -R 8ed8d9e954ea81e19ae35a6836359b00 -U dan -Z f96d100152be981f85597b50bc9a8134 +P 60de5f23424552c98aa760ac89149a3d51f895be +R 22b08ad19af1727f96b09a8caa1d2b95 +U drh +Z 5e461470e8ebbd6a466d30753f42166b diff --git a/manifest.uuid b/manifest.uuid index 90fb983695..d9bf317509 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -60de5f23424552c98aa760ac89149a3d51f895be \ No newline at end of file +19d9f9ce691963310fa73ac5ff728ea8dea9d2b2 \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 9ced9480b7..1889aec79f 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -837,7 +837,6 @@ void sqlite3VdbeChangeToNoop(Vdbe *p, int addr){ freeP4(db, pOp->p4type, pOp->p4.p); memset(pOp, 0, sizeof(pOp[0])); pOp->opcode = OP_Noop; - if( addr==p->nOp-1 ) p->nOp--; } } From a9124d359b4fe798a0d1ed3531427c4012b1ff2e Mon Sep 17 00:00:00 2001 From: mistachkin Date: Tue, 24 Nov 2015 01:17:01 +0000 Subject: [PATCH 09/53] Add a clarifying comment to the virtual table test module 'test8'. FossilOrigin-Name: e92f97a6794440eb9d64e21218d39cb0e297a98e --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/test8.c | 7 +++++++ 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 164471ab97..7f76cef1ff 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\stry\sto\seliminate\sNo-ops\sat\sthe\send\sof\sVDBE\sprogram\sas\sthis\scan\scause\nproblems\sfor\ssome\sDISTINCT\shandling\salgorithms,\sand\sdoes\snot\simprove\nperformance.\s\sThis\salso\sfixes\san\sassertion\sfault\sfound\sby\slibFuzzer. -D 2015-11-24T00:49:44.712 +C Add\sa\sclarifying\scomment\sto\sthe\svirtual\stable\stest\smodule\s'test8'. +D 2015-11-24T01:17:01.246 F Makefile.in d828db6afa6c1fa060d01e33e4674408df1942a1 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e928e68168df69b353300ac87c10105206653a03 @@ -356,7 +356,7 @@ F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e F src/test5.c 5a34feec76d9b3a86aab30fd4f6cc9c48cbab4c1 F src/test6.c 41cacf3b0dd180823919bf9e1fbab287c9266723 F src/test7.c 9c89a4f1ed6bb13af0ed805b8d782bd83fcd57e3 -F src/test8.c 610e3d523018ca63b08081795e76794a2121ec38 +F src/test8.c 697c9c84a13e08c72ea95a3637d4374caf54fc93 F src/test9.c bea1e8cf52aa93695487badedd6e1886c321ea60 F src/test_async.c 21e11293a2f72080eda70e1124e9102044531cd8 F src/test_autoext.c dea8a01a7153b9adc97bd26161e4226329546e12 @@ -1404,7 +1404,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 60de5f23424552c98aa760ac89149a3d51f895be -R 22b08ad19af1727f96b09a8caa1d2b95 -U drh -Z 5e461470e8ebbd6a466d30753f42166b +P 19d9f9ce691963310fa73ac5ff728ea8dea9d2b2 +R 5f2e3f4f59d38b9500a642209d9901f8 +U mistachkin +Z 92cc12dd9fcb76285889b066a4a2f02e diff --git a/manifest.uuid b/manifest.uuid index d9bf317509..e7ce74a97f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -19d9f9ce691963310fa73ac5ff728ea8dea9d2b2 \ No newline at end of file +e92f97a6794440eb9d64e21218d39cb0e297a98e \ No newline at end of file diff --git a/src/test8.c b/src/test8.c index 2107710a99..7d3756aece 100644 --- a/src/test8.c +++ b/src/test8.c @@ -848,6 +848,13 @@ static int echoBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ case SQLITE_INDEX_CONSTRAINT_GE: zOp = ">="; break; case SQLITE_INDEX_CONSTRAINT_MATCH: + /* Purposely translate the MATCH operator into a LIKE, which + ** will be used by the next block of code to construct a new + ** query. It should also be noted here that the next block + ** of code requires the first letter of this operator to be + ** in upper-case to trigger the special MATCH handling (i.e. + ** wrapping the bound parameter with literal '%'s). + */ zOp = "LIKE"; break; } if( zOp[0]=='L' ){ From 2edc5fd73a9d98d7dabe896c01fa4b0438af25de Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 24 Nov 2015 02:10:52 +0000 Subject: [PATCH 10/53] Remove an incorrect ALWAYS() macro. Fix for ticket [e5c6268dd807fa8950] - a problem introduced in SQLite 3.9.0 and found by libFuzzer. FossilOrigin-Name: 824ad96f72cb0c948ec98aca9d17a7e6790c575f --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/expr.c | 2 +- test/distinct.test | 17 +++++++++++++++++ 4 files changed, 27 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 7f76cef1ff..8f1d010fc6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\sclarifying\scomment\sto\sthe\svirtual\stable\stest\smodule\s'test8'. -D 2015-11-24T01:17:01.246 +C Remove\san\sincorrect\sALWAYS()\smacro.\s\sFix\sfor\sticket\s[e5c6268dd807fa8950]\s-\s\na\sproblem\sintroduced\sin\sSQLite\s3.9.0\sand\sfound\sby\slibFuzzer. +D 2015-11-24T02:10:52.306 F Makefile.in d828db6afa6c1fa060d01e33e4674408df1942a1 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e928e68168df69b353300ac87c10105206653a03 @@ -292,7 +292,7 @@ F src/ctime.c 509ef9c64d1321f42448f111da86400b1799218a F src/date.c fb1c99172017dcc8e237339132c91a21a0788584 F src/dbstat.c ffd63fc8ba7541476ced189b95e95d7f2bc63f78 F src/delete.c 00af9f08a15ddc5cba5962d3d3e5bf2d67b2e7da -F src/expr.c dfccb439a2a981d71970ce3d15effeb59b258798 +F src/expr.c cb1a419508e5b27769a91e00e36e94724e7b1d51 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 31900763094a3736a5fc887469202eb579fef2d0 F src/func.c ecdd69ec6a1e406f04cc73324be2ebbf6354197f @@ -579,7 +579,7 @@ F test/descidx1.test 6d03b44c8538fe0eb4924e19fba10cdd8f3c9240 F test/descidx2.test 9f1a0c83fd57f8667c82310ca21b30a350888b5d F test/descidx3.test 09ddbe3f5295f482d2f8b687cf6db8bad7acd9a2 F test/diskfull.test 106391384780753ea6896b7b4f005d10e9866b6e -F test/distinct.test 175d49ee783febaf368192dfe7f5afbc68910230 +F test/distinct.test a1783b960ad8c15a77cd9f207be072898db1026c F test/distinctagg.test 1a6ef9c87a58669438fc771450d7a72577417376 F test/e_blobbytes.test 9bea1d3e2b20f3010b04abba58f6ba172301f49f F test/e_blobclose.test df756753f571bc30e42e3a6cba2807576e49e716 @@ -1404,7 +1404,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 19d9f9ce691963310fa73ac5ff728ea8dea9d2b2 -R 5f2e3f4f59d38b9500a642209d9901f8 -U mistachkin -Z 92cc12dd9fcb76285889b066a4a2f02e +P e92f97a6794440eb9d64e21218d39cb0e297a98e +R 67e74267bda19ceddf30801e5b6dab85 +U drh +Z 988f4fae8dad66d5bbc6c477f18a57af diff --git a/manifest.uuid b/manifest.uuid index e7ce74a97f..3fce085be0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e92f97a6794440eb9d64e21218d39cb0e297a98e \ No newline at end of file +824ad96f72cb0c948ec98aca9d17a7e6790c575f \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 0255d6902f..8cf018f9d4 100644 --- a/src/expr.c +++ b/src/expr.c @@ -3818,7 +3818,7 @@ int sqlite3ExprCompare(Expr *pA, Expr *pB, int iTab){ } return 2; } - if( pA->op!=TK_COLUMN && ALWAYS(pA->op!=TK_AGG_COLUMN) && pA->u.zToken ){ + if( pA->op!=TK_COLUMN && pA->op!=TK_AGG_COLUMN && pA->u.zToken ){ if( pA->op==TK_FUNCTION ){ if( sqlite3StrICmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2; }else if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){ diff --git a/test/distinct.test b/test/distinct.test index 2fb90dc3e3..dac2269b0b 100644 --- a/test/distinct.test +++ b/test/distinct.test @@ -252,4 +252,21 @@ do_execsql_test 5.6 { SELECT DISTINCT x FROM t1 ORDER BY x; } {1 2 3 4 5 6} +#------------------------------------------------------------------------- +# 2015-11-23. Problem discovered by Kostya Serebryany using libFuzzer +# +db close +sqlite3 db :memory: +do_execsql_test 6.1 { + CREATE TABLE jjj(x); + SELECT (SELECT 'mmm' UNION SELECT DISTINCT max(name) ORDER BY 1) + FROM sqlite_master; +} {jjj} +do_execsql_test 6.2 { + CREATE TABLE nnn(x); + SELECT (SELECT 'mmm' UNION SELECT DISTINCT max(name) ORDER BY 1) + FROM sqlite_master; +} {mmm} + + finish_test From 7060ef9294f2ec3e6eed0fac0e30952c46027f2c Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 24 Nov 2015 03:50:16 +0000 Subject: [PATCH 11/53] Add a test case for the fix of check-in [19d9f9ce691963310] FossilOrigin-Name: 19a9c07b26a4123dc60abdcc84a956f88c352bab --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/hexlit.test | 3 +++ 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 8f1d010fc6..d75d52e9d5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sincorrect\sALWAYS()\smacro.\s\sFix\sfor\sticket\s[e5c6268dd807fa8950]\s-\s\na\sproblem\sintroduced\sin\sSQLite\s3.9.0\sand\sfound\sby\slibFuzzer. -D 2015-11-24T02:10:52.306 +C Add\sa\stest\scase\sfor\sthe\sfix\sof\scheck-in\s[19d9f9ce691963310] +D 2015-11-24T03:50:16.891 F Makefile.in d828db6afa6c1fa060d01e33e4674408df1942a1 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e928e68168df69b353300ac87c10105206653a03 @@ -761,7 +761,7 @@ F test/fuzzdata4.db 1882f0055fb63214d8407ddc7aca9b0b1c59af21 F test/fuzzer1.test d4c52aaf3ef923da293a2653cfab33d02f718a36 F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536 F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98 -F test/hexlit.test 1d312fa816dfd3650a3bb488093bc09a0c927f67 +F test/hexlit.test d7b0a5f41123df1e43985b91b8b2e70f95282d21 F test/hidden.test 23c1393a79e846d68fd902d72c85d5e5dcf98711 F test/hook.test 162d7cef7a2d2b04839fe14402934e6a1b79442f F test/icu.test 70df4faca133254c042d02ae342c0a141f2663f4 @@ -1404,7 +1404,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P e92f97a6794440eb9d64e21218d39cb0e297a98e -R 67e74267bda19ceddf30801e5b6dab85 +P 824ad96f72cb0c948ec98aca9d17a7e6790c575f +R 9c18c36b835edbc9e97b6e63032cda67 U drh -Z 988f4fae8dad66d5bbc6c477f18a57af +Z babd8e22395e7e3423172e307e2f6983 diff --git a/manifest.uuid b/manifest.uuid index 3fce085be0..4c32ac931c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -824ad96f72cb0c948ec98aca9d17a7e6790c575f \ No newline at end of file +19a9c07b26a4123dc60abdcc84a956f88c352bab \ No newline at end of file diff --git a/test/hexlit.test b/test/hexlit.test index 2edd458e89..c48930b49b 100644 --- a/test/hexlit.test +++ b/test/hexlit.test @@ -109,6 +109,9 @@ do_execsql_test hexlit-301 { do_catchsql_test hexlist-400 { SELECT 0x10000000000000000; } {1 {hex literal too big: 0x10000000000000000}} +do_catchsql_test hexlist-401 { + SELECT DISTINCT 0x10000000000000000; +} {1 {hex literal too big: 0x10000000000000000}} do_catchsql_test hexlist-410 { DROP TABLE IF EXISTS t1; CREATE TABLE t1(x); From 6226ca2a6d33b2499fed9320d0d6319599bd8bc8 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 24 Nov 2015 15:06:28 +0000 Subject: [PATCH 12/53] Make the geteuid() system call overloadable using xSetSystemCall() on the unix VFSes. FossilOrigin-Name: 6c2ddea65e1871b2fcb4991c5b3e6992993db3ea --- manifest | 14 ++++++------- manifest.uuid | 2 +- src/os_unix.c | 51 ++++++++++++++++++++++++++--------------------- test/syscall.test | 2 +- 4 files changed, 37 insertions(+), 32 deletions(-) diff --git a/manifest b/manifest index d75d52e9d5..2d0b9a58f6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\stest\scase\sfor\sthe\sfix\sof\scheck-in\s[19d9f9ce691963310] -D 2015-11-24T03:50:16.891 +C Make\sthe\sgeteuid()\ssystem\scall\soverloadable\susing\sxSetSystemCall()\son\sthe\nunix\sVFSes. +D 2015-11-24T15:06:28.338 F Makefile.in d828db6afa6c1fa060d01e33e4674408df1942a1 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e928e68168df69b353300ac87c10105206653a03 @@ -323,7 +323,7 @@ F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8 F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf F src/os_common.h abdb9a191a367793268fe553d25bab894e986a0e F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa -F src/os_unix.c bddde71dc024574ace03ffee859abb99d152fd4a +F src/os_unix.c c5e7976c47cfd3134513ebfb2d140825d50e5275 F src/os_win.c 386fba30419e8458b13209781c2af5590eab2811 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c 18341e2b759b447cbc82fb9215d08d9c5864e92e @@ -1051,7 +1051,7 @@ F test/subtype1.test 7fe09496352f97053af1437150751be2d0a0cae8 F test/superlock.test 1cde669f68d2dd37d6c9bd35eee1d95491ae3fc2 F test/symlink.test 2513f7c030df0f435c6415687ba8b739f3d312df F test/sync.test a34cd43e98b7fb84eabbf38f7ed8f7349b3f3d85 -F test/syscall.test fba9ebdc6905d05bba6a835e691f20ed9ea2cc88 +F test/syscall.test 2aa9e111b79fb385681ff8940124def6f8faab87 F test/sysfault.test fa776e60bf46bdd3ae69f0b73e46ee3977a58ae6 F test/tabfunc01.test cc33684f9480fcf1fd5ce287ac28d22971cad1cc F test/table.test b708f3e5fa2542fa51dfab21fc07b36ea445cb2f @@ -1404,7 +1404,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 824ad96f72cb0c948ec98aca9d17a7e6790c575f -R 9c18c36b835edbc9e97b6e63032cda67 +P 19a9c07b26a4123dc60abdcc84a956f88c352bab +R 02104466c6b651805702e9bf38bb181e U drh -Z babd8e22395e7e3423172e307e2f6983 +Z eddf0171a3f4a4814f215292a42ba620 diff --git a/manifest.uuid b/manifest.uuid index 4c32ac931c..ef64e4e41c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -19a9c07b26a4123dc60abdcc84a956f88c352bab \ No newline at end of file +6c2ddea65e1871b2fcb4991c5b3e6992993db3ea \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 4594e2d870..687baa107e 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -324,19 +324,6 @@ static int posixOpen(const char *zFile, int flags, int mode){ return open(zFile, flags, mode); } -/* -** On some systems, calls to fchown() will trigger a message in a security -** log if they come from non-root processes. So avoid calling fchown() if -** we are not running as root. -*/ -static int posixFchown(int fd, uid_t uid, gid_t gid){ -#if OS_VXWORKS - return 0; -#else - return geteuid() ? 0 : fchown(fd,uid,gid); -#endif -} - /* Forward reference */ static int openDirectory(const char*, int*); static int unixGetpagesize(void); @@ -423,7 +410,7 @@ static struct unix_syscall { #define osPwrite64 ((ssize_t(*)(int,const void*,size_t,off_t))\ aSyscall[13].pCurrent) - { "fchmod", (sqlite3_syscall_ptr)fchmod, 0 }, + { "fchmod", (sqlite3_syscall_ptr)fchmod, 0 }, #define osFchmod ((int(*)(int,mode_t))aSyscall[14].pCurrent) #if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE @@ -445,32 +432,50 @@ static struct unix_syscall { { "rmdir", (sqlite3_syscall_ptr)rmdir, 0 }, #define osRmdir ((int(*)(const char*))aSyscall[19].pCurrent) - { "fchown", (sqlite3_syscall_ptr)posixFchown, 0 }, + { "fchown", (sqlite3_syscall_ptr)fchown, 0 }, #define osFchown ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent) + { "geteuid", (sqlite3_syscall_ptr)geteuid, 0 }, +#define osGeteuid ((uid_t(*)(void))aSyscall[21].pCurrent) + #if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 { "mmap", (sqlite3_syscall_ptr)mmap, 0 }, -#define osMmap ((void*(*)(void*,size_t,int,int,int,off_t))aSyscall[21].pCurrent) +#define osMmap ((void*(*)(void*,size_t,int,int,int,off_t))aSyscall[22].pCurrent) { "munmap", (sqlite3_syscall_ptr)munmap, 0 }, -#define osMunmap ((void*(*)(void*,size_t))aSyscall[22].pCurrent) +#define osMunmap ((void*(*)(void*,size_t))aSyscall[23].pCurrent) #if HAVE_MREMAP { "mremap", (sqlite3_syscall_ptr)mremap, 0 }, #else { "mremap", (sqlite3_syscall_ptr)0, 0 }, #endif -#define osMremap ((void*(*)(void*,size_t,size_t,int,...))aSyscall[23].pCurrent) +#define osMremap ((void*(*)(void*,size_t,size_t,int,...))aSyscall[24].pCurrent) + { "getpagesize", (sqlite3_syscall_ptr)unixGetpagesize, 0 }, -#define osGetpagesize ((int(*)(void))aSyscall[24].pCurrent) +#define osGetpagesize ((int(*)(void))aSyscall[25].pCurrent) { "readlink", (sqlite3_syscall_ptr)readlink, 0 }, -#define osReadlink ((ssize_t(*)(const char*,char*,size_t))aSyscall[25].pCurrent) +#define osReadlink ((ssize_t(*)(const char*,char*,size_t))aSyscall[26].pCurrent) #endif }; /* End of the overrideable system calls */ + +/* +** On some systems, calls to fchown() will trigger a message in a security +** log if they come from non-root processes. So avoid calling fchown() if +** we are not running as root. +*/ +static int robustFchown(int fd, uid_t uid, gid_t gid){ +#if OS_VXWORKS + return 0; +#else + return osGeteuid() ? 0 : osFchown(fd,uid,gid); +#endif +} + /* ** This is the xSetSystemCall() method of sqlite3_vfs for all of the ** "unix" VFSes. Return SQLITE_OK opon successfully updating the @@ -4343,7 +4348,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){ ** is owned by the same user that owns the original database. Otherwise, ** the original owner will not be able to connect. */ - osFchown(pShmNode->h, sStat.st_uid, sStat.st_gid); + robustFchown(pShmNode->h, sStat.st_uid, sStat.st_gid); /* Check to see if another process is holding the dead-man switch. ** If not, truncate the file to zero length. @@ -5827,7 +5832,7 @@ static int unixOpen( ** the same as the original database. */ if( flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){ - osFchown(fd, uid, gid); + robustFchown(fd, uid, gid); } } assert( fd>=0 ); @@ -7584,7 +7589,7 @@ int sqlite3_os_init(void){ /* Double-check that the aSyscall[] array has been constructed ** correctly. See ticket [bb3a86e890c8e96ab] */ - assert( ArraySize(aSyscall)==26 ); + assert( ArraySize(aSyscall)==27 ); /* Register all VFSes defined in the aVfs[] array */ for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){ diff --git a/test/syscall.test b/test/syscall.test index 83b8b8b40f..a935957d39 100644 --- a/test/syscall.test +++ b/test/syscall.test @@ -60,7 +60,7 @@ foreach s { open close access getcwd stat fstat ftruncate fcntl read pread write pwrite fchmod fallocate pread64 pwrite64 unlink openDirectory mkdir rmdir - statvfs fchown umask mmap munmap mremap + statvfs fchown geteuid umask mmap munmap mremap getpagesize readlink } { if {[test_syscall exists $s]} {lappend syscall_list $s} From aaeaa18e2e4ba3f82c4f11929f50fa9837d50e00 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 24 Nov 2015 15:12:47 +0000 Subject: [PATCH 13/53] Fix a comment typo in the unix VFS. No changes to code. FossilOrigin-Name: 32e138796c66c88e8cbb77aa3a4282a38d1f959a --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/os_unix.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 2d0b9a58f6..69d2b5459d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\sthe\sgeteuid()\ssystem\scall\soverloadable\susing\sxSetSystemCall()\son\sthe\nunix\sVFSes. -D 2015-11-24T15:06:28.338 +C Fix\sa\scomment\stypo\sin\sthe\sunix\sVFS.\s\sNo\schanges\sto\scode. +D 2015-11-24T15:12:47.482 F Makefile.in d828db6afa6c1fa060d01e33e4674408df1942a1 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e928e68168df69b353300ac87c10105206653a03 @@ -323,7 +323,7 @@ F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8 F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf F src/os_common.h abdb9a191a367793268fe553d25bab894e986a0e F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa -F src/os_unix.c c5e7976c47cfd3134513ebfb2d140825d50e5275 +F src/os_unix.c 3ca4a23db3ad0b809a0b8d7f879cf66f56b693d5 F src/os_win.c 386fba30419e8458b13209781c2af5590eab2811 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c 18341e2b759b447cbc82fb9215d08d9c5864e92e @@ -1404,7 +1404,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 19a9c07b26a4123dc60abdcc84a956f88c352bab -R 02104466c6b651805702e9bf38bb181e +P 6c2ddea65e1871b2fcb4991c5b3e6992993db3ea +R 81ff6ba247633e5ac5ffc463969dd7f1 U drh -Z eddf0171a3f4a4814f215292a42ba620 +Z 2bab8f8a8131461afe24bb3f0bfc9cb2 diff --git a/manifest.uuid b/manifest.uuid index ef64e4e41c..501322045a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6c2ddea65e1871b2fcb4991c5b3e6992993db3ea \ No newline at end of file +32e138796c66c88e8cbb77aa3a4282a38d1f959a \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 687baa107e..768a2a9eec 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -1104,7 +1104,7 @@ static unixInodeInfo *inodeList = 0; /* ** -** This function - unixLogError_x(), is only ever called via the macro +** This function - unixLogErrorAtLine(), is only ever called via the macro ** unixLogError(). ** ** It is invoked after an error occurs in an OS function and errno has been From 5a8d190b9ecf9e38857bfa77440a4e9c91aa28e3 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 24 Nov 2015 16:40:23 +0000 Subject: [PATCH 14/53] Remove from os_unix.c pointless logic that tries to prevent a recurrence of a warning message that can only occur once. FossilOrigin-Name: 20256177072caa4f2b4114038ad1c8f6e26bc562 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/os_unix.c | 12 +----------- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index 69d2b5459d..36e5b27570 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\scomment\stypo\sin\sthe\sunix\sVFS.\s\sNo\schanges\sto\scode. -D 2015-11-24T15:12:47.482 +C Remove\sfrom\sos_unix.c\spointless\slogic\sthat\stries\sto\sprevent\sa\srecurrence\sof\na\swarning\smessage\sthat\scan\sonly\soccur\sonce. +D 2015-11-24T16:40:23.118 F Makefile.in d828db6afa6c1fa060d01e33e4674408df1942a1 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e928e68168df69b353300ac87c10105206653a03 @@ -323,7 +323,7 @@ F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8 F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf F src/os_common.h abdb9a191a367793268fe553d25bab894e986a0e F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa -F src/os_unix.c 3ca4a23db3ad0b809a0b8d7f879cf66f56b693d5 +F src/os_unix.c 80ec49758dbce979e4f89eda7695bbc01b0c4cd3 F src/os_win.c 386fba30419e8458b13209781c2af5590eab2811 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c 18341e2b759b447cbc82fb9215d08d9c5864e92e @@ -1404,7 +1404,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 6c2ddea65e1871b2fcb4991c5b3e6992993db3ea -R 81ff6ba247633e5ac5ffc463969dd7f1 +P 32e138796c66c88e8cbb77aa3a4282a38d1f959a +R 39dda72890996a1a2961e4723fcfeb24 U drh -Z 2bab8f8a8131461afe24bb3f0bfc9cb2 +Z 6e0fb81bf9792119f74030230681d485 diff --git a/manifest.uuid b/manifest.uuid index 501322045a..9df0621fea 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -32e138796c66c88e8cbb77aa3a4282a38d1f959a \ No newline at end of file +20256177072caa4f2b4114038ad1c8f6e26bc562 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 768a2a9eec..82224053f0 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -258,8 +258,7 @@ static pid_t randomnessPid = 0; #define UNIXFILE_DELETE 0x20 /* Delete on close */ #define UNIXFILE_URI 0x40 /* Filename might have query parameters */ #define UNIXFILE_NOLOCK 0x80 /* Do no file locking */ -#define UNIXFILE_WARNED 0x0100 /* verifyDbFile() warnings issued */ -#define UNIXFILE_BLOCK 0x0200 /* Next SHM lock might block */ +#define UNIXFILE_BLOCK 0x0100 /* Next SHM lock might block */ /* ** Include code that is common to all os_*.c files @@ -1360,30 +1359,21 @@ static int fileHasMoved(unixFile *pFile){ static void verifyDbFile(unixFile *pFile){ struct stat buf; int rc; - if( pFile->ctrlFlags & UNIXFILE_WARNED ){ - /* One or more of the following warnings have already been issued. Do not - ** repeat them so as not to clutter the error log */ - return; - } rc = osFstat(pFile->h, &buf); if( rc!=0 ){ sqlite3_log(SQLITE_WARNING, "cannot fstat db file %s", pFile->zPath); - pFile->ctrlFlags |= UNIXFILE_WARNED; return; } if( buf.st_nlink==0 && (pFile->ctrlFlags & UNIXFILE_DELETE)==0 ){ sqlite3_log(SQLITE_WARNING, "file unlinked while open: %s", pFile->zPath); - pFile->ctrlFlags |= UNIXFILE_WARNED; return; } if( buf.st_nlink>1 ){ sqlite3_log(SQLITE_WARNING, "multiple links to file: %s", pFile->zPath); - pFile->ctrlFlags |= UNIXFILE_WARNED; return; } if( fileHasMoved(pFile) ){ sqlite3_log(SQLITE_WARNING, "file renamed while open: %s", pFile->zPath); - pFile->ctrlFlags |= UNIXFILE_WARNED; return; } } From 43970dd7745c3fdb258ce6bb86971fd5ce87cfdf Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 24 Nov 2015 17:39:01 +0000 Subject: [PATCH 15/53] Add further tests and related fixes for GLOB/REGEXP/LIKE support in virtual tables. FossilOrigin-Name: c5e9fd0dc92a07db3d3b5f5c5ad8fb63b3425c2b --- manifest | 21 +++-- manifest.uuid | 2 +- src/test_tclvar.c | 194 +++++++++++++++++++++++++++++++++++++++------- src/whereexpr.c | 17 ++-- test/vtabE.test | 2 + test/vtabH.test | 63 ++++++++++++++- 6 files changed, 252 insertions(+), 47 deletions(-) diff --git a/manifest b/manifest index 77ed28994e..1a5fc94c5f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sexperimental\ssupport\sfor\sLIKE,\sGLOB\sand\sREGEXP\sto\sthe\svirtual\stable\sinterface. -D 2015-11-23T21:09:54.478 +C Add\sfurther\stests\sand\srelated\sfixes\sfor\sGLOB/REGEXP/LIKE\ssupport\sin\svirtual\stables. +D 2015-11-24T17:39:01.810 F Makefile.in d828db6afa6c1fa060d01e33e4674408df1942a1 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e928e68168df69b353300ac87c10105206653a03 @@ -389,7 +389,7 @@ F src/test_server.c a2615049954cbb9cfb4a62e18e2f0616e4dc38fe F src/test_sqllog.c 0d138a8180a312bf996b37fa66da5c5799d4d57b F src/test_superlock.c 06797157176eb7085027d9dd278c0d7a105e3ec9 F src/test_syscall.c 2e21ca7f7dc54a028f1967b63f1e76155c356f9b -F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa +F src/test_tclvar.c 2fd910e9f0ef7686889f50f448d33810c895da86 F src/test_thread.c af391ec03d23486dffbcc250b7e58e073f172af9 F src/test_vfs.c 3b65d42e18b262805716bd96178c81da8f2d9283 F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698 @@ -419,7 +419,7 @@ F src/walker.c 2e14d17f592d176b6dc879c33fbdec4fbccaa2ba F src/where.c 6687fb2675d9c1c1936ceca77529e2f21fb3a769 F src/whereInt.h 6afc0d70cf6213e58e8fbe10b6e50d1aa16f122f F src/wherecode.c 4c96182e7b25e4be54008dee2da5b9c2f8480b9b -F src/whereexpr.c 12c6fa7576674d24bf0116364a39885925c89188 +F src/whereexpr.c 17d62d8bb7fd357920b46ee86851b5d6629412bf F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1272,9 +1272,9 @@ F test/vtabA.test 1317f06a03597eee29f40a49b6c21e1aaba4285f F test/vtabB.test 04df5dc531b9f44d9ca65b9c1b79f12b5922a796 F test/vtabC.test 4528f459a13136f982e75614d120aef165f17292 F test/vtabD.test 05b3f1d77117271671089e48719524b676842e96 -F test/vtabE.test 7c4693638d7797ce2eda17af74292b97e705cc61 +F test/vtabE.test d5024aa42754962f6bb0afd261681686488e7afe F test/vtabF.test fd5ad376f5a34fe0891df1f3cddb4fe7c3eb077e -F test/vtabH.test 15e137d2af9b0b81fedca6697518eb8834c013f4 +F test/vtabH.test 694aa399eb28ed0db2aef59f2f37532781eeb957 F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5 F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8 F test/vtab_shared.test ea8778d5b0df200adef2ca7c00c3c37d4375f772 @@ -1405,10 +1405,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 60de5f23424552c98aa760ac89149a3d51f895be -R b6557d1407b51115ef511b97d0fc16c1 -T *branch * vtab-like-operator -T *sym-vtab-like-operator * -T -sym-trunk * +P 277a5b4027d4c2caba8143228a4f7d6df899dbb4 +R f59356e8fc475908365127ad504d9518 U dan -Z 249ced27266ff2c4ebd31fcaec9b55b5 +Z 673386578c6b1eaa8b17502c533df301 diff --git a/manifest.uuid b/manifest.uuid index eee0121605..77e0da032b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -277a5b4027d4c2caba8143228a4f7d6df899dbb4 \ No newline at end of file +c5e9fd0dc92a07db3d3b5f5c5ad8fb63b3425c2b \ No newline at end of file diff --git a/src/test_tclvar.c b/src/test_tclvar.c index 1219190c03..975f07fc8d 100644 --- a/src/test_tclvar.c +++ b/src/test_tclvar.c @@ -23,6 +23,15 @@ #ifndef SQLITE_OMIT_VIRTUALTABLE +/* +** Characters that make up the idxStr created by xBestIndex for xFilter. +*/ +#define TCLVAR_NAME_EQ 'e' +#define TCLVAR_NAME_MATCH 'm' +#define TCLVAR_VALUE_GLOB 'g' +#define TCLVAR_VALUE_REGEXP 'r' +#define TCLVAR_VALUE_LIKE 'l' + typedef struct tclvar_vtab tclvar_vtab; typedef struct tclvar_cursor tclvar_cursor; @@ -155,15 +164,44 @@ static int tclvarFilter( ){ tclvar_cursor *pCur = (tclvar_cursor *)pVtabCursor; Tcl_Interp *interp = ((tclvar_vtab *)(pVtabCursor->pVtab))->interp; + Tcl_Obj *p = Tcl_NewStringObj("tclvar_filter_cmd", -1); - Tcl_Obj *p = Tcl_NewStringObj("info vars", -1); - Tcl_IncrRefCount(p); + const char *zEq = ""; + const char *zMatch = ""; + const char *zGlob = ""; + const char *zRegexp = ""; + const char *zLike = ""; + int i; - assert( argc==0 || argc==1 ); - if( argc==1 ){ - Tcl_Obj *pArg = Tcl_NewStringObj((char*)sqlite3_value_text(argv[0]), -1); - Tcl_ListObjAppendElement(0, p, pArg); + for(i=0; idxStr[i]; i++){ + switch( idxStr[i] ){ + case TCLVAR_NAME_EQ: + zEq = sqlite3_value_text(argv[i]); + break; + case TCLVAR_NAME_MATCH: + zMatch = sqlite3_value_text(argv[i]); + break; + case TCLVAR_VALUE_GLOB: + zGlob = sqlite3_value_text(argv[i]); + break; + case TCLVAR_VALUE_REGEXP: + zRegexp = sqlite3_value_text(argv[i]); + break; + case TCLVAR_VALUE_LIKE: + zLike = sqlite3_value_text(argv[i]); + break; + default: + assert( 0 ); + } } + + Tcl_IncrRefCount(p); + Tcl_ListObjAppendElement(0, p, Tcl_NewStringObj(zEq, -1)); + Tcl_ListObjAppendElement(0, p, Tcl_NewStringObj(zMatch, -1)); + Tcl_ListObjAppendElement(0, p, Tcl_NewStringObj(zGlob, -1)); + Tcl_ListObjAppendElement(0, p, Tcl_NewStringObj(zRegexp, -1)); + Tcl_ListObjAppendElement(0, p, Tcl_NewStringObj(zLike, -1)); + Tcl_EvalObjEx(interp, p, TCL_EVAL_GLOBAL); if( pCur->pList1 ){ Tcl_DecrRefCount(pCur->pList1); @@ -176,7 +214,6 @@ static int tclvarFilter( pCur->i2 = 0; pCur->pList1 = Tcl_GetObjResult(interp); Tcl_IncrRefCount(pCur->pList1); - assert( pCur->i1==0 && pCur->i2==0 && pCur->pList2==0 ); Tcl_DecrRefCount(p); return tclvarNext(pVtabCursor); @@ -224,32 +261,113 @@ static int tclvarEof(sqlite3_vtab_cursor *cur){ return (pCur->pList2?0:1); } +/* +** If nul-terminated string zStr does not already contain the character +** passed as the second argument, append it and return 0. Or, if there is +** already an instance of x in zStr, do nothing return 1; +** +** There is guaranteed to be enough room in the buffer pointed to by zStr +** for the new character and nul-terminator. +*/ +static int tclvarAddToIdxstr(char *zStr, char x){ + int i; + for(i=0; zStr[i]; i++){ + if( zStr[i]==x ) return 1; + } + zStr[i] = x; + zStr[i+1] = '\0'; + return 0; +} + +/* +** Return true if variable $::tclvar_set_omit exists and is set to true. +** False otherwise. +*/ +static int tclvarSetOmit(Tcl_Interp *interp){ + int rc; + int res = 0; + Tcl_Obj *pRes; + rc = Tcl_Eval(interp, + "expr {[info exists ::tclvar_set_omit] && $::tclvar_set_omit}" + ); + if( rc==TCL_OK ){ + pRes = Tcl_GetObjResult(interp); + rc = Tcl_GetBooleanFromObj(0, pRes, &res); + } + return (rc==TCL_OK && res); +} + +/* +** The xBestIndex() method. This virtual table supports the following +** operators: +** +** name = ? (omit flag clear) +** name MATCH ? (omit flag set) +** value GLOB ? (omit flag set iff $::tclvar_set_omit) +** value REGEXP ? (omit flag set iff $::tclvar_set_omit) +** value LIKE ? (omit flag set iff $::tclvar_set_omit) +** +** For each constraint present, the corresponding TCLVAR_XXX character is +** appended to the idxStr value. +*/ static int tclvarBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ + tclvar_vtab *pTab = (tclvar_vtab*)tab; int ii; + char *zStr = sqlite3_malloc(32); + int iStr = 0; + + if( zStr==0 ) return SQLITE_NOMEM; + zStr[0] = '\0'; for(ii=0; iinConstraint; ii++){ struct sqlite3_index_constraint const *pCons = &pIdxInfo->aConstraint[ii]; - if( pCons->iColumn==0 && pCons->usable - && pCons->op==SQLITE_INDEX_CONSTRAINT_EQ ){ - struct sqlite3_index_constraint_usage *pUsage; - pUsage = &pIdxInfo->aConstraintUsage[ii]; - pUsage->omit = 0; - pUsage->argvIndex = 1; - return SQLITE_OK; - } - } + struct sqlite3_index_constraint_usage *pUsage; + + pUsage = &pIdxInfo->aConstraintUsage[ii]; + if( pCons->usable ){ + /* name = ? */ + if( pCons->op==SQLITE_INDEX_CONSTRAINT_EQ && pCons->iColumn==0 ){ + if( 0==tclvarAddToIdxstr(zStr, TCLVAR_NAME_EQ) ){ + pUsage->argvIndex = ++iStr; + pUsage->omit = 0; + } + } - for(ii=0; iinConstraint; ii++){ - struct sqlite3_index_constraint const *pCons = &pIdxInfo->aConstraint[ii]; - if( pCons->iColumn==0 && pCons->usable - && pCons->op==SQLITE_INDEX_CONSTRAINT_MATCH ){ - struct sqlite3_index_constraint_usage *pUsage; - pUsage = &pIdxInfo->aConstraintUsage[ii]; - pUsage->omit = 1; - pUsage->argvIndex = 1; - return SQLITE_OK; + /* name MATCH ? */ + if( pCons->op==SQLITE_INDEX_CONSTRAINT_MATCH && pCons->iColumn==0 ){ + if( 0==tclvarAddToIdxstr(zStr, TCLVAR_NAME_MATCH) ){ + pUsage->argvIndex = ++iStr; + pUsage->omit = 1; + } + } + + /* value GLOB ? */ + if( pCons->op==SQLITE_INDEX_CONSTRAINT_GLOB && pCons->iColumn==2 ){ + if( 0==tclvarAddToIdxstr(zStr, TCLVAR_VALUE_GLOB) ){ + pUsage->argvIndex = ++iStr; + pUsage->omit = tclvarSetOmit(pTab->interp); + } + } + + /* value REGEXP ? */ + if( pCons->op==SQLITE_INDEX_CONSTRAINT_REGEXP && pCons->iColumn==2 ){ + if( 0==tclvarAddToIdxstr(zStr, TCLVAR_VALUE_REGEXP) ){ + pUsage->argvIndex = ++iStr; + pUsage->omit = tclvarSetOmit(pTab->interp); + } + } + + /* value LIKE ? */ + if( pCons->op==SQLITE_INDEX_CONSTRAINT_LIKE && pCons->iColumn==2 ){ + if( 0==tclvarAddToIdxstr(zStr, TCLVAR_VALUE_LIKE) ){ + pUsage->argvIndex = ++iStr; + pUsage->omit = tclvarSetOmit(pTab->interp); + } + } } } + pIdxInfo->idxStr = zStr; + pIdxInfo->needToFreeIdxStr = 1; return SQLITE_OK; } @@ -295,6 +413,7 @@ static int register_tclvar_module( int objc, /* Number of arguments */ Tcl_Obj *CONST objv[] /* Command arguments */ ){ + int rc = TCL_OK; sqlite3 *db; if( objc!=2 ){ Tcl_WrongNumArgs(interp, 1, objv, "DB"); @@ -302,9 +421,30 @@ static int register_tclvar_module( } if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; #ifndef SQLITE_OMIT_VIRTUALTABLE - sqlite3_create_module(db, "tclvar", &tclvarModule, (void *)interp); + sqlite3_create_module(db, "tclvar", &tclvarModule, (void*)interp); + rc = Tcl_Eval(interp, + "proc like {pattern str} {\n" + " set p [string map {% * _ ?} $pattern]\n" + " string match $p $str\n" + "}\n" + "proc tclvar_filter_cmd {eq match glob regexp like} {\n" + " set res {}\n" + " set pattern $eq\n" + " if {$pattern=={}} { set pattern $match }\n" + " if {$pattern=={}} { set pattern * }\n" + " foreach v [uplevel #0 info vars $pattern] {\n" + " if {($glob=={} || [string match $glob [uplevel #0 set $v]])\n" + " && ($like=={} || [like $like [uplevel #0 set $v]])\n" + " && ($regexp=={} || [regexp $regexp [uplevel #0 set $v]])\n" + " } {\n" + " lappend res $v\n" + " }\n" + " }\n" + " set res\n" + "}\n" + ); #endif - return TCL_OK; + return rc; } #endif diff --git a/src/whereexpr.c b/src/whereexpr.c index 0cc2fd7209..8ef91b03eb 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -277,7 +277,10 @@ static int isLikeOrGlob( /* ** Check to see if the given expression is of the form ** -** column MATCH expr +** column OP expr +** +** where OP is one of MATCH, GLOB, LIKE or REGEXP and "column" is a +** column of a virtual table. ** ** If it is then return TRUE. If not, return FALSE. */ @@ -289,12 +292,13 @@ static int isMatchOfColumn( const char *zOp; unsigned char eOp2; } aOp[] = { - { "match", SQLITE_INDEX_CONSTRAINT_MATCH }, - { "glob", SQLITE_INDEX_CONSTRAINT_GLOB }, - { "like", SQLITE_INDEX_CONSTRAINT_LIKE }, - { "regex", SQLITE_INDEX_CONSTRAINT_REGEXP } + { "match", SQLITE_INDEX_CONSTRAINT_MATCH }, + { "glob", SQLITE_INDEX_CONSTRAINT_GLOB }, + { "like", SQLITE_INDEX_CONSTRAINT_LIKE }, + { "regexp", SQLITE_INDEX_CONSTRAINT_REGEXP } }; ExprList *pList; + Expr *pCol; /* Column reference */ int i; if( pExpr->op!=TK_FUNCTION ){ @@ -304,7 +308,8 @@ static int isMatchOfColumn( if( pList->nExpr!=2 ){ return 0; } - if( pList->a[1].pExpr->op != TK_COLUMN ){ + pCol = pList->a[1].pExpr; + if( pCol->op!=TK_COLUMN || !IsVirtual(pCol->pTab) ){ return 0; } for(i=0; i Date: Tue, 24 Nov 2015 18:04:39 +0000 Subject: [PATCH 16/53] Fix harmless compiler warnings in the TCL test harness logic. FossilOrigin-Name: 2fba7a96566b5448f527a4ec6a26e860c4889813 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/test_tclvar.c | 10 +++++----- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 19ec7c82ff..bf1a2b9a42 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\slatest\strunk\schanges\swith\sthis\sbranch. -D 2015-11-24T17:44:26.959 +C Fix\sharmless\scompiler\swarnings\sin\sthe\sTCL\stest\sharness\slogic. +D 2015-11-24T18:04:39.335 F Makefile.in d828db6afa6c1fa060d01e33e4674408df1942a1 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e928e68168df69b353300ac87c10105206653a03 @@ -389,7 +389,7 @@ F src/test_server.c a2615049954cbb9cfb4a62e18e2f0616e4dc38fe F src/test_sqllog.c 0d138a8180a312bf996b37fa66da5c5799d4d57b F src/test_superlock.c 06797157176eb7085027d9dd278c0d7a105e3ec9 F src/test_syscall.c 2e21ca7f7dc54a028f1967b63f1e76155c356f9b -F src/test_tclvar.c 2fd910e9f0ef7686889f50f448d33810c895da86 +F src/test_tclvar.c d86412527da65468ee6fa1b8607c65d0af736bc4 F src/test_thread.c af391ec03d23486dffbcc250b7e58e073f172af9 F src/test_vfs.c 3b65d42e18b262805716bd96178c81da8f2d9283 F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698 @@ -1405,7 +1405,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P c5e9fd0dc92a07db3d3b5f5c5ad8fb63b3425c2b 20256177072caa4f2b4114038ad1c8f6e26bc562 -R f66db3dfd01f74a8efe805dce920d093 -U dan -Z 1605220e9da94a8d162b093db7a72a24 +P 99222bb3e5f9b2a9a10d9561a9fd8c0f717baaff +R a81a9eaa4d026b7ec9f13ce6cc6dd8d0 +U drh +Z 1d3e92ad91e9ae564e61187f77c574d6 diff --git a/manifest.uuid b/manifest.uuid index 8f981f6a08..72fbceb60b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -99222bb3e5f9b2a9a10d9561a9fd8c0f717baaff \ No newline at end of file +2fba7a96566b5448f527a4ec6a26e860c4889813 \ No newline at end of file diff --git a/src/test_tclvar.c b/src/test_tclvar.c index 975f07fc8d..63ed394734 100644 --- a/src/test_tclvar.c +++ b/src/test_tclvar.c @@ -176,19 +176,19 @@ static int tclvarFilter( for(i=0; idxStr[i]; i++){ switch( idxStr[i] ){ case TCLVAR_NAME_EQ: - zEq = sqlite3_value_text(argv[i]); + zEq = (const char*)sqlite3_value_text(argv[i]); break; case TCLVAR_NAME_MATCH: - zMatch = sqlite3_value_text(argv[i]); + zMatch = (const char*)sqlite3_value_text(argv[i]); break; case TCLVAR_VALUE_GLOB: - zGlob = sqlite3_value_text(argv[i]); + zGlob = (const char*)sqlite3_value_text(argv[i]); break; case TCLVAR_VALUE_REGEXP: - zRegexp = sqlite3_value_text(argv[i]); + zRegexp = (const char*)sqlite3_value_text(argv[i]); break; case TCLVAR_VALUE_LIKE: - zLike = sqlite3_value_text(argv[i]); + zLike = (const char*)sqlite3_value_text(argv[i]); break; default: assert( 0 ); From ff7b22b714eb6202412b7b0aa5bc81fdbaad43c0 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 24 Nov 2015 18:16:15 +0000 Subject: [PATCH 17/53] Fix a problem in whereexpr.c causing a crash while processing a user-function taht accepts zero arguments. FossilOrigin-Name: 069e51b19c773aa3017a8d307c8daa0766c224ba --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/whereexpr.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index bf1a2b9a42..95094a3c1e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings\sin\sthe\sTCL\stest\sharness\slogic. -D 2015-11-24T18:04:39.335 +C Fix\sa\sproblem\sin\swhereexpr.c\scausing\sa\scrash\swhile\sprocessing\sa\suser-function\staht\saccepts\szero\sarguments. +D 2015-11-24T18:16:15.798 F Makefile.in d828db6afa6c1fa060d01e33e4674408df1942a1 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e928e68168df69b353300ac87c10105206653a03 @@ -419,7 +419,7 @@ F src/walker.c 2e14d17f592d176b6dc879c33fbdec4fbccaa2ba F src/where.c 6687fb2675d9c1c1936ceca77529e2f21fb3a769 F src/whereInt.h 6afc0d70cf6213e58e8fbe10b6e50d1aa16f122f F src/wherecode.c 4c96182e7b25e4be54008dee2da5b9c2f8480b9b -F src/whereexpr.c 17d62d8bb7fd357920b46ee86851b5d6629412bf +F src/whereexpr.c eebba8340c90de73b3d3bbe8c43b84559b8e6e2c F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1405,7 +1405,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 99222bb3e5f9b2a9a10d9561a9fd8c0f717baaff -R a81a9eaa4d026b7ec9f13ce6cc6dd8d0 -U drh -Z 1d3e92ad91e9ae564e61187f77c574d6 +P 2fba7a96566b5448f527a4ec6a26e860c4889813 +R f36b8e4e640480a045269560fe77bd48 +U dan +Z 2212cd97f0c21ee66344a63115e7e327 diff --git a/manifest.uuid b/manifest.uuid index 72fbceb60b..2adfe4df8a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2fba7a96566b5448f527a4ec6a26e860c4889813 \ No newline at end of file +069e51b19c773aa3017a8d307c8daa0766c224ba \ No newline at end of file diff --git a/src/whereexpr.c b/src/whereexpr.c index 8ef91b03eb..99a97079be 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -305,7 +305,7 @@ static int isMatchOfColumn( return 0; } pList = pExpr->x.pList; - if( pList->nExpr!=2 ){ + if( pList==0 || pList->nExpr!=2 ){ return 0; } pCol = pList->a[1].pExpr; From 8b4a94adc1dea3254a7eed1e33c210509c496e2d Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 24 Nov 2015 21:23:59 +0000 Subject: [PATCH 18/53] Add the sqlite3_strlike() interface, which might be useful for implementing LIKE operators on virtual tables. FossilOrigin-Name: e70ec71d6883f2f8fc75301ff985bccb5aa06127 --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/analyze.c | 2 +- src/func.c | 7 +++++++ src/sqlite.h.in | 27 +++++++++++++++++++++++++++ src/sqlite3ext.h | 4 ++++ 6 files changed, 50 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 95094a3c1e..f37520206d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\sin\swhereexpr.c\scausing\sa\scrash\swhile\sprocessing\sa\suser-function\staht\saccepts\szero\sarguments. -D 2015-11-24T18:16:15.798 +C Add\sthe\ssqlite3_strlike()\sinterface,\swhich\smight\sbe\suseful\sfor\simplementing\nLIKE\soperators\son\svirtual\stables. +D 2015-11-24T21:23:59.705 F Makefile.in d828db6afa6c1fa060d01e33e4674408df1942a1 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e928e68168df69b353300ac87c10105206653a03 @@ -276,7 +276,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c 9d649e46c780166e416fb11dbd23f8d49aab8267 -F src/analyze.c 4c308880cf53c558070cb8513bdff4ffb1a38a77 +F src/analyze.c 977bd50c751bb939ef52917892e12bedbfcea7ce F src/attach.c e944d0052b577703b9b83aac1638452ff42a8395 F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c 2869a76c03eb393ee795416e2387005553df72bc @@ -295,7 +295,7 @@ F src/delete.c 00af9f08a15ddc5cba5962d3d3e5bf2d67b2e7da F src/expr.c cb1a419508e5b27769a91e00e36e94724e7b1d51 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 31900763094a3736a5fc887469202eb579fef2d0 -F src/func.c ecdd69ec6a1e406f04cc73324be2ebbf6354197f +F src/func.c 5790a898a0c53e6787020ec268425d415e7e03c9 F src/global.c 508e4087f7b41d688e4762dcf4d4fe28cfbc87f9 F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5 F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094 @@ -341,9 +341,9 @@ F src/resolve.c f4c897ca76ca6d5e0b3f0499c627392ffe657c8e F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e F src/select.c e10586c750d87211caa8f4b239e2bfa6a2049e5b F src/shell.c f0f59ea60ad297f671b7ae0fb957a736ad17c92c -F src/sqlite.h.in a71226fe80bded2af3b99c5aed7363ef486962e1 +F src/sqlite.h.in cbe8643b6a1c7313bf6447a2aa7abdb31c73dd77 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad -F src/sqlite3ext.h 4b66e3e3435da4b4c8c83696d0349f0c503b3924 +F src/sqlite3ext.h 41ef50b0418a7c5ad1337bb80db5a7928dee764f F src/sqliteInt.h 64256d193a16a147d9f6317cc4e095fdd3e0a2e9 F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba @@ -1405,7 +1405,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 2fba7a96566b5448f527a4ec6a26e860c4889813 -R f36b8e4e640480a045269560fe77bd48 -U dan -Z 2212cd97f0c21ee66344a63115e7e327 +P 069e51b19c773aa3017a8d307c8daa0766c224ba +R d30ed8c32e99c9a94479405580943fff +U drh +Z d8529710de4140b85add41abcb0a95e1 diff --git a/manifest.uuid b/manifest.uuid index 2adfe4df8a..79fcb989cf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -069e51b19c773aa3017a8d307c8daa0766c224ba \ No newline at end of file +e70ec71d6883f2f8fc75301ff985bccb5aa06127 \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index ad752d2c0e..06918eb744 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -990,7 +990,7 @@ static void analyzeOneTable( /* Do not gather statistics on views or virtual tables */ return; } - if( sqlite3_strnicmp(pTab->zName, "sqlite_", 7)==0 ){ + if( sqlite3_strlike("sqlite_%", pTab->zName, 0)==0 ){ /* Do not gather statistics on system tables */ return; } diff --git a/src/func.c b/src/func.c index 8ea1169327..b134c1a7c2 100644 --- a/src/func.c +++ b/src/func.c @@ -763,6 +763,13 @@ int sqlite3_strglob(const char *zGlobPattern, const char *zString){ return patternCompare((u8*)zGlobPattern, (u8*)zString, &globInfo, 0)==0; } +/* +** The sqlite3_strlike() interface. +*/ +int sqlite3_strlike(const char *zPattern, const char *zStr, unsigned int esc){ + return patternCompare((u8*)zPattern, (u8*)zStr, &likeInfoNorm, esc)==0; +} + /* ** Count the number of times that the LIKE operator (or GLOB which is ** just a variation of LIKE) gets called. This is used for testing diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 42652061fb..b93ff5873e 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -7377,9 +7377,36 @@ int sqlite3_strnicmp(const char *, const char *, int); ** ** Note that this routine returns zero on a match and non-zero if the strings ** do not match, the same as [sqlite3_stricmp()] and [sqlite3_strnicmp()]. +** +** See also: sqlite3_strlike(). */ int sqlite3_strglob(const char *zGlob, const char *zStr); +/* +** CAPI3REF: String LIKE Matching +* +** ^The [sqlite3_strlike(P,X,E)] interface returns zero if string X matches +** the LIKE pattern P with escape character E, and it returns non-zero if +** string X does not match the like pattern. +** ^The definition of LIKE pattern matching used in +** [sqlite3_strlike(P,X,E)] is the same as for the "X LIKE P ESCAPE E" +** operator in the SQL dialect used by SQLite. ^For "X LIKE P" without +** the ESCAPE clause, set the E parameter of [sqlite3_strlike(P,X,E)] to 0. +** ^As with the LIKE operator, the [sqlite3_str(P,X,E)] function is case +** insensitive - equivalent upper and lower case ASCII characters match +** one another. +** +** ^The [sqlite3_strlike(P,X,E)] function matches Unicode characters, though +** only ASCII characters are case folded. (This is because when SQLite was +** first written, the case folding rules for Unicode where still in flux.) +** +** Note that this routine returns zero on a match and non-zero if the strings +** do not match, the same as [sqlite3_stricmp()] and [sqlite3_strnicmp()]. +** +** See also: sqlite3_strglob(). +*/ +int sqlite3_strlike(const char *zGlob, const char *zStr, unsigned int cEsc); + /* ** CAPI3REF: Error Logging Interface ** diff --git a/src/sqlite3ext.h b/src/sqlite3ext.h index 017ea308b1..3029a82fa1 100644 --- a/src/sqlite3ext.h +++ b/src/sqlite3ext.h @@ -275,6 +275,8 @@ struct sqlite3_api_routines { /* Version 3.9.0 and later */ unsigned int (*value_subtype)(sqlite3_value*); void (*result_subtype)(sqlite3_context*,unsigned int); + /* Version 3.10.0 and later */ + int (*strlike)(const char*,const char*,unsigned int); }; /* @@ -514,6 +516,8 @@ struct sqlite3_api_routines { /* Version 3.9.0 and later */ #define sqlite3_value_subtype sqlite3_api->value_subtype #define sqlite3_result_subtype sqlite3_api->result_subtype +/* Version 3.10.0 and later */ +#define sqlite3_strlike sqlite3_api->strlike #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) From f5d8c58950c808bf7e08bc99b374bb63d0887309 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 25 Nov 2015 11:56:24 +0000 Subject: [PATCH 19/53] Fix the fts5 "prefix=" option to match the documentation (space separated list, multiple prefix= options supported). The undocumented comma-separated format (compatible with fts4) still works. FossilOrigin-Name: 11eb8e877e2ba859ef6b44318f286597186dfaf2 --- ext/fts5/fts5_config.c | 47 ++++++++++++++++++++++++----------- ext/fts5/test/fts5config.test | 22 +++++++++++----- ext/fts5/test/fts5prefix.test | 42 +++++++++++++++++++++++++++++++ manifest | 19 +++++++------- manifest.uuid | 2 +- 5 files changed, 101 insertions(+), 31 deletions(-) diff --git a/ext/fts5/fts5_config.c b/ext/fts5/fts5_config.c index 4f6272dbe2..6b0e2b28b6 100644 --- a/ext/fts5/fts5_config.c +++ b/ext/fts5/fts5_config.c @@ -216,34 +216,53 @@ static int fts5ConfigParseSpecial( if( sqlite3_strnicmp("prefix", zCmd, nCmd)==0 ){ const int nByte = sizeof(int) * FTS5_MAX_PREFIX_INDEXES; const char *p; - if( pConfig->aPrefix ){ - *pzErr = sqlite3_mprintf("multiple prefix=... directives"); - rc = SQLITE_ERROR; - }else{ + int bFirst = 1; + if( pConfig->aPrefix==0 ){ pConfig->aPrefix = sqlite3Fts5MallocZero(&rc, nByte); + if( rc ) return rc; } + p = zArg; - while( rc==SQLITE_OK && p[0] ){ + while( 1 ){ int nPre = 0; + while( p[0]==' ' ) p++; + if( bFirst==0 && p[0]==',' ){ + p++; + while( p[0]==' ' ) p++; + }else if( p[0]=='\0' ){ + break; + } + if( p[0]<'0' || p[0]>'9' ){ + *pzErr = sqlite3_mprintf("malformed prefix=... directive"); + rc = SQLITE_ERROR; + break; + } + + if( pConfig->nPrefix==FTS5_MAX_PREFIX_INDEXES ){ + *pzErr = sqlite3_mprintf( + "too many prefix indexes (max %d)", FTS5_MAX_PREFIX_INDEXES + ); + rc = SQLITE_ERROR; + break; + } + while( p[0]>='0' && p[0]<='9' && nPre<1000 ){ nPre = nPre*10 + (p[0] - '0'); p++; } - while( p[0]==' ' ) p++; - if( p[0]==',' ){ - p++; - }else if( p[0] ){ - *pzErr = sqlite3_mprintf("malformed prefix=... directive"); - rc = SQLITE_ERROR; - } - if( rc==SQLITE_OK && (nPre==0 || nPre>=1000) ){ - *pzErr = sqlite3_mprintf("prefix length out of range: %d", nPre); + + if( rc==SQLITE_OK && (nPre<=0 || nPre>=1000) ){ + *pzErr = sqlite3_mprintf("prefix length out of range (max 999)"); rc = SQLITE_ERROR; + break; } + pConfig->aPrefix[pConfig->nPrefix] = nPre; pConfig->nPrefix++; + bFirst = 0; } + assert( pConfig->nPrefix<=FTS5_MAX_PREFIX_INDEXES ); return rc; } diff --git a/ext/fts5/test/fts5config.test b/ext/fts5/test/fts5config.test index 7c88e03d38..dcda2d42a6 100644 --- a/ext/fts5/test/fts5config.test +++ b/ext/fts5/test/fts5config.test @@ -42,6 +42,8 @@ foreach {tn opt} { 1 {prefix=x} 2 {prefix='x'} 3 {prefix='$'} + 4 {prefix='1,2,'} + 5 {prefix=',1'} } { set res [list 1 {malformed prefix=... directive}] do_catchsql_test 2.$tn "CREATE VIRTUAL TABLE f1 USING fts5(x, $opt)" $res @@ -118,18 +120,15 @@ do_catchsql_test 5.3 { #------------------------------------------------------------------------- # Errors in prefix= directives. # -do_catchsql_test 6.1 { - CREATE VIRTUAL TABLE abc USING fts5(a, prefix=1, prefix=2); -} {1 {multiple prefix=... directives}} do_catchsql_test 6.2 { CREATE VIRTUAL TABLE abc USING fts5(a, prefix='1, 2, 1001'); -} {1 {prefix length out of range: 1001}} +} {1 {prefix length out of range (max 999)}} do_catchsql_test 6.3 { CREATE VIRTUAL TAbLE abc USING fts5(a, prefix='1, 2, 0000'); -} {1 {prefix length out of range: 0}} +} {1 {prefix length out of range (max 999)}} do_catchsql_test 6.4 { CREATE VIRTUAL TABLE abc USING fts5(a, prefix='1 , 1000000'); -} {1 {malformed prefix=... directive}} +} {1 {prefix length out of range (max 999)}} #------------------------------------------------------------------------- # Duplicate tokenize= and other options. @@ -204,5 +203,16 @@ do_catchsql_test 9.4.1 { INSERT INTO abc(abc, rank) VALUES('nosuchoption', 1); } {1 {SQL logic error or missing database}} +#------------------------------------------------------------------------- +# Too many prefix indexes. Maximum allowed is 31. +# +foreach {tn spec} { + 1 {prefix="1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32"} + 2 {prefix="1 2 3 4", prefix="5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32"} +} { + set sql "CREATE VIRTUAL TABLE xyz USING fts5(x, $spec)" + do_catchsql_test 10.$tn $sql {1 {too many prefix indexes (max 31)}} +} + finish_test diff --git a/ext/fts5/test/fts5prefix.test b/ext/fts5/test/fts5prefix.test index 70de0bc78a..8e0d5a2954 100644 --- a/ext/fts5/test/fts5prefix.test +++ b/ext/fts5/test/fts5prefix.test @@ -298,6 +298,48 @@ foreach {tn col pattern} { do_execsql_test 6.$tn { SELECT rowid FROM t5($query) } $res } +#------------------------------------------------------------------------- +# Check that the various ways of creating prefix indexes produce the +# same database on disk. +# +save_prng_state +foreach {tn create} { + 1 { CREATE VIRTUAL TABLE tt USING fts5(x, y, prefix="1,2,3") } + 2 { CREATE VIRTUAL TABLE tt USING fts5(x, y, prefix="1 2 3") } + 3 { CREATE VIRTUAL TABLE tt USING fts5(x, y, prefix=1, prefix=2, prefix=3) } + 4 { CREATE VIRTUAL TABLE tt USING fts5(x, y, prefix="1 2", prefix=3) } +} { + execsql { DROP TABLE IF EXISTS tt } + restore_prng_state + execsql $create + execsql { + INSERT INTO tt VALUES('cc b ggg ccc aa eee hh', 'aa g b hh a e'); + INSERT INTO tt VALUES('cc bb cc gg j g cc', 'ii jjj ggg jjj cc cc'); + INSERT INTO tt VALUES('h eee cc h iii', 'aaa iii dd iii dd'); + INSERT INTO tt VALUES('jjj hh eee c e b gg', 'j bbb jj ddd jj'); + INSERT INTO tt VALUES('ii hhh aaa ff c hhh iii', 'j cc hh bb e'); + INSERT INTO tt VALUES('e fff hhh i aaa', 'g b aa gg c aa dd'); + INSERT INTO tt VALUES('i aaa ccc gg hhh aa h', 'j bbb bbb d ff'); + INSERT INTO tt VALUES('g f gg ff ff jjj d', 'jjj d j fff fff ee j'); + INSERT INTO tt VALUES('a cc e ccc jjj c', 'ccc iii d bb a eee g'); + INSERT INTO tt VALUES('jj hh hh bb bbb gg', 'j c jjj bb iii f'); + INSERT INTO tt VALUES('a ggg g cc ccc aa', 'jjj j j aaa c'); + INSERT INTO tt VALUES('ddd j dd b i', 'aaa bbb iii ggg ff ccc ddd'); + INSERT INTO tt VALUES('jj ii hh c ii h gg', 'hhh bbb ddd bbb hh g ggg'); + INSERT INTO tt VALUES('aa hhh ccc h ggg ccc', 'iii d jj a ff ii'); + } + + #db eval {SELECT rowid, fts5_decode(rowid, block) aS r FROM tt_data} {puts $r} + + if {$tn==1} { + set ::checksum [execsql {SELECT md5sum(id, block) FROM tt_data}] + } else { + do_execsql_test 7.$tn { + SELECT md5sum(id, block) FROM tt_data + } [list $::checksum] + } +} + finish_test diff --git a/manifest b/manifest index 85f1621207..3b43cff7f4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhancement\sthe\svirtual\stable\sinterface\sto\ssupport\sLIKE,\sGLOB,\sand\sREGEXP\noperators.\s\sAlso\sadd\sthe\ssqlite3_strlike()\sinterface,\swhich\smight\sbe\suseful\nas\spart\sof\sthe\simplementation\sof\sLIKE\son\ssome\svirtual\stables. -D 2015-11-25T01:57:42.585 +C Fix\sthe\sfts5\s"prefix="\soption\sto\smatch\sthe\sdocumentation\s(space\sseparated\slist,\smultiple\sprefix=\soptions\ssupported).\sThe\sundocumented\scomma-separated\sformat\s(compatible\swith\sfts4)\sstill\sworks. +D 2015-11-25T11:56:24.532 F Makefile.in d828db6afa6c1fa060d01e33e4674408df1942a1 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e928e68168df69b353300ac87c10105206653a03 @@ -106,7 +106,7 @@ F ext/fts5/fts5.h 8b9a13b309b180e9fb88ea5666c0d8d73c6102d9 F ext/fts5/fts5Int.h acf968e43d57b6b1caf7554d34ec35d6ed3b4fe8 F ext/fts5/fts5_aux.c 1f384972d606375b8fa078319f25ab4b5feb1b35 F ext/fts5/fts5_buffer.c 1e49512a535045e621246dc7f4f65f3593fa0fc2 -F ext/fts5/fts5_config.c 6fc92c0b1bda5244c28a54c9ba740736bd5513d9 +F ext/fts5/fts5_config.c 0ee66188609a62342e9f9aeefa3c3e44518a4dd6 F ext/fts5/fts5_expr.c 28b15c9ae296204bc0a2e5cf7a667d840a9d2900 F ext/fts5/fts5_hash.c a9d4c1efebc2a91d26ad7ebdfcbf2678ceac405f F ext/fts5/fts5_index.c b622a0a70f57a96469e6828da2dd70e0872aeb37 @@ -139,7 +139,7 @@ F ext/fts5/test/fts5aux.test 8c687c948cc98e9a94be014df7d518acc1b3b74f F ext/fts5/test/fts5auxdata.test 141a7cbffcceb1bd2799b4b29c183ff8780d586e F ext/fts5/test/fts5bigpl.test 04ee0d7eebbebf17c31f5a0b5c5f9494eac3a0cb F ext/fts5/test/fts5columnsize.test a8cfef21ffa1c264b9f670a7d94eeaccb5341c07 -F ext/fts5/test/fts5config.test ad2ff42ddc856aed2d05bf89dc1c578c8a39ea3b +F ext/fts5/test/fts5config.test 42c1336cc6ed33d7e9c4a05dbce81721b765e7d0 F ext/fts5/test/fts5conflict.test 26f4e46c4d31e16221794832a990dc4e30e18de5 F ext/fts5/test/fts5content.test 9a952c95518a14182dc3b59e3c8fa71cda82a4e1 F ext/fts5/test/fts5corrupt.test c2ad090192708150d50d961278df10ae7a4b8b62 @@ -168,7 +168,7 @@ F ext/fts5/test/fts5phrase.test f6d1d464da5beb25dc56277aa4f1d6102f0d9a2f F ext/fts5/test/fts5plan.test 6a55ecbac9890765b0e16f8c421c7e0888cfe436 F ext/fts5/test/fts5porter.test 7cdc07bef301d70eebbfa75dcaf45c3680e1d0e1 F ext/fts5/test/fts5porter2.test 2e65633d58a1c525d5af0f6c01e5a59155bb3487 -F ext/fts5/test/fts5prefix.test 7ccbdf180ed561a912acef520519e85af8642239 +F ext/fts5/test/fts5prefix.test efd42e00bb8e8a36383f25c838185508681c093f F ext/fts5/test/fts5query.test f5ec25f5f2fbb70033424113cdffc101b1985a40 F ext/fts5/test/fts5rank.test 7e9e64eac7245637f6f2033aec4b292aaf611aab F ext/fts5/test/fts5rebuild.test 03935f617ace91ed23a6099c7c74d905227ff29b @@ -1405,8 +1405,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 20256177072caa4f2b4114038ad1c8f6e26bc562 e70ec71d6883f2f8fc75301ff985bccb5aa06127 -R d30ed8c32e99c9a94479405580943fff -T +closed e70ec71d6883f2f8fc75301ff985bccb5aa06127 -U drh -Z 535a3252c539f51f296331cdb8ca572e +P a6bfd4692c3f8b107546fbcaeb985d2c1817b3c1 +R 1d5b11516958faf6b08e74d20f3f2fa4 +U dan +Z 6f4c4e6edf8914578c51e0efeab8cf04 diff --git a/manifest.uuid b/manifest.uuid index 453c2a5a99..70c5c2cfac 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a6bfd4692c3f8b107546fbcaeb985d2c1817b3c1 \ No newline at end of file +11eb8e877e2ba859ef6b44318f286597186dfaf2 \ No newline at end of file From 91c4defbcf7f53e37720efb67209ad3b76f0f834 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 25 Nov 2015 14:00:07 +0000 Subject: [PATCH 20/53] Simplification of the error code translator in os_unix.c. Code cleanup only. The logic is unchanged. FossilOrigin-Name: 2a20f793fdf6a2e88b679a7bd4e8ccf2935df049 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/os_unix.c | 53 +++++---------------------------------------------- 3 files changed, 13 insertions(+), 56 deletions(-) diff --git a/manifest b/manifest index 3b43cff7f4..2454a3f417 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sfts5\s"prefix="\soption\sto\smatch\sthe\sdocumentation\s(space\sseparated\slist,\smultiple\sprefix=\soptions\ssupported).\sThe\sundocumented\scomma-separated\sformat\s(compatible\swith\sfts4)\sstill\sworks. -D 2015-11-25T11:56:24.532 +C Simplification\sof\sthe\serror\scode\stranslator\sin\sos_unix.c.\s\sCode\scleanup\sonly.\nThe\slogic\sis\sunchanged. +D 2015-11-25T14:00:07.501 F Makefile.in d828db6afa6c1fa060d01e33e4674408df1942a1 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e928e68168df69b353300ac87c10105206653a03 @@ -323,7 +323,7 @@ F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8 F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf F src/os_common.h abdb9a191a367793268fe553d25bab894e986a0e F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa -F src/os_unix.c 80ec49758dbce979e4f89eda7695bbc01b0c4cd3 +F src/os_unix.c cedce5fdeec172e9392a54805979423cf5720159 F src/os_win.c 386fba30419e8458b13209781c2af5590eab2811 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c 18341e2b759b447cbc82fb9215d08d9c5864e92e @@ -1405,7 +1405,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P a6bfd4692c3f8b107546fbcaeb985d2c1817b3c1 -R 1d5b11516958faf6b08e74d20f3f2fa4 -U dan -Z 6f4c4e6edf8914578c51e0efeab8cf04 +P 11eb8e877e2ba859ef6b44318f286597186dfaf2 +R 6dd872f66c2b35bfdd31a4b155581f40 +U drh +Z ffd91438f4f00e7137108dd3e9d6d335 diff --git a/manifest.uuid b/manifest.uuid index 70c5c2cfac..100264e01f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -11eb8e877e2ba859ef6b44318f286597186dfaf2 \ No newline at end of file +2a20f793fdf6a2e88b679a7bd4e8ccf2935df049 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 82224053f0..6afbfe5cae 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -759,23 +759,12 @@ static int robust_ftruncate(int h, sqlite3_int64 sz){ ** should handle ENOLCK, ENOTSUP, EOPNOTSUPP separately. */ static int sqliteErrorFromPosixError(int posixError, int sqliteIOErr) { + assert( (sqliteIOErr == SQLITE_IOERR_LOCK) || + (sqliteIOErr == SQLITE_IOERR_UNLOCK) || + (sqliteIOErr == SQLITE_IOERR_RDLOCK) || + (sqliteIOErr == SQLITE_IOERR_CHECKRESERVEDLOCK) ); switch (posixError) { -#if 0 - /* At one point this code was not commented out. In theory, this branch - ** should never be hit, as this function should only be called after - ** a locking-related function (i.e. fcntl()) has returned non-zero with - ** the value of errno as the first argument. Since a system call has failed, - ** errno should be non-zero. - ** - ** Despite this, if errno really is zero, we still don't want to return - ** SQLITE_OK. The system call failed, and *some* SQLite error should be - ** propagated back to the caller. Commenting this branch out means errno==0 - ** will be handled by the "default:" case below. - */ - case 0: - return SQLITE_OK; -#endif - + case EACCES: case EAGAIN: case ETIMEDOUT: case EBUSY: @@ -785,41 +774,9 @@ static int sqliteErrorFromPosixError(int posixError, int sqliteIOErr) { * introspection, in which it actually means what it says */ return SQLITE_BUSY; - case EACCES: - /* EACCES is like EAGAIN during locking operations, but not any other time*/ - if( (sqliteIOErr == SQLITE_IOERR_LOCK) || - (sqliteIOErr == SQLITE_IOERR_UNLOCK) || - (sqliteIOErr == SQLITE_IOERR_RDLOCK) || - (sqliteIOErr == SQLITE_IOERR_CHECKRESERVEDLOCK) ){ - return SQLITE_BUSY; - } - /* else fall through */ case EPERM: return SQLITE_PERM; -#if EOPNOTSUPP!=ENOTSUP - case EOPNOTSUPP: - /* something went terribly awry, unless during file system support - * introspection, in which it actually means what it says */ -#endif -#ifdef ENOTSUP - case ENOTSUP: - /* invalid fd, unless during file system support introspection, in which - * it actually means what it says */ -#endif - case EIO: - case EBADF: - case EINVAL: - case ENOTCONN: - case ENODEV: - case ENXIO: - case ENOENT: -#ifdef ESTALE /* ESTALE is not defined on Interix systems */ - case ESTALE: -#endif - case ENOSYS: - /* these should force the client to close the file and reconnect */ - default: return sqliteIOErr; } From 5337dacbad4d61f48873ad228a0bf4399043d854 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 25 Nov 2015 15:15:03 +0000 Subject: [PATCH 21/53] Remove unused methods from the unix VFS. FossilOrigin-Name: 228bd15bbb7a1e6e3e0d03832e7f39ba169356a8 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/os_unix.c | 8 ++++++++ test/fuzzcheck.c | 10 ++-------- 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index 2454a3f417..4aa83052a7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplification\sof\sthe\serror\scode\stranslator\sin\sos_unix.c.\s\sCode\scleanup\sonly.\nThe\slogic\sis\sunchanged. -D 2015-11-25T14:00:07.501 +C Remove\sunused\smethods\sfrom\sthe\sunix\sVFS. +D 2015-11-25T15:15:03.618 F Makefile.in d828db6afa6c1fa060d01e33e4674408df1942a1 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e928e68168df69b353300ac87c10105206653a03 @@ -323,7 +323,7 @@ F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8 F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf F src/os_common.h abdb9a191a367793268fe553d25bab894e986a0e F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa -F src/os_unix.c cedce5fdeec172e9392a54805979423cf5720159 +F src/os_unix.c a6ed7d9ae6e2308b61bd842d6aa296727d26b4fd F src/os_win.c 386fba30419e8458b13209781c2af5590eab2811 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c 18341e2b759b447cbc82fb9215d08d9c5864e92e @@ -753,7 +753,7 @@ F test/fuzz2.test 76dc35b32b6d6f965259508508abce75a6c4d7e1 F test/fuzz3.test 53fabcd5f0f430f8b221282f6c12c4d0903c21eb F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26 -F test/fuzzcheck.c 7c61352f20a28429b221f406f3854cf9c912f63b +F test/fuzzcheck.c ccdcdc28579b2c9744696bca8726bdbd729eea11 F test/fuzzdata1.db 7ee3227bad0e7ccdeb08a9e6822916777073c664 F test/fuzzdata2.db f03a420d3b822cc82e4f894ca957618fbe9c4973 F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba @@ -1405,7 +1405,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 11eb8e877e2ba859ef6b44318f286597186dfaf2 -R 6dd872f66c2b35bfdd31a4b155581f40 +P 2a20f793fdf6a2e88b679a7bd4e8ccf2935df049 +R 9425887a4af2be1f5866057e942bff78 U drh -Z ffd91438f4f00e7137108dd3e9d6d335 +Z 8531bdf5b0fab73861e87c8c638f4398 diff --git a/manifest.uuid b/manifest.uuid index 100264e01f..468142cf2d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2a20f793fdf6a2e88b679a7bd4e8ccf2935df049 \ No newline at end of file +228bd15bbb7a1e6e3e0d03832e7f39ba169356a8 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 6afbfe5cae..e31843af3b 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -6227,6 +6227,7 @@ static int unixCurrentTimeInt64(sqlite3_vfs *NotUsed, sqlite3_int64 *piNow){ return rc; } +#if 0 /* Not used */ /* ** Find the current time (in Universal Coordinated Time). Write the ** current time and date as a Julian Day number into *prNow and @@ -6240,7 +6241,11 @@ static int unixCurrentTime(sqlite3_vfs *NotUsed, double *prNow){ *prNow = i/86400000.0; return rc; } +#else +# define unixCurrentTime 0 +#endif +#if 0 /* Not used */ /* ** We added the xGetLastError() method with the intention of providing ** better low-level error messages when operating-system problems come up @@ -6254,6 +6259,9 @@ static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){ UNUSED_PARAMETER(NotUsed3); return 0; } +#else +# define unixGetLastError 0 +#endif /* diff --git a/test/fuzzcheck.c b/test/fuzzcheck.c index 32690dc466..6d9c745528 100644 --- a/test/fuzzcheck.c +++ b/test/fuzzcheck.c @@ -588,18 +588,13 @@ static int inmemFullPathname( return SQLITE_OK; } -/* GetLastError() is never used */ -static int inmemGetLastError(sqlite3_vfs *pVfs, int n, char *z){ - return SQLITE_OK; -} - /* ** Register the VFS that reads from the g.aFile[] set of files. */ static void inmemVfsRegister(void){ static sqlite3_vfs inmemVfs; sqlite3_vfs *pDefault = sqlite3_vfs_find(0); - inmemVfs.iVersion = 1; + inmemVfs.iVersion = 3; inmemVfs.szOsFile = sizeof(VHandle); inmemVfs.mxPathname = 200; inmemVfs.zName = "inmem"; @@ -609,8 +604,7 @@ static void inmemVfsRegister(void){ inmemVfs.xFullPathname = inmemFullPathname; inmemVfs.xRandomness = pDefault->xRandomness; inmemVfs.xSleep = pDefault->xSleep; - inmemVfs.xCurrentTime = pDefault->xCurrentTime; - inmemVfs.xGetLastError = inmemGetLastError; + inmemVfs.xCurrentTimeInt64 = pDefault->xCurrentTimeInt64; sqlite3_vfs_register(&inmemVfs, 0); }; From d260b5b2ce9acf1d8ef5eafc1c9d8754c5babe57 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 25 Nov 2015 18:03:33 +0000 Subject: [PATCH 22/53] Make the xAccess method of the unix VFS smaller and faster. FossilOrigin-Name: 191aef986ffc4ef34d813e417e52a4ec820b0300 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/os_unix.c | 31 ++++++++++--------------------- 3 files changed, 17 insertions(+), 28 deletions(-) diff --git a/manifest b/manifest index 4aa83052a7..412e61730b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sunused\smethods\sfrom\sthe\sunix\sVFS. -D 2015-11-25T15:15:03.618 +C Make\sthe\sxAccess\smethod\sof\sthe\sunix\sVFS\ssmaller\sand\sfaster. +D 2015-11-25T18:03:33.041 F Makefile.in d828db6afa6c1fa060d01e33e4674408df1942a1 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e928e68168df69b353300ac87c10105206653a03 @@ -323,7 +323,7 @@ F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8 F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf F src/os_common.h abdb9a191a367793268fe553d25bab894e986a0e F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa -F src/os_unix.c a6ed7d9ae6e2308b61bd842d6aa296727d26b4fd +F src/os_unix.c 066d6f8e4ea9c9b82e93eef2daee3cf25759fa36 F src/os_win.c 386fba30419e8458b13209781c2af5590eab2811 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c 18341e2b759b447cbc82fb9215d08d9c5864e92e @@ -1405,7 +1405,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 2a20f793fdf6a2e88b679a7bd4e8ccf2935df049 -R 9425887a4af2be1f5866057e942bff78 +P 228bd15bbb7a1e6e3e0d03832e7f39ba169356a8 +R e147c2a2e15689c8fb9a94a36196c06f U drh -Z 8531bdf5b0fab73861e87c8c638f4398 +Z 62ff0fd6ec1e0622890fd7a98828488f diff --git a/manifest.uuid b/manifest.uuid index 468142cf2d..a972ab8efd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -228bd15bbb7a1e6e3e0d03832e7f39ba169356a8 \ No newline at end of file +191aef986ffc4ef34d813e417e52a4ec820b0300 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index e31843af3b..48f38fdfa2 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -5940,29 +5940,19 @@ static int unixAccess( int flags, /* What do we want to learn about the zPath file? */ int *pResOut /* Write result boolean here */ ){ - int amode = 0; UNUSED_PARAMETER(NotUsed); SimulateIOError( return SQLITE_IOERR_ACCESS; ); - switch( flags ){ - case SQLITE_ACCESS_EXISTS: - amode = F_OK; - break; - case SQLITE_ACCESS_READWRITE: - amode = W_OK|R_OK; - break; - case SQLITE_ACCESS_READ: - amode = R_OK; - break; + assert( pResOut!=0 ); - default: - assert(!"Invalid flags argument"); - } - *pResOut = (osAccess(zPath, amode)==0); - if( flags==SQLITE_ACCESS_EXISTS && *pResOut ){ + /* The spec says there are three possible values for flags. But only + ** two of them are actually used */ + assert( flags==SQLITE_ACCESS_EXISTS || flags==SQLITE_ACCESS_READWRITE ); + + if( flags==SQLITE_ACCESS_EXISTS ){ struct stat buf; - if( 0==osStat(zPath, &buf) && buf.st_size==0 ){ - *pResOut = 0; - } + *pResOut = (0==osStat(zPath, &buf) && buf.st_size>0); + }else{ + *pResOut = osAccess(zPath, W_OK|R_OK)==0; } return SQLITE_OK; } @@ -6005,8 +5995,7 @@ static int unixFullPathname( if( errno!=EINVAL && errno!=ENOENT ){ return unixLogError(SQLITE_CANTOPEN_BKPT, "readlink", zPath); } - zOut[nOut-1] = '\0'; - sqlite3_snprintf(nOut-1, zOut, "%s", zPath); + sqlite3_snprintf(nOut, zOut, "%s", zPath); nByte = sqlite3Strlen30(zOut); }else{ zOut[nByte] = '\0'; From 1e93173ffcfbe2ebb4eae02622cd6e52c36a1729 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 25 Nov 2015 18:07:46 +0000 Subject: [PATCH 23/53] Update test_fs.c to include a virtual table that reads a file-system hierarchy. Use it to further test GLOB and LIKE support for virtual tables. FossilOrigin-Name: 6ef6578c03b7cfbeaaf3627b9eea2febf501ace5 --- manifest | 18 +- manifest.uuid | 2 +- src/test_fs.c | 543 +++++++++++++++++++++++++++++++++++++++++- test/fts4content.test | 4 +- test/vtabH.test | 80 ++++++- 5 files changed, 631 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index 412e61730b..4c40672e14 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\sthe\sxAccess\smethod\sof\sthe\sunix\sVFS\ssmaller\sand\sfaster. -D 2015-11-25T18:03:33.041 +C Update\stest_fs.c\sto\sinclude\sa\svirtual\stable\sthat\sreads\sa\sfile-system\shierarchy.\sUse\sit\sto\sfurther\stest\sGLOB\sand\sLIKE\ssupport\sfor\svirtual\stables. +D 2015-11-25T18:07:46.837 F Makefile.in d828db6afa6c1fa060d01e33e4674408df1942a1 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e928e68168df69b353300ac87c10105206653a03 @@ -366,7 +366,7 @@ F src/test_btree.c 2e9978eca99a9a4bfa8cae949efb00886860a64f F src/test_config.c f2824de39f59d8d621e2d6ec5cc67006d000b2eb F src/test_demovfs.c 0de72c2c89551629f58486fde5734b7d90758852 F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc -F src/test_fs.c ced436e3d4b8e4681328409b8081051ce614e28f +F src/test_fs.c 802b1863c77f0531603c4a70f30ac5bca89a60da F src/test_func.c 0d9c25956152adefee8881c6fadc8354793764d0 F src/test_hexio.c abfdecb6fa58c354623978efceb088ca18e379cd F src/test_init.c 66b33120ffe9cd853b5a905ec850d51151337b32 @@ -728,7 +728,7 @@ F test/fts3tok_err.test 52273cd193b9036282f7bacb43da78c6be87418d F test/fts3varint.test 752c08ed5d32c5d7dc211b056f4ed68a76b7e36e F test/fts4aa.test 10aac8e9d62c7357590acfabe3fad01e9a9ce1cb F test/fts4check.test 9d9e818fd6cb29c0e007cd6d00447739d4fde430 -F test/fts4content.test abb0c77bc3da3df64fec72e00844d2257a90025d +F test/fts4content.test 8707425b926663f8ca81de866c007900442b5ec0 F test/fts4docid.test e33c383cfbdff0284685604d256f347a18fdbf01 F test/fts4growth.test df10fde9f47cf5c71861e63fd8efcd573c4f7e53 F test/fts4growth2.test 2f063be1902a73cd087355837c52fed42ac11a5d @@ -1274,7 +1274,7 @@ F test/vtabC.test 4528f459a13136f982e75614d120aef165f17292 F test/vtabD.test 05b3f1d77117271671089e48719524b676842e96 F test/vtabE.test d5024aa42754962f6bb0afd261681686488e7afe F test/vtabF.test fd5ad376f5a34fe0891df1f3cddb4fe7c3eb077e -F test/vtabH.test 694aa399eb28ed0db2aef59f2f37532781eeb957 +F test/vtabH.test 2030e7183e41c3cc7521c06aa7bc5a232f7e8986 F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5 F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8 F test/vtab_shared.test ea8778d5b0df200adef2ca7c00c3c37d4375f772 @@ -1405,7 +1405,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 228bd15bbb7a1e6e3e0d03832e7f39ba169356a8 -R e147c2a2e15689c8fb9a94a36196c06f -U drh -Z 62ff0fd6ec1e0622890fd7a98828488f +P 191aef986ffc4ef34d813e417e52a4ec820b0300 +R 98283e54084b319f4a987e20b98e348d +U dan +Z 4eb24c0ce56061f040de45e89ced3c69 diff --git a/manifest.uuid b/manifest.uuid index a972ab8efd..44129864bc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -191aef986ffc4ef34d813e417e52a4ec820b0300 \ No newline at end of file +6ef6578c03b7cfbeaaf3627b9eea2febf501ace5 \ No newline at end of file diff --git a/src/test_fs.c b/src/test_fs.c index 417c81b49f..eab5a4a7ad 100644 --- a/src/test_fs.c +++ b/src/test_fs.c @@ -29,6 +29,37 @@ ** Adding the row to the idx table automatically creates a row in the ** virtual table with rowid=4, path=/etc/passwd and a text field that ** contains data read from file /etc/passwd on disk. +** +************************************************************************* +** Virtual table module "fsdir" +** +** This module is designed to be used as a read-only eponymous virtual table. +** Its schema is as follows: +** +** CREATE TABLE fsdir(dir TEXT, name TEXT); +** +** When queried, a WHERE term of the form "dir = $dir" must be provided. The +** virtual table then appears to have one row for each entry in file-system +** directory $dir. Column dir contains a copy of $dir, and column "name" +** contains the name of the directory entry. +** +** If the specified $dir cannot be opened or is not a directory, it is not +** an error. The virtual table appears to be empty in this case. +** +************************************************************************* +** Virtual table module "fstree" +** +** This module is also a read-only eponymous virtual table with the +** following schema: +** +** CREATE TABLE fstree(path TEXT, size INT, data BLOB); +** +** Running a "SELECT * FROM fstree" query on this table returns the entire +** contents of the file-system, starting at "/". To restrict the search +** space, the virtual table supports LIKE and GLOB constraints on the +** 'path' column. For example: +** +** SELECT * FROM fstree WHERE path LIKE '/home/dan/sqlite/%' */ #include "sqliteInt.h" #include "tcl.h" @@ -41,6 +72,7 @@ #if SQLITE_OS_UNIX # include +# include #endif #if SQLITE_OS_WIN # include @@ -70,6 +102,463 @@ struct fs_cursor { int nAlloc; }; +/************************************************************************* +** Start of fsdir implementation. +*/ +typedef struct FsdirVtab FsdirVtab; +typedef struct FsdirCsr FsdirCsr; +struct FsdirVtab { + sqlite3_vtab base; +}; + +struct FsdirCsr { + sqlite3_vtab_cursor base; + char *zDir; /* Buffer containing directory scanned */ + DIR *pDir; /* Open directory */ + sqlite3_int64 iRowid; + struct dirent entry; /* Current entry */ +}; + +/* +** This function is the implementation of both the xConnect and xCreate +** methods of the fsdir virtual table. +** +** The argv[] array contains the following: +** +** argv[0] -> module name ("fs") +** argv[1] -> database name +** argv[2] -> table name +** argv[...] -> other module argument fields. +*/ +static int fsdirConnect( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + FsdirVtab *pTab; + + if( argc!=3 ){ + *pzErr = sqlite3_mprintf("wrong number of arguments"); + return SQLITE_ERROR; + } + + pTab = (FsdirVtab *)sqlite3_malloc(sizeof(FsdirVtab)); + if( !pTab ) return SQLITE_NOMEM; + memset(pTab, 0, sizeof(FsdirVtab)); + + *ppVtab = &pTab->base; + sqlite3_declare_vtab(db, "CREATE TABLE xyz(dir, name);"); + + return SQLITE_OK; +} + +/* +** xDestroy/xDisconnect implementation. +*/ +static int fsdirDisconnect(sqlite3_vtab *pVtab){ + sqlite3_free(pVtab); + return SQLITE_OK; +} + +/* +** xBestIndex implementation. The only constraint supported is: +** +** (dir = ?) +*/ +static int fsdirBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ + int ii; + + pIdxInfo->estimatedCost = 1000000000.0; + + for(ii=0; iinConstraint; ii++){ + struct sqlite3_index_constraint const *p = &pIdxInfo->aConstraint[ii]; + if( p->iColumn==0 && p->usable && p->op==SQLITE_INDEX_CONSTRAINT_EQ ){ + struct sqlite3_index_constraint_usage *pUsage; + pUsage = &pIdxInfo->aConstraintUsage[ii]; + pUsage->omit = 1; + pUsage->argvIndex = 1; + pIdxInfo->idxNum = 1; + pIdxInfo->estimatedCost = 1.0; + break; + } + } + + return SQLITE_OK; +} + +/* +** xOpen implementation. +** +** Open a new fsdir cursor. +*/ +static int fsdirOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ + FsdirCsr *pCur; + pCur = (FsdirCsr*)sqlite3_malloc(sizeof(FsdirCsr)); + if( pCur==0 ) return SQLITE_NOMEM; + memset(pCur, 0, sizeof(FsdirCsr)); + *ppCursor = &pCur->base; + return SQLITE_OK; +} + +/* +** Close a fsdir cursor. +*/ +static int fsdirClose(sqlite3_vtab_cursor *cur){ + FsdirCsr *pCur = (FsdirCsr*)cur; + if( pCur->pDir ) closedir(pCur->pDir); + sqlite3_free(pCur->zDir); + sqlite3_free(pCur); + return SQLITE_OK; +} + +/* +** Skip the cursor to the next entry. +*/ +static int fsdirNext(sqlite3_vtab_cursor *cur){ + FsdirCsr *pCsr = (FsdirCsr*)cur; + + if( pCsr->pDir ){ + struct dirent *pRes = 0; + readdir_r(pCsr->pDir, &pCsr->entry, &pRes); + if( pRes==0 ){ + closedir(pCsr->pDir); + pCsr->pDir = 0; + } + pCsr->iRowid++; + } + + return SQLITE_OK; +} + +/* +** xFilter method implementation. +*/ +static int fsdirFilter( + sqlite3_vtab_cursor *pVtabCursor, + int idxNum, const char *idxStr, + int argc, sqlite3_value **argv +){ + FsdirCsr *pCsr = (FsdirCsr*)pVtabCursor; + int rc; + const char *zDir; + int nDir; + + + if( idxNum!=1 || argc!=1 ){ + return SQLITE_ERROR; + } + + pCsr->iRowid = 0; + sqlite3_free(pCsr->zDir); + if( pCsr->pDir ){ + closedir(pCsr->pDir); + pCsr->pDir = 0; + } + + zDir = (const char*)sqlite3_value_text(argv[0]); + nDir = sqlite3_value_bytes(argv[0]); + pCsr->zDir = sqlite3_malloc(nDir+1); + if( pCsr->zDir==0 ) return SQLITE_NOMEM; + memcpy(pCsr->zDir, zDir, nDir+1); + + pCsr->pDir = opendir(pCsr->zDir); + return fsdirNext(pVtabCursor); +} + +/* +** xEof method implementation. +*/ +static int fsdirEof(sqlite3_vtab_cursor *cur){ + FsdirCsr *pCsr = (FsdirCsr*)cur; + return pCsr->pDir==0; +} + +/* +** xColumn method implementation. +*/ +static int fsdirColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ + FsdirCsr *pCsr = (FsdirCsr*)cur; + switch( i ){ + case 0: /* dir */ + sqlite3_result_text(ctx, pCsr->zDir, -1, SQLITE_STATIC); + break; + + case 1: /* name */ + sqlite3_result_text(ctx, pCsr->entry.d_name, -1, SQLITE_TRANSIENT); + break; + + default: + assert( 0 ); + } + + return SQLITE_OK; +} + +/* +** xRowid method implementation. +*/ +static int fsdirRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ + FsdirCsr *pCsr = (FsdirCsr*)cur; + *pRowid = pCsr->iRowid; + return SQLITE_OK; +} +/* +** End of fsdir implementation. +*************************************************************************/ + +/************************************************************************* +** Start of fstree implementation. +*/ +typedef struct FstreeVtab FstreeVtab; +typedef struct FstreeCsr FstreeCsr; +struct FstreeVtab { + sqlite3_vtab base; + sqlite3 *db; +}; + +struct FstreeCsr { + sqlite3_vtab_cursor base; + sqlite3_stmt *pStmt; /* Statement to list paths */ + int fd; /* File descriptor open on current path */ +}; + +/* +** This function is the implementation of both the xConnect and xCreate +** methods of the fstree virtual table. +** +** The argv[] array contains the following: +** +** argv[0] -> module name ("fs") +** argv[1] -> database name +** argv[2] -> table name +** argv[...] -> other module argument fields. +*/ +static int fstreeConnect( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + FstreeVtab *pTab; + + if( argc!=3 ){ + *pzErr = sqlite3_mprintf("wrong number of arguments"); + return SQLITE_ERROR; + } + + pTab = (FstreeVtab *)sqlite3_malloc(sizeof(FstreeVtab)); + if( !pTab ) return SQLITE_NOMEM; + memset(pTab, 0, sizeof(FstreeVtab)); + pTab->db = db; + + *ppVtab = &pTab->base; + sqlite3_declare_vtab(db, "CREATE TABLE xyz(path, size, data);"); + + return SQLITE_OK; +} + +/* +** xDestroy/xDisconnect implementation. +*/ +static int fstreeDisconnect(sqlite3_vtab *pVtab){ + sqlite3_free(pVtab); + return SQLITE_OK; +} + +/* +** xBestIndex implementation. The only constraint supported is: +** +** (dir = ?) +*/ +static int fstreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ + int ii; + + for(ii=0; iinConstraint; ii++){ + struct sqlite3_index_constraint const *p = &pIdxInfo->aConstraint[ii]; + if( p->iColumn==0 && p->usable && ( + p->op==SQLITE_INDEX_CONSTRAINT_GLOB + || p->op==SQLITE_INDEX_CONSTRAINT_LIKE + || p->op==SQLITE_INDEX_CONSTRAINT_EQ + )){ + struct sqlite3_index_constraint_usage *pUsage; + pUsage = &pIdxInfo->aConstraintUsage[ii]; + pIdxInfo->idxNum = p->op; + pUsage->argvIndex = 1; + pIdxInfo->estimatedCost = 100000.0; + return SQLITE_OK; + } + } + + pIdxInfo->estimatedCost = 1000000000.0; + return SQLITE_OK; +} + +/* +** xOpen implementation. +** +** Open a new fstree cursor. +*/ +static int fstreeOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ + FstreeCsr *pCur; + pCur = (FstreeCsr*)sqlite3_malloc(sizeof(FstreeCsr)); + if( pCur==0 ) return SQLITE_NOMEM; + memset(pCur, 0, sizeof(FstreeCsr)); + pCur->fd = -1; + *ppCursor = &pCur->base; + return SQLITE_OK; +} + +static void fstreeCloseFd(FstreeCsr *pCsr){ + if( pCsr->fd>=0 ){ + close(pCsr->fd); + pCsr->fd = -1; + } +} + +/* +** Close a fstree cursor. +*/ +static int fstreeClose(sqlite3_vtab_cursor *cur){ + FstreeCsr *pCsr = (FstreeCsr*)cur; + sqlite3_finalize(pCsr->pStmt); + fstreeCloseFd(pCsr); + sqlite3_free(pCsr); + return SQLITE_OK; +} + +/* +** Skip the cursor to the next entry. +*/ +static int fstreeNext(sqlite3_vtab_cursor *cur){ + FstreeCsr *pCsr = (FstreeCsr*)cur; + int rc; + + fstreeCloseFd(pCsr); + rc = sqlite3_step(pCsr->pStmt); + if( rc!=SQLITE_ROW ){ + rc = sqlite3_finalize(pCsr->pStmt); + pCsr->pStmt = 0; + }else{ + rc = SQLITE_OK; + pCsr->fd = open(sqlite3_column_text(pCsr->pStmt, 0), O_RDONLY); + } + + return rc; +} + +/* +** xFilter method implementation. +*/ +static int fstreeFilter( + sqlite3_vtab_cursor *pVtabCursor, + int idxNum, const char *idxStr, + int argc, sqlite3_value **argv +){ + FstreeCsr *pCsr = (FstreeCsr*)pVtabCursor; + FstreeVtab *pTab = (FstreeVtab*)(pCsr->base.pVtab); + int rc; + const char *zSql = +"WITH r(d) AS (" +" SELECT CASE WHEN dir='/' THEN '' ELSE dir END || '/' || name " +" FROM fsdir WHERE dir=? AND name NOT LIKE '.%'" +" UNION ALL" +" SELECT dir || '/' || name FROM r, fsdir WHERE dir=d AND name NOT LIKE '.%'" +") SELECT d FROM r;"; + + const char *zDir = "/"; + int nDir = 1; + char aWild[2] = {'\0', '\0' }; + + fstreeCloseFd(pCsr); + sqlite3_finalize(pCsr->pStmt); + pCsr->pStmt = 0; + rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pStmt, 0); + if( rc!=SQLITE_OK ) return rc; + + if( idxNum ){ + const char *zQuery = (const char*)sqlite3_value_text(argv[0]); + switch( idxNum ){ + case SQLITE_INDEX_CONSTRAINT_GLOB: + aWild[0] = '*'; + aWild[1] = '?'; + break; + case SQLITE_INDEX_CONSTRAINT_LIKE: + aWild[0] = '_'; + aWild[1] = '%'; + break; + } + + if( zQuery[0]=='/' ){ + int i; + for(i=1; zQuery[i]; i++){ + if( zQuery[i]==aWild[0] || zQuery[i]==aWild[1] ) break; + if( zQuery[i]=='/' ) nDir = i; + } + zDir = zQuery; + } + } + + sqlite3_bind_text(pCsr->pStmt, 1, zDir, nDir, SQLITE_TRANSIENT); + + return fstreeNext(pVtabCursor); +} + +/* +** xEof method implementation. +*/ +static int fstreeEof(sqlite3_vtab_cursor *cur){ + FstreeCsr *pCsr = (FstreeCsr*)cur; + return pCsr->pStmt==0; +} + +/* +** xColumn method implementation. +*/ +static int fstreeColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ + FstreeCsr *pCsr = (FstreeCsr*)cur; + if( i==0 ){ /* path */ + sqlite3_result_value(ctx, sqlite3_column_value(pCsr->pStmt, 0)); + }else{ + struct stat sBuf; + fstat(pCsr->fd, &sBuf); + + if( S_ISREG(sBuf.st_mode) ){ + if( i==1 ){ + sqlite3_result_int64(ctx, sBuf.st_size); + }else{ + int nRead; + char *aBuf = sqlite3_malloc(sBuf.st_mode+1); + if( !aBuf ) return SQLITE_NOMEM; + nRead = read(pCsr->fd, aBuf, sBuf.st_mode); + if( nRead!=sBuf.st_mode ){ + return SQLITE_IOERR; + } + sqlite3_result_blob(ctx, aBuf, nRead, SQLITE_TRANSIENT); + sqlite3_free(aBuf); + } + } + } + + return SQLITE_OK; +} + +/* +** xRowid method implementation. +*/ +static int fstreeRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ + *pRowid = 0; + return SQLITE_OK; +} +/* +** End of fstree implementation. +*************************************************************************/ + + + + /* ** This function is the implementation of both the xConnect and xCreate ** methods of the fs virtual table. @@ -109,7 +598,7 @@ static int fsConnect( memcpy(pVtab->zTbl, zTbl, strlen(zTbl)); memcpy(pVtab->zDb, zDb, strlen(zDb)); *ppVtab = &pVtab->base; - sqlite3_declare_vtab(db, "CREATE TABLE xyz(path TEXT, data TEXT)"); + sqlite3_declare_vtab(db, "CREATE TABLE x(path TEXT, data TEXT)"); return SQLITE_OK; } @@ -188,15 +677,15 @@ static int fsFilter( static int fsColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ fs_cursor *pCur = (fs_cursor*)cur; - assert( i==0 || i==1 ); + assert( i==0 || i==1 || i==2 ); if( i==0 ){ sqlite3_result_value(ctx, sqlite3_column_value(pCur->pStmt, 0)); }else{ const char *zFile = (const char *)sqlite3_column_text(pCur->pStmt, 1); struct stat sbuf; int fd; - int n; + int n; fd = open(zFile, O_RDONLY); if( fd<0 ) return SQLITE_IOERR; fstat(fd, &sbuf); @@ -284,6 +773,52 @@ static sqlite3_module fsModule = { 0, /* xRename */ }; +static sqlite3_module fsdirModule = { + 0, /* iVersion */ + fsdirConnect, /* xCreate */ + fsdirConnect, /* xConnect */ + fsdirBestIndex, /* xBestIndex */ + fsdirDisconnect, /* xDisconnect */ + fsdirDisconnect, /* xDestroy */ + fsdirOpen, /* xOpen - open a cursor */ + fsdirClose, /* xClose - close a cursor */ + fsdirFilter, /* xFilter - configure scan constraints */ + fsdirNext, /* xNext - advance a cursor */ + fsdirEof, /* xEof - check for end of scan */ + fsdirColumn, /* xColumn - read data */ + fsdirRowid, /* xRowid - read data */ + 0, /* xUpdate */ + 0, /* xBegin */ + 0, /* xSync */ + 0, /* xCommit */ + 0, /* xRollback */ + 0, /* xFindMethod */ + 0, /* xRename */ +}; + +static sqlite3_module fstreeModule = { + 0, /* iVersion */ + fstreeConnect, /* xCreate */ + fstreeConnect, /* xConnect */ + fstreeBestIndex, /* xBestIndex */ + fstreeDisconnect, /* xDisconnect */ + fstreeDisconnect, /* xDestroy */ + fstreeOpen, /* xOpen - open a cursor */ + fstreeClose, /* xClose - close a cursor */ + fstreeFilter, /* xFilter - configure scan constraints */ + fstreeNext, /* xNext - advance a cursor */ + fstreeEof, /* xEof - check for end of scan */ + fstreeColumn, /* xColumn - read data */ + fstreeRowid, /* xRowid - read data */ + 0, /* xUpdate */ + 0, /* xBegin */ + 0, /* xSync */ + 0, /* xCommit */ + 0, /* xRollback */ + 0, /* xFindMethod */ + 0, /* xRename */ +}; + /* ** Decode a pointer to an sqlite3 object. */ @@ -306,6 +841,8 @@ static int register_fs_module( if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; #ifndef SQLITE_OMIT_VIRTUALTABLE sqlite3_create_module(db, "fs", &fsModule, (void *)interp); + sqlite3_create_module(db, "fsdir", &fsdirModule, 0); + sqlite3_create_module(db, "fstree", &fstreeModule, 0); #endif return TCL_OK; } diff --git a/test/fts4content.test b/test/fts4content.test index 481c6ec008..5a91987867 100644 --- a/test/fts4content.test +++ b/test/fts4content.test @@ -587,7 +587,7 @@ do_execsql_test 10.1 { INSERT INTO idx VALUES (3, 't3.txt'); CREATE VIRTUAL TABLE vt USING fs(idx); - SELECT * FROM vt; + SELECT path, data FROM vt; } { 1 {a b c d e f g h i j k l m n o p q r s t u v w x y z} 2 {a b c d e f g h i j k l m a b c d e f g h i j k l m} @@ -595,7 +595,7 @@ do_execsql_test 10.1 { } do_execsql_test 10.2 { - SELECT * FROM vt WHERE rowid = 2; + SELECT path, data FROM vt WHERE rowid = 2; } { 2 {a b c d e f g h i j k l m a b c d e f g h i j k l m} } diff --git a/test/vtabH.test b/test/vtabH.test index 53ecf0a948..dab5343da5 100644 --- a/test/vtabH.test +++ b/test/vtabH.test @@ -92,7 +92,6 @@ foreach ::tclvar_set_omit {0 1} { 2 {value LIKE '%ac%'} {x1 aback x7 backbone x8 backarrow} 300 3 {value REGEXP '^......$'} {x5 babble x6 baboon x9 castle} 30000 } { - if {$tn==3} breakpoint db cache flush set ::gfunc 0 if {$::tclvar_set_omit} {set cnt 0} @@ -107,4 +106,83 @@ foreach ::tclvar_set_omit {0 1} { } } +#------------------------------------------------------------------------- +# +if {$::tcl_platform(platform)=="unix"} { + reset_db + register_fs_module db + do_execsql_test 3.0 { + SELECT name FROM fsdir WHERE dir = '.' AND name = 'test.db'; + SELECT name FROM fsdir WHERE dir = '.' AND name = '.' + } {test.db .} + + # Read the first 5 entries from the root directory. + # + set res [list] + foreach p [lrange [exec ls -U /] 0 4] { + lappend res "/$p" + } + do_execsql_test 3.1 { + SELECT path FROM fstree LIMIT 5; + } $res + + # Read all entries in the current directory. + # + proc contents {pattern} { + set res [list] + foreach f [glob -nocomplain $pattern] { + lappend res $f + if {[file isdir $f]} { + set res [concat $res [contents "$f/*"]] + } + } + set res + } + set pwd "[pwd]/*" + set res [contents $pwd] + do_execsql_test 3.2 { + SELECT path FROM fstree WHERE path GLOB $pwd ORDER BY 1 + } [lsort $res] + + # Add some sub-directories and files to the current directory. + # + do_test 3.3 { + catch { file delete -force subdir } + foreach {path sz} { + subdir/x1.txt 143 + subdir/x2.txt 153 + } { + set dir [file dirname $path] + catch { file mkdir $dir } + set fd [open $path w] + puts -nonewline $fd [string repeat 1 $sz] + close $fd + } + } {} + + set pwd [pwd] + do_execsql_test 3.5 { + SELECT path, size FROM fstree WHERE path GLOB $pwd || '/subdir/*' ORDER BY 1 + } [list \ + "$pwd/subdir/x1.txt" 143 \ + "$pwd/subdir/x2.txt" 153 \ + ] + do_execsql_test 3.6 { + SELECT path, size FROM fstree WHERE path LIKE $pwd || '/subdir/%' ORDER BY 1 + } [list \ + "$pwd/subdir/x1.txt" 143 \ + "$pwd/subdir/x2.txt" 153 \ + ] + do_execsql_test 3.7 { + SELECT sum(size) FROM fstree WHERE path LIKE $pwd || '/subdir/%' + } 296 + do_execsql_test 3.8 { + SELECT size FROM fstree WHERE path = $pwd || '/subdir/x1.txt' + } 143 + +} + + finish_test + + From 489f1e86e3ad5dcf7e2a84c472c752d52355a8f9 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 25 Nov 2015 18:40:38 +0000 Subject: [PATCH 24/53] Fix harmless compiler warnings in test_fs.c. Fix typos and clean up the text of the documentation for sqlite3_strglob() and sqlite3_strlike(). FossilOrigin-Name: 697b20534c2d780cdd8cc165d2930f6e56480770 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/sqlite.h.in | 28 +++++++++++++--------------- src/test_fs.c | 3 +-- 4 files changed, 23 insertions(+), 26 deletions(-) diff --git a/manifest b/manifest index 4c40672e14..3eb5cb0f1a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\stest_fs.c\sto\sinclude\sa\svirtual\stable\sthat\sreads\sa\sfile-system\shierarchy.\sUse\sit\sto\sfurther\stest\sGLOB\sand\sLIKE\ssupport\sfor\svirtual\stables. -D 2015-11-25T18:07:46.837 +C Fix\sharmless\scompiler\swarnings\sin\stest_fs.c.\s\sFix\stypos\sand\sclean\sup\sthe\stext\nof\sthe\sdocumentation\sfor\ssqlite3_strglob()\sand\ssqlite3_strlike(). +D 2015-11-25T18:40:38.741 F Makefile.in d828db6afa6c1fa060d01e33e4674408df1942a1 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e928e68168df69b353300ac87c10105206653a03 @@ -341,7 +341,7 @@ F src/resolve.c f4c897ca76ca6d5e0b3f0499c627392ffe657c8e F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e F src/select.c e10586c750d87211caa8f4b239e2bfa6a2049e5b F src/shell.c f0f59ea60ad297f671b7ae0fb957a736ad17c92c -F src/sqlite.h.in cbe8643b6a1c7313bf6447a2aa7abdb31c73dd77 +F src/sqlite.h.in 1340aa105f53fbc6fd5b9918b54b64c64e910ee7 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h 41ef50b0418a7c5ad1337bb80db5a7928dee764f F src/sqliteInt.h 64256d193a16a147d9f6317cc4e095fdd3e0a2e9 @@ -366,7 +366,7 @@ F src/test_btree.c 2e9978eca99a9a4bfa8cae949efb00886860a64f F src/test_config.c f2824de39f59d8d621e2d6ec5cc67006d000b2eb F src/test_demovfs.c 0de72c2c89551629f58486fde5734b7d90758852 F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc -F src/test_fs.c 802b1863c77f0531603c4a70f30ac5bca89a60da +F src/test_fs.c 9a56a587ce1db424af430d5ff650b5736b498238 F src/test_func.c 0d9c25956152adefee8881c6fadc8354793764d0 F src/test_hexio.c abfdecb6fa58c354623978efceb088ca18e379cd F src/test_init.c 66b33120ffe9cd853b5a905ec850d51151337b32 @@ -1405,7 +1405,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 191aef986ffc4ef34d813e417e52a4ec820b0300 -R 98283e54084b319f4a987e20b98e348d -U dan -Z 4eb24c0ce56061f040de45e89ced3c69 +P 6ef6578c03b7cfbeaaf3627b9eea2febf501ace5 +R 6a7e3073277459e34ef3bc33d986fb8e +U drh +Z 86f0abe6c80c8309344887b29ae04a0c diff --git a/manifest.uuid b/manifest.uuid index 44129864bc..c10a55b520 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6ef6578c03b7cfbeaaf3627b9eea2febf501ace5 \ No newline at end of file +697b20534c2d780cdd8cc165d2930f6e56480770 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index b93ff5873e..d340c05bf9 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -7368,42 +7368,40 @@ int sqlite3_strnicmp(const char *, const char *, int); /* ** CAPI3REF: String Globbing * -** ^The [sqlite3_strglob(P,X)] interface returns zero if string X matches -** the glob pattern P, and it returns non-zero if string X does not match -** the glob pattern P. ^The definition of glob pattern matching used in +** ^The [sqlite3_strglob(P,X)] interface returns zero if and only if +** string X matches the [GLOB] pattern P. +** ^The definition of [GLOB] pattern matching used in ** [sqlite3_strglob(P,X)] is the same as for the "X GLOB P" operator in the -** SQL dialect used by SQLite. ^The sqlite3_strglob(P,X) function is case -** sensitive. +** SQL dialect understood by SQLite. ^The [sqlite3_strglob(P,X)] function +** is case sensitive. ** ** Note that this routine returns zero on a match and non-zero if the strings ** do not match, the same as [sqlite3_stricmp()] and [sqlite3_strnicmp()]. ** -** See also: sqlite3_strlike(). +** See also: [sqlite3_strlike()]. */ int sqlite3_strglob(const char *zGlob, const char *zStr); /* ** CAPI3REF: String LIKE Matching * -** ^The [sqlite3_strlike(P,X,E)] interface returns zero if string X matches -** the LIKE pattern P with escape character E, and it returns non-zero if -** string X does not match the like pattern. -** ^The definition of LIKE pattern matching used in +** ^The [sqlite3_strlike(P,X,E)] interface returns zero if and only if +** string X matches the [LIKE] pattern P with escape character E. +** ^The definition of [LIKE] pattern matching used in ** [sqlite3_strlike(P,X,E)] is the same as for the "X LIKE P ESCAPE E" -** operator in the SQL dialect used by SQLite. ^For "X LIKE P" without +** operator in the SQL dialect understood by SQLite. ^For "X LIKE P" without ** the ESCAPE clause, set the E parameter of [sqlite3_strlike(P,X,E)] to 0. -** ^As with the LIKE operator, the [sqlite3_str(P,X,E)] function is case +** ^As with the LIKE operator, the [sqlite3_strlike(P,X,E)] function is case ** insensitive - equivalent upper and lower case ASCII characters match ** one another. ** ** ^The [sqlite3_strlike(P,X,E)] function matches Unicode characters, though -** only ASCII characters are case folded. (This is because when SQLite was -** first written, the case folding rules for Unicode where still in flux.) +** only ASCII characters are case folded. ** ** Note that this routine returns zero on a match and non-zero if the strings ** do not match, the same as [sqlite3_stricmp()] and [sqlite3_strnicmp()]. ** -** See also: sqlite3_strglob(). +** See also: [sqlite3_strglob()]. */ int sqlite3_strlike(const char *zGlob, const char *zStr, unsigned int cEsc); diff --git a/src/test_fs.c b/src/test_fs.c index eab5a4a7ad..213b65689a 100644 --- a/src/test_fs.c +++ b/src/test_fs.c @@ -241,7 +241,6 @@ static int fsdirFilter( int argc, sqlite3_value **argv ){ FsdirCsr *pCsr = (FsdirCsr*)pVtabCursor; - int rc; const char *zDir; int nDir; @@ -443,7 +442,7 @@ static int fstreeNext(sqlite3_vtab_cursor *cur){ pCsr->pStmt = 0; }else{ rc = SQLITE_OK; - pCsr->fd = open(sqlite3_column_text(pCsr->pStmt, 0), O_RDONLY); + pCsr->fd = open((const char*)sqlite3_column_text(pCsr->pStmt, 0), O_RDONLY); } return rc; From 970942e4fc734b8a33c1b7c36849c1843f4c9ef5 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 25 Nov 2015 23:13:14 +0000 Subject: [PATCH 25/53] Simplify the temporary filename generator and the time-of-day functions in the unix VFS. FossilOrigin-Name: 6c5621ce1b1a65913b088ed8be65f9b689260d2c --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/os_unix.c | 35 +++++++++-------------------------- 3 files changed, 16 insertions(+), 33 deletions(-) diff --git a/manifest b/manifest index 3eb5cb0f1a..36771d7a16 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings\sin\stest_fs.c.\s\sFix\stypos\sand\sclean\sup\sthe\stext\nof\sthe\sdocumentation\sfor\ssqlite3_strglob()\sand\ssqlite3_strlike(). -D 2015-11-25T18:40:38.741 +C Simplify\sthe\stemporary\sfilename\sgenerator\sand\sthe\stime-of-day\sfunctions\sin\nthe\sunix\sVFS. +D 2015-11-25T23:13:14.833 F Makefile.in d828db6afa6c1fa060d01e33e4674408df1942a1 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e928e68168df69b353300ac87c10105206653a03 @@ -323,7 +323,7 @@ F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8 F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf F src/os_common.h abdb9a191a367793268fe553d25bab894e986a0e F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa -F src/os_unix.c 066d6f8e4ea9c9b82e93eef2daee3cf25759fa36 +F src/os_unix.c 3f22d7f2577b963261e9ef3b177b10a3083ed518 F src/os_win.c 386fba30419e8458b13209781c2af5590eab2811 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c 18341e2b759b447cbc82fb9215d08d9c5864e92e @@ -1405,7 +1405,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 6ef6578c03b7cfbeaaf3627b9eea2febf501ace5 -R 6a7e3073277459e34ef3bc33d986fb8e +P 697b20534c2d780cdd8cc165d2930f6e56480770 +R 8a05f9924f5556e21d4d47be27f99435 U drh -Z 86f0abe6c80c8309344887b29ae04a0c +Z fea2e37220480a85fb0635b776213ee8 diff --git a/manifest.uuid b/manifest.uuid index c10a55b520..1b75114db0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -697b20534c2d780cdd8cc165d2930f6e56480770 \ No newline at end of file +6c5621ce1b1a65913b088ed8be65f9b689260d2c \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 48f38fdfa2..3745827f69 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -5424,11 +5424,6 @@ static const char *unixTempFileDir(void){ ** pVfs->mxPathname bytes. */ static int unixGetTempname(int nBuf, char *zBuf){ - static const unsigned char zChars[] = - "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "0123456789"; - unsigned int i, j; const char *zDir; /* It's odd to simulate an io-error here, but really this is just @@ -5439,23 +5434,14 @@ static int unixGetTempname(int nBuf, char *zBuf){ zDir = unixTempFileDir(); if( zDir==0 ) zDir = "."; - - /* Check that the output buffer is large enough for the temporary file - ** name. If it is not, return SQLITE_ERROR. - */ - if( (strlen(zDir) + strlen(SQLITE_TEMP_FILE_PREFIX) + 18) >= (size_t)nBuf ){ - return SQLITE_ERROR; - } - do{ - sqlite3_snprintf(nBuf-18, zBuf, "%s/"SQLITE_TEMP_FILE_PREFIX, zDir); - j = (int)strlen(zBuf); - sqlite3_randomness(15, &zBuf[j]); - for(i=0; i<15; i++, j++){ - zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; - } - zBuf[j] = 0; - zBuf[j+1] = 0; + u64 r; + sqlite3_randomness(sizeof(r), &r); + assert( nBuf>2 ); + zBuf[nBuf-2] = 0; + sqlite3_snprintf(nBuf, zBuf, "%s/"SQLITE_TEMP_FILE_PREFIX"%llx%c", + zDir, r, 0); + if( zBuf[nBuf-2]!=0 ) return SQLITE_ERROR; }while( osAccess(zBuf,0)==0 ); return SQLITE_OK; } @@ -6200,11 +6186,8 @@ static int unixCurrentTimeInt64(sqlite3_vfs *NotUsed, sqlite3_int64 *piNow){ *piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_nsec/1000000; #else struct timeval sNow; - if( gettimeofday(&sNow, 0)==0 ){ - *piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_usec/1000; - }else{ - rc = SQLITE_ERROR; - } + (void)gettimeofday(&sNow, 0); /* Cannot fail given valid arguments */ + *piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_usec/1000; #endif #ifdef SQLITE_TEST From 5a2d970a1a0e1d2a292ae60552dacbb77c1ca598 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 26 Nov 2015 02:21:05 +0000 Subject: [PATCH 26/53] Small simplification to the xOpen method in the unix VFS. FossilOrigin-Name: 96e7d638ecdabbf84a152036eb01d408d142839e --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/os_unix.c | 3 ++- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 36771d7a16..38bdbfc421 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplify\sthe\stemporary\sfilename\sgenerator\sand\sthe\stime-of-day\sfunctions\sin\nthe\sunix\sVFS. -D 2015-11-25T23:13:14.833 +C Small\ssimplification\sto\sthe\sxOpen\smethod\sin\sthe\sunix\sVFS. +D 2015-11-26T02:21:05.964 F Makefile.in d828db6afa6c1fa060d01e33e4674408df1942a1 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e928e68168df69b353300ac87c10105206653a03 @@ -323,7 +323,7 @@ F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8 F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf F src/os_common.h abdb9a191a367793268fe553d25bab894e986a0e F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa -F src/os_unix.c 3f22d7f2577b963261e9ef3b177b10a3083ed518 +F src/os_unix.c 9b3a586ea41129a0a09c13fe421b2d9464964330 F src/os_win.c 386fba30419e8458b13209781c2af5590eab2811 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c 18341e2b759b447cbc82fb9215d08d9c5864e92e @@ -1405,7 +1405,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 697b20534c2d780cdd8cc165d2930f6e56480770 -R 8a05f9924f5556e21d4d47be27f99435 +P 6c5621ce1b1a65913b088ed8be65f9b689260d2c +R 8d655a3f1e63bc6ba67ee6f8b2910653 U drh -Z fea2e37220480a85fb0635b776213ee8 +Z 1746dd40560755829f1cb168fd739f6f diff --git a/manifest.uuid b/manifest.uuid index 1b75114db0..89850da981 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6c5621ce1b1a65913b088ed8be65f9b689260d2c \ No newline at end of file +96e7d638ecdabbf84a152036eb01d408d142839e \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 3745827f69..d86a4a7457 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -5746,7 +5746,8 @@ static int unixOpen( } fd = robust_open(zName, openFlags, openMode); OSTRACE(("OPENX %-3d %s 0%o\n", fd, zName, openFlags)); - if( fd<0 && errno!=EISDIR && isReadWrite && !isExclusive ){ + assert( !isExclusive || (openFlags & O_CREAT)!=0 ); + if( fd<0 && errno!=EISDIR && isReadWrite ){ /* Failed to open the file for read/write access. Try read-only. */ flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE); openFlags &= ~(O_RDWR|O_CREAT); From acb6b28d6065e07b73587c9ca5671f9ebf341678 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 26 Nov 2015 10:37:05 +0000 Subject: [PATCH 27/53] Simplify logic for syncing directories after creating or deleting a file in the unix VFS. FossilOrigin-Name: eb180b4f04d412dcd0af138e2dd7f62fbb5ac439 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/os_unix.c | 11 +++++++---- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 38bdbfc421..cf9f6bf0a7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Small\ssimplification\sto\sthe\sxOpen\smethod\sin\sthe\sunix\sVFS. -D 2015-11-26T02:21:05.964 +C Simplify\slogic\sfor\ssyncing\sdirectories\safter\screating\sor\sdeleting\sa\sfile\sin\nthe\sunix\sVFS. +D 2015-11-26T10:37:05.218 F Makefile.in d828db6afa6c1fa060d01e33e4674408df1942a1 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e928e68168df69b353300ac87c10105206653a03 @@ -323,7 +323,7 @@ F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8 F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf F src/os_common.h abdb9a191a367793268fe553d25bab894e986a0e F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa -F src/os_unix.c 9b3a586ea41129a0a09c13fe421b2d9464964330 +F src/os_unix.c 8b35dc3b8b0a789052855cfc6eab6cd1d206fb81 F src/os_win.c 386fba30419e8458b13209781c2af5590eab2811 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c 18341e2b759b447cbc82fb9215d08d9c5864e92e @@ -1405,7 +1405,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 6c5621ce1b1a65913b088ed8be65f9b689260d2c -R 8d655a3f1e63bc6ba67ee6f8b2910653 +P 96e7d638ecdabbf84a152036eb01d408d142839e +R d6c3f6ff43a112db1f417e3ad4527c02 U drh -Z 1746dd40560755829f1cb168fd739f6f +Z aa5e5077b0093450034838901b6e8de8 diff --git a/manifest.uuid b/manifest.uuid index 89850da981..ec7fac2084 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -96e7d638ecdabbf84a152036eb01d408d142839e \ No newline at end of file +eb180b4f04d412dcd0af138e2dd7f62fbb5ac439 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index d86a4a7457..43eec4c1f5 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -3500,7 +3500,8 @@ static int openDirectory(const char *zFilename, int *pFd){ } } *pFd = fd; - return (fd>=0?SQLITE_OK:unixLogError(SQLITE_CANTOPEN_BKPT, "open", zDirname)); + if( fd>=0 ) return SQLITE_OK; + return unixLogError(SQLITE_CANTOPEN_BKPT, "openDirectory", zDirname); } /* @@ -3553,10 +3554,11 @@ static int unixSync(sqlite3_file *id, int flags){ OSTRACE(("DIRSYNC %s (have_fullfsync=%d fullsync=%d)\n", pFile->zPath, HAVE_FULLFSYNC, isFullsync)); rc = osOpenDirectory(pFile->zPath, &dirfd); - if( rc==SQLITE_OK && dirfd>=0 ){ + if( rc==SQLITE_OK ){ full_fsync(dirfd, 0, 0); robust_close(pFile, dirfd, __LINE__); - }else if( rc==SQLITE_CANTOPEN ){ + }else{ + assert( rc==SQLITE_CANTOPEN ); rc = SQLITE_OK; } pFile->ctrlFlags &= ~UNIXFILE_DIRSYNC; @@ -5903,7 +5905,8 @@ static int unixDelete( rc = unixLogError(SQLITE_IOERR_DIR_FSYNC, "fsync", zPath); } robust_close(0, fd, __LINE__); - }else if( rc==SQLITE_CANTOPEN ){ + }else{ + assert( rc==SQLITE_CANTOPEN ); rc = SQLITE_OK; } } From fab1d401f80e1646341727c50b91377e6f5eb80a Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 26 Nov 2015 15:51:55 +0000 Subject: [PATCH 28/53] Fix a problem with the userauth extension and no-authentication databases. Run the tests for this extension as part of the Debug-One module in releasetest.tcl. FossilOrigin-Name: 8b15621952889b4ba53b2ea3171fef7ef0479ddb --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/build.c | 7 +------ test/releasetest.tcl | 1 + 4 files changed, 11 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index cf9f6bf0a7..ca8c3ee0ee 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplify\slogic\sfor\ssyncing\sdirectories\safter\screating\sor\sdeleting\sa\sfile\sin\nthe\sunix\sVFS. -D 2015-11-26T10:37:05.218 +C Fix\sa\sproblem\swith\sthe\suserauth\sextension\sand\sno-authentication\sdatabases.\sRun\sthe\stests\sfor\sthis\sextension\sas\spart\sof\sthe\sDebug-One\smodule\sin\sreleasetest.tcl. +D 2015-11-26T15:51:55.157 F Makefile.in d828db6afa6c1fa060d01e33e4674408df1942a1 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e928e68168df69b353300ac87c10105206653a03 @@ -285,7 +285,7 @@ F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79 F src/btree.c d3bdd8462a86492e2ebc9aca4a0168429017de25 F src/btree.h 2d76dee44704c47eed323356a758662724b674a0 F src/btreeInt.h 3ab435ed27adea54d040584b0bcc488ee7db1e38 -F src/build.c 19f7585c9747d5043dae64bc82f9cac759f69700 +F src/build.c e83da4d004a4e050c01acbb821ff7a7b1019c29b F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0 F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f F src/ctime.c 509ef9c64d1321f42448f111da86400b1799218a @@ -950,7 +950,7 @@ F test/rbu.test 168573d353cd0fd10196b87b0caa322c144ef736 F test/rdonly.test 64e2696c322e3538df0b1ed624e21f9a23ed9ff8 F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8 F test/reindex.test 44edd3966b474468b823d481eafef0c305022254 -F test/releasetest.tcl 622f2381b217facdf429584a5c292cc1fc47e7c0 +F test/releasetest.tcl 7e1cda0cf50a41a0eb9f4de0ac8198d4db0423d3 F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb F test/rollback.test 458fe73eb3ffdfdf9f6ba3e9b7350a6220414dea F test/rollback2.test fc14cf6d1a2b250d2735ef16124b971bce152f14 @@ -1405,7 +1405,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 96e7d638ecdabbf84a152036eb01d408d142839e -R d6c3f6ff43a112db1f417e3ad4527c02 -U drh -Z aa5e5077b0093450034838901b6e8de8 +P eb180b4f04d412dcd0af138e2dd7f62fbb5ac439 +R f2567fd8ad211c2f6878e625db7a4000 +U dan +Z 033052b1e1d9566ff82c655910d67041 diff --git a/manifest.uuid b/manifest.uuid index ec7fac2084..ffee151b00 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -eb180b4f04d412dcd0af138e2dd7f62fbb5ac439 \ No newline at end of file +8b15621952889b4ba53b2ea3171fef7ef0479ddb \ No newline at end of file diff --git a/src/build.c b/src/build.c index 5f2dc28235..765196f821 100644 --- a/src/build.c +++ b/src/build.c @@ -376,12 +376,7 @@ Table *sqlite3LocateTable( } pParse->checkSchema = 1; } -#if SQLITE_USER_AUTHENTICATION - else if( pParse->db->auth.authLevel Date: Thu, 26 Nov 2015 19:33:41 +0000 Subject: [PATCH 29/53] Add the "colUsed" field to the sqlite3_index_info structure passed to virtual table xBestIndex methods. To indicate the subset of the virtual table columns that may be required by the current scan. FossilOrigin-Name: 116b206494eb8ba963c7c5acfbf9e7b6db11c79c --- manifest | 30 ++++++----- manifest.uuid | 2 +- src/sqlite.h.in | 13 +++++ src/test8.c | 38 ++++++++++++-- src/update.c | 8 +-- src/where.c | 1 + test/tkt3871.test | 10 ++-- test/vtab1.test | 86 ++++++++++++++++--------------- test/vtab4.test | 32 ++++++------ test/vtabH.test | 8 +-- test/vtabI.test | 126 ++++++++++++++++++++++++++++++++++++++++++++++ 11 files changed, 267 insertions(+), 87 deletions(-) create mode 100644 test/vtabI.test diff --git a/manifest b/manifest index ca8c3ee0ee..f8aee8c533 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\swith\sthe\suserauth\sextension\sand\sno-authentication\sdatabases.\sRun\sthe\stests\sfor\sthis\sextension\sas\spart\sof\sthe\sDebug-One\smodule\sin\sreleasetest.tcl. -D 2015-11-26T15:51:55.157 +C Add\sthe\s"colUsed"\sfield\sto\sthe\ssqlite3_index_info\sstructure\spassed\sto\svirtual\stable\sxBestIndex\smethods.\sTo\sindicate\sthe\ssubset\sof\sthe\svirtual\stable\scolumns\sthat\smay\sbe\srequired\sby\sthe\scurrent\sscan. +D 2015-11-26T19:33:41.794 F Makefile.in d828db6afa6c1fa060d01e33e4674408df1942a1 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e928e68168df69b353300ac87c10105206653a03 @@ -341,7 +341,7 @@ F src/resolve.c f4c897ca76ca6d5e0b3f0499c627392ffe657c8e F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e F src/select.c e10586c750d87211caa8f4b239e2bfa6a2049e5b F src/shell.c f0f59ea60ad297f671b7ae0fb957a736ad17c92c -F src/sqlite.h.in 1340aa105f53fbc6fd5b9918b54b64c64e910ee7 +F src/sqlite.h.in e7eed45d38f9426b7608b761260574d2c61873f1 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h 41ef50b0418a7c5ad1337bb80db5a7928dee764f F src/sqliteInt.h 64256d193a16a147d9f6317cc4e095fdd3e0a2e9 @@ -356,7 +356,7 @@ F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e F src/test5.c 5a34feec76d9b3a86aab30fd4f6cc9c48cbab4c1 F src/test6.c 41cacf3b0dd180823919bf9e1fbab287c9266723 F src/test7.c 9c89a4f1ed6bb13af0ed805b8d782bd83fcd57e3 -F src/test8.c 85b8c6a0309130300d560e2334ee71e70391785e +F src/test8.c b3a416298dab54537d5aec68697a8b31f5ddf69c F src/test9.c bea1e8cf52aa93695487badedd6e1886c321ea60 F src/test_async.c 21e11293a2f72080eda70e1124e9102044531cd8 F src/test_autoext.c dea8a01a7153b9adc97bd26161e4226329546e12 @@ -398,7 +398,7 @@ F src/threads.c bbfb74450643cb5372a43ad4f6cffd7e9dfcecb0 F src/tokenize.c 5606871a377f390af7040ec3c12e0d183512d785 F src/treeview.c 78842e90c1f71269e7a73a1d4221b6fe360bab66 F src/trigger.c 322f23aad694e8f31d384dcfa386d52a48d3c52f -F src/update.c 40e51cd0883cb5bfd6abb7d8a7cd8aa47fab2945 +F src/update.c 17332f9fe818cbc0444c36a811800af8498af4c3 F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c F src/util.c e802e8e311a0d6c48cd1b3e89db164f6f0248d70 F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701 @@ -416,7 +416,7 @@ F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb F src/wal.c 18b0ed49830cf04fe2d68224b41838a73ac6cd24 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 2e14d17f592d176b6dc879c33fbdec4fbccaa2ba -F src/where.c 6687fb2675d9c1c1936ceca77529e2f21fb3a769 +F src/where.c 9c04982ba9ecfc7751c670ed5a3bddc81d7eb74c F src/whereInt.h 6afc0d70cf6213e58e8fbe10b6e50d1aa16f122f F src/wherecode.c 4c96182e7b25e4be54008dee2da5b9c2f8480b9b F src/whereexpr.c eebba8340c90de73b3d3bbe8c43b84559b8e6e2c @@ -1204,7 +1204,7 @@ F test/tkt3824.test 150aa00bb6220672e5f0eb14dc8eaa36750425f0 F test/tkt3832.test 2300d10d57562b89875b72148338ac3e14f8847d F test/tkt3838.test 292e72489101cd1320d7278dc111c173ebf334d4 F test/tkt3841.test 4659845bc53f809a5932c61c6ce8c5bb9d6b947f -F test/tkt3871.test 43ecbc8d90dc83908e2a454aef345acc9d160c6f +F test/tkt3871.test d921703d07c68f4fd5312073215a17fa34b0401d F test/tkt3879.test 2ad5bef2c87e9991ce941e054c31abe26ef7fb90 F test/tkt3911.test 74cd324f3ba653040cc6d94cc4857b290d12d633 F test/tkt3918.test ea78bf164e4d55cbde0d83c671ef6fbe930a0032 @@ -1259,10 +1259,10 @@ F test/vacuum4.test d3f8ecff345f166911568f397d2432c16d2867d9 F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102 F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661 F test/view.test f6c3a39e0c819891265e1d0754e99960d81ef6c9 -F test/vtab1.test ec5cb767277d7e0eff34d3a02824c1dd959a5959 +F test/vtab1.test 7c4b81abd88361ada9cbe414c459efca26be6bda F test/vtab2.test f8cd1bb9aba7143eba97812d9617880a36d247ad F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e -F test/vtab4.test 942f8b8280b3ea8a41dae20e7822d065ca1cb275 +F test/vtab4.test 8e73ed268f3d596bc3590f45fc948fb40f28e9c3 F test/vtab5.test 889f444970393c73f1e077e2bdc5d845e157a391 F test/vtab6.test d2986cf418dc51e7fb81d12366bea2caa8b812df F test/vtab7.test ae560ebea870ed04e9aa4177cc302f910faaabb5 @@ -1274,7 +1274,8 @@ F test/vtabC.test 4528f459a13136f982e75614d120aef165f17292 F test/vtabD.test 05b3f1d77117271671089e48719524b676842e96 F test/vtabE.test d5024aa42754962f6bb0afd261681686488e7afe F test/vtabF.test fd5ad376f5a34fe0891df1f3cddb4fe7c3eb077e -F test/vtabH.test 2030e7183e41c3cc7521c06aa7bc5a232f7e8986 +F test/vtabH.test 186f118d6a4dd25fdb36adfd471993003f83790c +F test/vtabI.test 751b07636700dbdea328e4265b6077ccd6811a3f F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5 F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8 F test/vtab_shared.test ea8778d5b0df200adef2ca7c00c3c37d4375f772 @@ -1405,7 +1406,10 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P eb180b4f04d412dcd0af138e2dd7f62fbb5ac439 -R f2567fd8ad211c2f6878e625db7a4000 +P 8b15621952889b4ba53b2ea3171fef7ef0479ddb +R 5ccf7ece7a7865caf2729b522847c5bb +T *branch * vtab-colused +T *sym-vtab-colused * +T -sym-trunk * U dan -Z 033052b1e1d9566ff82c655910d67041 +Z 5f2bf909c1f2bf69ad08297f10962d86 diff --git a/manifest.uuid b/manifest.uuid index ffee151b00..f1b8240b4f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8b15621952889b4ba53b2ea3171fef7ef0479ddb \ No newline at end of file +116b206494eb8ba963c7c5acfbf9e7b6db11c79c \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index d340c05bf9..ea23eb27e2 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -5615,6 +5615,17 @@ struct sqlite3_module { ** ^Information about the ORDER BY clause is stored in aOrderBy[]. ** ^Each term of aOrderBy records a column of the ORDER BY clause. ** +** The colUsed field indicates which columns of the virtual table may be +** required by the current scan. Virtual table columns are numbered from +** zero in the order in which they appear within the CREATE TABLE statement +** passed to sqlite3_declare_vtab(). For the first 63 columns (columns 0-62), +** the corresponding bit is set within the colUsed mask if the column may be +** required by SQLite. If the table has at least 64 columns and any column +** to the right of the first 63 is required, then bit 63 of colUsed is also +** set. In other words, column iCol may be required if the expression +** (colUsed & ((sqlite3_uint64)1 << (iCol>=63 ? 63 : iCol))) evaluates to +** non-zero. +** ** The [xBestIndex] method must fill aConstraintUsage[] with information ** about what parameters to pass to xFilter. ^If argvIndex>0 then ** the right-hand side of the corresponding aConstraint[] is evaluated @@ -5694,6 +5705,8 @@ struct sqlite3_index_info { sqlite3_int64 estimatedRows; /* Estimated number of rows returned */ /* Fields below are only available in SQLite 3.9.0 and later */ int idxFlags; /* Mask of SQLITE_INDEX_SCAN_* flags */ + /* Fields below are only available in SQLite 3.10.0 and later */ + sqlite3_uint64 colUsed; /* Input: Mask of columns used by statement */ }; /* diff --git a/src/test8.c b/src/test8.c index 0c5dc0206e..3e506e36b4 100644 --- a/src/test8.c +++ b/src/test8.c @@ -745,6 +745,34 @@ static void string_concat(char **pzStr, char *zAppend, int doFree, int *pRc){ } } +/* +** This function returns a pointer to an sqlite3_malloc()ed buffer +** containing the select-list (the thing between keywords SELECT and FROM) +** to query the underlying real table with for the scan described by +** argument pIdxInfo. +** +** If the current SQLite version is earlier than 3.10.0, this is just "*" +** (select all columns). Or, for version 3.10.0 and greater, the list of +** columns identified by the pIdxInfo->colUsed mask. +*/ +static char *echoSelectList(echo_vtab *pTab, sqlite3_index_info *pIdxInfo){ + char *zRet = 0; + if( sqlite3_libversion_number()<3010000 ){ + zRet = sqlite3_mprintf(", *"); + }else{ + int i; + for(i=0; inCol; i++){ + if( pIdxInfo->colUsed & ((sqlite3_uint64)1 << (i>=63 ? 63 : i)) ){ + zRet = sqlite3_mprintf("%z, %s", zRet, pTab->aCol[i]); + }else{ + zRet = sqlite3_mprintf("%z, NULL", zRet); + } + if( !zRet ) break; + } + } + return zRet; +} + /* ** The echo module implements the subset of query constraints and sort ** orders that may take advantage of SQLite indices on the underlying @@ -770,6 +798,7 @@ static void string_concat(char **pzStr, char *zAppend, int doFree, int *pRc){ static int echoBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ int ii; char *zQuery = 0; + char *zCol = 0; char *zNew; int nArg = 0; const char *zSep = "WHERE"; @@ -817,10 +846,11 @@ static int echoBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ } } - zQuery = sqlite3_mprintf("SELECT rowid, * FROM %Q", pVtab->zTableName); - if( !zQuery ){ - return SQLITE_NOMEM; - } + zCol = echoSelectList(pVtab, pIdxInfo); + if( !zCol ) return SQLITE_NOMEM; + zQuery = sqlite3_mprintf("SELECT rowid%z FROM %Q", zCol, pVtab->zTableName); + if( !zQuery ) return SQLITE_NOMEM; + for(ii=0; iinConstraint; ii++){ const struct sqlite3_index_constraint *pConstraint; struct sqlite3_index_constraint_usage *pUsage; diff --git a/src/update.c b/src/update.c index 1335c269ed..a9735cadca 100644 --- a/src/update.c +++ b/src/update.c @@ -263,10 +263,12 @@ void sqlite3Update( assert( chngPk==0 || chngPk==1 ); chngKey = chngRowid + chngPk; - /* The SET expressions are not actually used inside the WHERE loop. - ** So reset the colUsed mask + /* The SET expressions are not actually used inside the WHERE loop. + ** So reset the colUsed mask. Unless this is a virtual table. In that + ** case, set all bits of the colUsed mask (to ensure that the virtual + ** table implementation makes all columns available). */ - pTabList->a[0].colUsed = 0; + pTabList->a[0].colUsed = IsVirtual(pTab) ? (Bitmask)-1 : 0; hasFK = sqlite3FkRequired(pParse, pTab, aXRef, chngKey); diff --git a/src/where.c b/src/where.c index 737bfc4e6f..30ad58e01b 100644 --- a/src/where.c +++ b/src/where.c @@ -2864,6 +2864,7 @@ static int whereLoopAddVirtual( pIdxInfo->estimatedCost = SQLITE_BIG_DBL / (double)2; pIdxInfo->estimatedRows = 25; pIdxInfo->idxFlags = 0; + pIdxInfo->colUsed = (sqlite3_int64)pSrc->colUsed; rc = vtabBestIndex(pParse, pTab, pIdxInfo); if( rc ) goto whereLoopAddVtab_exit; pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint; diff --git a/test/tkt3871.test b/test/tkt3871.test index e7dbfde714..d587910d39 100644 --- a/test/tkt3871.test +++ b/test/tkt3871.test @@ -32,8 +32,8 @@ do_test tkt3871-1.3 { execsql { SELECT * FROM e WHERE a = 1 OR a = 2 } set echo_module } [list \ - xFilter {SELECT rowid, * FROM 't1' WHERE a = ?} 1 \ - xFilter {SELECT rowid, * FROM 't1' WHERE a = ?} 2 \ + xFilter {SELECT rowid, a, b FROM 't1' WHERE a = ?} 1 \ + xFilter {SELECT rowid, a, b FROM 't1' WHERE a = ?} 2 \ ] do_test tkt3871-1.4 { @@ -44,9 +44,9 @@ do_test tkt3871-1.5 { execsql { SELECT * FROM e WHERE a = 1 OR a = 2 OR b = 9 } set echo_module } [list \ - xFilter {SELECT rowid, * FROM 't1' WHERE a = ?} 1 \ - xFilter {SELECT rowid, * FROM 't1' WHERE a = ?} 2 \ - xFilter {SELECT rowid, * FROM 't1' WHERE b = ?} 9 + xFilter {SELECT rowid, a, b FROM 't1' WHERE a = ?} 1 \ + xFilter {SELECT rowid, a, b FROM 't1' WHERE a = ?} 2 \ + xFilter {SELECT rowid, a, b FROM 't1' WHERE b = ?} 9 ] diff --git a/test/vtab1.test b/test/vtab1.test index d5fae941af..6b6a0e2683 100644 --- a/test/vtab1.test +++ b/test/vtab1.test @@ -393,7 +393,7 @@ do_test vtab1-3.7 { SELECT rowid, * FROM t1; } } {1 1 2 3 2 4 5 6} -do_test vtab1-3.8 { +do_test vtab1-3.8.1 { execsql { SELECT a AS d, b AS e, c AS f FROM t1; } @@ -404,14 +404,14 @@ do_test vtab1-3.8 { # in test8.c) to make sure the xBestIndex() and xFilter() methods were # called correctly. # -do_test vtab1-3.8 { +do_test vtab1-3.8.2 { set echo_module "" execsql { SELECT * FROM t1; } set echo_module -} [list xBestIndex {SELECT rowid, * FROM 'treal'} \ - xFilter {SELECT rowid, * FROM 'treal'} ] +} [list xBestIndex {SELECT rowid, a, b, c FROM 'treal'} \ + xFilter {SELECT rowid, a, b, c FROM 'treal'} ] do_test vtab1-3.9 { set echo_module "" execsql { @@ -420,8 +420,8 @@ do_test vtab1-3.9 { } {4 5 6} do_test vtab1-3.10 { set echo_module -} [list xBestIndex {SELECT rowid, * FROM 'treal' WHERE b = ?} \ - xFilter {SELECT rowid, * FROM 'treal' WHERE b = ?} 5 ] +} [list xBestIndex {SELECT rowid, a, b, c FROM 'treal' WHERE b = ?} \ + xFilter {SELECT rowid, a, b, c FROM 'treal' WHERE b = ?} 5 ] do_test vtab1-3.10 { set echo_module "" execsql { @@ -430,8 +430,9 @@ do_test vtab1-3.10 { } {4 5 6} do_test vtab1-3.11 { set echo_module -} [list xBestIndex {SELECT rowid, * FROM 'treal' WHERE b >= ? AND b <= ?} \ - xFilter {SELECT rowid, * FROM 'treal' WHERE b >= ? AND b <= ?} 5 10 ] +} [list xBestIndex {SELECT rowid, a, b, c FROM 'treal' WHERE b >= ? AND b <= ?}\ + xFilter {SELECT rowid, a, b, c FROM 'treal' WHERE b >= ? AND b <= ?}\ + 5 10 ] do_test vtab1-3.12 { set echo_module "" execsql { @@ -440,8 +441,9 @@ do_test vtab1-3.12 { } {1 2 3 4 5 6} do_test vtab1-3.13 { set echo_module -} [list xBestIndex {SELECT rowid, * FROM 'treal' WHERE b >= ? AND b <= ?} \ - xFilter {SELECT rowid, * FROM 'treal' WHERE b >= ? AND b <= ?} 2 10 ] +} [list xBestIndex {SELECT rowid, a, b, c FROM 'treal' WHERE b >= ? AND b <= ?}\ + xFilter {SELECT rowid, a, b, c FROM 'treal' WHERE b >= ? AND b <= ?}\ + 2 10 ] # Add a function for the MATCH operator. Everything always matches! #proc test_match {lhs rhs} { @@ -459,8 +461,8 @@ do_test vtab1-3.12 { } {1 {unable to use function MATCH in the requested context}} do_test vtab1-3.13 { set echo_module -} [list xBestIndex {SELECT rowid, * FROM 'treal'} \ - xFilter {SELECT rowid, * FROM 'treal'}] +} [list xBestIndex {SELECT rowid, a, b, c FROM 'treal'} \ + xFilter {SELECT rowid, a, b, c FROM 'treal'}] ifcapable subquery { # The echo module uses a subquery internally to implement the MATCH operator. do_test vtab1-3.14 { @@ -472,9 +474,9 @@ do_test vtab1-3.14 { do_test vtab1-3.15 { set echo_module } [list xBestIndex \ - {SELECT rowid, * FROM 'treal' WHERE b LIKE (SELECT '%'||?||'%')} \ + {SELECT rowid, a, b, c FROM 'treal' WHERE b LIKE (SELECT '%'||?||'%')} \ xFilter \ - {SELECT rowid, * FROM 'treal' WHERE b LIKE (SELECT '%'||?||'%')} \ + {SELECT rowid, a, b, c FROM 'treal' WHERE b LIKE (SELECT '%'||?||'%')} \ string ] }; #ifcapable subquery @@ -505,8 +507,8 @@ do_test vtab1-4.1 { } {2 5 nosort} do_test vtab1-4.2 { set echo_module -} [list xBestIndex {SELECT rowid, * FROM 'treal' ORDER BY b ASC} \ - xFilter {SELECT rowid, * FROM 'treal' ORDER BY b ASC} ] +} [list xBestIndex {SELECT rowid, NULL, b, NULL FROM 'treal' ORDER BY b ASC} \ + xFilter {SELECT rowid, NULL, b, NULL FROM 'treal' ORDER BY b ASC} ] do_test vtab1-4.3 { set echo_module "" cksort { @@ -515,8 +517,8 @@ do_test vtab1-4.3 { } {5 2 nosort} do_test vtab1-4.4 { set echo_module -} [list xBestIndex {SELECT rowid, * FROM 'treal' ORDER BY b DESC} \ - xFilter {SELECT rowid, * FROM 'treal' ORDER BY b DESC} ] +} [list xBestIndex {SELECT rowid, NULL, b, NULL FROM 'treal' ORDER BY b DESC} \ + xFilter {SELECT rowid, NULL, b, NULL FROM 'treal' ORDER BY b DESC} ] do_test vtab1-4.3 { set echo_module "" cksort { @@ -525,8 +527,8 @@ do_test vtab1-4.3 { } {2 5 sort} do_test vtab1-4.4 { set echo_module -} [list xBestIndex {SELECT rowid, * FROM 'treal'} \ - xFilter {SELECT rowid, * FROM 'treal'} ] +} [list xBestIndex {SELECT rowid, NULL, b, NULL FROM 'treal'} \ + xFilter {SELECT rowid, NULL, b, NULL FROM 'treal'} ] execsql { DROP TABLE t1; @@ -575,9 +577,9 @@ do_test vtab1-5-2 { do_test vtab1-5-3 { filter $echo_module } [list \ - xFilter {SELECT rowid, * FROM 't1'} \ - xFilter {SELECT rowid, * FROM 't2'} \ - xFilter {SELECT rowid, * FROM 't2'} \ + xFilter {SELECT rowid, a, b, c FROM 't1'} \ + xFilter {SELECT rowid, d, e, f FROM 't2'} \ + xFilter {SELECT rowid, d, e, f FROM 't2'} \ ] do_test vtab1-5-4 { set echo_module "" @@ -591,9 +593,9 @@ do_test vtab1-5-4 { do_test vtab1-5-5 { filter $echo_module } [list \ - xFilter {SELECT rowid, * FROM 't1'} \ - xFilter {SELECT rowid, * FROM 't2'} \ - xFilter {SELECT rowid, * FROM 't2'} \ + xFilter {SELECT rowid, a, b, c FROM 't1'} \ + xFilter {SELECT rowid, d, e, f FROM 't2'} \ + xFilter {SELECT rowid, d, e, f FROM 't2'} \ ] do_test vtab1-5-6 { execsql { @@ -615,9 +617,9 @@ do_test vtab1-5-6 { do_test vtab1-5-7 { filter $::echo_module } [list \ - xFilter {SELECT rowid, * FROM 't1'} \ - xFilter {SELECT rowid, * FROM 't2' WHERE d = ?} \ - xFilter {SELECT rowid, * FROM 't2' WHERE d = ?} \ + xFilter {SELECT rowid, a, b, c FROM 't1'} \ + xFilter {SELECT rowid, d, e, f FROM 't2' WHERE d = ?} \ + xFilter {SELECT rowid, d, e, f FROM 't2' WHERE d = ?} \ ] execsql { @@ -967,8 +969,8 @@ do_test vtab1.10-5 { } set echo_module } [list \ - xBestIndex {SELECT rowid, * FROM 'r'} \ - xFilter {SELECT rowid, * FROM 'r'} \ + xBestIndex {SELECT rowid, a, b, c FROM 'r'} \ + xFilter {SELECT rowid, a, b, c FROM 'r'} \ ] proc match_func {args} {return ""} do_test vtab1.10-6 { @@ -979,8 +981,8 @@ do_test vtab1.10-6 { } set echo_module } [list \ - xBestIndex {SELECT rowid, * FROM 'r'} \ - xFilter {SELECT rowid, * FROM 'r'} \ + xBestIndex {SELECT rowid, a, b, c FROM 'r'} \ + xFilter {SELECT rowid, a, b, c FROM 'r'} \ ] @@ -1153,13 +1155,15 @@ do_test vtab1-14.2 { set echo_module "" execsql { SELECT * FROM echo_c WHERE rowid = 1 } set echo_module -} [list xBestIndex {SELECT rowid, * FROM 'c' WHERE rowid = ?} xFilter {SELECT rowid, * FROM 'c' WHERE rowid = ?} 1] +} [list xBestIndex {SELECT rowid, a, b, c FROM 'c' WHERE rowid = ?} \ + xFilter {SELECT rowid, a, b, c FROM 'c' WHERE rowid = ?} 1] do_test vtab1-14.3 { set echo_module "" execsql { SELECT * FROM echo_c WHERE a = 1 } set echo_module -} [list xBestIndex {SELECT rowid, * FROM 'c' WHERE a = ?} xFilter {SELECT rowid, * FROM 'c' WHERE a = ?} 1] +} [list xBestIndex {SELECT rowid, a, b, c FROM 'c' WHERE a = ?} \ + xFilter {SELECT rowid, a, b, c FROM 'c' WHERE a = ?} 1] #do_test vtab1-14.4 { # set echo_module "" @@ -1300,16 +1304,16 @@ do_execsql_test 18.1.0 { foreach {tn sql res filter} { 1.1 "SELECT a FROM e6 WHERE b>'James'" {4 1 5} - {xFilter {SELECT rowid, * FROM 't6' WHERE b > ?} James} + {xFilter {SELECT rowid, a, b FROM 't6' WHERE b > ?} James} 1.2 "SELECT a FROM e6 WHERE b>='J' AND b<'K'" {3 4} - {xFilter {SELECT rowid, * FROM 't6' WHERE b >= ? AND b < ?} J K} + {xFilter {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ?} J K} 1.3 "SELECT a FROM e6 WHERE b LIKE 'J%'" {3 4} - {xFilter {SELECT rowid, * FROM 't6' WHERE b like ?} J%} + {xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} J%} 1.4 "SELECT a FROM e6 WHERE b LIKE 'j%'" {3 4} - {xFilter {SELECT rowid, * FROM 't6' WHERE b like ?} j%} + {xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} j%} } { set echo_module {} do_execsql_test 18.$tn.1 $sql $res @@ -1319,10 +1323,10 @@ foreach {tn sql res filter} { do_execsql_test 18.2.0 { PRAGMA case_sensitive_like = ON } foreach {tn sql res filter} { 2.1 "SELECT a FROM e6 WHERE b LIKE 'J%'" {3 4} - {xFilter {SELECT rowid, * FROM 't6' WHERE b like ?} J%} + {xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} J%} 2.2 "SELECT a FROM e6 WHERE b LIKE 'j%'" {} - {xFilter {SELECT rowid, * FROM 't6' WHERE b like ?} j%} + {xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} j%} } { set echo_module {} do_execsql_test 18.$tn.1 $sql $res diff --git a/test/vtab4.test b/test/vtab4.test index 07b6e839d7..d12ca33cc0 100644 --- a/test/vtab4.test +++ b/test/vtab4.test @@ -57,9 +57,9 @@ do_test vtab4-1.3 { UPDATE techo SET a = 2; } set echo_module -} [list xBestIndex {SELECT rowid, * FROM 'treal'} \ +} [list xBestIndex {SELECT rowid, a, b, c FROM 'treal'} \ xBegin echo(treal) \ - xFilter {SELECT rowid, * FROM 'treal'} \ + xFilter {SELECT rowid, a, b, c FROM 'treal'} \ xSync echo(treal) \ xCommit echo(treal) \ ] @@ -69,9 +69,9 @@ do_test vtab4-1.4 { DELETE FROM techo; } set echo_module -} [list xBestIndex {SELECT rowid, * FROM 'treal'} \ +} [list xBestIndex {SELECT rowid, NULL, NULL, NULL FROM 'treal'} \ xBegin echo(treal) \ - xFilter {SELECT rowid, * FROM 'treal'} \ + xFilter {SELECT rowid, NULL, NULL, NULL FROM 'treal'} \ xSync echo(treal) \ xCommit echo(treal) \ ] @@ -105,12 +105,12 @@ do_test vtab4-2.2 { COMMIT; } set echo_module -} [list xBestIndex {SELECT rowid, * FROM 'treal'} \ +} [list xBestIndex {SELECT rowid, a, b, c FROM 'treal'} \ xBegin echo(sreal) \ - xFilter {SELECT rowid, * FROM 'treal'} \ - xBestIndex {SELECT rowid, * FROM 'treal'} \ + xFilter {SELECT rowid, a, b, c FROM 'treal'} \ + xBestIndex {SELECT rowid, NULL, NULL, NULL FROM 'treal'} \ xBegin echo(treal) \ - xFilter {SELECT rowid, * FROM 'treal'} \ + xFilter {SELECT rowid, NULL, NULL, NULL FROM 'treal'} \ xSync echo(sreal) \ xSync echo(treal) \ xCommit echo(sreal) \ @@ -137,12 +137,12 @@ do_test vtab4-2.5 { ROLLBACK; } set echo_module -} [list xBestIndex {SELECT rowid, * FROM 'sreal'} \ +} [list xBestIndex {SELECT rowid, a, b, c FROM 'sreal'} \ xBegin echo(treal) \ - xFilter {SELECT rowid, * FROM 'sreal'} \ - xBestIndex {SELECT rowid, * FROM 'sreal'} \ + xFilter {SELECT rowid, a, b, c FROM 'sreal'} \ + xBestIndex {SELECT rowid, NULL, NULL, NULL FROM 'sreal'} \ xBegin echo(sreal) \ - xFilter {SELECT rowid, * FROM 'sreal'} \ + xFilter {SELECT rowid, NULL, NULL, NULL FROM 'sreal'} \ xRollback echo(treal) \ xRollback echo(sreal) \ ] @@ -178,12 +178,12 @@ do_test vtab4-3.3 { COMMIT; } set echo_module -} [list xBestIndex {SELECT rowid, * FROM 'sreal'} \ +} [list xBestIndex {SELECT rowid, a, b, c FROM 'sreal'} \ xBegin echo(treal) \ - xFilter {SELECT rowid, * FROM 'sreal'} \ - xBestIndex {SELECT rowid, * FROM 'sreal'} \ + xFilter {SELECT rowid, a, b, c FROM 'sreal'} \ + xBestIndex {SELECT rowid, NULL, NULL, NULL FROM 'sreal'} \ xBegin echo(sreal) \ - xFilter {SELECT rowid, * FROM 'sreal'} \ + xFilter {SELECT rowid, NULL, NULL, NULL FROM 'sreal'} \ xSync echo(treal) \ xSync echo(sreal) \ xRollback echo(treal) \ diff --git a/test/vtabH.test b/test/vtabH.test index dab5343da5..7216677d2a 100644 --- a/test/vtabH.test +++ b/test/vtabH.test @@ -32,13 +32,13 @@ do_execsql_test 1.0 { foreach {tn sql expect} { 1 "SELECT * FROM e6 WHERE b LIKE 'abc'" { - xBestIndex {SELECT rowid, * FROM 't6' WHERE b like ?} - xFilter {SELECT rowid, * FROM 't6' WHERE b like ?} abc + xBestIndex {SELECT rowid, a, b FROM 't6' WHERE b like ?} + xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} abc } 2 "SELECT * FROM e6 WHERE b GLOB 'abc'" { - xBestIndex {SELECT rowid, * FROM 't6' WHERE b glob ?} - xFilter {SELECT rowid, * FROM 't6' WHERE b glob ?} abc + xBestIndex {SELECT rowid, a, b FROM 't6' WHERE b glob ?} + xFilter {SELECT rowid, a, b FROM 't6' WHERE b glob ?} abc } } { do_test 1.$tn { diff --git a/test/vtabI.test b/test/vtabI.test new file mode 100644 index 0000000000..4b5a0a8c32 --- /dev/null +++ b/test/vtabI.test @@ -0,0 +1,126 @@ +# 2015 Nov 26 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. Specifically, +# it tests the sqlite3_index_info.colUsed variable is set correctly. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix vtabI + +ifcapable !vtab { + finish_test + return +} + +register_echo_module db + +do_execsql_test 1.0 { + CREATE TABLE t1(a, b, c, d, e); + CREATE VIRTUAL TABLE e1 USING echo(t1); +} + +foreach {tn query filter} { + 1 {SELECT * FROM e1} + {SELECT rowid, a, b, c, d, e FROM 't1'} + + 2 {SELECT a, b FROM e1} + {SELECT rowid, a, b, NULL, NULL, NULL FROM 't1'} + + 3 {SELECT count(*) FROM e1 GROUP BY b} + {SELECT rowid, NULL, b, NULL, NULL, NULL FROM 't1'} + + 4 {SELECT count(*) FROM e1 GROUP BY b HAVING a=?} + {SELECT rowid, a, b, NULL, NULL, NULL FROM 't1'} + + 5 {SELECT a FROM e1 WHERE c=?} + {SELECT rowid, a, NULL, c, NULL, NULL FROM 't1'} + + 6 {SELECT a FROM e1 ORDER BY e} + {SELECT rowid, a, NULL, NULL, NULL, e FROM 't1'} + + 7 {SELECT a FROM e1 ORDER BY e, d} + {SELECT rowid, a, NULL, NULL, d, e FROM 't1'} +} { + do_test 1.$tn { + set ::echo_module [list] + execsql $query + set idx [lsearch -exact $::echo_module xFilter] + lindex $::echo_module [expr $idx+1] + } $filter +} + +#------------------------------------------------------------------------- +# Tests with a table with more than 64 columns. +# +proc all_col_list {} { + set L [list] + for {set i 1} {$i <= 100} {incr i} { lappend L "c$i" } + set L +} + +proc part_col_list {cols} { + set L [list] + for {set i 1} {$i <= 100} {incr i} { + set c "c$i" + if {[lsearch $cols $c]>=0} { + lappend L "c$i" + } else { + lappend L NULL + } + } + set L +} +proc CL {args} { + join [part_col_list $args] ", " +} +proc CLT {args} { + set cols $args + for {set i 64} {$i <= 100} {incr i} { + lappend cols "c$i" + } + join [part_col_list $cols] ", " +} + +do_test 2.0 { + execsql "CREATE TABLE t2([join [all_col_list] ,])" + execsql "CREATE VIRTUAL TABLE e2 USING echo(t2)" +} {} + +foreach {tn query filter} { + 1 {SELECT c1, c10, c20 FROM e2} + {SELECT rowid, [CL c1 c10 c20] FROM 't2'} + + 2 {SELECT c40, c50, c60 FROM e2} + {SELECT rowid, [CL c40 c50 c60] FROM 't2'} + + 3 {SELECT c7, c80, c90 FROM e2} + {SELECT rowid, [CLT c7] FROM 't2'} + + 4 {SELECT c64 FROM e2} + {SELECT rowid, [CLT c64] FROM 't2'} + + 5 {SELECT c63 FROM e2} + {SELECT rowid, [CL c63] FROM 't2'} + + 6 {SELECT c22 FROM e2 ORDER BY c50, c70} + {SELECT rowid, [CLT c22 c50] FROM 't2'} + +} { + do_test 2.$tn { + set ::echo_module [list] + execsql $query + set idx [lsearch -exact $::echo_module xFilter] + lindex $::echo_module [expr $idx+1] + } [subst $filter] +} + +finish_test From a6082f699e1ce60b67781b3133c83bdd34ebcc5e Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 26 Nov 2015 22:12:41 +0000 Subject: [PATCH 30/53] The first argument to SQLITE_CONFIG_PAGECACHE, SQLITE_CONFIG_SCRATCH, and SQLITE_CONFIG_HEAP must always be a pointer. FossilOrigin-Name: 5e14cadff09d7425c8e1cc5e817f2b0609e52a46 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/pcache1.c | 2 +- src/test_malloc.c | 4 ++-- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index ca8c3ee0ee..7225dffcc9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\swith\sthe\suserauth\sextension\sand\sno-authentication\sdatabases.\sRun\sthe\stests\sfor\sthis\sextension\sas\spart\sof\sthe\sDebug-One\smodule\sin\sreleasetest.tcl. -D 2015-11-26T15:51:55.157 +C The\sfirst\sargument\sto\sSQLITE_CONFIG_PAGECACHE,\sSQLITE_CONFIG_SCRATCH,\sand\nSQLITE_CONFIG_HEAP\smust\salways\sbe\sa\spointer. +D 2015-11-26T22:12:41.852 F Makefile.in d828db6afa6c1fa060d01e33e4674408df1942a1 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e928e68168df69b353300ac87c10105206653a03 @@ -331,7 +331,7 @@ F src/pager.h 87c4118a71ba3965184148b379a6d93179071091 F src/parse.y 23737e649c26ce327603799e57f5c2ff50e5e6ba F src/pcache.c 73895411fa6b7bd6f0091212feabbe833b358d23 F src/pcache.h 1ff11adce609ba7de139b6abfabaf9a2bac947b5 -F src/pcache1.c 902e1bc7bdaa81b40f8543407c5e2ac8ef4dc035 +F src/pcache1.c 46a110be31a8d9f9b41431733836822ca0dd27ab F src/pragma.c f3e7147299ca05ef4304a36f1fd6e002729c72c6 F src/pragma.h 3d94aebbebd2089899fecc01909bf2608b39507d F src/prepare.c 82e5db1013846a819f198336fed72c44c974e7b1 @@ -374,7 +374,7 @@ F src/test_intarray.c 870124b95ec4c645d4eb84f15efb7133528fb1a5 F src/test_intarray.h 9dc57417fb65bc7835cc18548852cc08cc062202 F src/test_journal.c 5360fbe1d1e4416ca36290562fd5a2e3f70f32aa F src/test_loadext.c a5251f956ab6af21e138dc1f9c0399394a510cb4 -F src/test_malloc.c 27d9e11b6e9d30267465d41ad81edbe24256408b +F src/test_malloc.c 8e1c2112fa4f543b46c990a8872f9e6d37938744 F src/test_multiplex.c 9fefd23f6cc3fa9bf0748a5e453167e7b9f193ce F src/test_multiplex.h c08e4e8f8651f0c5e0509b138ff4d5b43ed1f5d3 F src/test_mutex.c dbdfaff8580071f2212a0deae3325a93a737819c @@ -1405,7 +1405,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P eb180b4f04d412dcd0af138e2dd7f62fbb5ac439 -R f2567fd8ad211c2f6878e625db7a4000 -U dan -Z 033052b1e1d9566ff82c655910d67041 +P 8b15621952889b4ba53b2ea3171fef7ef0479ddb +R a3e84259ce6e6a067ea3262d31b1f32d +U drh +Z 19eaefd26a6af3441c1f68a49d2dd3d1 diff --git a/manifest.uuid b/manifest.uuid index ffee151b00..7899946004 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8b15621952889b4ba53b2ea3171fef7ef0479ddb \ No newline at end of file +5e14cadff09d7425c8e1cc5e817f2b0609e52a46 \ No newline at end of file diff --git a/src/pcache1.c b/src/pcache1.c index 256e53a579..3f56d025e2 100644 --- a/src/pcache1.c +++ b/src/pcache1.c @@ -65,7 +65,7 @@ ** that is allocated when the page cache is created. The size of the local ** bulk allocation can be adjusted using ** -** sqlite3_config(SQLITE_CONFIG_PAGECACHE, 0, 0, N). +** sqlite3_config(SQLITE_CONFIG_PAGECACHE, (void*)0, 0, N). ** ** If N is positive, then N pages worth of memory are allocated using a single ** sqlite3Malloc() call and that memory is used for the first N pages allocated. diff --git a/src/test_malloc.c b/src/test_malloc.c index 3ab177dcb7..a3ff9d205b 100644 --- a/src/test_malloc.c +++ b/src/test_malloc.c @@ -910,7 +910,7 @@ static int test_config_scratch( free(buf); if( sz<0 ){ buf = 0; - rc = sqlite3_config(SQLITE_CONFIG_SCRATCH, 0, 0, 0); + rc = sqlite3_config(SQLITE_CONFIG_SCRATCH, (void*)0, 0, 0); }else{ buf = malloc( sz*N + 1 ); rc = sqlite3_config(SQLITE_CONFIG_SCRATCH, buf, sz, N); @@ -957,7 +957,7 @@ static int test_config_pagecache( Tcl_SetObjResult(interp, pRes); if( sz<0 ){ - sqlite3_config(SQLITE_CONFIG_PAGECACHE, 0, 0, 0); + sqlite3_config(SQLITE_CONFIG_PAGECACHE, (void*)0, 0, 0); }else{ buf = malloc( sz*N ); sqlite3_config(SQLITE_CONFIG_PAGECACHE, buf, sz, N); From ecf0c275bb0533cf30db987983446604eeda51af Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 28 Nov 2015 17:38:22 +0000 Subject: [PATCH 31/53] Disable testing with SQLITE_USER_AUTHENTICATION as the makefiles are not set up to do that. FossilOrigin-Name: 14bbcdc64ecc21f47aed8935858788928ca63107 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/releasetest.tcl | 1 - 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 7225dffcc9..918524a62f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\sfirst\sargument\sto\sSQLITE_CONFIG_PAGECACHE,\sSQLITE_CONFIG_SCRATCH,\sand\nSQLITE_CONFIG_HEAP\smust\salways\sbe\sa\spointer. -D 2015-11-26T22:12:41.852 +C Disable\stesting\swith\sSQLITE_USER_AUTHENTICATION\sas\sthe\smakefiles\sare\snot\sset\nup\sto\sdo\sthat. +D 2015-11-28T17:38:22.785 F Makefile.in d828db6afa6c1fa060d01e33e4674408df1942a1 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e928e68168df69b353300ac87c10105206653a03 @@ -950,7 +950,7 @@ F test/rbu.test 168573d353cd0fd10196b87b0caa322c144ef736 F test/rdonly.test 64e2696c322e3538df0b1ed624e21f9a23ed9ff8 F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8 F test/reindex.test 44edd3966b474468b823d481eafef0c305022254 -F test/releasetest.tcl 7e1cda0cf50a41a0eb9f4de0ac8198d4db0423d3 +F test/releasetest.tcl 622f2381b217facdf429584a5c292cc1fc47e7c0 F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb F test/rollback.test 458fe73eb3ffdfdf9f6ba3e9b7350a6220414dea F test/rollback2.test fc14cf6d1a2b250d2735ef16124b971bce152f14 @@ -1405,7 +1405,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 8b15621952889b4ba53b2ea3171fef7ef0479ddb -R a3e84259ce6e6a067ea3262d31b1f32d +P 5e14cadff09d7425c8e1cc5e817f2b0609e52a46 +R 7798aa5b56dd0b98eb234cc9b845071b U drh -Z 19eaefd26a6af3441c1f68a49d2dd3d1 +Z b2af84eb02809218e4429ecabdfe0703 diff --git a/manifest.uuid b/manifest.uuid index 7899946004..4af52e1a7c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5e14cadff09d7425c8e1cc5e817f2b0609e52a46 \ No newline at end of file +14bbcdc64ecc21f47aed8935858788928ca63107 \ No newline at end of file diff --git a/test/releasetest.tcl b/test/releasetest.tcl index a6ddae530c..7f53fd1523 100644 --- a/test/releasetest.tcl +++ b/test/releasetest.tcl @@ -121,7 +121,6 @@ array set ::Configs [strip_comments { -DSQLITE_ENABLE_STAT4 -DSQLITE_ENABLE_HIDDEN_COLUMNS -DSQLITE_MAX_ATTACHED=125 - -DSQLITE_USER_AUTHENTICATION=1 } "Fast-One" { -O6 From 790f287c532a1803b71eb960b871cf84e875fe60 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 28 Nov 2015 18:06:36 +0000 Subject: [PATCH 32/53] Add the SQLITE_FCNTL_VFS_POINTER file control which obtains a pointer to the top-level VFS in use by a database connection. FossilOrigin-Name: 7c6a809e25138950f50554e1fb96e0b6ebbe0bd4 --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/main.c | 3 +++ src/pager.c | 2 +- src/pager.h | 2 +- src/shell.c | 15 +++++++++++++++ src/sqlite.h.in | 10 ++++++++++ 7 files changed, 41 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 918524a62f..6f5906d400 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Disable\stesting\swith\sSQLITE_USER_AUTHENTICATION\sas\sthe\smakefiles\sare\snot\sset\nup\sto\sdo\sthat. -D 2015-11-28T17:38:22.785 +C Add\sthe\sSQLITE_FCNTL_VFS_POINTER\sfile\scontrol\swhich\sobtains\sa\spointer\sto\nthe\stop-level\sVFS\sin\suse\sby\sa\sdatabase\sconnection. +D 2015-11-28T18:06:36.652 F Makefile.in d828db6afa6c1fa060d01e33e4674408df1942a1 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e928e68168df69b353300ac87c10105206653a03 @@ -304,7 +304,7 @@ F src/insert.c e1d20ae8979e25519c2670233718676bedcfedc9 F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e F src/loadext.c 18586e45a215325f15096821e9c082035d4fb810 -F src/main.c 91feb5c7e393ad8f0c434754114a3493c3b0617a +F src/main.c 3f2828fce1e45c3ad096c69eee1e96962c7281c5 F src/malloc.c 337bbe9c7d436ef9b7d06b5dd10bbfc8f3025972 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b @@ -326,8 +326,8 @@ F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c 8b35dc3b8b0a789052855cfc6eab6cd1d206fb81 F src/os_win.c 386fba30419e8458b13209781c2af5590eab2811 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca -F src/pager.c 18341e2b759b447cbc82fb9215d08d9c5864e92e -F src/pager.h 87c4118a71ba3965184148b379a6d93179071091 +F src/pager.c f92aacd5216d8815136c9e0190041783c602641a +F src/pager.h 9153c71a89dc82a5a77e485f3929792116c70aae F src/parse.y 23737e649c26ce327603799e57f5c2ff50e5e6ba F src/pcache.c 73895411fa6b7bd6f0091212feabbe833b358d23 F src/pcache.h 1ff11adce609ba7de139b6abfabaf9a2bac947b5 @@ -340,8 +340,8 @@ F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c f4c897ca76ca6d5e0b3f0499c627392ffe657c8e F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e F src/select.c e10586c750d87211caa8f4b239e2bfa6a2049e5b -F src/shell.c f0f59ea60ad297f671b7ae0fb957a736ad17c92c -F src/sqlite.h.in 1340aa105f53fbc6fd5b9918b54b64c64e910ee7 +F src/shell.c 2796237990d42e6a5a7beafee65ef70cc8767d21 +F src/sqlite.h.in 4334a48781a59d6cedd99d4033a1febf33e6bd08 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h 41ef50b0418a7c5ad1337bb80db5a7928dee764f F src/sqliteInt.h 64256d193a16a147d9f6317cc4e095fdd3e0a2e9 @@ -1405,7 +1405,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 5e14cadff09d7425c8e1cc5e817f2b0609e52a46 -R 7798aa5b56dd0b98eb234cc9b845071b +P 14bbcdc64ecc21f47aed8935858788928ca63107 +R 52e474e0d673136d0f27ca1064e30322 U drh -Z b2af84eb02809218e4429ecabdfe0703 +Z 722f1d3b58c0811ab92bc5ee1b6e0186 diff --git a/manifest.uuid b/manifest.uuid index 4af52e1a7c..1b5072eef9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -14bbcdc64ecc21f47aed8935858788928ca63107 \ No newline at end of file +7c6a809e25138950f50554e1fb96e0b6ebbe0bd4 \ No newline at end of file diff --git a/src/main.c b/src/main.c index 9078630892..2bcecdb78b 100644 --- a/src/main.c +++ b/src/main.c @@ -3420,6 +3420,9 @@ int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, void *pArg){ if( op==SQLITE_FCNTL_FILE_POINTER ){ *(sqlite3_file**)pArg = fd; rc = SQLITE_OK; + }else if( op==SQLITE_FCNTL_VFS_POINTER ){ + *(sqlite3_vfs**)pArg = sqlite3PagerVfs(pPager); + rc = SQLITE_OK; }else if( fd->pMethods ){ rc = sqlite3OsFileControl(fd, op, pArg); }else{ diff --git a/src/pager.c b/src/pager.c index f633a77927..bf74eac549 100644 --- a/src/pager.c +++ b/src/pager.c @@ -6679,7 +6679,7 @@ const char *sqlite3PagerFilename(Pager *pPager, int nullIfMemDb){ /* ** Return the VFS structure for the pager. */ -const sqlite3_vfs *sqlite3PagerVfs(Pager *pPager){ +sqlite3_vfs *sqlite3PagerVfs(Pager *pPager){ return pPager->pVfs; } diff --git a/src/pager.h b/src/pager.h index 22e73f4c76..cf9cda625d 100644 --- a/src/pager.h +++ b/src/pager.h @@ -182,7 +182,7 @@ u32 sqlite3PagerDataVersion(Pager*); #endif int sqlite3PagerMemUsed(Pager*); const char *sqlite3PagerFilename(Pager*, int); -const sqlite3_vfs *sqlite3PagerVfs(Pager*); +sqlite3_vfs *sqlite3PagerVfs(Pager*); sqlite3_file *sqlite3PagerFile(Pager*); const char *sqlite3PagerJournalname(Pager*); int sqlite3PagerNosync(Pager*); diff --git a/src/shell.c b/src/shell.c index d2f9ca500a..bcad59e806 100644 --- a/src/shell.c +++ b/src/shell.c @@ -1847,6 +1847,7 @@ static char zHelp[] = ".timeout MS Try opening locked tables for MS milliseconds\n" ".timer on|off Turn SQL timer on or off\n" ".trace FILE|off Output each SQL statement as it is run\n" + ".vfsinfo ?AUX? Information about the top-level VFS\n" ".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" @@ -4067,6 +4068,20 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3_libversion(), sqlite3_sourceid()); }else + if( c=='v' && strncmp(azArg[0], "vfsinfo", n)==0 ){ + const char *zDbName = nArg==2 ? azArg[1] : "main"; + sqlite3_vfs *pVfs; + if( p->db ){ + sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFS_POINTER, &pVfs); + if( pVfs ){ + fprintf(p->out, "vfs.zName = \"%s\"\n", pVfs->zName); + fprintf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion); + fprintf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile); + fprintf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname); + } + } + }else + if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){ const char *zDbName = nArg==2 ? azArg[1] : "main"; char *zVfsName = 0; diff --git a/src/sqlite.h.in b/src/sqlite.h.in index d340c05bf9..54ce42dee9 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -882,6 +882,15 @@ struct sqlite3_io_methods { ** pointer in case this file-control is not implemented. This file-control ** is intended for diagnostic use only. ** +**
  • [[SQLITE_FCNTL_VFS_POINTER]] +** ^The [SQLITE_FCNTL_VFS_POINTER] opcode finds a pointer to the top-level +** [VFSes] currently in use. ^(The argument X in +** sqlite3_file_control(db,SQLITE_FCNTL_VFS_POINTER,X) must be +** of type "[sqlite3_vfs] **". This opcodes will set *X +** to a pointer to the top-level VFS.^) +** ^When there are multiple VFS shims in the stack, this opcode finds the +** upper-most shim only. +** **
  • [[SQLITE_FCNTL_PRAGMA]] ** ^Whenever a [PRAGMA] statement is parsed, an [SQLITE_FCNTL_PRAGMA] ** file control is sent to the open [sqlite3_file] object corresponding @@ -1000,6 +1009,7 @@ struct sqlite3_io_methods { #define SQLITE_FCNTL_WAL_BLOCK 24 #define SQLITE_FCNTL_ZIPVFS 25 #define SQLITE_FCNTL_RBU 26 +#define SQLITE_FCNTL_VFS_POINTER 27 /* deprecated names */ #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE From b7e50ad55590416474a292e5233e2b2e8d4f46de Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 28 Nov 2015 21:49:53 +0000 Subject: [PATCH 33/53] Improvements to temporary file creation logic in the unix VFS. FossilOrigin-Name: d6e177fd09c83d46adc5b5d36e9a439aa5397450 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/os_unix.c | 16 +++++++--------- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index 6f5906d400..0d6185d0cc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sSQLITE_FCNTL_VFS_POINTER\sfile\scontrol\swhich\sobtains\sa\spointer\sto\nthe\stop-level\sVFS\sin\suse\sby\sa\sdatabase\sconnection. -D 2015-11-28T18:06:36.652 +C Improvements\sto\stemporary\sfile\screation\slogic\sin\sthe\sunix\sVFS. +D 2015-11-28T21:49:53.832 F Makefile.in d828db6afa6c1fa060d01e33e4674408df1942a1 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e928e68168df69b353300ac87c10105206653a03 @@ -323,7 +323,7 @@ F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8 F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf F src/os_common.h abdb9a191a367793268fe553d25bab894e986a0e F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa -F src/os_unix.c 8b35dc3b8b0a789052855cfc6eab6cd1d206fb81 +F src/os_unix.c 951ef130fd491531d03f4ab07ba4ac4df7861364 F src/os_win.c 386fba30419e8458b13209781c2af5590eab2811 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c f92aacd5216d8815136c9e0190041783c602641a @@ -1405,7 +1405,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 14bbcdc64ecc21f47aed8935858788928ca63107 -R 52e474e0d673136d0f27ca1064e30322 +P 7c6a809e25138950f50554e1fb96e0b6ebbe0bd4 +R ca93330e61d31cc358456a5d19f9fb0f U drh -Z 722f1d3b58c0811ab92bc5ee1b6e0186 +Z a3585e71cbbc630dcd21f2a2025e8592 diff --git a/manifest.uuid b/manifest.uuid index 1b5072eef9..09f90bf155 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7c6a809e25138950f50554e1fb96e0b6ebbe0bd4 \ No newline at end of file +d6e177fd09c83d46adc5b5d36e9a439aa5397450 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 43eec4c1f5..82224e18ff 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -5395,21 +5395,19 @@ static int fillInUnixFile( */ static const char *unixTempFileDir(void){ static const char *azDirs[] = { - 0, 0, 0, "/var/tmp", "/usr/tmp", "/tmp", - 0 /* List terminator */ + "." }; unsigned int i; struct stat buf; - const char *zDir = 0; + const char *zDir = sqlite3_temp_directory; - azDirs[0] = sqlite3_temp_directory; - if( !azDirs[1] ) azDirs[1] = getenv("SQLITE_TMPDIR"); - if( !azDirs[2] ) azDirs[2] = getenv("TMPDIR"); + if( !azDirs[0] ) azDirs[0] = getenv("SQLITE_TMPDIR"); + if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR"); for(i=0; i10 ) return SQLITE_ERROR; }while( osAccess(zBuf,0)==0 ); return SQLITE_OK; } @@ -5715,7 +5713,7 @@ static int unixOpen( }else if( !zName ){ /* If zName is NULL, the upper layer is requesting a temp file. */ assert(isDelete && !syncDir); - rc = unixGetTempname(MAX_PATHNAME+2, zTmpname); + rc = unixGetTempname(pVfs->mxPathname, zTmpname); if( rc!=SQLITE_OK ){ return rc; } From 06db66f989d10807c66b0bc64d9ecdbe142e6b24 Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 29 Nov 2015 21:46:19 +0000 Subject: [PATCH 34/53] Fix the sqldiff utility program so that it works for schemas that have tables with zero-length column names. FossilOrigin-Name: 64263ccb8f9835c615242de6e28db24f953422fa --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/sqldiff.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 0d6185d0cc..9c1ed45896 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvements\sto\stemporary\sfile\screation\slogic\sin\sthe\sunix\sVFS. -D 2015-11-28T21:49:53.832 +C Fix\sthe\ssqldiff\sutility\sprogram\sso\sthat\sit\sworks\sfor\sschemas\sthat\shave\ntables\swith\szero-length\scolumn\snames. +D 2015-11-29T21:46:19.675 F Makefile.in d828db6afa6c1fa060d01e33e4674408df1942a1 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e928e68168df69b353300ac87c10105206653a03 @@ -1394,7 +1394,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 7ce07da76b5e745783e703a834417d725b7d45fd F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c -F tool/sqldiff.c db1232df457fdd4cbf2a919a497fc44bb18fb933 +F tool/sqldiff.c 653db1a9294e0b34849c4504599c282a18d8b8c6 F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43 F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d F tool/symbols.sh fec58532668296d7c7dc48be9c87f75ccdb5814f @@ -1405,7 +1405,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 7c6a809e25138950f50554e1fb96e0b6ebbe0bd4 -R ca93330e61d31cc358456a5d19f9fb0f +P d6e177fd09c83d46adc5b5d36e9a439aa5397450 +R 6d96f803f67943fdc4d03a972304e707 U drh -Z a3585e71cbbc630dcd21f2a2025e8592 +Z e1ff9fd256204ded8600114936035e27 diff --git a/manifest.uuid b/manifest.uuid index 09f90bf155..8041987da4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d6e177fd09c83d46adc5b5d36e9a439aa5397450 \ No newline at end of file +64263ccb8f9835c615242de6e28db24f953422fa \ No newline at end of file diff --git a/tool/sqldiff.c b/tool/sqldiff.c index 0f406d8a03..56ff53ee25 100644 --- a/tool/sqldiff.c +++ b/tool/sqldiff.c @@ -155,6 +155,7 @@ static char *safeId(const char *zId){ "WITH", "WITHOUT", }; int lwr, upr, mid, c, i, x; + if( zId[0]==0 ) return sqlite3_mprintf("\"\""); for(i=x=0; (c = zId[i])!=0; i++){ if( !isalpha(c) && c!='_' ){ if( i>0 && isdigit(c) ){ From a8de1e1c90d45521dfdcf198b58ba95f1c12e9fa Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 30 Nov 2015 00:05:39 +0000 Subject: [PATCH 35/53] Simplifications to the locking logic in the unix-dotfile VFS. FossilOrigin-Name: 583813525888c7e106f3e8cb46c1a507006daee6 --- manifest | 12 +++---- manifest.uuid | 2 +- src/os_unix.c | 92 +++++++++++++++++++-------------------------------- 3 files changed, 41 insertions(+), 65 deletions(-) diff --git a/manifest b/manifest index 9c1ed45896..a4e23dcb0f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\ssqldiff\sutility\sprogram\sso\sthat\sit\sworks\sfor\sschemas\sthat\shave\ntables\swith\szero-length\scolumn\snames. -D 2015-11-29T21:46:19.675 +C Simplifications\sto\sthe\slocking\slogic\sin\sthe\sunix-dotfile\sVFS. +D 2015-11-30T00:05:39.456 F Makefile.in d828db6afa6c1fa060d01e33e4674408df1942a1 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e928e68168df69b353300ac87c10105206653a03 @@ -323,7 +323,7 @@ F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8 F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf F src/os_common.h abdb9a191a367793268fe553d25bab894e986a0e F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa -F src/os_unix.c 951ef130fd491531d03f4ab07ba4ac4df7861364 +F src/os_unix.c d4ca37d4fa3d65d2d553751f147e61276f5e06bf F src/os_win.c 386fba30419e8458b13209781c2af5590eab2811 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c f92aacd5216d8815136c9e0190041783c602641a @@ -1405,7 +1405,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P d6e177fd09c83d46adc5b5d36e9a439aa5397450 -R 6d96f803f67943fdc4d03a972304e707 +P 64263ccb8f9835c615242de6e28db24f953422fa +R dc472c39e1975a0a69aca2b2404edc3d U drh -Z e1ff9fd256204ded8600114936035e27 +Z 57f1db7fea7d09de3a215136ff8d3a37 diff --git a/manifest.uuid b/manifest.uuid index 8041987da4..edbe835481 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -64263ccb8f9835c615242de6e28db24f953422fa \ No newline at end of file +583813525888c7e106f3e8cb46c1a507006daee6 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 82224e18ff..eb20041ed5 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -1350,6 +1350,7 @@ static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){ SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); assert( pFile ); + assert( pFile->eFileLock<=SHARED_LOCK ); unixEnterMutex(); /* Because pFile->pInode is shared across threads */ /* Check if a thread in this process holds such a lock */ @@ -1760,9 +1761,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ if( unixFileLock(pFile, &lock)==(-1) ){ tErrno = errno; rc = SQLITE_IOERR_UNLOCK; - if( IS_LOCK_ERROR(rc) ){ - storeLastErrno(pFile, tErrno); - } + storeLastErrno(pFile, tErrno); goto end_unlock; } lock.l_type = F_RDLCK; @@ -1784,9 +1783,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ if( unixFileLock(pFile, &lock)==(-1) ){ tErrno = errno; rc = SQLITE_IOERR_UNLOCK; - if( IS_LOCK_ERROR(rc) ){ - storeLastErrno(pFile, tErrno); - } + storeLastErrno(pFile, tErrno); goto end_unlock; } }else @@ -2037,17 +2034,7 @@ static int dotlockCheckReservedLock(sqlite3_file *id, int *pResOut) { SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); assert( pFile ); - - /* Check if a thread in this process holds such a lock */ - if( pFile->eFileLock>SHARED_LOCK ){ - /* Either this connection or some other connection in the same process - ** holds a lock on the file. No need to check further. */ - reserved = 1; - }else{ - /* The lock is held if and only if the lockfile exists */ - const char *zLockFile = (const char*)pFile->lockingContext; - reserved = osAccess(zLockFile, 0)==0; - } + reserved = osAccess((const char*)pFile->lockingContext, 0)==0; OSTRACE(("TEST WR-LOCK %d %d %d (dotlock)\n", pFile->h, rc, reserved)); *pResOut = reserved; return rc; @@ -2109,7 +2096,7 @@ static int dotlockLock(sqlite3_file *id, int eFileLock) { rc = SQLITE_BUSY; } else { rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); - if( IS_LOCK_ERROR(rc) ){ + if( rc!=SQLITE_BUSY ){ storeLastErrno(pFile, tErrno); } } @@ -2156,14 +2143,12 @@ static int dotlockUnlock(sqlite3_file *id, int eFileLock) { /* To fully unlock the database, delete the lock file */ assert( eFileLock==NO_LOCK ); rc = osRmdir(zLockFile); - if( rc<0 && errno==ENOTDIR ) rc = osUnlink(zLockFile); if( rc<0 ){ int tErrno = errno; - rc = 0; - if( ENOENT != tErrno ){ + if( tErrno==ENOENT ){ + rc = SQLITE_OK; + }else{ rc = SQLITE_IOERR_UNLOCK; - } - if( IS_LOCK_ERROR(rc) ){ storeLastErrno(pFile, tErrno); } return rc; @@ -2176,14 +2161,11 @@ static int dotlockUnlock(sqlite3_file *id, int eFileLock) { ** Close a file. Make sure the lock has been released before closing. */ static int dotlockClose(sqlite3_file *id) { - int rc = SQLITE_OK; - if( id ){ - unixFile *pFile = (unixFile*)id; - dotlockUnlock(id, NO_LOCK); - sqlite3_free(pFile->lockingContext); - rc = closeUnixFile(id); - } - return rc; + unixFile *pFile = (unixFile*)id; + assert( id!=0 ); + dotlockUnlock(id, NO_LOCK); + sqlite3_free(pFile->lockingContext); + return closeUnixFile(id); } /****************** End of the dot-file lock implementation ******************* ******************************************************************************/ @@ -2249,10 +2231,8 @@ static int flockCheckReservedLock(sqlite3_file *id, int *pResOut){ int tErrno = errno; /* unlock failed with an error */ lrc = SQLITE_IOERR_UNLOCK; - if( IS_LOCK_ERROR(lrc) ){ - storeLastErrno(pFile, tErrno); - rc = lrc; - } + storeLastErrno(pFile, tErrno); + rc = lrc; } } else { int tErrno = errno; @@ -2385,12 +2365,9 @@ static int flockUnlock(sqlite3_file *id, int eFileLock) { ** Close a file. */ static int flockClose(sqlite3_file *id) { - int rc = SQLITE_OK; - if( id ){ - flockUnlock(id, NO_LOCK); - rc = closeUnixFile(id); - } - return rc; + assert( id!=0 ); + flockUnlock(id, NO_LOCK); + return closeUnixFile(id); } #endif /* SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORK */ @@ -3015,23 +2992,22 @@ static int afpUnlock(sqlite3_file *id, int eFileLock) { */ static int afpClose(sqlite3_file *id) { int rc = SQLITE_OK; - if( id ){ - unixFile *pFile = (unixFile*)id; - afpUnlock(id, NO_LOCK); - unixEnterMutex(); - if( pFile->pInode && pFile->pInode->nLock ){ - /* If there are outstanding locks, do not actually close the file just - ** yet because that would clear those locks. Instead, add the file - ** descriptor to pInode->aPending. It will be automatically closed when - ** the last lock is cleared. - */ - setPendingFd(pFile); - } - releaseInodeInfo(pFile); - sqlite3_free(pFile->lockingContext); - rc = closeUnixFile(id); - unixLeaveMutex(); + unixFile *pFile = (unixFile*)id; + assert( id!=0 ); + afpUnlock(id, NO_LOCK); + unixEnterMutex(); + if( pFile->pInode && pFile->pInode->nLock ){ + /* If there are outstanding locks, do not actually close the file just + ** yet because that would clear those locks. Instead, add the file + ** descriptor to pInode->aPending. It will be automatically closed when + ** the last lock is cleared. + */ + setPendingFd(pFile); } + releaseInodeInfo(pFile); + sqlite3_free(pFile->lockingContext); + rc = closeUnixFile(id); + unixLeaveMutex(); return rc; } @@ -7374,7 +7350,7 @@ static int proxyUnlock(sqlite3_file *id, int eFileLock) { ** Close a file that uses proxy locks. */ static int proxyClose(sqlite3_file *id) { - if( id ){ + if( ALWAYS(id) ){ unixFile *pFile = (unixFile*)id; proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; unixFile *lockProxy = pCtx->lockProxy; From f8b0be48d157d30a0f5aed78ab732b3a83223ded Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 30 Nov 2015 19:15:25 +0000 Subject: [PATCH 36/53] Fix the threadtest3 test program so that it works with VFSes that omit the xCurrentTime() method and supply only xCurrentTimeInt64(). FossilOrigin-Name: 3b155855f3d5918f1df7dbd19783215b3da0ca3e --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/threadtest3.c | 36 ++++++++++++++++++------------------ 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/manifest b/manifest index f39be554da..5201b9519b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s"colUsed"\sfield\sto\sthe\ssqlite3_index_info\sstructure\spassed\sto\svirtual\stable\sxBestIndex\smethods.\sTo\sindicate\sthe\ssubset\sof\sthe\svirtual\stable\scolumns\sthat\smay\sbe\srequired\sby\sthe\scurrent\sscan. -D 2015-11-30T12:01:37.135 +C Fix\sthe\sthreadtest3\stest\sprogram\sso\sthat\sit\sworks\swith\sVFSes\sthat\somit\sthe\nxCurrentTime()\smethod\sand\ssupply\sonly\sxCurrentTimeInt64(). +D 2015-11-30T19:15:25.436 F Makefile.in d828db6afa6c1fa060d01e33e4674408df1942a1 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e928e68168df69b353300ac87c10105206653a03 @@ -1072,7 +1072,7 @@ F test/thread2.test f35d2106452b77523b3a2b7d1dcde2e5ee8f9e46 F test/thread_common.tcl 334639cadcb9f912bf82aa73f49efd5282e6cadd F test/threadtest1.c 6029d9c5567db28e6dc908a0c63099c3ba6c383b F test/threadtest2.c a70a8e94bef23339d34226eb9521015ef99f4df8 -F test/threadtest3.c 9ab4b168681c3a6f70f6c833ba08e0d48dd4af9b +F test/threadtest3.c 0707c28e0954acbef654f91675e14f3573cf9a10 F test/threadtest4.c c1e67136ceb6c7ec8184e56ac61db28f96bd2925 F test/tkt-02a8e81d44.test 6c80d9c7514e2a42d4918bf87bf6bc54f379110c F test/tkt-26ff0c2d1e.test 888324e751512972c6e0d1a09df740d8f5aaf660 @@ -1406,7 +1406,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 583813525888c7e106f3e8cb46c1a507006daee6 116b206494eb8ba963c7c5acfbf9e7b6db11c79c -R 85fc84cc9bc3e1532ec1e735dc703c3b -U dan -Z eb992ed0e070d727cd79b36741d8ea82 +P 47f10b7e5d8c1d965df891990090623444933cc9 +R 585e8fe5d4364350ebf759c316009b08 +U drh +Z a830d371ea8bc3ea09f7879f209590a2 diff --git a/manifest.uuid b/manifest.uuid index 29b821c451..a098f55953 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -47f10b7e5d8c1d965df891990090623444933cc9 \ No newline at end of file +3b155855f3d5918f1df7dbd19783215b3da0ca3e \ No newline at end of file diff --git a/test/threadtest3.c b/test/threadtest3.c index 25caeb89f9..a3fcae28cc 100644 --- a/test/threadtest3.c +++ b/test/threadtest3.c @@ -868,22 +868,28 @@ static void filecopy_x( ** Used by setstoptime() and timetostop(). */ static double timelimit = 0.0; -static sqlite3_vfs *pTimelimitVfs = 0; + +static double currentTime(void){ + double t; + static sqlite3_vfs *pTimelimitVfs = 0; + if( pTimelimitVfs==0 ) pTimelimitVfs = sqlite3_vfs_find(0); + if( pTimelimitVfs->iVersion>=1 && pTimelimitVfs->xCurrentTimeInt64!=0 ){ + sqlite3_int64 tm; + pTimelimitVfs->xCurrentTimeInt64(pTimelimitVfs, &tm); + t = tm/86400000.0; + }else{ + pTimelimitVfs->xCurrentTime(pTimelimitVfs, &t); + } + return t; +} static void setstoptime_x( Error *pErr, /* IN/OUT: Error code */ int nMs /* Milliseconds until "stop time" */ ){ if( pErr->rc==SQLITE_OK ){ - double t; - int rc; - pTimelimitVfs = sqlite3_vfs_find(0); - rc = pTimelimitVfs->xCurrentTime(pTimelimitVfs, &t); - if( rc!=SQLITE_OK ){ - pErr->rc = rc; - }else{ - timelimit = t + ((double)nMs)/(1000.0*60.0*60.0*24.0); - } + double t = currentTime(); + timelimit = t + ((double)nMs)/(1000.0*60.0*60.0*24.0); } } @@ -892,14 +898,8 @@ static int timetostop_x( ){ int ret = 1; if( pErr->rc==SQLITE_OK ){ - double t; - int rc; - rc = pTimelimitVfs->xCurrentTime(pTimelimitVfs, &t); - if( rc!=SQLITE_OK ){ - pErr->rc = rc; - }else{ - ret = (t >= timelimit); - } + double t = currentTime(); + ret = (t >= timelimit); } return ret; } From 40fe8d31f54a823da92a85f9aa43fde92091fca5 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 30 Nov 2015 20:36:26 +0000 Subject: [PATCH 37/53] The EOVERFLOW errors from fstat() is not possible unless SQLite has been compiled with SQLITE_DISABLE_LFS. FossilOrigin-Name: 8cfb7a50bb70ba1e021c1d12d31563e98a20d291 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/os_unix.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 5201b9519b..c54175987a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sthreadtest3\stest\sprogram\sso\sthat\sit\sworks\swith\sVFSes\sthat\somit\sthe\nxCurrentTime()\smethod\sand\ssupply\sonly\sxCurrentTimeInt64(). -D 2015-11-30T19:15:25.436 +C The\sEOVERFLOW\serrors\sfrom\sfstat()\sis\snot\spossible\sunless\sSQLite\shas\sbeen\ncompiled\swith\sSQLITE_DISABLE_LFS. +D 2015-11-30T20:36:26.173 F Makefile.in d828db6afa6c1fa060d01e33e4674408df1942a1 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e928e68168df69b353300ac87c10105206653a03 @@ -323,7 +323,7 @@ F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8 F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf F src/os_common.h abdb9a191a367793268fe553d25bab894e986a0e F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa -F src/os_unix.c d4ca37d4fa3d65d2d553751f147e61276f5e06bf +F src/os_unix.c 641b7da6960b5bfa2120a97464578da436f4876c F src/os_win.c 386fba30419e8458b13209781c2af5590eab2811 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c f92aacd5216d8815136c9e0190041783c602641a @@ -1406,7 +1406,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 47f10b7e5d8c1d965df891990090623444933cc9 -R 585e8fe5d4364350ebf759c316009b08 +P 3b155855f3d5918f1df7dbd19783215b3da0ca3e +R 8c60b47a7d3bee2b87d7070795b628ee U drh -Z a830d371ea8bc3ea09f7879f209590a2 +Z 055a22d7d501db707cd4b91440df8d3a diff --git a/manifest.uuid b/manifest.uuid index a098f55953..9535da50f6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3b155855f3d5918f1df7dbd19783215b3da0ca3e \ No newline at end of file +8cfb7a50bb70ba1e021c1d12d31563e98a20d291 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index eb20041ed5..49f6563b17 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -1229,7 +1229,7 @@ static int findInodeInfo( rc = osFstat(fd, &statbuf); if( rc!=0 ){ storeLastErrno(pFile, errno); -#ifdef EOVERFLOW +#if defined(EOVERFLOW) && defined(SQLITE_DISABLE_LFS) if( pFile->lastErrno==EOVERFLOW ) return SQLITE_NOLFS; #endif return SQLITE_IOERR; From 025d2f7ad8d29f25c111b3abb668528b7389570a Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 30 Nov 2015 22:22:23 +0000 Subject: [PATCH 38/53] Fix a problem in xFullPathname for the unix VFS. The problem was found by Kostya Serebryany using libFuzzer. FossilOrigin-Name: bb1e2c4df0b81327923f121dd6c002845486a314 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/os_unix.c | 4 +++- test/symlink.test | 10 ++++++++++ 4 files changed, 21 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index c54175987a..882023698b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\sEOVERFLOW\serrors\sfrom\sfstat()\sis\snot\spossible\sunless\sSQLite\shas\sbeen\ncompiled\swith\sSQLITE_DISABLE_LFS. -D 2015-11-30T20:36:26.173 +C Fix\sa\sproblem\sin\sxFullPathname\sfor\sthe\sunix\sVFS.\s\sThe\sproblem\swas\sfound\sby\nKostya\sSerebryany\susing\slibFuzzer. +D 2015-11-30T22:22:23.455 F Makefile.in d828db6afa6c1fa060d01e33e4674408df1942a1 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e928e68168df69b353300ac87c10105206653a03 @@ -323,7 +323,7 @@ F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8 F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf F src/os_common.h abdb9a191a367793268fe553d25bab894e986a0e F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa -F src/os_unix.c 641b7da6960b5bfa2120a97464578da436f4876c +F src/os_unix.c 88d9fd1da4f3d26c64ef954fb32cce583605eba0 F src/os_win.c 386fba30419e8458b13209781c2af5590eab2811 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c f92aacd5216d8815136c9e0190041783c602641a @@ -1049,7 +1049,7 @@ F test/subselect.test d24fd8757daf97dafd2e889c73ea4c4272dcf4e4 F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a F test/subtype1.test 7fe09496352f97053af1437150751be2d0a0cae8 F test/superlock.test 1cde669f68d2dd37d6c9bd35eee1d95491ae3fc2 -F test/symlink.test 2513f7c030df0f435c6415687ba8b739f3d312df +F test/symlink.test cbf6cb8c6c4b63a39e9f0f6b0d5c99e249dbc102 F test/sync.test a34cd43e98b7fb84eabbf38f7ed8f7349b3f3d85 F test/syscall.test 2aa9e111b79fb385681ff8940124def6f8faab87 F test/sysfault.test fa776e60bf46bdd3ae69f0b73e46ee3977a58ae6 @@ -1406,7 +1406,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 3b155855f3d5918f1df7dbd19783215b3da0ca3e -R 8c60b47a7d3bee2b87d7070795b628ee +P 8cfb7a50bb70ba1e021c1d12d31563e98a20d291 +R f79c0be9f023b27dbe04efacb9601efe U drh -Z 055a22d7d501db707cd4b91440df8d3a +Z cf313c6c46c31a94ce13dac473c0da9d diff --git a/manifest.uuid b/manifest.uuid index 9535da50f6..eb072bebe4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8cfb7a50bb70ba1e021c1d12d31563e98a20d291 \ No newline at end of file +bb1e2c4df0b81327923f121dd6c002845486a314 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 49f6563b17..e5103856bd 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -5981,7 +5981,9 @@ static int unixFullPathname( ** truncated to make it fit. This is Ok, as SQLite refuses to open any ** file for which this function returns a full path larger than (nOut-8) ** bytes in size. */ - if( zOut[0]!='/' ){ + testcase( nByte==nOut-5 ); + testcase( nByte==nOut-4 ); + if( zOut[0]!='/' && nByte Date: Mon, 30 Nov 2015 22:52:14 +0000 Subject: [PATCH 39/53] Add the SQLITE_PRINTF_PRECISION_LIMIT compile-time option. FossilOrigin-Name: ecad75d69e0d5c83dd3584d363e557e84b65f7f2 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/printf.c | 14 ++++++++++++++ 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 882023698b..135ade46f1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\sin\sxFullPathname\sfor\sthe\sunix\sVFS.\s\sThe\sproblem\swas\sfound\sby\nKostya\sSerebryany\susing\slibFuzzer. -D 2015-11-30T22:22:23.455 +C Add\sthe\sSQLITE_PRINTF_PRECISION_LIMIT\scompile-time\soption. +D 2015-11-30T22:52:14.011 F Makefile.in d828db6afa6c1fa060d01e33e4674408df1942a1 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e928e68168df69b353300ac87c10105206653a03 @@ -335,7 +335,7 @@ F src/pcache1.c 46a110be31a8d9f9b41431733836822ca0dd27ab F src/pragma.c f3e7147299ca05ef4304a36f1fd6e002729c72c6 F src/pragma.h 3d94aebbebd2089899fecc01909bf2608b39507d F src/prepare.c 82e5db1013846a819f198336fed72c44c974e7b1 -F src/printf.c f8fc8f04e75b1e983ef2793c27ec7a43b287e94a +F src/printf.c ca05561795ad6c2fa47acdd007702586282f7feb F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c f4c897ca76ca6d5e0b3f0499c627392ffe657c8e F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e @@ -1406,7 +1406,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 8cfb7a50bb70ba1e021c1d12d31563e98a20d291 -R f79c0be9f023b27dbe04efacb9601efe +P bb1e2c4df0b81327923f121dd6c002845486a314 +R d3b18adc3009f6c25adcd36c4f052eab U drh -Z cf313c6c46c31a94ce13dac473c0da9d +Z 7ba0fba490eff520c14229730eb61dd8 diff --git a/manifest.uuid b/manifest.uuid index eb072bebe4..3749928415 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bb1e2c4df0b81327923f121dd6c002845486a314 \ No newline at end of file +ecad75d69e0d5c83dd3584d363e557e84b65f7f2 \ No newline at end of file diff --git a/src/printf.c b/src/printf.c index 9caeef8ff7..88bb82e3e3 100644 --- a/src/printf.c +++ b/src/printf.c @@ -270,6 +270,12 @@ void sqlite3VXPrintf( testcase( wx>0x7fffffff ); width = wx & 0x7fffffff; } + assert( width>=0 ); +#ifdef SQLITE_PRINTF_PRECISION_LIMIT + if( width>SQLITE_PRINTF_PRECISION_LIMIT ){ + width = SQLITE_PRINTF_PRECISION_LIMIT; + } +#endif /* Get the precision */ if( c=='.' ){ @@ -296,6 +302,14 @@ void sqlite3VXPrintf( }else{ precision = -1; } + assert( precision>=(-1) ); +#ifdef SQLITE_PRINTF_PRECISION_LIMIT + if( precision>SQLITE_PRINTF_PRECISION_LIMIT ){ + precision = SQLITE_PRINTF_PRECISION_LIMIT; + } +#endif + + /* Get the conversion type modifier */ if( c=='l' ){ flag_long = 1; From 92af1ebc75d8077c4885d02436e3630d7e91d473 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Mon, 30 Nov 2015 23:29:07 +0000 Subject: [PATCH 40/53] Add experimental support for the 'test_fs' test module on Win32. FossilOrigin-Name: f3ffb3aeea95712e92919fd5071741327add9643 --- Makefile.in | 1 + Makefile.msc | 1 + main.mk | 1 + manifest | 27 +++++--- manifest.uuid | 2 +- src/test_fs.c | 51 +++++++++++--- src/test_windirent.c | 157 +++++++++++++++++++++++++++++++++++++++++++ src/test_windirent.h | 105 +++++++++++++++++++++++++++++ test/vtabH.test | 38 +++++++++-- 9 files changed, 358 insertions(+), 25 deletions(-) create mode 100644 src/test_windirent.c create mode 100644 src/test_windirent.h diff --git a/Makefile.in b/Makefile.in index eaf021b412..f8766ac8f7 100644 --- a/Makefile.in +++ b/Makefile.in @@ -402,6 +402,7 @@ TESTSRC = \ $(TOP)/src/test_tclvar.c \ $(TOP)/src/test_thread.c \ $(TOP)/src/test_vfs.c \ + $(TOP)/src/test_windirent.c \ $(TOP)/src/test_wsd.c \ $(TOP)/ext/fts3/fts3_term.c \ $(TOP)/ext/fts3/fts3_test.c \ diff --git a/Makefile.msc b/Makefile.msc index 57fba11c53..5c72001532 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -1071,6 +1071,7 @@ TESTSRC = \ $(TOP)\src\test_tclvar.c \ $(TOP)\src\test_thread.c \ $(TOP)\src\test_vfs.c \ + $(TOP)\src\test_windirent.c \ $(TOP)\src\test_wsd.c \ $(TOP)\ext\fts3\fts3_term.c \ $(TOP)\ext\fts3\fts3_test.c \ diff --git a/main.mk b/main.mk index 838e0753d9..f3a37dc194 100644 --- a/main.mk +++ b/main.mk @@ -312,6 +312,7 @@ TESTSRC = \ $(TOP)/src/test_tclvar.c \ $(TOP)/src/test_thread.c \ $(TOP)/src/test_vfs.c \ + $(TOP)/src/test_windirent.c \ $(TOP)/src/test_wsd.c # Extensions to be statically loaded. diff --git a/manifest b/manifest index 135ade46f1..885c09aea0 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C Add\sthe\sSQLITE_PRINTF_PRECISION_LIMIT\scompile-time\soption. -D 2015-11-30T22:52:14.011 -F Makefile.in d828db6afa6c1fa060d01e33e4674408df1942a1 +C Add\sexperimental\ssupport\sfor\sthe\s'test_fs'\stest\smodule\son\sWin32. +D 2015-11-30T23:29:07.971 +F Makefile.in 23d9a63484a383fc64951b25ef44067930f98dc6 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc e928e68168df69b353300ac87c10105206653a03 +F Makefile.msc e8fdca1cb89a1b58b5f4d3a130ea9a3d28cb314d F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F VERSION 8b9d3ac6f1962f94e06ba05462422a544f9c4e36 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -263,7 +263,7 @@ F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 -F main.mk ae99be5eb22933b1ecf80f94d41d25a3ea80aaf3 +F main.mk 9001039f432baeba1074e2d1885f3dfd572b8636 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 @@ -366,7 +366,7 @@ F src/test_btree.c 2e9978eca99a9a4bfa8cae949efb00886860a64f F src/test_config.c f2824de39f59d8d621e2d6ec5cc67006d000b2eb F src/test_demovfs.c 0de72c2c89551629f58486fde5734b7d90758852 F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc -F src/test_fs.c 9a56a587ce1db424af430d5ff650b5736b498238 +F src/test_fs.c aab47ac456316502faa265daadf9ac832fea12b9 F src/test_func.c 0d9c25956152adefee8881c6fadc8354793764d0 F src/test_hexio.c abfdecb6fa58c354623978efceb088ca18e379cd F src/test_init.c 66b33120ffe9cd853b5a905ec850d51151337b32 @@ -393,6 +393,8 @@ F src/test_tclvar.c d86412527da65468ee6fa1b8607c65d0af736bc4 F src/test_thread.c af391ec03d23486dffbcc250b7e58e073f172af9 F src/test_vfs.c 3b65d42e18b262805716bd96178c81da8f2d9283 F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698 +F src/test_windirent.c 8f5fada630348558d5745b334702f301da1ffc61 +F src/test_windirent.h b12055cab6227f7be10f5c19296f67c60cc5e2a5 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c bbfb74450643cb5372a43ad4f6cffd7e9dfcecb0 F src/tokenize.c 5606871a377f390af7040ec3c12e0d183512d785 @@ -1274,7 +1276,7 @@ F test/vtabC.test 4528f459a13136f982e75614d120aef165f17292 F test/vtabD.test 05b3f1d77117271671089e48719524b676842e96 F test/vtabE.test d5024aa42754962f6bb0afd261681686488e7afe F test/vtabF.test fd5ad376f5a34fe0891df1f3cddb4fe7c3eb077e -F test/vtabH.test 186f118d6a4dd25fdb36adfd471993003f83790c +F test/vtabH.test 2803a8773d1017ac93bbec6900fc7c35bb56c1c3 F test/vtabI.test 751b07636700dbdea328e4265b6077ccd6811a3f F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5 F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8 @@ -1406,7 +1408,10 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P bb1e2c4df0b81327923f121dd6c002845486a314 -R d3b18adc3009f6c25adcd36c4f052eab -U drh -Z 7ba0fba490eff520c14229730eb61dd8 +P ecad75d69e0d5c83dd3584d363e557e84b65f7f2 +R b2c7ca19fb46e255338240c0ac77a2e4 +T *branch * testFsWin32 +T *sym-testFsWin32 * +T -sym-trunk * +U mistachkin +Z b75cf97131a1f035edfb9c37c590fcf6 diff --git a/manifest.uuid b/manifest.uuid index 3749928415..2659aede24 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ecad75d69e0d5c83dd3584d363e557e84b65f7f2 \ No newline at end of file +f3ffb3aeea95712e92919fd5071741327add9643 \ No newline at end of file diff --git a/src/test_fs.c b/src/test_fs.c index 213b65689a..de332fa2f5 100644 --- a/src/test_fs.c +++ b/src/test_fs.c @@ -73,9 +73,16 @@ #if SQLITE_OS_UNIX # include # include +# ifndef DIRENT +# define DIRENT dirent +# endif #endif #if SQLITE_OS_WIN # include +# include "test_windirent.h" +# ifndef S_ISREG +# define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) +# endif #endif #ifndef SQLITE_OMIT_VIRTUALTABLE @@ -116,7 +123,7 @@ struct FsdirCsr { char *zDir; /* Buffer containing directory scanned */ DIR *pDir; /* Open directory */ sqlite3_int64 iRowid; - struct dirent entry; /* Current entry */ + struct DIRENT entry; /* Current entry */ }; /* @@ -220,7 +227,7 @@ static int fsdirNext(sqlite3_vtab_cursor *cur){ FsdirCsr *pCsr = (FsdirCsr*)cur; if( pCsr->pDir ){ - struct dirent *pRes = 0; + struct DIRENT *pRes = 0; readdir_r(pCsr->pDir, &pCsr->entry, &pRes); if( pRes==0 ){ closedir(pCsr->pDir); @@ -461,15 +468,34 @@ static int fstreeFilter( int rc; const char *zSql = "WITH r(d) AS (" -" SELECT CASE WHEN dir='/' THEN '' ELSE dir END || '/' || name " -" FROM fsdir WHERE dir=? AND name NOT LIKE '.%'" +" SELECT CASE WHEN dir=?2 THEN ?3 ELSE dir END || '/' || name " +" FROM fsdir WHERE dir=?1 AND name NOT LIKE '.%'" " UNION ALL" " SELECT dir || '/' || name FROM r, fsdir WHERE dir=d AND name NOT LIKE '.%'" ") SELECT d FROM r;"; - const char *zDir = "/"; - int nDir = 1; - char aWild[2] = {'\0', '\0' }; + char *zRoot; + int nRoot; + char *zPrefix; + int nPrefix; + const char *zDir; + int nDir; + char aWild[2] = { '\0', '\0' }; + +#if SQLITE_OS_WIN + zRoot = sqlite3_mprintf("%s%c", getenv("SystemDrive"), '/'); + nRoot = strlen(zRoot); + zPrefix = sqlite3_mprintf("%s", getenv("SystemDrive")); + nPrefix = strlen(zPrefix); +#else + zRoot = "/"; + nRoot = 1; + zPrefix = ""; + nPrefix = 0; +#endif + + zDir = zRoot; + nDir = nRoot; fstreeCloseFd(pCsr); sqlite3_finalize(pCsr->pStmt); @@ -490,9 +516,9 @@ static int fstreeFilter( break; } - if( zQuery[0]=='/' ){ + if( sqlite3_strnicmp(zQuery, zPrefix, nPrefix)==0 ){ int i; - for(i=1; zQuery[i]; i++){ + for(i=nPrefix; zQuery[i]; i++){ if( zQuery[i]==aWild[0] || zQuery[i]==aWild[1] ) break; if( zQuery[i]=='/' ) nDir = i; } @@ -501,6 +527,13 @@ static int fstreeFilter( } sqlite3_bind_text(pCsr->pStmt, 1, zDir, nDir, SQLITE_TRANSIENT); + sqlite3_bind_text(pCsr->pStmt, 2, zRoot, nRoot, SQLITE_TRANSIENT); + sqlite3_bind_text(pCsr->pStmt, 3, zPrefix, nPrefix, SQLITE_TRANSIENT); + +#if SQLITE_OS_WIN + sqlite3_free(zPrefix); + sqlite3_free(zRoot); +#endif return fstreeNext(pVtabCursor); } diff --git a/src/test_windirent.c b/src/test_windirent.c new file mode 100644 index 0000000000..11d7dc07d0 --- /dev/null +++ b/src/test_windirent.c @@ -0,0 +1,157 @@ +/* +** 2015 November 30 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains code to implement most of the opendir() family of +** POSIX functions on Win32 using the MSVCRT. +*/ + +#if defined(_WIN32) && defined(_MSC_VER) + +#include "test_windirent.h" + +/* +** Implementation of the POSIX opendir() function using the MSVCRT. +*/ +LPDIR opendir( + const char *dirname +){ + struct _finddata_t data; + LPDIR dirp = (LPDIR)sqlite3_malloc(sizeof(DIR)); + SIZE_T namesize = sizeof(data.name) / sizeof(data.name[0]); + + if( dirp==NULL ) return NULL; + memset(dirp, 0, sizeof(DIR)); + + /* TODO: Remove this if Unix-style root paths are not used. */ + if( sqlite3_stricmp(dirname, "/")==0 ){ + dirname = getenv("SystemDrive"); + } + + _snprintf(data.name, namesize, "%s\\*", dirname); + dirp->d_handle = _findfirst(data.name, &data); + + if( dirp->d_handle==BAD_INTPTR_T ){ + closedir(dirp); + return NULL; + } + + /* TODO: Remove this block to allow hidden and system files. */ + if( data.attrib&_A_HIDDEN || data.attrib&_A_SYSTEM ){ + if( _findnext(dirp->d_handle, &data)==-1 ){ + closedir(dirp); + return NULL; + } + } + + dirp->d_first.d_attributes = data.attrib; + strncpy(dirp->d_first.d_name, data.name, NAME_MAX); + dirp->d_first.d_name[NAME_MAX] = '\0'; + + return dirp; +} + +/* +** Implementation of the POSIX readdir() function using the MSVCRT. +*/ +LPDIRENT readdir( + LPDIR dirp +){ + struct _finddata_t data; + + if( dirp==NULL ) return NULL; + + if( dirp->d_first.d_ino==0 ){ + dirp->d_first.d_ino++; + dirp->d_next.d_ino++; + + return &dirp->d_first; + } + +next: + + if( _findnext(dirp->d_handle, &data)==-1 ) return NULL; + + /* TODO: Remove this block to allow hidden and system files. */ + if( data.attrib&_A_HIDDEN ) goto next; + if( data.attrib&_A_SYSTEM ) goto next; + + dirp->d_next.d_ino++; + dirp->d_next.d_attributes = data.attrib; + strncpy(dirp->d_next.d_name, data.name, NAME_MAX); + dirp->d_next.d_name[NAME_MAX] = '\0'; + + return &dirp->d_next; +} + +/* +** Implementation of the POSIX readdir_r() function using the MSVCRT. +*/ +INT readdir_r( + LPDIR dirp, + LPDIRENT entry, + LPDIRENT *result +){ + struct _finddata_t data; + + if( dirp==NULL ) return EBADF; + + if( dirp->d_first.d_ino==0 ){ + dirp->d_first.d_ino++; + dirp->d_next.d_ino++; + + entry->d_ino = dirp->d_first.d_ino; + entry->d_attributes = dirp->d_first.d_attributes; + strncpy(entry->d_name, dirp->d_first.d_name, NAME_MAX); + entry->d_name[NAME_MAX] = '\0'; + + *result = entry; + return 0; + } + +next: + + if( _findnext(dirp->d_handle, &data)==-1 ){ + *result = NULL; + return ENOENT; + } + + /* TODO: Remove this block to allow hidden and system files. */ + if( data.attrib&_A_HIDDEN ) goto next; + if( data.attrib&_A_SYSTEM ) goto next; + + entry->d_ino = (ino_t)-1; /* not available */ + entry->d_attributes = data.attrib; + strncpy(entry->d_name, data.name, NAME_MAX); + entry->d_name[NAME_MAX] = '\0'; + + *result = entry; + return 0; +} + +/* +** Implementation of the POSIX closedir() function using the MSVCRT. +*/ +INT closedir( + LPDIR dirp +){ + INT result = 0; + + if( dirp==NULL ) return EINVAL; + + if( dirp->d_handle!=NULL_INTPTR_T && dirp->d_handle!=BAD_INTPTR_T ){ + result = _findclose(dirp->d_handle); + } + + sqlite3_free(dirp); + return result; +} + +#endif /* defined(WIN32) && defined(_MSC_VER) */ diff --git a/src/test_windirent.h b/src/test_windirent.h new file mode 100644 index 0000000000..0b8d1a7b51 --- /dev/null +++ b/src/test_windirent.h @@ -0,0 +1,105 @@ +/* +** 2015 November 30 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains declarations for most of the opendir() family of +** POSIX functions on Win32 using the MSVCRT. +*/ + +#if defined(_WIN32) && defined(_MSC_VER) + +/* +** We need several data types from the Windows SDK header. +*/ + +#define WIN32_LEAN_AND_MEAN +#include "windows.h" + +/* +** We need several support functions from the SQLite core. +*/ + +#include "sqlite3.h" + +/* +** We need several things from the ANSI and MSVCRT headers. +*/ + +#include +#include +#include +#include +#include + +/* +** We may need to provide the "ino_t" type. +*/ + +#ifndef INO_T_DEFINED + #define INO_T_DEFINED + typedef unsigned short ino_t; +#endif + +/* +** We need to define "NAME_MAX" if it was not present in "limits.h". +*/ + +#ifndef NAME_MAX +# ifdef FILENAME_MAX +# define NAME_MAX (FILENAME_MAX) +# else +# define NAME_MAX (260) +# endif +#endif + +/* +** We need to define "NULL_INTPTR_T" and "BAD_INTPTR_T". +*/ + +#ifndef NULL_INTPTR_T +# define NULL_INTPTR_T ((intptr_t)(0)) +#endif + +#ifndef BAD_INTPTR_T +# define BAD_INTPTR_T ((intptr_t)(-1)) +#endif + +/* +** We need to provide the necessary structures and related types. +*/ + +typedef struct DIRENT DIRENT; +typedef struct DIR DIR; +typedef DIRENT *LPDIRENT; +typedef DIR *LPDIR; + +struct DIRENT { + ino_t d_ino; /* Sequence number, do not use. */ + unsigned d_attributes; /* Win32 file attributes. */ + char d_name[NAME_MAX + 1]; /* Name within the directory. */ +}; + +struct DIR { + intptr_t d_handle; /* Value returned by "_findfirst". */ + DIRENT d_first; /* DIRENT constructed based on "_findfirst". */ + DIRENT d_next; /* DIRENT constructed based on "_findnext". */ +}; + +/* +** Finally, we can provide the function prototypes for the opendir(), +** readdir(), readdir_r(), and closedir() POSIX functions. +*/ + +extern LPDIR opendir(const char *dirname); +extern LPDIRENT readdir(LPDIR dirp); +extern INT readdir_r(LPDIR dirp, LPDIRENT entry, LPDIRENT *result); +extern INT closedir(LPDIR dirp); + +#endif /* defined(WIN32) && defined(_MSC_VER) */ diff --git a/test/vtabH.test b/test/vtabH.test index 7216677d2a..6034d95fa1 100644 --- a/test/vtabH.test +++ b/test/vtabH.test @@ -108,7 +108,7 @@ foreach ::tclvar_set_omit {0 1} { #------------------------------------------------------------------------- # -if {$::tcl_platform(platform)=="unix"} { +if {1} { reset_db register_fs_module db do_execsql_test 3.0 { @@ -116,11 +116,41 @@ if {$::tcl_platform(platform)=="unix"} { SELECT name FROM fsdir WHERE dir = '.' AND name = '.' } {test.db .} + proc list_root_files {} { + if {$::tcl_platform(platform) eq "windows"} { + set res [list] + foreach name [glob -directory $::env(SystemDrive)/ -- *] { + if {[string index [file tail $name] 0] eq "."} continue + lappend res $name + } + return $res + } else { + return [exec ls -U /] + } + } + + proc list_files { pattern } { + if {$::tcl_platform(platform) eq "windows"} { + set res [list] + foreach name [glob -nocomplain $pattern] { + if {[string index [file tail $name] 0] eq "."} continue + lappend res $name + } + return $res + } else { + return [glob -nocomplain $pattern] + } + } + # Read the first 5 entries from the root directory. # set res [list] - foreach p [lrange [exec ls -U /] 0 4] { - lappend res "/$p" + foreach p [lrange [list_root_files] 0 4] { + if {$::tcl_platform(platform) eq "windows"} { + lappend res $p + } else { + lappend res "/$p" + } } do_execsql_test 3.1 { SELECT path FROM fstree LIMIT 5; @@ -130,7 +160,7 @@ if {$::tcl_platform(platform)=="unix"} { # proc contents {pattern} { set res [list] - foreach f [glob -nocomplain $pattern] { + foreach f [list_files $pattern] { lappend res $f if {[file isdir $f]} { set res [concat $res [contents "$f/*"]] From e1818ec7400a9917fbdbec566a70769b3fc94235 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 1 Dec 2015 16:21:35 +0000 Subject: [PATCH 41/53] Simplification to the read and write primatives in the unix VFS. FossilOrigin-Name: 9eefa449792f03c4c149edcbc6b9b7692617994c --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/os_unix.c | 25 +++++++++++-------------- 3 files changed, 18 insertions(+), 21 deletions(-) diff --git a/manifest b/manifest index 135ade46f1..245528dd63 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sSQLITE_PRINTF_PRECISION_LIMIT\scompile-time\soption. -D 2015-11-30T22:52:14.011 +C Simplification\sto\sthe\sread\sand\swrite\sprimatives\sin\sthe\sunix\sVFS. +D 2015-12-01T16:21:35.045 F Makefile.in d828db6afa6c1fa060d01e33e4674408df1942a1 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e928e68168df69b353300ac87c10105206653a03 @@ -323,7 +323,7 @@ F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8 F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf F src/os_common.h abdb9a191a367793268fe553d25bab894e986a0e F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa -F src/os_unix.c 88d9fd1da4f3d26c64ef954fb32cce583605eba0 +F src/os_unix.c 7d56433ac85e77423d2d613fd5e53db08c5868ed F src/os_win.c 386fba30419e8458b13209781c2af5590eab2811 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c f92aacd5216d8815136c9e0190041783c602641a @@ -1406,7 +1406,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P bb1e2c4df0b81327923f121dd6c002845486a314 -R d3b18adc3009f6c25adcd36c4f052eab +P ecad75d69e0d5c83dd3584d363e557e84b65f7f2 +R bca4975588f4da52a9a8fe0cd42dc56d U drh -Z 7ba0fba490eff520c14229730eb61dd8 +Z 462bb50cf4ea1a0b7483c62da14af105 diff --git a/manifest.uuid b/manifest.uuid index 3749928415..669572ced9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ecad75d69e0d5c83dd3584d363e557e84b65f7f2 \ No newline at end of file +9eefa449792f03c4c149edcbc6b9b7692617994c \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index e5103856bd..475beed28b 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -3086,13 +3086,9 @@ static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){ SimulateIOError( got = -1 ); #else newOffset = lseek(id->h, offset, SEEK_SET); - SimulateIOError( newOffset-- ); - if( newOffset!=offset ){ - if( newOffset == -1 ){ - storeLastErrno((unixFile*)id, errno); - }else{ - storeLastErrno((unixFile*)id, 0); - } + SimulateIOError( newOffset = -1 ); + if( newOffset<0 ){ + storeLastErrno((unixFile*)id, errno); return -1; } got = osRead(id->h, pBuf, cnt); @@ -3191,6 +3187,7 @@ static int seekAndWriteFd( assert( nBuf==(nBuf&0x1ffff) ); assert( fd>2 ); + assert( piErrno!=0 ); nBuf &= 0x1ffff; TIMER_START; @@ -3201,11 +3198,10 @@ static int seekAndWriteFd( #else do{ i64 iSeek = lseek(fd, iOff, SEEK_SET); - SimulateIOError( iSeek-- ); - - if( iSeek!=iOff ){ - if( piErrno ) *piErrno = (iSeek==-1 ? errno : 0); - return -1; + SimulateIOError( iSeek = -1 ); + if( iSeek<0 ){ + rc = -1; + break; } rc = osWrite(fd, pBuf, nBuf); }while( rc<0 && errno==EINTR ); @@ -3214,7 +3210,7 @@ static int seekAndWriteFd( TIMER_END; OSTRACE(("WRITE %-3d %5d %7lld %llu\n", fd, rc, iOff, TIMER_ELAPSED)); - if( rc<0 && piErrno ) *piErrno = errno; + if( rc<0 ) *piErrno = errno; return rc; } @@ -4410,7 +4406,8 @@ static int unixShmMap( /* Write to the last byte of each newly allocated or extended page */ assert( (nByte % pgsz)==0 ); for(iPg=(sStat.st_size/pgsz); iPg<(nByte/pgsz); iPg++){ - if( seekAndWriteFd(pShmNode->h, iPg*pgsz + pgsz-1, "", 1, 0)!=1 ){ + int x = 0; + if( seekAndWriteFd(pShmNode->h, iPg*pgsz + pgsz-1, "", 1, &x)!=1 ){ const char *zFile = pShmNode->zFilename; rc = unixLogError(SQLITE_IOERR_SHMSIZE, "write", zFile); goto shmpage_out; From 41d2e66ef3de25a0d78a79bfbb781f305842c77b Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 1 Dec 2015 21:23:07 +0000 Subject: [PATCH 42/53] Add the SQLITE_LIKE_DOESNT_MATCH_BLOBS compile-time option. FossilOrigin-Name: 9e1d6d4c391ff90077f0d1cdeb567969fee9f747 --- manifest | 35 +++++++++++++++++------------------ manifest.uuid | 2 +- src/ctime.c | 3 +++ src/func.c | 11 +++++++++++ src/test_config.c | 6 ++++++ src/vdbe.c | 2 ++ src/where.c | 2 ++ src/whereInt.h | 2 ++ src/wherecode.c | 14 ++++++++++++++ test/analyze3.test | 20 ++++++++++++++------ test/enc3.test | 5 +++-- test/like.test | 36 ++++++++++++++++++++++++++---------- test/like3.test | 7 +++++-- test/where8.test | 22 +++++++++++++++------- 14 files changed, 121 insertions(+), 46 deletions(-) diff --git a/manifest b/manifest index 25c8979c29..1171656df0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\stest_fs.c\stest\smodule\snow\sworks\son\sWindows. -D 2015-12-01T17:48:45.370 +C Add\sthe\sSQLITE_LIKE_DOESNT_MATCH_BLOBS\scompile-time\soption. +D 2015-12-01T21:23:07.560 F Makefile.in 23d9a63484a383fc64951b25ef44067930f98dc6 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e8fdca1cb89a1b58b5f4d3a130ea9a3d28cb314d @@ -288,14 +288,14 @@ F src/btreeInt.h 3ab435ed27adea54d040584b0bcc488ee7db1e38 F src/build.c e83da4d004a4e050c01acbb821ff7a7b1019c29b F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0 F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f -F src/ctime.c 509ef9c64d1321f42448f111da86400b1799218a +F src/ctime.c 58eda76364fb6f374e044aa4493219b13abf9400 F src/date.c fb1c99172017dcc8e237339132c91a21a0788584 F src/dbstat.c ffd63fc8ba7541476ced189b95e95d7f2bc63f78 F src/delete.c 00af9f08a15ddc5cba5962d3d3e5bf2d67b2e7da F src/expr.c cb1a419508e5b27769a91e00e36e94724e7b1d51 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 31900763094a3736a5fc887469202eb579fef2d0 -F src/func.c 5790a898a0c53e6787020ec268425d415e7e03c9 +F src/func.c fe50a9ab977acc0bb0fcd46741e0071fa388888e F src/global.c 508e4087f7b41d688e4762dcf4d4fe28cfbc87f9 F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5 F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094 @@ -363,7 +363,7 @@ F src/test_autoext.c dea8a01a7153b9adc97bd26161e4226329546e12 F src/test_backup.c 2e6e6a081870150f20c526a2e9d0d29cda47d803 F src/test_blob.c e5a7a81d61a780da79101aeb1e60d300af169e07 F src/test_btree.c 2e9978eca99a9a4bfa8cae949efb00886860a64f -F src/test_config.c f2824de39f59d8d621e2d6ec5cc67006d000b2eb +F src/test_config.c 48850687dd5abc8260e23835632511054ccae172 F src/test_demovfs.c 0de72c2c89551629f58486fde5734b7d90758852 F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc F src/test_fs.c aab47ac456316502faa265daadf9ac832fea12b9 @@ -404,7 +404,7 @@ F src/update.c 17332f9fe818cbc0444c36a811800af8498af4c3 F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c F src/util.c e802e8e311a0d6c48cd1b3e89db164f6f0248d70 F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701 -F src/vdbe.c b56b2fc9b2f2d0a99d1dbd02d47efaacec253a4c +F src/vdbe.c 4d75375fa8bf911aa76ab8383d6f7eea0dec0fda F src/vdbe.h efb7a8c1459e31f3ea4377824c6a7e4cb5068637 F src/vdbeInt.h 75c2e82ee3357e9210c06474f8d9bdf12c81105d F src/vdbeapi.c 020681b943e77766b32ae1cddf86d7831b7374ca @@ -418,9 +418,9 @@ F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb F src/wal.c 18b0ed49830cf04fe2d68224b41838a73ac6cd24 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 2e14d17f592d176b6dc879c33fbdec4fbccaa2ba -F src/where.c 9c04982ba9ecfc7751c670ed5a3bddc81d7eb74c -F src/whereInt.h 6afc0d70cf6213e58e8fbe10b6e50d1aa16f122f -F src/wherecode.c 4c96182e7b25e4be54008dee2da5b9c2f8480b9b +F src/where.c b18edbb9e5afabb77f4f27550c471c5c824e0fe7 +F src/whereInt.h e20801d89e34de1912bb6a3babb30c390da27add +F src/wherecode.c dfbfe198e418b01f208b489e088edd230c91a4e7 F src/whereexpr.c eebba8340c90de73b3d3bbe8c43b84559b8e6e2c F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -435,7 +435,7 @@ F test/alter4.test c461150723ac957f3b2214aa0b11552cd72023ec F test/altermalloc.test e81ac9657ed25c6c5bb09bebfa5a047cd8e4acfc F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f F test/analyze.test 3eb35a4af972f98422e5dc0586501b17d103d321 -F test/analyze3.test 0f0ee6135b293a0e5af471a8423b80b688469d71 +F test/analyze3.test 1dccda46a6c374018af617fba00bfe297a61d442 F test/analyze4.test eff2df19b8dd84529966420f29ea52edc6b56213 F test/analyze5.test 765c4e284aa69ca172772aa940946f55629bc8c4 F test/analyze6.test f1c552ce39cca4ec922a7e4e0e5d0203d6b3281f @@ -610,7 +610,7 @@ F test/e_walckpt.test 65e29b6631e51f210f83e4ff11571e647ba93608 F test/e_walhook.test da3ea8b3483d1af72190337bda50155a91a4b664 F test/enc.test e54531cd6bf941ee6760be041dff19a104c7acea F test/enc2.test 83437a79ba1545a55fb549309175c683fb334473 -F test/enc3.test 90683ad0e6ea587b9d5542ca93568af9a9858c40 +F test/enc3.test 6807f7a7740a00361ca8d0ccd66bc60c8dc5f2b6 F test/enc4.test c8f1ce3618508fd0909945beb8b8831feef2c020 F test/eqp.test 85873fa5816c48915c82c4e74cb5c35a5b48160f F test/errmsg.test f31592a594b44ee121371d25ddd5d63497bb3401 @@ -829,9 +829,9 @@ F test/json102.test bf3fe7a706d30936a76a0f7a0375e1e8e73aff5a F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63 F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200 -F test/like.test 4f2a71d36a536233727f71995fef900756705e56 +F test/like.test edcf6d0a055816fd793eab92454597c1be91f720 F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da -F test/like3.test 7b0525a39e4f25c4fd113de7e2e28eb712dcdedf +F test/like3.test 3608a2042b6f922f900fbfd5d3ce4e7eca57f7c4 F test/limit.test 0c99a27a87b14c646a9d583c7c89fd06c352663e F test/loadext.test 648cb95f324d1775c54a55c12271b2d1156b633b F test/loadext2.test 0408380b57adca04004247179837a18e866a74f7 @@ -1315,7 +1315,7 @@ F test/where4.test 4a371bfcc607f41d233701bdec33ac2972908ba8 F test/where5.test fdf66f96d29a064b63eb543e28da4dfdccd81ad2 F test/where6.test 5da5a98cec820d488e82708301b96cb8c18a258b F test/where7.test 5a4b0abc207d71da4deecd734ad8579e8dd40aa8 -F test/where8.test 2eafe74e01cc10355985874e1ff868ac03dbae5e +F test/where8.test 98eedca0d375fb400b8377269c4b4686582dfb45 F test/where8m.test da346596e19d54f0aba35ebade032a7c47d79739 F test/where9.test 729c3ba9b47e8f9f1aab96bae7dad2a524f1d1a2 F test/whereA.test 4d253178d135ec46d1671e440cd8f2b916aa6e6b @@ -1408,8 +1408,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 9eefa449792f03c4c149edcbc6b9b7692617994c f3ffb3aeea95712e92919fd5071741327add9643 -R e64b655038c6ea5e388ada04c5bc3077 -T +closed f3ffb3aeea95712e92919fd5071741327add9643 +P e3d8628456848a70035bbdeca6dc6c21f688b9a5 +R ee2257e707ea5c58e9d484a1c772cd3c U drh -Z d6f52c287ea9591be795be1577b20991 +Z b3c4a1b23e3be107d1964e5242f6524b diff --git a/manifest.uuid b/manifest.uuid index e2f8fb6ba3..b0e59d95bb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e3d8628456848a70035bbdeca6dc6c21f688b9a5 \ No newline at end of file +9e1d6d4c391ff90077f0d1cdeb567969fee9f747 \ No newline at end of file diff --git a/src/ctime.c b/src/ctime.c index 17dd710bc3..c3149ad913 100644 --- a/src/ctime.c +++ b/src/ctime.c @@ -158,6 +158,9 @@ static const char * const azCompileOpt[] = { #ifdef SQLITE_INT64_TYPE "INT64_TYPE", #endif +#ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS + "LIKE_DOESNT_MATCH_BLOBS", +#endif #if SQLITE_LOCK_TRACE "LOCK_TRACE", #endif diff --git a/src/func.c b/src/func.c index b134c1a7c2..3fbd2b736b 100644 --- a/src/func.c +++ b/src/func.c @@ -802,6 +802,17 @@ static void likeFunc( int nPat; sqlite3 *db = sqlite3_context_db_handle(context); +#ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS + if( sqlite3_value_type(argv[0])==SQLITE_BLOB + || sqlite3_value_type(argv[1])==SQLITE_BLOB + ){ +#ifdef SQLITE_TEST + sqlite3_like_count++; +#endif + sqlite3_result_int(context, 0); + return; + } +#endif zB = sqlite3_value_text(argv[0]); zA = sqlite3_value_text(argv[1]); diff --git a/src/test_config.c b/src/test_config.c index b84424bbdc..a9ef182e02 100644 --- a/src/test_config.c +++ b/src/test_config.c @@ -185,6 +185,12 @@ static void set_options(Tcl_Interp *interp){ Tcl_SetVar2(interp, "sqlite_options", "json1", "0", TCL_GLOBAL_ONLY); #endif +#ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS + Tcl_SetVar2(interp, "sqlite_options", "like_match_blobs", "0", TCL_GLOBAL_ONLY); +#else + Tcl_SetVar2(interp, "sqlite_options", "like_match_blobs", "1", TCL_GLOBAL_ONLY); +#endif + #ifdef SQLITE_OMIT_ATTACH Tcl_SetVar2(interp, "sqlite_options", "attach", "0", TCL_GLOBAL_ONLY); #else diff --git a/src/vdbe.c b/src/vdbe.c index 66b507b285..f87fddafed 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1088,6 +1088,7 @@ case OP_String: { /* out2 */ pOut->n = pOp->p1; pOut->enc = encoding; UPDATE_MAX_BLOBSIZE(pOut); +#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS if( pOp->p5 ){ assert( pOp->p3>0 ); assert( pOp->p3<=(p->nMem-p->nCursor) ); @@ -1095,6 +1096,7 @@ case OP_String: { /* out2 */ assert( pIn3->flags & MEM_Int ); if( pIn3->u.i ) pOut->flags = MEM_Blob|MEM_Static|MEM_Term; } +#endif break; } diff --git a/src/where.c b/src/where.c index 30ad58e01b..7d68664598 100644 --- a/src/where.c +++ b/src/where.c @@ -4492,6 +4492,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ sqlite3VdbeJumpHere(v, pLevel->addrSkip); sqlite3VdbeJumpHere(v, pLevel->addrSkip-2); } +#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS if( pLevel->addrLikeRep ){ int op; if( sqlite3VdbeGetOp(v, pLevel->addrLikeRep-1)->p1 ){ @@ -4502,6 +4503,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ sqlite3VdbeAddOp2(v, op, pLevel->iLikeRepCntr, pLevel->addrLikeRep); VdbeCoverage(v); } +#endif if( pLevel->iLeftJoin ){ addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin); VdbeCoverage(v); assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 diff --git a/src/whereInt.h b/src/whereInt.h index 86164d8c1f..63d2d71cb4 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -69,8 +69,10 @@ struct WhereLevel { int addrCont; /* Jump here to continue with the next loop cycle */ int addrFirst; /* First instruction of interior of the loop */ int addrBody; /* Beginning of the body of this loop */ +#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS int iLikeRepCntr; /* LIKE range processing counter register */ int addrLikeRep; /* LIKE range processing address */ +#endif u8 iFrom; /* Which entry in the FROM clause */ u8 op, p3, p5; /* Opcode, P3 & P5 of the opcode that ends the loop */ int p1, p2; /* Operands of the opcode used to ends the loop */ diff --git a/src/wherecode.c b/src/wherecode.c index 87db0e0a25..bc72e0ac7d 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -561,6 +561,7 @@ static int codeAllEqualityTerms( return regBase; } +#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS /* ** If the most recently coded instruction is a constant range contraint ** that originated from the LIKE optimization, then change the P3 to be @@ -572,6 +573,10 @@ static int codeAllEqualityTerms( ** The OP_String opcodes on the second pass convert the upper and lower ** bound string contants to blobs. This routine makes the necessary changes ** to the OP_String opcodes for that to happen. +** +** Except, of course, if SQLITE_LIKE_DOESNT_MATCH_BLOBS is defined, then +** only the one pass through the string space is required, so this routine +** becomes a no-op. */ static void whereLikeOptimizationStringFixup( Vdbe *v, /* prepared statement under construction */ @@ -589,6 +594,9 @@ static void whereLikeOptimizationStringFixup( pOp->p5 = 1; } } +#else +# define whereLikeOptimizationStringFixup(A,B,C) +#endif #ifdef SQLITE_ENABLE_CURSOR_HINTS /* @@ -1075,6 +1083,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( if( pLoop->wsFlags & WHERE_TOP_LIMIT ){ pRangeEnd = pLoop->aLTerm[j++]; nExtraReg = 1; +#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS if( (pRangeEnd->wtFlags & TERM_LIKEOPT)!=0 ){ assert( pRangeStart!=0 ); /* LIKE opt constraints */ assert( pRangeStart->wtFlags & TERM_LIKEOPT ); /* occur in pairs */ @@ -1087,6 +1096,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( VdbeComment((v, "LIKE loop counter")); pLevel->addrLikeRep = sqlite3VdbeCurrentAddr(v); } +#endif if( pRangeStart==0 && (j = pIdx->aiColumn[nEq])>=0 && pIdx->pTable->aCol[j].notNull==0 @@ -1590,9 +1600,13 @@ Bitmask sqlite3WhereCodeOneLoopStart( continue; } if( pTerm->wtFlags & TERM_LIKECOND ){ +#ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS + continue; +#else assert( pLevel->iLikeRepCntr>0 ); skipLikeAddr = sqlite3VdbeAddOp1(v, OP_IfNot, pLevel->iLikeRepCntr); VdbeCoverage(v); +#endif } sqlite3ExprIfFalse(pParse, pE, addrCont, SQLITE_JUMPIFNULL); if( skipLikeAddr ) sqlite3VdbeJumpHere(v, skipLikeAddr); diff --git a/test/analyze3.test b/test/analyze3.test index d61d21a947..2fb558d16a 100644 --- a/test/analyze3.test +++ b/test/analyze3.test @@ -283,9 +283,17 @@ do_eqp_test analyze3-2.3 { SELECT count(a) FROM t1 WHERE b LIKE '%a' } {0 0 0 {SCAN TABLE t1}} +# Return the first argument if like_match_blobs is true (the default) +# or the second argument if not +# +proc ilmb {a b} { + ifcapable like_match_blobs {return $a} + return $b +} + do_test analyze3-2.4 { sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE 'a%' } -} {102 0 100} +} [list [ilmb 102 101] 0 100] do_test analyze3-2.5 { sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE '%a' } } {999 999 100} @@ -293,7 +301,7 @@ do_test analyze3-2.5 { do_test analyze3-2.6 { set like "a%" sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like } -} {102 0 100} +} [list [ilmb 102 101] 0 100] do_test analyze3-2.7 { set like "%a" sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like } @@ -301,19 +309,19 @@ do_test analyze3-2.7 { do_test analyze3-2.8 { set like "a" sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like } -} {102 0 0} +} [list [ilmb 102 101] 0 0] do_test analyze3-2.9 { set like "ab" sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like } -} {12 0 0} +} [list [ilmb 12 11] 0 0] do_test analyze3-2.10 { set like "abc" sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like } -} {3 0 1} +} [list [ilmb 3 2] 0 1] do_test analyze3-2.11 { set like "a_c" sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like } -} {102 0 10} +} [list [ilmb 102 101] 0 10] #------------------------------------------------------------------------- diff --git a/test/enc3.test b/test/enc3.test index 1d8a258165..7ede2b716f 100644 --- a/test/enc3.test +++ b/test/enc3.test @@ -62,7 +62,7 @@ ifcapable {bloblit && utf16} { execsql { CREATE TABLE t2(a); INSERT INTO t2 VALUES(x'61006200630064006500'); - SELECT CAST(a AS text) FROM t2 WHERE a LIKE 'abc%'; + SELECT CAST(a AS text) FROM t2 WHERE CAST(a AS text) LIKE 'abc%'; } } {abcde} do_test enc3-2.3 { @@ -72,7 +72,8 @@ ifcapable {bloblit && utf16} { } {abcde} do_test enc3-2.4 { execsql { - SELECT rowid FROM t2 WHERE a LIKE x'610062002500'; + SELECT rowid FROM t2 + WHERE CAST(a AS text) LIKE CAST(x'610062002500' AS text); } } {1} } diff --git a/test/like.test b/test/like.test index 18a01dc996..ceb5f2bfac 100644 --- a/test/like.test +++ b/test/like.test @@ -745,11 +745,19 @@ ifcapable like_opt&&!icu { SELECT a FROM t10 WHERE e LIKE '12%' ORDER BY +a; } } {12 123 scan 5 like 6} - do_test like-10.5 { - count { - SELECT a FROM t10 WHERE f LIKE '12%' ORDER BY +a; - } - } {12 123 scan 4 like 0} + ifcapable like_match_blobs { + do_test like-10.5a { + count { + SELECT a FROM t10 WHERE f LIKE '12%' ORDER BY +a; + } + } {12 123 scan 4 like 0} + } else { + do_test like-10.5b { + count { + SELECT a FROM t10 WHERE f LIKE '12%' ORDER BY +a; + } + } {12 123 scan 3 like 0} + } do_test like-10.6 { count { SELECT a FROM t10 WHERE a LIKE '12%' ORDER BY +a; @@ -786,11 +794,19 @@ ifcapable like_opt&&!icu { SELECT a FROM t10b WHERE e GLOB '12*' ORDER BY +a; } } {12 123 scan 5 like 6} - do_test like-10.14 { - count { - SELECT a FROM t10b WHERE f GLOB '12*' ORDER BY +a; - } - } {12 123 scan 4 like 0} + ifcapable like_match_blobs { + do_test like-10.14 { + count { + SELECT a FROM t10b WHERE f GLOB '12*' ORDER BY +a; + } + } {12 123 scan 4 like 0} + } else { + do_test like-10.14 { + count { + SELECT a FROM t10b WHERE f GLOB '12*' ORDER BY +a; + } + } {12 123 scan 3 like 0} + } do_test like-10.15 { count { SELECT a FROM t10b WHERE a GLOB '12*' ORDER BY +a; diff --git a/test/like3.test b/test/like3.test index a1faf76915..9280c2c5d2 100644 --- a/test/like3.test +++ b/test/like3.test @@ -29,6 +29,11 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl +ifcapable !like_match_blobs { + finish_test + return +} + do_execsql_test like3-1.1 { PRAGMA encoding=UTF8; CREATE TABLE t1(a,b TEXT COLLATE nocase); @@ -107,6 +112,4 @@ do_execsql_test like3-4.2ck { SELECT quote(x) FROM t4 WHERE x LIKE 'ab%' ORDER BY +x ASC; } {'abc' 'abd' 'abe' X'616263' X'616264' X'616265'} - - finish_test diff --git a/test/where8.test b/test/where8.test index a155a95ab2..38214bc895 100644 --- a/test/where8.test +++ b/test/where8.test @@ -64,13 +64,21 @@ do_test where8-1.3 { execsql_status2 { SELECT c FROM t1 WHERE a > 8 OR b = 'two' } } {IX X II 0 0 6} -do_test where8-1.4 { - execsql_status2 { SELECT c FROM t1 WHERE a > 8 OR b GLOB 't*' } -} {IX X III II 0 0 10} - -do_test where8-1.5 { - execsql_status2 { SELECT c FROM t1 WHERE a > 8 OR b GLOB 'f*' } -} {IX X V IV 0 0 10} +ifcapable like_match_blobs { + do_test where8-1.4a { + execsql_status2 { SELECT c FROM t1 WHERE a > 8 OR b GLOB 't*' } + } {IX X III II 0 0 10} + do_test where8-1.5a { + execsql_status2 { SELECT c FROM t1 WHERE a > 8 OR b GLOB 'f*' } + } {IX X V IV 0 0 10} +} else { + do_test where8-1.4b { + execsql_status2 { SELECT c FROM t1 WHERE a > 8 OR b GLOB 't*' } + } {IX X III II 0 0 9} + do_test where8-1.5 { + execsql_status2 { SELECT c FROM t1 WHERE a > 8 OR b GLOB 'f*' } + } {IX X V IV 0 0 9} +} do_test where8-1.6 { execsql_status { SELECT c FROM t1 WHERE a = 1 OR b = 'three' ORDER BY rowid } From 053378dfa82c7e03f76dd78d5968ea43b0b1cce5 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 1 Dec 2015 22:09:42 +0000 Subject: [PATCH 43/53] Simplification to the posix_fallocate() replacement used for the SQLITE_FCNTL_SIZE_HINT file control in the unix VFS. FossilOrigin-Name: 74934d3f60ad9f6550297410eada0f288e0123c4 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/os_unix.c | 10 +++------- 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 1171656df0..ce2f2c25e3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sSQLITE_LIKE_DOESNT_MATCH_BLOBS\scompile-time\soption. -D 2015-12-01T21:23:07.560 +C Simplification\sto\sthe\sposix_fallocate()\sreplacement\sused\sfor\sthe\nSQLITE_FCNTL_SIZE_HINT\sfile\scontrol\sin\sthe\sunix\sVFS. +D 2015-12-01T22:09:42.967 F Makefile.in 23d9a63484a383fc64951b25ef44067930f98dc6 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e8fdca1cb89a1b58b5f4d3a130ea9a3d28cb314d @@ -323,7 +323,7 @@ F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8 F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf F src/os_common.h abdb9a191a367793268fe553d25bab894e986a0e F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa -F src/os_unix.c 7d56433ac85e77423d2d613fd5e53db08c5868ed +F src/os_unix.c 5808a077bf6842a47d65197f7843d4c391636b75 F src/os_win.c 386fba30419e8458b13209781c2af5590eab2811 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c f92aacd5216d8815136c9e0190041783c602641a @@ -1408,7 +1408,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P e3d8628456848a70035bbdeca6dc6c21f688b9a5 -R ee2257e707ea5c58e9d484a1c772cd3c +P 9e1d6d4c391ff90077f0d1cdeb567969fee9f747 +R 769374e25ea21fa88cb308a9a19cbf86 U drh -Z b3c4a1b23e3be107d1964e5242f6524b +Z d260ee6b5b66bd6991fd3ea098b02c75 diff --git a/manifest.uuid b/manifest.uuid index b0e59d95bb..dc83ba56f8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9e1d6d4c391ff90077f0d1cdeb567969fee9f747 \ No newline at end of file +74934d3f60ad9f6550297410eada0f288e0123c4 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 475beed28b..e3a6f778dd 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -3662,18 +3662,14 @@ static int fcntlSizeHint(unixFile *pFile, i64 nByte){ int nWrite = 0; /* Number of bytes written by seekAndWrite */ i64 iWrite; /* Next offset to write to */ - iWrite = ((buf.st_size + 2*nBlk - 1)/nBlk)*nBlk-1; + iWrite = (buf.st_size/nBlk)*nBlk + nBlk - 1; assert( iWrite>=buf.st_size ); - assert( (iWrite/nBlk)==((buf.st_size+nBlk-1)/nBlk) ); assert( ((iWrite+1)%nBlk)==0 ); - for(/*no-op*/; iWrite=nSize ) iWrite = nSize - 1; nWrite = seekAndWrite(pFile, iWrite, "", 1); if( nWrite!=1 ) return SQLITE_IOERR_WRITE; } - if( nWrite==0 || (nSize%nBlk) ){ - nWrite = seekAndWrite(pFile, nSize-1, "", 1); - if( nWrite!=1 ) return SQLITE_IOERR_WRITE; - } #endif } } From dcfb9652fda0becc56e4a2f507155e5352c785ab Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 2 Dec 2015 00:05:26 +0000 Subject: [PATCH 44/53] Remove all traces of SQLITE_FCNTL_WAL_BLOCK from the unix VFS - that feature had been disabled for a long time and never actually worked. FossilOrigin-Name: e1d5320ca089336e26d200305b744b06ce883be4 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/os_unix.c | 10 +--------- 3 files changed, 8 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index ce2f2c25e3..278638f8a9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplification\sto\sthe\sposix_fallocate()\sreplacement\sused\sfor\sthe\nSQLITE_FCNTL_SIZE_HINT\sfile\scontrol\sin\sthe\sunix\sVFS. -D 2015-12-01T22:09:42.967 +C Remove\sall\straces\sof\sSQLITE_FCNTL_WAL_BLOCK\sfrom\sthe\sunix\sVFS\s-\sthat\sfeature\nhad\sbeen\sdisabled\sfor\sa\slong\stime\sand\snever\sactually\sworked. +D 2015-12-02T00:05:26.857 F Makefile.in 23d9a63484a383fc64951b25ef44067930f98dc6 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e8fdca1cb89a1b58b5f4d3a130ea9a3d28cb314d @@ -323,7 +323,7 @@ F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8 F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf F src/os_common.h abdb9a191a367793268fe553d25bab894e986a0e F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa -F src/os_unix.c 5808a077bf6842a47d65197f7843d4c391636b75 +F src/os_unix.c 8f8f11b64aa5b20f75f0a9e4ed494e51a641e62f F src/os_win.c 386fba30419e8458b13209781c2af5590eab2811 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c f92aacd5216d8815136c9e0190041783c602641a @@ -1408,7 +1408,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 9e1d6d4c391ff90077f0d1cdeb567969fee9f747 -R 769374e25ea21fa88cb308a9a19cbf86 +P 74934d3f60ad9f6550297410eada0f288e0123c4 +R 1d7fdc365e66b6a0c98551c7522b87df U drh -Z d260ee6b5b66bd6991fd3ea098b02c75 +Z 0a345589f1af443a2c8f5dbd810973ee diff --git a/manifest.uuid b/manifest.uuid index dc83ba56f8..8cf64f6d0d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -74934d3f60ad9f6550297410eada0f288e0123c4 \ No newline at end of file +e1d5320ca089336e26d200305b744b06ce883be4 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index e3a6f778dd..35f401e74c 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -258,7 +258,6 @@ static pid_t randomnessPid = 0; #define UNIXFILE_DELETE 0x20 /* Delete on close */ #define UNIXFILE_URI 0x40 /* Filename might have query parameters */ #define UNIXFILE_NOLOCK 0x80 /* Do no file locking */ -#define UNIXFILE_BLOCK 0x0100 /* Next SHM lock might block */ /* ** Include code that is common to all os_*.c files @@ -3717,10 +3716,6 @@ static int unixGetTempname(int nBuf, char *zBuf); static int unixFileControl(sqlite3_file *id, int op, void *pArg){ unixFile *pFile = (unixFile*)id; switch( op ){ - case SQLITE_FCNTL_WAL_BLOCK: { - /* pFile->ctrlFlags |= UNIXFILE_BLOCK; // Deferred feature */ - return SQLITE_OK; - } case SQLITE_FCNTL_LOCKSTATE: { *(int*)pArg = pFile->eFileLock; return SQLITE_OK; @@ -4050,7 +4045,6 @@ static int unixShmSystemLock( assert( n>=1 && nh>=0 ){ - int lkType; /* Initialize the locking parameters */ memset(&f, 0, sizeof(f)); f.l_type = lockType; @@ -4058,10 +4052,8 @@ static int unixShmSystemLock( f.l_start = ofst; f.l_len = n; - lkType = (pFile->ctrlFlags & UNIXFILE_BLOCK)!=0 ? F_SETLKW : F_SETLK; - rc = osFcntl(pShmNode->h, lkType, &f); + rc = osFcntl(pShmNode->h, F_SETLK, &f); rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY; - pFile->ctrlFlags &= ~UNIXFILE_BLOCK; } /* Update the global lock state and do debug tracing */ From 50358adfaaef3ab020bbf0d51560141d9a6713db Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 2 Dec 2015 01:04:33 +0000 Subject: [PATCH 45/53] Simplification of the logic used to take the process-wide lock in the unix-excl VFS. FossilOrigin-Name: 73defd52bb0e3e5db763d3bfbeebc972b645867e --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/os_unix.c | 4 +--- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 278638f8a9..f950ba358b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sall\straces\sof\sSQLITE_FCNTL_WAL_BLOCK\sfrom\sthe\sunix\sVFS\s-\sthat\sfeature\nhad\sbeen\sdisabled\sfor\sa\slong\stime\sand\snever\sactually\sworked. -D 2015-12-02T00:05:26.857 +C Simplification\sof\sthe\slogic\sused\sto\stake\sthe\sprocess-wide\slock\sin\sthe\nunix-excl\sVFS. +D 2015-12-02T01:04:33.889 F Makefile.in 23d9a63484a383fc64951b25ef44067930f98dc6 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e8fdca1cb89a1b58b5f4d3a130ea9a3d28cb314d @@ -323,7 +323,7 @@ F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8 F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf F src/os_common.h abdb9a191a367793268fe553d25bab894e986a0e F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa -F src/os_unix.c 8f8f11b64aa5b20f75f0a9e4ed494e51a641e62f +F src/os_unix.c 207fef7c47f3d77cf8a52edd5ebd53b67e731fd1 F src/os_win.c 386fba30419e8458b13209781c2af5590eab2811 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c f92aacd5216d8815136c9e0190041783c602641a @@ -1408,7 +1408,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 74934d3f60ad9f6550297410eada0f288e0123c4 -R 1d7fdc365e66b6a0c98551c7522b87df +P e1d5320ca089336e26d200305b744b06ce883be4 +R 529fef7e01cd9bbdb6610da9a8964270 U drh -Z 0a345589f1af443a2c8f5dbd810973ee +Z 697c3f68f06eec6f2193816dd17daae9 diff --git a/manifest.uuid b/manifest.uuid index 8cf64f6d0d..9faa68982f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e1d5320ca089336e26d200305b744b06ce883be4 \ No newline at end of file +73defd52bb0e3e5db763d3bfbeebc972b645867e \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 35f401e74c..38c8d7b619 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -1406,9 +1406,7 @@ static int unixFileLock(unixFile *pFile, struct flock *pLock){ unixInodeInfo *pInode = pFile->pInode; assert( unixMutexHeld() ); assert( pInode!=0 ); - if( ((pFile->ctrlFlags & UNIXFILE_EXCL)!=0 || pInode->bProcessLock) - && ((pFile->ctrlFlags & UNIXFILE_RDONLY)==0) - ){ + if( (pFile->ctrlFlags & (UNIXFILE_EXCL|UNIXFILE_RDONLY))==UNIXFILE_EXCL ){ if( pInode->bProcessLock==0 ){ struct flock lock; assert( pInode->nLock==0 ); From adfa22e118e7a0db0a89ff899ddcd48d517e9c31 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 2 Dec 2015 02:08:30 +0000 Subject: [PATCH 46/53] Fix a (harmless) off-by-one error in the unix VFS logic that fsync()s a directory after deleting a file. FossilOrigin-Name: 3d02711a709a7e708edb0ea8ca5d17b39dd307f6 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/os_unix.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index f950ba358b..0870896448 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplification\sof\sthe\slogic\sused\sto\stake\sthe\sprocess-wide\slock\sin\sthe\nunix-excl\sVFS. -D 2015-12-02T01:04:33.889 +C Fix\sa\s(harmless)\soff-by-one\serror\sin\sthe\sunix\sVFS\slogic\sthat\sfsync()s\sa\ndirectory\safter\sdeleting\sa\sfile. +D 2015-12-02T02:08:30.997 F Makefile.in 23d9a63484a383fc64951b25ef44067930f98dc6 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e8fdca1cb89a1b58b5f4d3a130ea9a3d28cb314d @@ -323,7 +323,7 @@ F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8 F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf F src/os_common.h abdb9a191a367793268fe553d25bab894e986a0e F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa -F src/os_unix.c 207fef7c47f3d77cf8a52edd5ebd53b67e731fd1 +F src/os_unix.c 27a7ead71bfca5d90ad965f2ac46b37b63f07189 F src/os_win.c 386fba30419e8458b13209781c2af5590eab2811 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c f92aacd5216d8815136c9e0190041783c602641a @@ -1408,7 +1408,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P e1d5320ca089336e26d200305b744b06ce883be4 -R 529fef7e01cd9bbdb6610da9a8964270 +P 73defd52bb0e3e5db763d3bfbeebc972b645867e +R e028288719c771a5625e51b4f5de27be U drh -Z 697c3f68f06eec6f2193816dd17daae9 +Z 2550f7a73cc643eb4c13a681e63731c8 diff --git a/manifest.uuid b/manifest.uuid index 9faa68982f..9e1954b28f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -73defd52bb0e3e5db763d3bfbeebc972b645867e \ No newline at end of file +3d02711a709a7e708edb0ea8ca5d17b39dd307f6 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 38c8d7b619..8eff392a66 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -3461,7 +3461,7 @@ static int openDirectory(const char *zFilename, int *pFd){ sqlite3_snprintf(MAX_PATHNAME, zDirname, "%s", zFilename); for(ii=(int)strlen(zDirname); ii>1 && zDirname[ii]!='/'; ii--); - if( ii>0 ){ + if( ii>1 ){ zDirname[ii] = '\0'; fd = robust_open(zDirname, O_RDONLY|O_BINARY, 0); if( fd>=0 ){ From 2c8fd12f42e9f093b935e5225d9e6978825f77b6 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 2 Dec 2015 02:33:36 +0000 Subject: [PATCH 47/53] Change the SQLITE_NO_SYNC compile-time option to call fstat() in place of fsync() rather than being a total no-op. FossilOrigin-Name: f64ea8a052af9790d5e6987cbd5e81d77da6f172 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/os_unix.c | 9 +++++++-- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 0870896448..20fe8059ef 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\s(harmless)\soff-by-one\serror\sin\sthe\sunix\sVFS\slogic\sthat\sfsync()s\sa\ndirectory\safter\sdeleting\sa\sfile. -D 2015-12-02T02:08:30.997 +C Change\sthe\sSQLITE_NO_SYNC\scompile-time\soption\sto\scall\sfstat()\sin\splace\sof\nfsync()\srather\sthan\sbeing\sa\stotal\sno-op. +D 2015-12-02T02:33:36.549 F Makefile.in 23d9a63484a383fc64951b25ef44067930f98dc6 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e8fdca1cb89a1b58b5f4d3a130ea9a3d28cb314d @@ -323,7 +323,7 @@ F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8 F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf F src/os_common.h abdb9a191a367793268fe553d25bab894e986a0e F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa -F src/os_unix.c 27a7ead71bfca5d90ad965f2ac46b37b63f07189 +F src/os_unix.c badd3d7b007daa74df6a12c1e5a89a8504ef3594 F src/os_win.c 386fba30419e8458b13209781c2af5590eab2811 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c f92aacd5216d8815136c9e0190041783c602641a @@ -1408,7 +1408,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 73defd52bb0e3e5db763d3bfbeebc972b645867e -R e028288719c771a5625e51b4f5de27be +P 3d02711a709a7e708edb0ea8ca5d17b39dd307f6 +R 32c34918a379a944fbe8e3ec0a4b5179 U drh -Z 2550f7a73cc643eb4c13a681e63731c8 +Z d4a14e46436f968eb1bd48b7a43684a4 diff --git a/manifest.uuid b/manifest.uuid index 9e1954b28f..88f3adba23 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3d02711a709a7e708edb0ea8ca5d17b39dd307f6 \ No newline at end of file +f64ea8a052af9790d5e6987cbd5e81d77da6f172 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 8eff392a66..7038bf12df 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -3391,10 +3391,15 @@ static int full_fsync(int fd, int fullSync, int dataOnly){ #endif /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a - ** no-op + ** no-op. But go ahead and call fstat() to validate the file + ** descriptor as we need a method to provoke a failure during + ** coverate testing. */ #ifdef SQLITE_NO_SYNC - rc = SQLITE_OK; + { + struct stat buf; + rc = osFstat(fd, &buf); + } #elif HAVE_FULLFSYNC if( fullSync ){ rc = osFcntl(fd, F_FULLFSYNC, 0); From f3b1ed0fc219d9c3a7caac14694b18bcc6c5c025 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 2 Dec 2015 13:11:03 +0000 Subject: [PATCH 48/53] Minor simplifications to the unix VFS. FossilOrigin-Name: 2f13c16b45685ec6850cbd9da79e8198bad6a491 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/os_unix.c | 12 ++++-------- 3 files changed, 11 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 20fe8059ef..23275e1740 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\sSQLITE_NO_SYNC\scompile-time\soption\sto\scall\sfstat()\sin\splace\sof\nfsync()\srather\sthan\sbeing\sa\stotal\sno-op. -D 2015-12-02T02:33:36.549 +C Minor\ssimplifications\sto\sthe\sunix\sVFS. +D 2015-12-02T13:11:03.174 F Makefile.in 23d9a63484a383fc64951b25ef44067930f98dc6 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e8fdca1cb89a1b58b5f4d3a130ea9a3d28cb314d @@ -323,7 +323,7 @@ F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8 F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf F src/os_common.h abdb9a191a367793268fe553d25bab894e986a0e F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa -F src/os_unix.c badd3d7b007daa74df6a12c1e5a89a8504ef3594 +F src/os_unix.c 2b65298be9db161beb0e3ffadc9be0080d51c320 F src/os_win.c 386fba30419e8458b13209781c2af5590eab2811 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c f92aacd5216d8815136c9e0190041783c602641a @@ -1408,7 +1408,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 3d02711a709a7e708edb0ea8ca5d17b39dd307f6 -R 32c34918a379a944fbe8e3ec0a4b5179 +P f64ea8a052af9790d5e6987cbd5e81d77da6f172 +R 7335e7d7ad4ea5951ac863300cf3bdc9 U drh -Z d4a14e46436f968eb1bd48b7a43684a4 +Z 5e48ed834d343e9f2a57065e0ab37833 diff --git a/manifest.uuid b/manifest.uuid index 88f3adba23..4a79fe8bad 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f64ea8a052af9790d5e6987cbd5e81d77da6f172 \ No newline at end of file +2f13c16b45685ec6850cbd9da79e8198bad6a491 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 7038bf12df..00602c6b82 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -4123,7 +4123,7 @@ static int unixShmRegionPerMap(void){ static void unixShmPurge(unixFile *pFd){ unixShmNode *p = pFd->pInode->pShmNode; assert( unixMutexHeld() ); - if( p && p->nRef==0 ){ + if( p && ALWAYS(p->nRef==0) ){ int nShmPerMap = unixShmRegionPerMap(); int i; assert( p->pInode==pFd->pInode ); @@ -4210,7 +4210,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){ ** a new *-shm file is created, an attempt will be made to create it ** with the same permissions. */ - if( osFstat(pDbFd->h, &sStat) && pInode->bProcessLock==0 ){ + if( osFstat(pDbFd->h, &sStat) ){ rc = SQLITE_IOERR_FSTAT; goto shm_open_err; } @@ -4766,17 +4766,13 @@ static void unixRemapfile( ** recreated as a result of outstanding references) or an SQLite error ** code otherwise. */ -static int unixMapfile(unixFile *pFd, i64 nByte){ - i64 nMap = nByte; - int rc; - +static int unixMapfile(unixFile *pFd, i64 nMap){ assert( nMap>=0 || pFd->nFetchOut==0 ); if( pFd->nFetchOut>0 ) return SQLITE_OK; if( nMap<0 ){ struct stat statbuf; /* Low-level file information */ - rc = osFstat(pFd->h, &statbuf); - if( rc!=SQLITE_OK ){ + if( osFstat(pFd->h, &statbuf) ){ return SQLITE_IOERR_FSTAT; } nMap = statbuf.st_size; From 333e6ca9a5a38d756cac1e64669b4b4a5c65e8e8 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 2 Dec 2015 15:44:39 +0000 Subject: [PATCH 49/53] Remove an unreachable branch from the unixMapfile() routine of the unix VFS. FossilOrigin-Name: b50f67bc46e65fe4e51667d48b4add58706a9443 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/os_unix.c | 8 +++----- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 23275e1740..a287e3b468 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\ssimplifications\sto\sthe\sunix\sVFS. -D 2015-12-02T13:11:03.174 +C Remove\san\sunreachable\sbranch\sfrom\sthe\sunixMapfile()\sroutine\sof\sthe\sunix\sVFS. +D 2015-12-02T15:44:39.206 F Makefile.in 23d9a63484a383fc64951b25ef44067930f98dc6 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e8fdca1cb89a1b58b5f4d3a130ea9a3d28cb314d @@ -323,7 +323,7 @@ F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8 F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf F src/os_common.h abdb9a191a367793268fe553d25bab894e986a0e F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa -F src/os_unix.c 2b65298be9db161beb0e3ffadc9be0080d51c320 +F src/os_unix.c b2482c403890fc94ee6810a939c667911d871656 F src/os_win.c 386fba30419e8458b13209781c2af5590eab2811 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c f92aacd5216d8815136c9e0190041783c602641a @@ -1408,7 +1408,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P f64ea8a052af9790d5e6987cbd5e81d77da6f172 -R 7335e7d7ad4ea5951ac863300cf3bdc9 +P 2f13c16b45685ec6850cbd9da79e8198bad6a491 +R abab3e669867554a3d4200296f7779a0 U drh -Z 5e48ed834d343e9f2a57065e0ab37833 +Z cde83eb7aba3982fd2548e9f5c9718be diff --git a/manifest.uuid b/manifest.uuid index 4a79fe8bad..9a8daa1e72 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2f13c16b45685ec6850cbd9da79e8198bad6a491 \ No newline at end of file +b50f67bc46e65fe4e51667d48b4add58706a9443 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 00602c6b82..31e3215b8a 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -4768,6 +4768,7 @@ static void unixRemapfile( */ static int unixMapfile(unixFile *pFd, i64 nMap){ assert( nMap>=0 || pFd->nFetchOut==0 ); + assert( nMap>0 || (pFd->mmapSize==0 && pFd->pMapRegion==0) ); if( pFd->nFetchOut>0 ) return SQLITE_OK; if( nMap<0 ){ @@ -4781,12 +4782,9 @@ static int unixMapfile(unixFile *pFd, i64 nMap){ nMap = pFd->mmapSizeMax; } + assert( nMap>0 || (pFd->mmapSize==0 && pFd->pMapRegion==0) ); if( nMap!=pFd->mmapSize ){ - if( nMap>0 ){ - unixRemapfile(pFd, nMap); - }else{ - unixUnmapfile(pFd); - } + unixRemapfile(pFd, nMap); } return SQLITE_OK; From ab37277367effdaa555c11b02a62d75b2e962de2 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 2 Dec 2015 16:10:16 +0000 Subject: [PATCH 50/53] Remove more (dead) SQLITE_FCNTL_WAL_BLOCK logic from wal.c - code that was missed during the [e1d5320ca08933] check-in. FossilOrigin-Name: 58c15c6af964563ac7ece8606d16730ccf9ee72b --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/wal.c | 17 ++++++++--------- 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index a287e3b468..c2e303db81 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunreachable\sbranch\sfrom\sthe\sunixMapfile()\sroutine\sof\sthe\sunix\sVFS. -D 2015-12-02T15:44:39.206 +C Remove\smore\s(dead)\sSQLITE_FCNTL_WAL_BLOCK\slogic\sfrom\swal.c\s-\scode\sthat\swas\nmissed\sduring\sthe\s[e1d5320ca08933]\scheck-in. +D 2015-12-02T16:10:16.198 F Makefile.in 23d9a63484a383fc64951b25ef44067930f98dc6 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e8fdca1cb89a1b58b5f4d3a130ea9a3d28cb314d @@ -415,7 +415,7 @@ F src/vdbesort.c a7ec02da4494c59dfd071126dd3726be5a11459d F src/vdbetrace.c 8befe829faff6d9e6f6e4dee5a7d3f85cc85f1a0 F src/vtab.c 2a8b44aa372c33f6154208e7a7f6c44254549806 F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb -F src/wal.c 18b0ed49830cf04fe2d68224b41838a73ac6cd24 +F src/wal.c 1569802364cd192bbd5c4a8ea3fd6de593edecbd F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 2e14d17f592d176b6dc879c33fbdec4fbccaa2ba F src/where.c b18edbb9e5afabb77f4f27550c471c5c824e0fe7 @@ -1408,7 +1408,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 2f13c16b45685ec6850cbd9da79e8198bad6a491 -R abab3e669867554a3d4200296f7779a0 +P b50f67bc46e65fe4e51667d48b4add58706a9443 +R b4ba7b1cdaa73453f30b9d196a7f9fe7 U drh -Z cde83eb7aba3982fd2548e9f5c9718be +Z 22cdb6e0aa6d053c442a36686d71e782 diff --git a/manifest.uuid b/manifest.uuid index 9a8daa1e72..38bbe3b842 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b50f67bc46e65fe4e51667d48b4add58706a9443 \ No newline at end of file +58c15c6af964563ac7ece8606d16730ccf9ee72b \ No newline at end of file diff --git a/src/wal.c b/src/wal.c index d87d2c17ce..144db27a30 100644 --- a/src/wal.c +++ b/src/wal.c @@ -789,10 +789,9 @@ static void walUnlockShared(Wal *pWal, int lockIdx){ SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED); WALTRACE(("WAL%p: release SHARED-%s\n", pWal, walLockName(lockIdx))); } -static int walLockExclusive(Wal *pWal, int lockIdx, int n, int fBlock){ +static int walLockExclusive(Wal *pWal, int lockIdx, int n){ int rc; if( pWal->exclusiveMode ) return SQLITE_OK; - if( fBlock ) sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_WAL_BLOCK, 0); rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, n, SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE); WALTRACE(("WAL%p: acquire EXCLUSIVE-%s cnt=%d %s\n", pWal, @@ -1078,7 +1077,7 @@ static int walIndexRecover(Wal *pWal){ assert( pWal->writeLock ); iLock = WAL_ALL_BUT_WRITE + pWal->ckptLock; nLock = SQLITE_SHM_NLOCK - iLock; - rc = walLockExclusive(pWal, iLock, nLock, 0); + rc = walLockExclusive(pWal, iLock, nLock); if( rc ){ return rc; } @@ -1616,7 +1615,7 @@ static int walBusyLock( ){ int rc; do { - rc = walLockExclusive(pWal, lockIdx, n, 0); + rc = walLockExclusive(pWal, lockIdx, n); }while( xBusy && rc==SQLITE_BUSY && xBusy(pBusyArg) ); return rc; } @@ -2057,7 +2056,7 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){ walUnlockShared(pWal, WAL_WRITE_LOCK); rc = SQLITE_READONLY_RECOVERY; } - }else if( SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1, 1)) ){ + }else if( SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1)) ){ pWal->writeLock = 1; if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){ badHdr = walIndexTryHdr(pWal, pChanged); @@ -2263,7 +2262,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ && (mxReadMarkhdr.mxFrame || mxI==0) ){ for(i=1; iaReadMark[i] = pWal->hdr.mxFrame; mxI = i; @@ -2537,7 +2536,7 @@ int sqlite3WalBeginWriteTransaction(Wal *pWal){ /* Only one writer allowed at a time. Get the write lock. Return ** SQLITE_BUSY if unable. */ - rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1, 0); + rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1); if( rc ){ return rc; } @@ -2682,7 +2681,7 @@ static int walRestartLog(Wal *pWal){ if( pInfo->nBackfill>0 ){ u32 salt1; sqlite3_randomness(4, &salt1); - rc = walLockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1, 0); + rc = walLockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1); if( rc==SQLITE_OK ){ /* If all readers are using WAL_READ_LOCK(0) (in other words if no ** readers are currently using the WAL), then the transactions @@ -3007,7 +3006,7 @@ int sqlite3WalCheckpoint( /* IMPLEMENTATION-OF: R-62028-47212 All calls obtain an exclusive ** "checkpoint" lock on the database file. */ - rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1, 0); + rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1); if( rc ){ /* EVIDENCE-OF: R-10421-19736 If any other process is running a ** checkpoint operation at the same time, the lock cannot be obtained and From af19f173d3b5172a46f65ab34cff77b8ed71cc3f Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 2 Dec 2015 17:40:13 +0000 Subject: [PATCH 51/53] Fix an incorrect, though harmless, assert() in the unix VFS. FossilOrigin-Name: 4692ae84f93530e27d7c106a60236355e176b7fd --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/os_unix.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index c2e303db81..f70e8620e9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\smore\s(dead)\sSQLITE_FCNTL_WAL_BLOCK\slogic\sfrom\swal.c\s-\scode\sthat\swas\nmissed\sduring\sthe\s[e1d5320ca08933]\scheck-in. -D 2015-12-02T16:10:16.198 +C Fix\san\sincorrect,\sthough\sharmless,\sassert()\sin\sthe\sunix\sVFS. +D 2015-12-02T17:40:13.058 F Makefile.in 23d9a63484a383fc64951b25ef44067930f98dc6 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e8fdca1cb89a1b58b5f4d3a130ea9a3d28cb314d @@ -323,7 +323,7 @@ F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8 F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf F src/os_common.h abdb9a191a367793268fe553d25bab894e986a0e F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa -F src/os_unix.c b2482c403890fc94ee6810a939c667911d871656 +F src/os_unix.c 60997373a8d90bd17e1c0e49d11ef361b713439b F src/os_win.c 386fba30419e8458b13209781c2af5590eab2811 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c f92aacd5216d8815136c9e0190041783c602641a @@ -1408,7 +1408,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P b50f67bc46e65fe4e51667d48b4add58706a9443 -R b4ba7b1cdaa73453f30b9d196a7f9fe7 +P 58c15c6af964563ac7ece8606d16730ccf9ee72b +R b2d2115192da5a36c6008a1f85419e31 U drh -Z 22cdb6e0aa6d053c442a36686d71e782 +Z a2ea6ee7bac71fd2eda9f163b8a48c3e diff --git a/manifest.uuid b/manifest.uuid index 38bbe3b842..a67ac0541e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -58c15c6af964563ac7ece8606d16730ccf9ee72b \ No newline at end of file +4692ae84f93530e27d7c106a60236355e176b7fd \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 31e3215b8a..5f4cbca2aa 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -4045,7 +4045,7 @@ static int unixShmSystemLock( assert( n==1 || lockType!=F_RDLCK ); /* Locks are within range */ - assert( n>=1 && n=1 && n<=SQLITE_SHM_NLOCK ); if( pShmNode->h>=0 ){ /* Initialize the locking parameters */ From 9a8941fc83f87b45e5c149b936bebc8bb254acde Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 2 Dec 2015 18:59:44 +0000 Subject: [PATCH 52/53] Have the sqlite3_column_decltype() API report the declared types for the left-most SELECT statement in a compound SELECT. FossilOrigin-Name: 3e1d71fcaf57c0223ab9a7366c8607f8f66bb21c --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/select.c | 6 +++--- test/capi3c.test | 23 +++++++++++++++++++++++ 4 files changed, 35 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index f70e8620e9..c3e7dba328 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sincorrect,\sthough\sharmless,\sassert()\sin\sthe\sunix\sVFS. -D 2015-12-02T17:40:13.058 +C Have\sthe\ssqlite3_column_decltype()\sAPI\sreport\sthe\sdeclared\stypes\sfor\sthe\sleft-most\sSELECT\sstatement\sin\sa\scompound\sSELECT. +D 2015-12-02T18:59:44.537 F Makefile.in 23d9a63484a383fc64951b25ef44067930f98dc6 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e8fdca1cb89a1b58b5f4d3a130ea9a3d28cb314d @@ -339,7 +339,7 @@ F src/printf.c ca05561795ad6c2fa47acdd007702586282f7feb F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c f4c897ca76ca6d5e0b3f0499c627392ffe657c8e F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e -F src/select.c e10586c750d87211caa8f4b239e2bfa6a2049e5b +F src/select.c dd04f017d1402e1a8cbacb13f53c279dc48543b4 F src/shell.c 2796237990d42e6a5a7beafee65ef70cc8767d21 F src/sqlite.h.in 5bd83191711d3dc85030326daa9e8e5226a495e7 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad @@ -508,7 +508,7 @@ F test/cacheflush.test a755c93482ce2e20c04825304bef27e7b7ea0111 F test/capi2.test 011c16da245fdc0106a2785035de6b242c05e738 F test/capi3.test bf6f0308bbbba1e770dac13aa08e5c2ac61c7324 F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4 -F test/capi3c.test fdc0d67a2cb8e8fc400d5b7735e330161ea057a2 +F test/capi3c.test 06f6261f9e9b4ef6f76afcd9900f3665408af1c8 F test/capi3d.test 485048dc5cd07bc68011e4917ad035ad6047ab82 F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3 @@ -1408,7 +1408,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 58c15c6af964563ac7ece8606d16730ccf9ee72b -R b2d2115192da5a36c6008a1f85419e31 -U drh -Z a2ea6ee7bac71fd2eda9f163b8a48c3e +P 4692ae84f93530e27d7c106a60236355e176b7fd +R cccfb2982bfd6a0aab4098f75a44ccf8 +U dan +Z e453763f88995e08cd02dca755bc7590 diff --git a/manifest.uuid b/manifest.uuid index a67ac0541e..d924d8a8d3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4692ae84f93530e27d7c106a60236355e176b7fd \ No newline at end of file +3e1d71fcaf57c0223ab9a7366c8607f8f66bb21c \ No newline at end of file diff --git a/src/select.c b/src/select.c index cf486e5b85..c9d9637fcb 100644 --- a/src/select.c +++ b/src/select.c @@ -2369,7 +2369,7 @@ static int multiSelect( if( dest.eDest==SRT_Output ){ Select *pFirst = p; while( pFirst->pPrior ) pFirst = pFirst->pPrior; - generateColumnNames(pParse, 0, pFirst->pEList); + generateColumnNames(pParse, pFirst->pSrc, pFirst->pEList); } iBreak = sqlite3VdbeMakeLabel(v); iCont = sqlite3VdbeMakeLabel(v); @@ -2444,7 +2444,7 @@ static int multiSelect( if( dest.eDest==SRT_Output ){ Select *pFirst = p; while( pFirst->pPrior ) pFirst = pFirst->pPrior; - generateColumnNames(pParse, 0, pFirst->pEList); + generateColumnNames(pParse, pFirst->pSrc, pFirst->pEList); } iBreak = sqlite3VdbeMakeLabel(v); iCont = sqlite3VdbeMakeLabel(v); @@ -3059,7 +3059,7 @@ static int multiSelectOrderBy( if( pDest->eDest==SRT_Output ){ Select *pFirst = pPrior; while( pFirst->pPrior ) pFirst = pFirst->pPrior; - generateColumnNames(pParse, 0, pFirst->pEList); + generateColumnNames(pParse, pFirst->pSrc, pFirst->pEList); } /* Reassembly the compound query so that it will be freed correctly diff --git a/test/capi3c.test b/test/capi3c.test index 6ab3bc24f6..15307a7f7a 100644 --- a/test/capi3c.test +++ b/test/capi3c.test @@ -18,6 +18,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl +set testprefix capi3c # Do not use a codec for tests in this file, as the database file is # manipulated directly using tcl scripts (using the [hexio_write] command). @@ -1375,4 +1376,26 @@ do_test capi3c-24.3 { decltype {SELECT (SELECT x FROM (SELECT t5.a AS x)) FROM t5} } {INTEGER} + +# Further tests of sqlite3_column_decltype(): +# +do_execsql_test 25.0 { + CREATE TABLE t11(a VARCHAR(10), b INTEGER); + CREATE TABLE t12(a VARCHAR(15), b FLOAT); +} + +foreach {tn sql} { + 1 "SELECT * FROM t11 UNION ALL SELECT * FROM t12" + 2 "SELECT * FROM t11 UNION SELECT * FROM t12" + 3 "SELECT * FROM t11 EXCEPT SELECT * FROM t12" + 4 "SELECT * FROM t11 INTERSECT SELECT * FROM t12" + + 5 "SELECT * FROM t11 UNION ALL SELECT * FROM t12 ORDER BY 1" + 6 "SELECT * FROM t11 UNION SELECT * FROM t12 ORDER BY 1" + 7 "SELECT * FROM t11 EXCEPT SELECT * FROM t12 ORDER BY 1" + 8 "SELECT * FROM t11 INTERSECT SELECT * FROM t12 ORDER BY 1" +} { + do_test 25.$tn { decltype $sql } {VARCHAR(10) INTEGER} +} + finish_test From f7ce4291a94573cdb04e5f3fcf59ed9e69226479 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 2 Dec 2015 19:46:12 +0000 Subject: [PATCH 53/53] Remove unreachable branches from the decltype computation logic in the query planner. FossilOrigin-Name: 4f2bcff94c672312805be1400050a7026f93a9d7 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/select.c | 6 ++++-- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index c3e7dba328..123da22f21 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Have\sthe\ssqlite3_column_decltype()\sAPI\sreport\sthe\sdeclared\stypes\sfor\sthe\sleft-most\sSELECT\sstatement\sin\sa\scompound\sSELECT. -D 2015-12-02T18:59:44.537 +C Remove\sunreachable\sbranches\sfrom\sthe\sdecltype\scomputation\slogic\sin\sthe\squery\nplanner. +D 2015-12-02T19:46:12.775 F Makefile.in 23d9a63484a383fc64951b25ef44067930f98dc6 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e8fdca1cb89a1b58b5f4d3a130ea9a3d28cb314d @@ -339,7 +339,7 @@ F src/printf.c ca05561795ad6c2fa47acdd007702586282f7feb F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c f4c897ca76ca6d5e0b3f0499c627392ffe657c8e F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e -F src/select.c dd04f017d1402e1a8cbacb13f53c279dc48543b4 +F src/select.c 1611828a7116e5f6cc1e69cd07d59b0d2c662ea9 F src/shell.c 2796237990d42e6a5a7beafee65ef70cc8767d21 F src/sqlite.h.in 5bd83191711d3dc85030326daa9e8e5226a495e7 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad @@ -1408,7 +1408,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 4692ae84f93530e27d7c106a60236355e176b7fd -R cccfb2982bfd6a0aab4098f75a44ccf8 -U dan -Z e453763f88995e08cd02dca755bc7590 +P 3e1d71fcaf57c0223ab9a7366c8607f8f66bb21c +R 0397cf9717330ffe9055735c8207c81a +U drh +Z 6381d064415ccbeec9de47fb6017aaa8 diff --git a/manifest.uuid b/manifest.uuid index d924d8a8d3..c4252b6021 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3e1d71fcaf57c0223ab9a7366c8607f8f66bb21c \ No newline at end of file +4f2bcff94c672312805be1400050a7026f93a9d7 \ No newline at end of file diff --git a/src/select.c b/src/select.c index c9d9637fcb..fca8665cd7 100644 --- a/src/select.c +++ b/src/select.c @@ -1340,7 +1340,8 @@ static const char *columnTypeImpl( char const *zOrigCol = 0; #endif - if( NEVER(pExpr==0) || pNC->pSrcList==0 ) return 0; + assert( pExpr!=0 ); + assert( pNC->pSrcList!=0 ); switch( pExpr->op ){ case TK_AGG_COLUMN: case TK_COLUMN: { @@ -1528,6 +1529,7 @@ static void generateColumnNames( } #endif + assert( pTabList!=0 ); if( pParse->colNamesSet || NEVER(v==0) || db->mallocFailed ) return; pParse->colNamesSet = 1; fullNames = (db->flags & SQLITE_FullColNames)!=0; @@ -1540,7 +1542,7 @@ static void generateColumnNames( if( pEList->a[i].zName ){ char *zName = pEList->a[i].zName; sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_TRANSIENT); - }else if( (p->op==TK_COLUMN || p->op==TK_AGG_COLUMN) && pTabList ){ + }else if( p->op==TK_COLUMN || p->op==TK_AGG_COLUMN ){ Table *pTab; char *zCol; int iCol = p->iColumn;