| | @@ -135,11 +135,11 @@ |
| 135 | 135 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 136 | 136 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 137 | 137 | */ |
| 138 | 138 | #define SQLITE_VERSION "3.8.1" |
| 139 | 139 | #define SQLITE_VERSION_NUMBER 3008001 |
| 140 | | -#define SQLITE_SOURCE_ID "2013-10-14 21:14:42 9f66dd7e3790c04f0ab724419f5381bd21f9ebad" |
| 140 | +#define SQLITE_SOURCE_ID "2013-10-17 12:57:35 c78be6d786c19073b3a6730dfe3fb1be54f5657a" |
| 141 | 141 | |
| 142 | 142 | /* |
| 143 | 143 | ** CAPI3REF: Run-Time Library Version Numbers |
| 144 | 144 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 145 | 145 | ** |
| | @@ -33015,12 +33015,11 @@ |
| 33015 | 33015 | #endif |
| 33016 | 33016 | assert( pFile->h!=NULL && pFile->h!=INVALID_HANDLE_VALUE ); |
| 33017 | 33017 | OSTRACE(("CLOSE file=%p\n", pFile->h)); |
| 33018 | 33018 | |
| 33019 | 33019 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 33020 | | - rc = winUnmapfile(pFile); |
| 33021 | | - if( rc!=SQLITE_OK ) return rc; |
| 33020 | + winUnmapfile(pFile); |
| 33022 | 33021 | #endif |
| 33023 | 33022 | |
| 33024 | 33023 | do{ |
| 33025 | 33024 | rc = osCloseHandle(pFile->h); |
| 33026 | 33025 | /* SimulateIOError( rc=0; cnt=MX_CLOSE_ATTEMPT; ); */ |
| | @@ -33822,11 +33821,11 @@ |
| 33822 | 33821 | } |
| 33823 | 33822 | *(i64*)pArg = pFile->mmapSizeMax; |
| 33824 | 33823 | if( newLimit>=0 && newLimit!=pFile->mmapSizeMax && pFile->nFetchOut==0 ){ |
| 33825 | 33824 | pFile->mmapSizeMax = newLimit; |
| 33826 | 33825 | if( pFile->mmapSize>0 ){ |
| 33827 | | - (void)winUnmapfile(pFile); |
| 33826 | + winUnmapfile(pFile); |
| 33828 | 33827 | rc = winMapfile(pFile, -1); |
| 33829 | 33828 | } |
| 33830 | 33829 | } |
| 33831 | 33830 | OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc))); |
| 33832 | 33831 | return rc; |
| | @@ -34039,11 +34038,11 @@ |
| 34039 | 34038 | osGetCurrentProcessId(), deleteFlag)); |
| 34040 | 34039 | pp = &winShmNodeList; |
| 34041 | 34040 | while( (p = *pp)!=0 ){ |
| 34042 | 34041 | if( p->nRef==0 ){ |
| 34043 | 34042 | int i; |
| 34044 | | - if( p->mutex ) sqlite3_mutex_free(p->mutex); |
| 34043 | + if( p->mutex ){ sqlite3_mutex_free(p->mutex); } |
| 34045 | 34044 | for(i=0; i<p->nRegion; i++){ |
| 34046 | 34045 | BOOL bRc = osUnmapViewOfFile(p->aRegion[i].pMap); |
| 34047 | 34046 | OSTRACE(("SHM-PURGE-UNMAP pid=%lu, region=%d, rc=%s\n", |
| 34048 | 34047 | osGetCurrentProcessId(), i, bRc ? "ok" : "failed")); |
| 34049 | 34048 | UNUSED_VARIABLE_VALUE(bRc); |
| | @@ -34892,10 +34891,11 @@ |
| 34892 | 34891 | ** API prior to using it. |
| 34893 | 34892 | */ |
| 34894 | 34893 | if( winIsDriveLetterAndColon(zDir) ){ |
| 34895 | 34894 | zConverted = winConvertFromUtf8Filename(zDir); |
| 34896 | 34895 | if( !zConverted ){ |
| 34896 | + sqlite3_free(zBuf); |
| 34897 | 34897 | OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); |
| 34898 | 34898 | return SQLITE_IOERR_NOMEM; |
| 34899 | 34899 | } |
| 34900 | 34900 | if( winIsDir(zConverted) ){ |
| 34901 | 34901 | sqlite3_snprintf(nBuf-30, zBuf, "%s", zDir); |
| | @@ -34904,17 +34904,19 @@ |
| 34904 | 34904 | } |
| 34905 | 34905 | sqlite3_free(zConverted); |
| 34906 | 34906 | }else{ |
| 34907 | 34907 | zConverted = sqlite3MallocZero( nBuf+1 ); |
| 34908 | 34908 | if( !zConverted ){ |
| 34909 | + sqlite3_free(zBuf); |
| 34909 | 34910 | OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); |
| 34910 | 34911 | return SQLITE_IOERR_NOMEM; |
| 34911 | 34912 | } |
| 34912 | 34913 | if( cygwin_conv_path( |
| 34913 | 34914 | osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A, zDir, |
| 34914 | 34915 | zConverted, nBuf+1)<0 ){ |
| 34915 | 34916 | sqlite3_free(zConverted); |
| 34917 | + sqlite3_free(zBuf); |
| 34916 | 34918 | OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_CONVPATH\n")); |
| 34917 | 34919 | return winLogError(SQLITE_IOERR_CONVPATH, (DWORD)errno, |
| 34918 | 34920 | "winGetTempname1", zDir); |
| 34919 | 34921 | } |
| 34920 | 34922 | if( winIsDir(zConverted) ){ |
| | @@ -34924,10 +34926,11 @@ |
| 34924 | 34926 | */ |
| 34925 | 34927 | if( osIsNT() ){ |
| 34926 | 34928 | char *zUtf8 = winUnicodeToUtf8(zConverted); |
| 34927 | 34929 | if( !zUtf8 ){ |
| 34928 | 34930 | sqlite3_free(zConverted); |
| 34931 | + sqlite3_free(zBuf); |
| 34929 | 34932 | OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); |
| 34930 | 34933 | return SQLITE_IOERR_NOMEM; |
| 34931 | 34934 | } |
| 34932 | 34935 | sqlite3_snprintf(nBuf-30, zBuf, "%s", zUtf8); |
| 34933 | 34936 | sqlite3_free(zUtf8); |
| | @@ -34939,11 +34942,10 @@ |
| 34939 | 34942 | break; |
| 34940 | 34943 | } |
| 34941 | 34944 | } |
| 34942 | 34945 | sqlite3_free(zConverted); |
| 34943 | 34946 | } |
| 34944 | | - break; |
| 34945 | 34947 | } |
| 34946 | 34948 | } |
| 34947 | 34949 | #elif !SQLITE_OS_WINRT && !defined(__CYGWIN__) |
| 34948 | 34950 | else if( osIsNT() ){ |
| 34949 | 34951 | char *zMulti; |
| | @@ -35309,13 +35311,13 @@ |
| 35309 | 35311 | pFile->zDeleteOnClose = zConverted; |
| 35310 | 35312 | }else |
| 35311 | 35313 | #endif |
| 35312 | 35314 | { |
| 35313 | 35315 | sqlite3_free(zConverted); |
| 35314 | | - sqlite3_free(zTmpname); |
| 35315 | 35316 | } |
| 35316 | 35317 | |
| 35318 | + sqlite3_free(zTmpname); |
| 35317 | 35319 | pFile->pMethod = &winIoMethod; |
| 35318 | 35320 | pFile->pVfs = pVfs; |
| 35319 | 35321 | pFile->h = h; |
| 35320 | 35322 | if( isReadonly ){ |
| 35321 | 35323 | pFile->ctrlFlags |= WINFILE_RDONLY; |
| | @@ -52042,10 +52044,22 @@ |
| 52042 | 52044 | ** MX_CELL_SIZE(pBt) bytes. |
| 52043 | 52045 | */ |
| 52044 | 52046 | static void allocateTempSpace(BtShared *pBt){ |
| 52045 | 52047 | if( !pBt->pTmpSpace ){ |
| 52046 | 52048 | pBt->pTmpSpace = sqlite3PageMalloc( pBt->pageSize ); |
| 52049 | + |
| 52050 | + /* One of the uses of pBt->pTmpSpace is to format cells before |
| 52051 | + ** inserting them into a leaf page (function fillInCell()). If |
| 52052 | + ** a cell is less than 4 bytes in size, it is rounded up to 4 bytes |
| 52053 | + ** by the various routines that manipulate binary cells. Which |
| 52054 | + ** can mean that fillInCell() only initializes the first 2 or 3 |
| 52055 | + ** bytes of pTmpSpace, but that the first 4 bytes are copied from |
| 52056 | + ** it into a database page. This is not actually a problem, but it |
| 52057 | + ** does cause a valgrind error when the 1 or 2 bytes of unitialized |
| 52058 | + ** data is passed to system call write(). So to avoid this error, |
| 52059 | + ** zero the first 4 bytes of temp space here. */ |
| 52060 | + if( pBt->pTmpSpace ) memset(pBt->pTmpSpace, 0, 4); |
| 52047 | 52061 | } |
| 52048 | 52062 | } |
| 52049 | 52063 | |
| 52050 | 52064 | /* |
| 52051 | 52065 | ** Free the pBt->pTmpSpace allocation |
| | @@ -75424,11 +75438,11 @@ |
| 75424 | 75438 | pNC->nErr++; |
| 75425 | 75439 | } |
| 75426 | 75440 | }else{ |
| 75427 | 75441 | /* EVIDENCE-OF: R-61304-29449 The unlikely(X) function is equivalent to |
| 75428 | 75442 | ** likelihood(X, 0.0625). |
| 75429 | | - ** EVIDENCE-OF: R-35738-39582 The unlikely(X) fucntion is short-hand for |
| 75443 | + ** EVIDENCE-OF: R-01283-11636 The unlikely(X) function is short-hand for |
| 75430 | 75444 | ** likelihood(X,0.0625). */ |
| 75431 | 75445 | pExpr->iTable = 62; /* TUNING: Default 2nd arg to unlikely() is 0.0625 */ |
| 75432 | 75446 | } |
| 75433 | 75447 | } |
| 75434 | 75448 | } |
| | @@ -127745,10 +127759,11 @@ |
| 127745 | 127759 | sqlite3_vtab_cursor base; /* Base class used by SQLite core */ |
| 127746 | 127760 | Fts3MultiSegReader csr; /* Must be right after "base" */ |
| 127747 | 127761 | Fts3SegFilter filter; |
| 127748 | 127762 | char *zStop; |
| 127749 | 127763 | int nStop; /* Byte-length of string zStop */ |
| 127764 | + int iLangid; /* Language id to query */ |
| 127750 | 127765 | int isEof; /* True if cursor is at EOF */ |
| 127751 | 127766 | sqlite3_int64 iRowid; /* Current rowid */ |
| 127752 | 127767 | |
| 127753 | 127768 | int iCol; /* Current value of 'col' column */ |
| 127754 | 127769 | int nStat; /* Size of aStat[] array */ |
| | @@ -127759,11 +127774,12 @@ |
| 127759 | 127774 | }; |
| 127760 | 127775 | |
| 127761 | 127776 | /* |
| 127762 | 127777 | ** Schema of the terms table. |
| 127763 | 127778 | */ |
| 127764 | | -#define FTS3_TERMS_SCHEMA "CREATE TABLE x(term, col, documents, occurrences)" |
| 127779 | +#define FTS3_AUX_SCHEMA \ |
| 127780 | + "CREATE TABLE x(term, col, documents, occurrences, languageid HIDDEN)" |
| 127765 | 127781 | |
| 127766 | 127782 | /* |
| 127767 | 127783 | ** This function does all the work for both the xConnect and xCreate methods. |
| 127768 | 127784 | ** These tables have no persistent representation of their own, so xConnect |
| 127769 | 127785 | ** and xCreate are identical operations. |
| | @@ -127806,11 +127822,11 @@ |
| 127806 | 127822 | }else{ |
| 127807 | 127823 | zFts3 = argv[3]; |
| 127808 | 127824 | } |
| 127809 | 127825 | nFts3 = (int)strlen(zFts3); |
| 127810 | 127826 | |
| 127811 | | - rc = sqlite3_declare_vtab(db, FTS3_TERMS_SCHEMA); |
| 127827 | + rc = sqlite3_declare_vtab(db, FTS3_AUX_SCHEMA); |
| 127812 | 127828 | if( rc!=SQLITE_OK ) return rc; |
| 127813 | 127829 | |
| 127814 | 127830 | nByte = sizeof(Fts3auxTable) + sizeof(Fts3Table) + nDb + nFts3 + 2; |
| 127815 | 127831 | p = (Fts3auxTable *)sqlite3_malloc(nByte); |
| 127816 | 127832 | if( !p ) return SQLITE_NOMEM; |
| | @@ -127866,10 +127882,12 @@ |
| 127866 | 127882 | ){ |
| 127867 | 127883 | int i; |
| 127868 | 127884 | int iEq = -1; |
| 127869 | 127885 | int iGe = -1; |
| 127870 | 127886 | int iLe = -1; |
| 127887 | + int iLangid = -1; |
| 127888 | + int iNext = 1; /* Next free argvIndex value */ |
| 127871 | 127889 | |
| 127872 | 127890 | UNUSED_PARAMETER(pVTab); |
| 127873 | 127891 | |
| 127874 | 127892 | /* This vtab delivers always results in "ORDER BY term ASC" order. */ |
| 127875 | 127893 | if( pInfo->nOrderBy==1 |
| | @@ -127877,40 +127895,52 @@ |
| 127877 | 127895 | && pInfo->aOrderBy[0].desc==0 |
| 127878 | 127896 | ){ |
| 127879 | 127897 | pInfo->orderByConsumed = 1; |
| 127880 | 127898 | } |
| 127881 | 127899 | |
| 127882 | | - /* Search for equality and range constraints on the "term" column. */ |
| 127900 | + /* Search for equality and range constraints on the "term" column. |
| 127901 | + ** And equality constraints on the hidden "languageid" column. */ |
| 127883 | 127902 | for(i=0; i<pInfo->nConstraint; i++){ |
| 127884 | | - if( pInfo->aConstraint[i].usable && pInfo->aConstraint[i].iColumn==0 ){ |
| 127903 | + if( pInfo->aConstraint[i].usable ){ |
| 127885 | 127904 | int op = pInfo->aConstraint[i].op; |
| 127886 | | - if( op==SQLITE_INDEX_CONSTRAINT_EQ ) iEq = i; |
| 127887 | | - if( op==SQLITE_INDEX_CONSTRAINT_LT ) iLe = i; |
| 127888 | | - if( op==SQLITE_INDEX_CONSTRAINT_LE ) iLe = i; |
| 127889 | | - if( op==SQLITE_INDEX_CONSTRAINT_GT ) iGe = i; |
| 127890 | | - if( op==SQLITE_INDEX_CONSTRAINT_GE ) iGe = i; |
| 127905 | + int iCol = pInfo->aConstraint[i].iColumn; |
| 127906 | + |
| 127907 | + if( iCol==0 ){ |
| 127908 | + if( op==SQLITE_INDEX_CONSTRAINT_EQ ) iEq = i; |
| 127909 | + if( op==SQLITE_INDEX_CONSTRAINT_LT ) iLe = i; |
| 127910 | + if( op==SQLITE_INDEX_CONSTRAINT_LE ) iLe = i; |
| 127911 | + if( op==SQLITE_INDEX_CONSTRAINT_GT ) iGe = i; |
| 127912 | + if( op==SQLITE_INDEX_CONSTRAINT_GE ) iGe = i; |
| 127913 | + } |
| 127914 | + if( iCol==4 ){ |
| 127915 | + if( op==SQLITE_INDEX_CONSTRAINT_EQ ) iLangid = i; |
| 127916 | + } |
| 127891 | 127917 | } |
| 127892 | 127918 | } |
| 127893 | 127919 | |
| 127894 | 127920 | if( iEq>=0 ){ |
| 127895 | 127921 | pInfo->idxNum = FTS4AUX_EQ_CONSTRAINT; |
| 127896 | | - pInfo->aConstraintUsage[iEq].argvIndex = 1; |
| 127922 | + pInfo->aConstraintUsage[iEq].argvIndex = iNext++; |
| 127897 | 127923 | pInfo->estimatedCost = 5; |
| 127898 | 127924 | }else{ |
| 127899 | 127925 | pInfo->idxNum = 0; |
| 127900 | 127926 | pInfo->estimatedCost = 20000; |
| 127901 | 127927 | if( iGe>=0 ){ |
| 127902 | 127928 | pInfo->idxNum += FTS4AUX_GE_CONSTRAINT; |
| 127903 | | - pInfo->aConstraintUsage[iGe].argvIndex = 1; |
| 127929 | + pInfo->aConstraintUsage[iGe].argvIndex = iNext++; |
| 127904 | 127930 | pInfo->estimatedCost /= 2; |
| 127905 | 127931 | } |
| 127906 | 127932 | if( iLe>=0 ){ |
| 127907 | 127933 | pInfo->idxNum += FTS4AUX_LE_CONSTRAINT; |
| 127908 | | - pInfo->aConstraintUsage[iLe].argvIndex = 1 + (iGe>=0); |
| 127934 | + pInfo->aConstraintUsage[iLe].argvIndex = iNext++; |
| 127909 | 127935 | pInfo->estimatedCost /= 2; |
| 127910 | 127936 | } |
| 127911 | 127937 | } |
| 127938 | + if( iLangid>=0 ){ |
| 127939 | + pInfo->aConstraintUsage[iLangid].argvIndex = iNext++; |
| 127940 | + pInfo->estimatedCost--; |
| 127941 | + } |
| 127912 | 127942 | |
| 127913 | 127943 | return SQLITE_OK; |
| 127914 | 127944 | } |
| 127915 | 127945 | |
| 127916 | 127946 | /* |
| | @@ -128066,21 +128096,42 @@ |
| 128066 | 128096 | sqlite3_value **apVal /* Arguments for the indexing scheme */ |
| 128067 | 128097 | ){ |
| 128068 | 128098 | Fts3auxCursor *pCsr = (Fts3auxCursor *)pCursor; |
| 128069 | 128099 | Fts3Table *pFts3 = ((Fts3auxTable *)pCursor->pVtab)->pFts3Tab; |
| 128070 | 128100 | int rc; |
| 128071 | | - int isScan; |
| 128101 | + int isScan = 0; |
| 128102 | + int iLangVal = 0; /* Language id to query */ |
| 128103 | + |
| 128104 | + int iEq = -1; /* Index of term=? value in apVal */ |
| 128105 | + int iGe = -1; /* Index of term>=? value in apVal */ |
| 128106 | + int iLe = -1; /* Index of term<=? value in apVal */ |
| 128107 | + int iLangid = -1; /* Index of languageid=? value in apVal */ |
| 128108 | + int iNext = 0; |
| 128072 | 128109 | |
| 128073 | 128110 | UNUSED_PARAMETER(nVal); |
| 128074 | 128111 | UNUSED_PARAMETER(idxStr); |
| 128075 | 128112 | |
| 128076 | 128113 | assert( idxStr==0 ); |
| 128077 | 128114 | assert( idxNum==FTS4AUX_EQ_CONSTRAINT || idxNum==0 |
| 128078 | 128115 | || idxNum==FTS4AUX_LE_CONSTRAINT || idxNum==FTS4AUX_GE_CONSTRAINT |
| 128079 | 128116 | || idxNum==(FTS4AUX_LE_CONSTRAINT|FTS4AUX_GE_CONSTRAINT) |
| 128080 | 128117 | ); |
| 128081 | | - isScan = (idxNum!=FTS4AUX_EQ_CONSTRAINT); |
| 128118 | + |
| 128119 | + if( idxNum==FTS4AUX_EQ_CONSTRAINT ){ |
| 128120 | + iEq = iNext++; |
| 128121 | + }else{ |
| 128122 | + isScan = 1; |
| 128123 | + if( idxNum & FTS4AUX_GE_CONSTRAINT ){ |
| 128124 | + iGe = iNext++; |
| 128125 | + } |
| 128126 | + if( idxNum & FTS4AUX_LE_CONSTRAINT ){ |
| 128127 | + iLe = iNext++; |
| 128128 | + } |
| 128129 | + } |
| 128130 | + if( iNext<nVal ){ |
| 128131 | + iLangid = iNext++; |
| 128132 | + } |
| 128082 | 128133 | |
| 128083 | 128134 | /* In case this cursor is being reused, close and zero it. */ |
| 128084 | 128135 | testcase(pCsr->filter.zTerm); |
| 128085 | 128136 | sqlite3Fts3SegReaderFinish(&pCsr->csr); |
| 128086 | 128137 | sqlite3_free((void *)pCsr->filter.zTerm); |
| | @@ -128088,26 +128139,39 @@ |
| 128088 | 128139 | memset(&pCsr->csr, 0, ((u8*)&pCsr[1]) - (u8*)&pCsr->csr); |
| 128089 | 128140 | |
| 128090 | 128141 | pCsr->filter.flags = FTS3_SEGMENT_REQUIRE_POS|FTS3_SEGMENT_IGNORE_EMPTY; |
| 128091 | 128142 | if( isScan ) pCsr->filter.flags |= FTS3_SEGMENT_SCAN; |
| 128092 | 128143 | |
| 128093 | | - if( idxNum&(FTS4AUX_EQ_CONSTRAINT|FTS4AUX_GE_CONSTRAINT) ){ |
| 128144 | + if( iEq>=0 || iGe>=0 ){ |
| 128094 | 128145 | const unsigned char *zStr = sqlite3_value_text(apVal[0]); |
| 128146 | + assert( (iEq==0 && iGe==-1) || (iEq==-1 && iGe==0) ); |
| 128095 | 128147 | if( zStr ){ |
| 128096 | 128148 | pCsr->filter.zTerm = sqlite3_mprintf("%s", zStr); |
| 128097 | 128149 | pCsr->filter.nTerm = sqlite3_value_bytes(apVal[0]); |
| 128098 | 128150 | if( pCsr->filter.zTerm==0 ) return SQLITE_NOMEM; |
| 128099 | 128151 | } |
| 128100 | 128152 | } |
| 128101 | | - if( idxNum&FTS4AUX_LE_CONSTRAINT ){ |
| 128102 | | - int iIdx = (idxNum&FTS4AUX_GE_CONSTRAINT) ? 1 : 0; |
| 128103 | | - pCsr->zStop = sqlite3_mprintf("%s", sqlite3_value_text(apVal[iIdx])); |
| 128104 | | - pCsr->nStop = sqlite3_value_bytes(apVal[iIdx]); |
| 128153 | + |
| 128154 | + if( iLe>=0 ){ |
| 128155 | + pCsr->zStop = sqlite3_mprintf("%s", sqlite3_value_text(apVal[iLe])); |
| 128156 | + pCsr->nStop = sqlite3_value_bytes(apVal[iLe]); |
| 128105 | 128157 | if( pCsr->zStop==0 ) return SQLITE_NOMEM; |
| 128106 | 128158 | } |
| 128159 | + |
| 128160 | + if( iLangid>=0 ){ |
| 128161 | + iLangVal = sqlite3_value_int(apVal[iLangid]); |
| 128107 | 128162 | |
| 128108 | | - rc = sqlite3Fts3SegReaderCursor(pFts3, 0, 0, FTS3_SEGCURSOR_ALL, |
| 128163 | + /* If the user specified a negative value for the languageid, use zero |
| 128164 | + ** instead. This works, as the "languageid=?" constraint will also |
| 128165 | + ** be tested by the VDBE layer. The test will always be false (since |
| 128166 | + ** this module will not return a row with a negative languageid), and |
| 128167 | + ** so the overall query will return zero rows. */ |
| 128168 | + if( iLangVal<0 ) iLangVal = 0; |
| 128169 | + } |
| 128170 | + pCsr->iLangid = iLangVal; |
| 128171 | + |
| 128172 | + rc = sqlite3Fts3SegReaderCursor(pFts3, iLangVal, 0, FTS3_SEGCURSOR_ALL, |
| 128109 | 128173 | pCsr->filter.zTerm, pCsr->filter.nTerm, 0, isScan, &pCsr->csr |
| 128110 | 128174 | ); |
| 128111 | 128175 | if( rc==SQLITE_OK ){ |
| 128112 | 128176 | rc = sqlite3Fts3SegReaderStart(pFts3, &pCsr->csr, &pCsr->filter); |
| 128113 | 128177 | } |
| | @@ -128127,28 +128191,41 @@ |
| 128127 | 128191 | /* |
| 128128 | 128192 | ** xColumn - Return a column value. |
| 128129 | 128193 | */ |
| 128130 | 128194 | static int fts3auxColumnMethod( |
| 128131 | 128195 | sqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */ |
| 128132 | | - sqlite3_context *pContext, /* Context for sqlite3_result_xxx() calls */ |
| 128196 | + sqlite3_context *pCtx, /* Context for sqlite3_result_xxx() calls */ |
| 128133 | 128197 | int iCol /* Index of column to read value from */ |
| 128134 | 128198 | ){ |
| 128135 | 128199 | Fts3auxCursor *p = (Fts3auxCursor *)pCursor; |
| 128136 | 128200 | |
| 128137 | 128201 | assert( p->isEof==0 ); |
| 128138 | | - if( iCol==0 ){ /* Column "term" */ |
| 128139 | | - sqlite3_result_text(pContext, p->csr.zTerm, p->csr.nTerm, SQLITE_TRANSIENT); |
| 128140 | | - }else if( iCol==1 ){ /* Column "col" */ |
| 128141 | | - if( p->iCol ){ |
| 128142 | | - sqlite3_result_int(pContext, p->iCol-1); |
| 128143 | | - }else{ |
| 128144 | | - sqlite3_result_text(pContext, "*", -1, SQLITE_STATIC); |
| 128145 | | - } |
| 128146 | | - }else if( iCol==2 ){ /* Column "documents" */ |
| 128147 | | - sqlite3_result_int64(pContext, p->aStat[p->iCol].nDoc); |
| 128148 | | - }else{ /* Column "occurrences" */ |
| 128149 | | - sqlite3_result_int64(pContext, p->aStat[p->iCol].nOcc); |
| 128202 | + switch( iCol ){ |
| 128203 | + case 0: /* term */ |
| 128204 | + sqlite3_result_text(pCtx, p->csr.zTerm, p->csr.nTerm, SQLITE_TRANSIENT); |
| 128205 | + break; |
| 128206 | + |
| 128207 | + case 1: /* col */ |
| 128208 | + if( p->iCol ){ |
| 128209 | + sqlite3_result_int(pCtx, p->iCol-1); |
| 128210 | + }else{ |
| 128211 | + sqlite3_result_text(pCtx, "*", -1, SQLITE_STATIC); |
| 128212 | + } |
| 128213 | + break; |
| 128214 | + |
| 128215 | + case 2: /* documents */ |
| 128216 | + sqlite3_result_int64(pCtx, p->aStat[p->iCol].nDoc); |
| 128217 | + break; |
| 128218 | + |
| 128219 | + case 3: /* occurrences */ |
| 128220 | + sqlite3_result_int64(pCtx, p->aStat[p->iCol].nOcc); |
| 128221 | + break; |
| 128222 | + |
| 128223 | + default: /* languageid */ |
| 128224 | + assert( iCol==4 ); |
| 128225 | + sqlite3_result_int(pCtx, p->iLangid); |
| 128226 | + break; |
| 128150 | 128227 | } |
| 128151 | 128228 | |
| 128152 | 128229 | return SQLITE_OK; |
| 128153 | 128230 | } |
| 128154 | 128231 | |
| 128155 | 128232 | |