| | @@ -222,11 +222,11 @@ |
| 222 | 222 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 223 | 223 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 224 | 224 | */ |
| 225 | 225 | #define SQLITE_VERSION "3.8.5" |
| 226 | 226 | #define SQLITE_VERSION_NUMBER 3008005 |
| 227 | | -#define SQLITE_SOURCE_ID "2014-05-24 17:15:15 ebfb51fe40756713d269b4c0ade752666910bb6e" |
| 227 | +#define SQLITE_SOURCE_ID "2014-05-28 20:22:28 d018a34a05cec6adda61ed225d084c587343f2a6" |
| 228 | 228 | |
| 229 | 229 | /* |
| 230 | 230 | ** CAPI3REF: Run-Time Library Version Numbers |
| 231 | 231 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 232 | 232 | ** |
| | @@ -11141,11 +11141,11 @@ |
| 11141 | 11141 | int tnum; /* DB Page containing root of this index */ |
| 11142 | 11142 | LogEst szIdxRow; /* Estimated average row size in bytes */ |
| 11143 | 11143 | u16 nKeyCol; /* Number of columns forming the key */ |
| 11144 | 11144 | u16 nColumn; /* Number of columns stored in the index */ |
| 11145 | 11145 | u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ |
| 11146 | | - unsigned autoIndex:2; /* 1==UNIQUE, 2==PRIMARY KEY, 0==CREATE INDEX */ |
| 11146 | + unsigned idxType:2; /* 1==UNIQUE, 2==PRIMARY KEY, 0==CREATE INDEX */ |
| 11147 | 11147 | unsigned bUnordered:1; /* Use this index for == or IN queries only */ |
| 11148 | 11148 | unsigned uniqNotNull:1; /* True if UNIQUE and NOT NULL for all columns */ |
| 11149 | 11149 | unsigned isResized:1; /* True if resizeIndexObject() has been called */ |
| 11150 | 11150 | unsigned isCovering:1; /* True if this is a covering index */ |
| 11151 | 11151 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| | @@ -11154,10 +11154,20 @@ |
| 11154 | 11154 | tRowcnt *aAvgEq; /* Average nEq values for keys not in aSample */ |
| 11155 | 11155 | IndexSample *aSample; /* Samples of the left-most key */ |
| 11156 | 11156 | #endif |
| 11157 | 11157 | }; |
| 11158 | 11158 | |
| 11159 | +/* |
| 11160 | +** Allowed values for Index.idxType |
| 11161 | +*/ |
| 11162 | +#define SQLITE_IDXTYPE_APPDEF 0 /* Created using CREATE INDEX */ |
| 11163 | +#define SQLITE_IDXTYPE_UNIQUE 1 /* Implements a UNIQUE constraint */ |
| 11164 | +#define SQLITE_IDXTYPE_PRIMARYKEY 2 /* Is the PRIMARY KEY for the table */ |
| 11165 | + |
| 11166 | +/* Return true if index X is a PRIMARY KEY index */ |
| 11167 | +#define IsPrimaryKeyIndex(X) ((X)->idxType==SQLITE_IDXTYPE_PRIMARYKEY) |
| 11168 | + |
| 11159 | 11169 | /* |
| 11160 | 11170 | ** Each sample stored in the sqlite_stat3 table is represented in memory |
| 11161 | 11171 | ** using a structure of this type. See documentation at the top of the |
| 11162 | 11172 | ** analyze.c source file for additional information. |
| 11163 | 11173 | */ |
| | @@ -34430,11 +34440,11 @@ |
| 34430 | 34440 | #endif |
| 34431 | 34441 | if( res == 0 ){ |
| 34432 | 34442 | pFile->lastErrno = osGetLastError(); |
| 34433 | 34443 | /* No need to log a failure to lock */ |
| 34434 | 34444 | } |
| 34435 | | - OSTRACE(("READ-LOCK file=%p, rc=%s\n", pFile->h, sqlite3ErrName(res))); |
| 34445 | + OSTRACE(("READ-LOCK file=%p, result=%d\n", pFile->h, res)); |
| 34436 | 34446 | return res; |
| 34437 | 34447 | } |
| 34438 | 34448 | |
| 34439 | 34449 | /* |
| 34440 | 34450 | ** Undo a readlock |
| | @@ -34454,11 +34464,11 @@ |
| 34454 | 34464 | if( res==0 && ((lastErrno = osGetLastError())!=ERROR_NOT_LOCKED) ){ |
| 34455 | 34465 | pFile->lastErrno = lastErrno; |
| 34456 | 34466 | winLogError(SQLITE_IOERR_UNLOCK, pFile->lastErrno, |
| 34457 | 34467 | "winUnlockReadLock", pFile->zPath); |
| 34458 | 34468 | } |
| 34459 | | - OSTRACE(("READ-UNLOCK file=%p, rc=%s\n", pFile->h, sqlite3ErrName(res))); |
| 34469 | + OSTRACE(("READ-UNLOCK file=%p, result=%d\n", pFile->h, res)); |
| 34460 | 34470 | return res; |
| 34461 | 34471 | } |
| 34462 | 34472 | |
| 34463 | 34473 | /* |
| 34464 | 34474 | ** Lock the file with the lock specified by parameter locktype - one |
| | @@ -34529,12 +34539,12 @@ |
| 34529 | 34539 | ** around problems caused by indexing and/or anti-virus software on |
| 34530 | 34540 | ** Windows systems. |
| 34531 | 34541 | ** If you are using this code as a model for alternative VFSes, do not |
| 34532 | 34542 | ** copy this retry logic. It is a hack intended for Windows only. |
| 34533 | 34543 | */ |
| 34534 | | - OSTRACE(("LOCK-PENDING-FAIL file=%p, count=%d, rc=%s\n", |
| 34535 | | - pFile->h, cnt, sqlite3ErrName(res))); |
| 34544 | + OSTRACE(("LOCK-PENDING-FAIL file=%p, count=%d, result=%d\n", |
| 34545 | + pFile->h, cnt, res)); |
| 34536 | 34546 | if( cnt ) sqlite3_win32_sleep(1); |
| 34537 | 34547 | } |
| 34538 | 34548 | gotPendingLock = res; |
| 34539 | 34549 | if( !res ){ |
| 34540 | 34550 | lastErrno = osGetLastError(); |
| | @@ -34615,29 +34625,29 @@ |
| 34615 | 34625 | ** This routine checks if there is a RESERVED lock held on the specified |
| 34616 | 34626 | ** file by this or any other process. If such a lock is held, return |
| 34617 | 34627 | ** non-zero, otherwise zero. |
| 34618 | 34628 | */ |
| 34619 | 34629 | static int winCheckReservedLock(sqlite3_file *id, int *pResOut){ |
| 34620 | | - int rc; |
| 34630 | + int res; |
| 34621 | 34631 | winFile *pFile = (winFile*)id; |
| 34622 | 34632 | |
| 34623 | 34633 | SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); |
| 34624 | 34634 | OSTRACE(("TEST-WR-LOCK file=%p, pResOut=%p\n", pFile->h, pResOut)); |
| 34625 | 34635 | |
| 34626 | 34636 | assert( id!=0 ); |
| 34627 | 34637 | if( pFile->locktype>=RESERVED_LOCK ){ |
| 34628 | | - rc = 1; |
| 34629 | | - OSTRACE(("TEST-WR-LOCK file=%p, rc=%d (local)\n", pFile->h, rc)); |
| 34638 | + res = 1; |
| 34639 | + OSTRACE(("TEST-WR-LOCK file=%p, result=%d (local)\n", pFile->h, res)); |
| 34630 | 34640 | }else{ |
| 34631 | | - rc = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS,RESERVED_BYTE, 0, 1, 0); |
| 34632 | | - if( rc ){ |
| 34641 | + res = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS,RESERVED_BYTE, 0, 1, 0); |
| 34642 | + if( res ){ |
| 34633 | 34643 | winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0); |
| 34634 | 34644 | } |
| 34635 | | - rc = !rc; |
| 34636 | | - OSTRACE(("TEST-WR-LOCK file=%p, rc=%d (remote)\n", pFile->h, rc)); |
| 34645 | + res = !res; |
| 34646 | + OSTRACE(("TEST-WR-LOCK file=%p, result=%d (remote)\n", pFile->h, res)); |
| 34637 | 34647 | } |
| 34638 | | - *pResOut = rc; |
| 34648 | + *pResOut = res; |
| 34639 | 34649 | OSTRACE(("TEST-WR-LOCK file=%p, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n", |
| 34640 | 34650 | pFile->h, pResOut, *pResOut)); |
| 34641 | 34651 | return SQLITE_OK; |
| 34642 | 34652 | } |
| 34643 | 34653 | |
| | @@ -55333,16 +55343,10 @@ |
| 55333 | 55343 | assert( pCur->eState==CURSOR_VALID ); |
| 55334 | 55344 | assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); |
| 55335 | 55345 | assert( cursorHoldsMutex(pCur) ); |
| 55336 | 55346 | assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell ); |
| 55337 | 55347 | assert( pCur->info.nSize>0 ); |
| 55338 | | -#if 0 |
| 55339 | | - if( pCur->info.nSize==0 ){ |
| 55340 | | - btreeParseCell(pCur->apPage[pCur->iPage], pCur->aiIdx[pCur->iPage], |
| 55341 | | - &pCur->info); |
| 55342 | | - } |
| 55343 | | -#endif |
| 55344 | 55348 | *pAmt = pCur->info.nLocal; |
| 55345 | 55349 | return (void*)(pCur->info.pCell + pCur->info.nHeader); |
| 55346 | 55350 | } |
| 55347 | 55351 | |
| 55348 | 55352 | |
| | @@ -73737,11 +73741,11 @@ |
| 73737 | 73741 | #ifdef SQLITE_USE_FCNTL_TRACE |
| 73738 | 73742 | zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql); |
| 73739 | 73743 | if( zTrace ){ |
| 73740 | 73744 | int i; |
| 73741 | 73745 | for(i=0; i<db->nDb; i++){ |
| 73742 | | - if( MASKBIT(i) & p->btreeMask)==0 ) continue; |
| 73746 | + if( (MASKBIT(i) & p->btreeMask)==0 ) continue; |
| 73743 | 73747 | sqlite3_file_control(db, db->aDb[i].zName, SQLITE_FCNTL_TRACE, zTrace); |
| 73744 | 73748 | } |
| 73745 | 73749 | } |
| 73746 | 73750 | #endif /* SQLITE_USE_FCNTL_TRACE */ |
| 73747 | 73751 | #ifdef SQLITE_DEBUG |
| | @@ -74692,11 +74696,10 @@ |
| 74692 | 74696 | nRead = (int)(pSorter->iWriteOff - iStart); |
| 74693 | 74697 | } |
| 74694 | 74698 | rc = sqlite3OsRead( |
| 74695 | 74699 | pSorter->pTemp1, &pIter->aBuffer[iBuf], nRead, iStart |
| 74696 | 74700 | ); |
| 74697 | | - assert( rc!=SQLITE_IOERR_SHORT_READ ); |
| 74698 | 74701 | } |
| 74699 | 74702 | |
| 74700 | 74703 | if( rc==SQLITE_OK ){ |
| 74701 | 74704 | u64 nByte; /* Size of PMA in bytes */ |
| 74702 | 74705 | pIter->iEof = pSorter->iWriteOff; |
| | @@ -83655,11 +83658,11 @@ |
| 83655 | 83658 | nCol = pIdx->nKeyCol; |
| 83656 | 83659 | aGotoChng = sqlite3DbMallocRaw(db, sizeof(int)*(nCol+1)); |
| 83657 | 83660 | if( aGotoChng==0 ) continue; |
| 83658 | 83661 | |
| 83659 | 83662 | /* Populate the register containing the index name. */ |
| 83660 | | - if( pIdx->autoIndex==2 && !HasRowid(pTab) ){ |
| 83663 | + if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){ |
| 83661 | 83664 | zIdxName = pTab->zName; |
| 83662 | 83665 | }else{ |
| 83663 | 83666 | zIdxName = pIdx->zName; |
| 83664 | 83667 | } |
| 83665 | 83668 | sqlite3VdbeAddOp4(v, OP_String8, 0, regIdxname, 0, zIdxName, 0); |
| | @@ -86022,11 +86025,11 @@ |
| 86022 | 86025 | /* |
| 86023 | 86026 | ** Return the PRIMARY KEY index of a table |
| 86024 | 86027 | */ |
| 86025 | 86028 | SQLITE_PRIVATE Index *sqlite3PrimaryKeyIndex(Table *pTab){ |
| 86026 | 86029 | Index *p; |
| 86027 | | - for(p=pTab->pIndex; p && p->autoIndex!=2; p=p->pNext){} |
| 86030 | + for(p=pTab->pIndex; p && !IsPrimaryKeyIndex(p); p=p->pNext){} |
| 86028 | 86031 | return p; |
| 86029 | 86032 | } |
| 86030 | 86033 | |
| 86031 | 86034 | /* |
| 86032 | 86035 | ** Return the column of index pIdx that corresponds to table |
| | @@ -86551,11 +86554,11 @@ |
| 86551 | 86554 | Index *p; |
| 86552 | 86555 | if( v ) pParse->addrSkipPK = sqlite3VdbeAddOp0(v, OP_Noop); |
| 86553 | 86556 | p = sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0, |
| 86554 | 86557 | 0, sortOrder, 0); |
| 86555 | 86558 | if( p ){ |
| 86556 | | - p->autoIndex = 2; |
| 86559 | + p->idxType = SQLITE_IDXTYPE_PRIMARYKEY; |
| 86557 | 86560 | if( v ) sqlite3VdbeJumpHere(v, pParse->addrSkipPK); |
| 86558 | 86561 | } |
| 86559 | 86562 | pList = 0; |
| 86560 | 86563 | } |
| 86561 | 86564 | |
| | @@ -86926,11 +86929,11 @@ |
| 86926 | 86929 | pTab->aCol[pTab->iPKey].zName); |
| 86927 | 86930 | pList->a[0].sortOrder = pParse->iPkSortOrder; |
| 86928 | 86931 | assert( pParse->pNewTable==pTab ); |
| 86929 | 86932 | pPk = sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0); |
| 86930 | 86933 | if( pPk==0 ) return; |
| 86931 | | - pPk->autoIndex = 2; |
| 86934 | + pPk->idxType = SQLITE_IDXTYPE_PRIMARYKEY; |
| 86932 | 86935 | pTab->iPKey = -1; |
| 86933 | 86936 | }else{ |
| 86934 | 86937 | pPk = sqlite3PrimaryKeyIndex(pTab); |
| 86935 | 86938 | } |
| 86936 | 86939 | pPk->isCovering = 1; |
| | @@ -86949,11 +86952,11 @@ |
| 86949 | 86952 | /* Update the in-memory representation of all UNIQUE indices by converting |
| 86950 | 86953 | ** the final rowid column into one or more columns of the PRIMARY KEY. |
| 86951 | 86954 | */ |
| 86952 | 86955 | for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ |
| 86953 | 86956 | int n; |
| 86954 | | - if( pIdx->autoIndex==2 ) continue; |
| 86957 | + if( IsPrimaryKeyIndex(pIdx) ) continue; |
| 86955 | 86958 | for(i=n=0; i<nPk; i++){ |
| 86956 | 86959 | if( !hasColumn(pIdx->aiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) ) n++; |
| 86957 | 86960 | } |
| 86958 | 86961 | if( n==0 ){ |
| 86959 | 86962 | /* This index is a superset of the primary key */ |
| | @@ -88029,11 +88032,11 @@ |
| 88029 | 88032 | ** is a primary key or unique-constraint on the most recent column added |
| 88030 | 88033 | ** to the table currently under construction. |
| 88031 | 88034 | ** |
| 88032 | 88035 | ** If the index is created successfully, return a pointer to the new Index |
| 88033 | 88036 | ** structure. This is used by sqlite3AddPrimaryKey() to mark the index |
| 88034 | | -** as the tables primary key (Index.autoIndex==2). |
| 88037 | +** as the tables primary key (Index.idxType==SQLITE_IDXTYPE_PRIMARYKEY) |
| 88035 | 88038 | */ |
| 88036 | 88039 | SQLITE_PRIVATE Index *sqlite3CreateIndex( |
| 88037 | 88040 | Parse *pParse, /* All information about this parse */ |
| 88038 | 88041 | Token *pName1, /* First part of index name. May be NULL */ |
| 88039 | 88042 | Token *pName2, /* Second part of index name. May be NULL */ |
| | @@ -88244,11 +88247,11 @@ |
| 88244 | 88247 | zExtra += nName + 1; |
| 88245 | 88248 | memcpy(pIndex->zName, zName, nName+1); |
| 88246 | 88249 | pIndex->pTable = pTab; |
| 88247 | 88250 | pIndex->onError = (u8)onError; |
| 88248 | 88251 | pIndex->uniqNotNull = onError!=OE_None; |
| 88249 | | - pIndex->autoIndex = (u8)(pName==0); |
| 88252 | + pIndex->idxType = pName ? SQLITE_IDXTYPE_APPDEF : SQLITE_IDXTYPE_UNIQUE; |
| 88250 | 88253 | pIndex->pSchema = db->aDb[iDb].pSchema; |
| 88251 | 88254 | pIndex->nKeyCol = pList->nExpr; |
| 88252 | 88255 | if( pPIWhere ){ |
| 88253 | 88256 | sqlite3ResolveSelfReference(pParse, pTab, NC_PartIdx, pPIWhere, 0); |
| 88254 | 88257 | pIndex->pPartIdxWhere = pPIWhere; |
| | @@ -88356,11 +88359,11 @@ |
| 88356 | 88359 | */ |
| 88357 | 88360 | Index *pIdx; |
| 88358 | 88361 | for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ |
| 88359 | 88362 | int k; |
| 88360 | 88363 | assert( pIdx->onError!=OE_None ); |
| 88361 | | - assert( pIdx->autoIndex ); |
| 88364 | + assert( pIdx->idxType!=SQLITE_IDXTYPE_APPDEF ); |
| 88362 | 88365 | assert( pIndex->onError!=OE_None ); |
| 88363 | 88366 | |
| 88364 | 88367 | if( pIdx->nKeyCol!=pIndex->nKeyCol ) continue; |
| 88365 | 88368 | for(k=0; k<pIdx->nKeyCol; k++){ |
| 88366 | 88369 | const char *z1; |
| | @@ -88579,11 +88582,11 @@ |
| 88579 | 88582 | sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase); |
| 88580 | 88583 | } |
| 88581 | 88584 | pParse->checkSchema = 1; |
| 88582 | 88585 | goto exit_drop_index; |
| 88583 | 88586 | } |
| 88584 | | - if( pIndex->autoIndex ){ |
| 88587 | + if( pIndex->idxType!=SQLITE_IDXTYPE_APPDEF ){ |
| 88585 | 88588 | sqlite3ErrorMsg(pParse, "index associated with UNIQUE " |
| 88586 | 88589 | "or PRIMARY KEY constraint cannot be dropped", 0); |
| 88587 | 88590 | goto exit_drop_index; |
| 88588 | 88591 | } |
| 88589 | 88592 | iDb = sqlite3SchemaToIndex(db, pIndex->pSchema); |
| | @@ -89238,11 +89241,12 @@ |
| 89238 | 89241 | sqlite3StrAccumAppend(&errMsg, ".", 1); |
| 89239 | 89242 | sqlite3StrAccumAppendAll(&errMsg, zCol); |
| 89240 | 89243 | } |
| 89241 | 89244 | zErr = sqlite3StrAccumFinish(&errMsg); |
| 89242 | 89245 | sqlite3HaltConstraint(pParse, |
| 89243 | | - (pIdx->autoIndex==2)?SQLITE_CONSTRAINT_PRIMARYKEY:SQLITE_CONSTRAINT_UNIQUE, |
| 89246 | + IsPrimaryKeyIndex(pIdx) ? SQLITE_CONSTRAINT_PRIMARYKEY |
| 89247 | + : SQLITE_CONSTRAINT_UNIQUE, |
| 89244 | 89248 | onError, zErr, P4_DYNAMIC, P5_ConstraintUnique); |
| 89245 | 89249 | } |
| 89246 | 89250 | |
| 89247 | 89251 | |
| 89248 | 89252 | /* |
| | @@ -92816,12 +92820,12 @@ |
| 92816 | 92820 | ** column of pFKey, then this index is a winner. */ |
| 92817 | 92821 | |
| 92818 | 92822 | if( zKey==0 ){ |
| 92819 | 92823 | /* If zKey is NULL, then this foreign key is implicitly mapped to |
| 92820 | 92824 | ** the PRIMARY KEY of table pParent. The PRIMARY KEY index may be |
| 92821 | | - ** identified by the test (Index.autoIndex==2). */ |
| 92822 | | - if( pIdx->autoIndex==2 ){ |
| 92825 | + ** identified by the test. */ |
| 92826 | + if( IsPrimaryKeyIndex(pIdx) ){ |
| 92823 | 92827 | if( aiCol ){ |
| 92824 | 92828 | int i; |
| 92825 | 92829 | for(i=0; i<nCol; i++) aiCol[i] = pFKey->aCol[i].iFrom; |
| 92826 | 92830 | } |
| 92827 | 92831 | break; |
| | @@ -95411,11 +95415,11 @@ |
| 95411 | 95415 | ** For a UNIQUE index, only conflict if the PRIMARY KEY values |
| 95412 | 95416 | ** of the matched index row are different from the original PRIMARY |
| 95413 | 95417 | ** KEY values of this row before the update. */ |
| 95414 | 95418 | int addrJump = sqlite3VdbeCurrentAddr(v)+pPk->nKeyCol; |
| 95415 | 95419 | int op = OP_Ne; |
| 95416 | | - int regCmp = (pIdx->autoIndex==2 ? regIdx : regR); |
| 95420 | + int regCmp = (IsPrimaryKeyIndex(pIdx) ? regIdx : regR); |
| 95417 | 95421 | |
| 95418 | 95422 | for(i=0; i<pPk->nKeyCol; i++){ |
| 95419 | 95423 | char *p4 = (char*)sqlite3LocateCollSeq(pParse, pPk->azColl[i]); |
| 95420 | 95424 | x = pPk->aiColumn[i]; |
| 95421 | 95425 | if( i==(pPk->nKeyCol-1) ){ |
| | @@ -95512,11 +95516,11 @@ |
| 95512 | 95516 | VdbeCoverage(v); |
| 95513 | 95517 | } |
| 95514 | 95518 | sqlite3VdbeAddOp2(v, OP_IdxInsert, iIdxCur+i, aRegIdx[i]); |
| 95515 | 95519 | pik_flags = 0; |
| 95516 | 95520 | if( useSeekResult ) pik_flags = OPFLAG_USESEEKRESULT; |
| 95517 | | - if( pIdx->autoIndex==2 && !HasRowid(pTab) ){ |
| 95521 | + if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){ |
| 95518 | 95522 | assert( pParse->nested==0 ); |
| 95519 | 95523 | pik_flags |= OPFLAG_NCHANGE; |
| 95520 | 95524 | } |
| 95521 | 95525 | if( pik_flags ) sqlite3VdbeChangeP5(v, pik_flags); |
| 95522 | 95526 | } |
| | @@ -95598,11 +95602,11 @@ |
| 95598 | 95602 | } |
| 95599 | 95603 | if( piIdxCur ) *piIdxCur = iBase; |
| 95600 | 95604 | for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ |
| 95601 | 95605 | int iIdxCur = iBase++; |
| 95602 | 95606 | assert( pIdx->pSchema==pTab->pSchema ); |
| 95603 | | - if( pIdx->autoIndex==2 && !HasRowid(pTab) && piDataCur ){ |
| 95607 | + if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) && piDataCur ){ |
| 95604 | 95608 | *piDataCur = iIdxCur; |
| 95605 | 95609 | } |
| 95606 | 95610 | if( aToOpen==0 || aToOpen[i+1] ){ |
| 95607 | 95611 | sqlite3VdbeAddOp3(v, op, iIdxCur, pIdx->tnum, iDb); |
| 95608 | 95612 | sqlite3VdbeSetP4KeyInfo(pParse, pIdx); |
| | @@ -105060,11 +105064,11 @@ |
| 105060 | 105064 | Parse *pParse, /* Parse context */ |
| 105061 | 105065 | Table *pTab, /* Table being queried */ |
| 105062 | 105066 | Index *pIdx /* Index used to optimize scan, or NULL */ |
| 105063 | 105067 | ){ |
| 105064 | 105068 | if( pParse->explain==2 ){ |
| 105065 | | - int bCover = (pIdx!=0 && (HasRowid(pTab) || pIdx->autoIndex!=2)); |
| 105069 | + int bCover = (pIdx!=0 && (HasRowid(pTab) || !IsPrimaryKeyIndex(pIdx))); |
| 105066 | 105070 | char *zEqp = sqlite3MPrintf(pParse->db, "SCAN TABLE %s%s%s", |
| 105067 | 105071 | pTab->zName, |
| 105068 | 105072 | bCover ? " USING COVERING INDEX " : "", |
| 105069 | 105073 | bCover ? pIdx->zName : "" |
| 105070 | 105074 | ); |
| | @@ -107488,11 +107492,11 @@ |
| 107488 | 107492 | */ |
| 107489 | 107493 | pTabList->a[0].iCursor = iBaseCur = iDataCur = pParse->nTab++; |
| 107490 | 107494 | iIdxCur = iDataCur+1; |
| 107491 | 107495 | pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab); |
| 107492 | 107496 | for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ |
| 107493 | | - if( pIdx->autoIndex==2 && pPk!=0 ){ |
| 107497 | + if( IsPrimaryKeyIndex(pIdx) && pPk!=0 ){ |
| 107494 | 107498 | iDataCur = pParse->nTab; |
| 107495 | 107499 | pTabList->a[0].iCursor = iDataCur; |
| 107496 | 107500 | } |
| 107497 | 107501 | pParse->nTab++; |
| 107498 | 107502 | } |
| | @@ -112732,11 +112736,11 @@ |
| 112732 | 112736 | ){ |
| 112733 | 112737 | const char *zFmt; |
| 112734 | 112738 | Index *pIdx = pLoop->u.btree.pIndex; |
| 112735 | 112739 | char *zWhere = explainIndexRange(db, pLoop, pItem->pTab); |
| 112736 | 112740 | assert( !(flags&WHERE_AUTO_INDEX) || (flags&WHERE_IDX_ONLY) ); |
| 112737 | | - if( !HasRowid(pItem->pTab) && pIdx->autoIndex==2 ){ |
| 112741 | + if( !HasRowid(pItem->pTab) && IsPrimaryKeyIndex(pIdx) ){ |
| 112738 | 112742 | zFmt = zWhere ? "%s USING PRIMARY KEY%.0s%s" : "%s%.0s%s"; |
| 112739 | 112743 | }else if( flags & WHERE_AUTO_INDEX ){ |
| 112740 | 112744 | zFmt = "%s USING AUTOMATIC COVERING INDEX%.0s%s"; |
| 112741 | 112745 | }else if( flags & WHERE_IDX_ONLY ){ |
| 112742 | 112746 | zFmt = "%s USING COVERING INDEX %s%s"; |
| | @@ -113233,11 +113237,11 @@ |
| 113233 | 113237 | }else if( HasRowid(pIdx->pTable) ){ |
| 113234 | 113238 | iRowidReg = ++pParse->nMem; |
| 113235 | 113239 | sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, iRowidReg); |
| 113236 | 113240 | sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg); |
| 113237 | 113241 | sqlite3VdbeAddOp2(v, OP_Seek, iCur, iRowidReg); /* Deferred seek */ |
| 113238 | | - }else{ |
| 113242 | + }else if( iCur!=iIdxCur ){ |
| 113239 | 113243 | Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable); |
| 113240 | 113244 | iRowidReg = sqlite3GetTempRange(pParse, pPk->nKeyCol); |
| 113241 | 113245 | for(j=0; j<pPk->nKeyCol; j++){ |
| 113242 | 113246 | k = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[j]); |
| 113243 | 113247 | sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, iRowidReg+j); |
| | @@ -113303,10 +113307,14 @@ |
| 113303 | 113307 | ** |
| 113304 | 113308 | ** Return 2 # Jump back to the Gosub |
| 113305 | 113309 | ** |
| 113306 | 113310 | ** B: <after the loop> |
| 113307 | 113311 | ** |
| 113312 | + ** Added 2014-05-26: If the table is a WITHOUT ROWID table, then |
| 113313 | + ** use an ephermeral index instead of a RowSet to record the primary |
| 113314 | + ** keys of the rows we have already seen. |
| 113315 | + ** |
| 113308 | 113316 | */ |
| 113309 | 113317 | WhereClause *pOrWc; /* The OR-clause broken out into subterms */ |
| 113310 | 113318 | SrcList *pOrTab; /* Shortened table list or OR-clause generation */ |
| 113311 | 113319 | Index *pCov = 0; /* Potential covering index (or NULL) */ |
| 113312 | 113320 | int iCovCur = pParse->nTab++; /* Cursor used for index scans (if any) */ |
| | @@ -113317,10 +113325,11 @@ |
| 113317 | 113325 | int iLoopBody = sqlite3VdbeMakeLabel(v); /* Start of loop body */ |
| 113318 | 113326 | int iRetInit; /* Address of regReturn init */ |
| 113319 | 113327 | int untestedTerms = 0; /* Some terms not completely tested */ |
| 113320 | 113328 | int ii; /* Loop counter */ |
| 113321 | 113329 | Expr *pAndExpr = 0; /* An ".. AND (...)" expression */ |
| 113330 | + Table *pTab = pTabItem->pTab; |
| 113322 | 113331 | |
| 113323 | 113332 | pTerm = pLoop->aLTerm[0]; |
| 113324 | 113333 | assert( pTerm!=0 ); |
| 113325 | 113334 | assert( pTerm->eOperator & WO_OR ); |
| 113326 | 113335 | assert( (pTerm->wtFlags & TERM_ORINFO)!=0 ); |
| | @@ -113349,11 +113358,12 @@ |
| 113349 | 113358 | }else{ |
| 113350 | 113359 | pOrTab = pWInfo->pTabList; |
| 113351 | 113360 | } |
| 113352 | 113361 | |
| 113353 | 113362 | /* Initialize the rowset register to contain NULL. An SQL NULL is |
| 113354 | | - ** equivalent to an empty rowset. |
| 113363 | + ** equivalent to an empty rowset. Or, create an ephermeral index |
| 113364 | + ** capable of holding primary keys in the case of a WITHOUT ROWID. |
| 113355 | 113365 | ** |
| 113356 | 113366 | ** Also initialize regReturn to contain the address of the instruction |
| 113357 | 113367 | ** immediately following the OP_Return at the bottom of the loop. This |
| 113358 | 113368 | ** is required in a few obscure LEFT JOIN cases where control jumps |
| 113359 | 113369 | ** over the top of the loop into the body of it. In this case the |
| | @@ -113360,13 +113370,20 @@ |
| 113360 | 113370 | ** correct response for the end-of-loop code (the OP_Return) is to |
| 113361 | 113371 | ** fall through to the next instruction, just as an OP_Next does if |
| 113362 | 113372 | ** called on an uninitialized cursor. |
| 113363 | 113373 | */ |
| 113364 | 113374 | if( (pWInfo->wctrlFlags & WHERE_DUPLICATES_OK)==0 ){ |
| 113365 | | - regRowset = ++pParse->nMem; |
| 113375 | + if( HasRowid(pTab) ){ |
| 113376 | + regRowset = ++pParse->nMem; |
| 113377 | + sqlite3VdbeAddOp2(v, OP_Null, 0, regRowset); |
| 113378 | + }else{ |
| 113379 | + Index *pPk = sqlite3PrimaryKeyIndex(pTab); |
| 113380 | + regRowset = pParse->nTab++; |
| 113381 | + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, regRowset, pPk->nKeyCol); |
| 113382 | + sqlite3VdbeSetP4KeyInfo(pParse, pPk); |
| 113383 | + } |
| 113366 | 113384 | regRowid = ++pParse->nMem; |
| 113367 | | - sqlite3VdbeAddOp2(v, OP_Null, 0, regRowset); |
| 113368 | 113385 | } |
| 113369 | 113386 | iRetInit = sqlite3VdbeAddOp2(v, OP_Integer, 0, regReturn); |
| 113370 | 113387 | |
| 113371 | 113388 | /* If the original WHERE clause is z of the form: (x1 OR x2 OR ...) AND y |
| 113372 | 113389 | ** Then for every term xN, evaluate as the subexpression: xN AND z |
| | @@ -113398,15 +113415,20 @@ |
| 113398 | 113415 | if( pAndExpr ){ |
| 113399 | 113416 | pAndExpr = sqlite3PExpr(pParse, TK_AND, 0, pAndExpr, 0); |
| 113400 | 113417 | } |
| 113401 | 113418 | } |
| 113402 | 113419 | |
| 113420 | + /* Run a separate WHERE clause for each term of the OR clause. After |
| 113421 | + ** eliminating duplicates from other WHERE clauses, the action for each |
| 113422 | + ** sub-WHERE clause is to to invoke the main loop body as a subroutine. |
| 113423 | + */ |
| 113403 | 113424 | for(ii=0; ii<pOrWc->nTerm; ii++){ |
| 113404 | 113425 | WhereTerm *pOrTerm = &pOrWc->a[ii]; |
| 113405 | 113426 | if( pOrTerm->leftCursor==iCur || (pOrTerm->eOperator & WO_AND)!=0 ){ |
| 113406 | | - WhereInfo *pSubWInfo; /* Info for single OR-term scan */ |
| 113407 | | - Expr *pOrExpr = pOrTerm->pExpr; |
| 113427 | + WhereInfo *pSubWInfo; /* Info for single OR-term scan */ |
| 113428 | + Expr *pOrExpr = pOrTerm->pExpr; /* Current OR clause term */ |
| 113429 | + int j1 = 0; /* Address of jump operation */ |
| 113408 | 113430 | if( pAndExpr && !ExprHasProperty(pOrExpr, EP_FromJoin) ){ |
| 113409 | 113431 | pAndExpr->pLeft = pOrExpr; |
| 113410 | 113432 | pOrExpr = pAndExpr; |
| 113411 | 113433 | } |
| 113412 | 113434 | /* Loop through table entries that match term pOrTerm. */ |
| | @@ -113417,20 +113439,66 @@ |
| 113417 | 113439 | if( pSubWInfo ){ |
| 113418 | 113440 | WhereLoop *pSubLoop; |
| 113419 | 113441 | explainOneScan( |
| 113420 | 113442 | pParse, pOrTab, &pSubWInfo->a[0], iLevel, pLevel->iFrom, 0 |
| 113421 | 113443 | ); |
| 113444 | + /* This is the sub-WHERE clause body. First skip over |
| 113445 | + ** duplicate rows from prior sub-WHERE clauses, and record the |
| 113446 | + ** rowid (or PRIMARY KEY) for the current row so that the same |
| 113447 | + ** row will be skipped in subsequent sub-WHERE clauses. |
| 113448 | + */ |
| 113422 | 113449 | if( (pWInfo->wctrlFlags & WHERE_DUPLICATES_OK)==0 ){ |
| 113423 | | - int iSet = ((ii==pOrWc->nTerm-1)?-1:ii); |
| 113424 | 113450 | int r; |
| 113425 | | - r = sqlite3ExprCodeGetColumn(pParse, pTabItem->pTab, -1, iCur, |
| 113426 | | - regRowid, 0); |
| 113427 | | - sqlite3VdbeAddOp4Int(v, OP_RowSetTest, regRowset, |
| 113428 | | - sqlite3VdbeCurrentAddr(v)+2, r, iSet); |
| 113429 | | - VdbeCoverage(v); |
| 113451 | + int iSet = ((ii==pOrWc->nTerm-1)?-1:ii); |
| 113452 | + if( HasRowid(pTab) ){ |
| 113453 | + r = sqlite3ExprCodeGetColumn(pParse, pTab, -1, iCur, regRowid, 0); |
| 113454 | + j1 = sqlite3VdbeAddOp4Int(v, OP_RowSetTest, regRowset, 0, r,iSet); |
| 113455 | + VdbeCoverage(v); |
| 113456 | + }else{ |
| 113457 | + Index *pPk = sqlite3PrimaryKeyIndex(pTab); |
| 113458 | + int nPk = pPk->nKeyCol; |
| 113459 | + int iPk; |
| 113460 | + |
| 113461 | + /* Read the PK into an array of temp registers. */ |
| 113462 | + r = sqlite3GetTempRange(pParse, nPk); |
| 113463 | + for(iPk=0; iPk<nPk; iPk++){ |
| 113464 | + int iCol = pPk->aiColumn[iPk]; |
| 113465 | + sqlite3ExprCodeGetColumn(pParse, pTab, iCol, iCur, r+iPk, 0); |
| 113466 | + } |
| 113467 | + |
| 113468 | + /* Check if the temp table already contains this key. If so, |
| 113469 | + ** the row has already been included in the result set and |
| 113470 | + ** can be ignored (by jumping past the Gosub below). Otherwise, |
| 113471 | + ** insert the key into the temp table and proceed with processing |
| 113472 | + ** the row. |
| 113473 | + ** |
| 113474 | + ** Use some of the same optimizations as OP_RowSetTest: If iSet |
| 113475 | + ** is zero, assume that the key cannot already be present in |
| 113476 | + ** the temp table. And if iSet is -1, assume that there is no |
| 113477 | + ** need to insert the key into the temp table, as it will never |
| 113478 | + ** be tested for. */ |
| 113479 | + if( iSet ){ |
| 113480 | + j1 = sqlite3VdbeAddOp4Int(v, OP_Found, regRowset, 0, r, nPk); |
| 113481 | + VdbeCoverage(v); |
| 113482 | + } |
| 113483 | + if( iSet>=0 ){ |
| 113484 | + sqlite3VdbeAddOp3(v, OP_MakeRecord, r, nPk, regRowid); |
| 113485 | + sqlite3VdbeAddOp3(v, OP_IdxInsert, regRowset, regRowid, 0); |
| 113486 | + if( iSet ) sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); |
| 113487 | + } |
| 113488 | + |
| 113489 | + /* Release the array of temp registers */ |
| 113490 | + sqlite3ReleaseTempRange(pParse, r, nPk); |
| 113491 | + } |
| 113430 | 113492 | } |
| 113493 | + |
| 113494 | + /* Invoke the main loop body as a subroutine */ |
| 113431 | 113495 | sqlite3VdbeAddOp2(v, OP_Gosub, regReturn, iLoopBody); |
| 113496 | + |
| 113497 | + /* Jump here (skipping the main loop body subroutine) if the |
| 113498 | + ** current sub-WHERE row is a duplicate from prior sub-WHEREs. */ |
| 113499 | + if( j1 ) sqlite3VdbeJumpHere(v, j1); |
| 113432 | 113500 | |
| 113433 | 113501 | /* The pSubWInfo->untestedTerms flag means that this OR term |
| 113434 | 113502 | ** contained one or more AND term from a notReady table. The |
| 113435 | 113503 | ** terms from the notReady table could not be tested and will |
| 113436 | 113504 | ** need to be tested later. |
| | @@ -113451,10 +113519,11 @@ |
| 113451 | 113519 | */ |
| 113452 | 113520 | pSubLoop = pSubWInfo->a[0].pWLoop; |
| 113453 | 113521 | assert( (pSubLoop->wsFlags & WHERE_AUTO_INDEX)==0 ); |
| 113454 | 113522 | if( (pSubLoop->wsFlags & WHERE_INDEXED)!=0 |
| 113455 | 113523 | && (ii==0 || pSubLoop->u.btree.pIndex==pCov) |
| 113524 | + && (HasRowid(pTab) || !IsPrimaryKeyIndex(pSubLoop->u.btree.pIndex)) |
| 113456 | 113525 | ){ |
| 113457 | 113526 | assert( pSubWInfo->a[0].iIdxCur==iCovCur ); |
| 113458 | 113527 | pCov = pSubLoop->u.btree.pIndex; |
| 113459 | 113528 | }else{ |
| 113460 | 113529 | pCov = 0; |
| | @@ -114776,11 +114845,10 @@ |
| 114776 | 114845 | if( pWInfo->wctrlFlags & WHERE_AND_ONLY ) return SQLITE_OK; |
| 114777 | 114846 | pWCEnd = pWC->a + pWC->nTerm; |
| 114778 | 114847 | pNew = pBuilder->pNew; |
| 114779 | 114848 | memset(&sSum, 0, sizeof(sSum)); |
| 114780 | 114849 | pItem = pWInfo->pTabList->a + pNew->iTab; |
| 114781 | | - if( !HasRowid(pItem->pTab) ) return SQLITE_OK; |
| 114782 | 114850 | iCur = pItem->iCursor; |
| 114783 | 114851 | |
| 114784 | 114852 | for(pTerm=pWC->a; pTerm<pWCEnd && rc==SQLITE_OK; pTerm++){ |
| 114785 | 114853 | if( (pTerm->eOperator & WO_OR)!=0 |
| 114786 | 114854 | && (pTerm->u.pOrInfo->indexable & pNew->maskSelf)!=0 |
| | @@ -116025,11 +116093,18 @@ |
| 116025 | 116093 | Index *pIx = pLoop->u.btree.pIndex; |
| 116026 | 116094 | int iIndexCur; |
| 116027 | 116095 | int op = OP_OpenRead; |
| 116028 | 116096 | /* iIdxCur is always set if to a positive value if ONEPASS is possible */ |
| 116029 | 116097 | assert( iIdxCur!=0 || (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 ); |
| 116030 | | - if( pWInfo->okOnePass ){ |
| 116098 | + if( !HasRowid(pTab) && IsPrimaryKeyIndex(pIx) |
| 116099 | + && (wctrlFlags & WHERE_ONETABLE_ONLY)!=0 |
| 116100 | + ){ |
| 116101 | + /* This is one term of an OR-optimization using the PRIMARY KEY of a |
| 116102 | + ** WITHOUT ROWID table. No need for a separate index */ |
| 116103 | + iIndexCur = pLevel->iTabCur; |
| 116104 | + op = 0; |
| 116105 | + }else if( pWInfo->okOnePass ){ |
| 116031 | 116106 | Index *pJ = pTabItem->pTab->pIndex; |
| 116032 | 116107 | iIndexCur = iIdxCur; |
| 116033 | 116108 | assert( wctrlFlags & WHERE_ONEPASS_DESIRED ); |
| 116034 | 116109 | while( ALWAYS(pJ) && pJ!=pIx ){ |
| 116035 | 116110 | iIndexCur++; |
| | @@ -116043,13 +116118,15 @@ |
| 116043 | 116118 | iIndexCur = pParse->nTab++; |
| 116044 | 116119 | } |
| 116045 | 116120 | pLevel->iIdxCur = iIndexCur; |
| 116046 | 116121 | assert( pIx->pSchema==pTab->pSchema ); |
| 116047 | 116122 | assert( iIndexCur>=0 ); |
| 116048 | | - sqlite3VdbeAddOp3(v, op, iIndexCur, pIx->tnum, iDb); |
| 116049 | | - sqlite3VdbeSetP4KeyInfo(pParse, pIx); |
| 116050 | | - VdbeComment((v, "%s", pIx->zName)); |
| 116123 | + if( op ){ |
| 116124 | + sqlite3VdbeAddOp3(v, op, iIndexCur, pIx->tnum, iDb); |
| 116125 | + sqlite3VdbeSetP4KeyInfo(pParse, pIx); |
| 116126 | + VdbeComment((v, "%s", pIx->zName)); |
| 116127 | + } |
| 116051 | 116128 | } |
| 116052 | 116129 | if( iDb>=0 ) sqlite3CodeVerifySchema(pParse, iDb); |
| 116053 | 116130 | notReady &= ~getMask(&pWInfo->sMaskSet, pTabItem->iCursor); |
| 116054 | 116131 | } |
| 116055 | 116132 | pWInfo->iTop = sqlite3VdbeCurrentAddr(v); |
| | @@ -127015,11 +127092,13 @@ |
| 127015 | 127092 | /* Fill in the abNotindexed array */ |
| 127016 | 127093 | for(iCol=0; iCol<nCol; iCol++){ |
| 127017 | 127094 | int n = (int)strlen(p->azColumn[iCol]); |
| 127018 | 127095 | for(i=0; i<nNotindexed; i++){ |
| 127019 | 127096 | char *zNot = azNotindexed[i]; |
| 127020 | | - if( zNot && 0==sqlite3_strnicmp(p->azColumn[iCol], zNot, n) ){ |
| 127097 | + if( zNot && n==(int)strlen(zNot) |
| 127098 | + && 0==sqlite3_strnicmp(p->azColumn[iCol], zNot, n) |
| 127099 | + ){ |
| 127021 | 127100 | p->abNotindexed[iCol] = 1; |
| 127022 | 127101 | sqlite3_free(zNot); |
| 127023 | 127102 | azNotindexed[i] = 0; |
| 127024 | 127103 | } |
| 127025 | 127104 | } |
| | @@ -132492,11 +132571,11 @@ |
| 132492 | 132571 | if( rc==SQLITE_OK && !*ppExpr ){ rc = SQLITE_DONE; } |
| 132493 | 132572 | *pnConsumed = (int)(zInput - z) + 1 + nConsumed; |
| 132494 | 132573 | return rc; |
| 132495 | 132574 | }else if( *zInput==')' ){ |
| 132496 | 132575 | pParse->nNest--; |
| 132497 | | - *pnConsumed = (zInput - z) + 1; |
| 132576 | + *pnConsumed = (int)((zInput - z) + 1); |
| 132498 | 132577 | *ppExpr = 0; |
| 132499 | 132578 | return SQLITE_DONE; |
| 132500 | 132579 | } |
| 132501 | 132580 | } |
| 132502 | 132581 | |
| | @@ -138568,11 +138647,11 @@ |
| 138568 | 138647 | ** such segments are smaller than nLimit bytes in size, they will be |
| 138569 | 138648 | ** promoted to level iAbsLevel. */ |
| 138570 | 138649 | sqlite3_bind_int64(pRange, 1, iAbsLevel+1); |
| 138571 | 138650 | sqlite3_bind_int64(pRange, 2, iLast); |
| 138572 | 138651 | while( SQLITE_ROW==sqlite3_step(pRange) ){ |
| 138573 | | - i64 nSize, dummy; |
| 138652 | + i64 nSize = 0, dummy; |
| 138574 | 138653 | fts3ReadEndBlockField(pRange, 2, &dummy, &nSize); |
| 138575 | 138654 | if( nSize<=0 || nSize>nLimit ){ |
| 138576 | 138655 | /* If nSize==0, then the %_segdir.end_block field does not not |
| 138577 | 138656 | ** contain a size value. This happens if it was written by an |
| 138578 | 138657 | ** old version of FTS. In this case it is not possible to determine |
| | @@ -140373,11 +140452,11 @@ |
| 140373 | 140452 | |
| 140374 | 140453 | if( rc==SQLITE_OK ){ |
| 140375 | 140454 | rc = fts3IncrmergeOutputIdx(p, iAbsLevel, &iIdx); |
| 140376 | 140455 | assert( bUseHint==1 || bUseHint==0 ); |
| 140377 | 140456 | if( iIdx==0 || (bUseHint && iIdx==1) ){ |
| 140378 | | - int bIgnore; |
| 140457 | + int bIgnore = 0; |
| 140379 | 140458 | rc = fts3SegmentIsMaxLevel(p, iAbsLevel+1, &bIgnore); |
| 140380 | 140459 | if( bIgnore ){ |
| 140381 | 140460 | pFilter->flags |= FTS3_SEGMENT_IGNORE_EMPTY; |
| 140382 | 140461 | } |
| 140383 | 140462 | } |
| 140384 | 140463 | |