int nTerms; /* Number of terms in the query */
QueryTerm *pTerms; /* Array of terms. Space obtained from malloc() */
int nextIsOr; /* Set the isOr flag on the next inserted term */
- int iColumn; /* Text word parsed must be in this column */
+ int nextColumn; /* Next word parsed must be in this column */
+ int dfltColumn; /* The default column */
} Query;
/* Add a new term pTerm[0..nTerm-1] to the query *q.
t->nTerm = nTerm;
t->isOr = q->nextIsOr;
q->nextIsOr = 0;
- t->iColumn = q->iColumn;
- q->iColumn = -1;
+ t->iColumn = q->nextColumn;
+ q->nextColumn = q->dfltColumn;
}
-/* Free all of the memory that was malloced in order to build *q.
+/* Free all of the dynamically allocated memory held by *q
*/
-static void queryDestroy(Query *q){
+static void queryClear(Query *q){
int i;
for(i = 0; i < q->nTerms; ++i){
free(q->pTerms[i].pTerm);
if( !inPhrase &&
pSegment[iEnd]==':' &&
(iCol = checkColumnSpecifier(pQuery->pFts, pToken, nToken))>=0 ){
- pQuery->iColumn = iCol;
+ pQuery->nextColumn = iCol;
continue;
}
if( !inPhrase && pQuery->nTerms>0 && nToken==2
return pModule->xClose(pCursor);
}
-/* Parse a query string, yielding a Query object [pQuery], which the caller
- * must free. */
-static int parseQuery(fulltext_vtab *v, const char *pInput, int nInput,
- Query *pQuery){
+/* Parse a query string, yielding a Query object pQuery.
+**
+** The calling function will need to queryClear() to clean up
+** the dynamically allocated memory held by pQuery.
+*/
+static int parseQuery(
+ fulltext_vtab *v, /* The fulltext index */
+ const char *zInput, /* Input text of the query string */
+ int nInput, /* Size of the input text */
+ int dfltColumn, /* Default column of the index to match against */
+ Query *pQuery /* Write the parse results here. */
+){
int iInput, inPhrase = 0;
- if( nInput<0 ) nInput = strlen(pInput);
+ if( nInput<0 ) nInput = strlen(zInput);
pQuery->nTerms = 0;
pQuery->pTerms = NULL;
pQuery->nextIsOr = 0;
- pQuery->iColumn = -1;
+ pQuery->nextColumn = dfltColumn;
+ pQuery->dfltColumn = dfltColumn;
pQuery->pFts = v;
for(iInput=0; iInput<nInput; ++iInput){
int i;
- for(i=iInput; i<nInput && pInput[i]!='"'; ++i)
- ;
+ for(i=iInput; i<nInput && zInput[i]!='"'; ++i){}
if( i>iInput ){
- tokenizeSegment(v->pTokenizer, pInput+iInput, i-iInput, inPhrase,
+ tokenizeSegment(v->pTokenizer, zInput+iInput, i-iInput, inPhrase,
pQuery);
}
iInput = i;
if( i<nInput ){
- assert( pInput[i]=='"' );
+ assert( zInput[i]=='"' );
inPhrase = !inPhrase;
}
}
- if( inPhrase ){ /* unmatched quote */
- queryDestroy(pQuery);
+ if( inPhrase ){
+ /* unmatched quote */
+ queryClear(pQuery);
return SQLITE_ERROR;
}
return SQLITE_OK;
}
/* Perform a full-text query using the search expression in
-** pInput[0..nInput-1]. Return a list of matching documents
+** zInput[0..nInput-1]. Return a list of matching documents
** in pResult.
**
** Queries must match column iColumn. Or if iColumn>=nColumn
** they are allowed to match against any column.
*/
-static int fulltextQuery(fulltext_vtab *v, int iColumn,
- const char *pInput, int nInput, DocList **pResult){
+static int fulltextQuery(
+ fulltext_vtab *v, /* The full text index */
+ int iColumn, /* Match against this column by default */
+ const char *zInput, /* The query string */
+ int nInput, /* Number of bytes in zInput[] */
+ DocList **pResult /* Write the result doclist here */
+){
Query q;
int i, rc;
DocList *pLeft = NULL;
DocList *pRight, *pNew;
int nNot = 0;
- int iCol;
- rc = parseQuery(v, pInput, nInput, &q);
+ rc = parseQuery(v, zInput, nInput, iColumn, &q);
if( rc!=SQLITE_OK ) return rc;
/* Merge AND terms. */
continue;
}
- iCol = q.pTerms[i].iColumn;
- if( iCol<0 ) iCol = iColumn;
- rc = docListOfTerm(v, iCol, &q.pTerms[i], &pRight);
+ rc = docListOfTerm(v, q.pTerms[i].iColumn, &q.pTerms[i], &pRight);
if( rc ){
- queryDestroy(&q);
+ queryClear(&q);
return rc;
}
if( pLeft==0 ){
/* Do the EXCEPT terms */
for(i=0; i<q.nTerms; i += q.pTerms[i].nPhrase + 1){
if( !q.pTerms[i].isNot ) continue;
- iCol = q.pTerms[i].iColumn;
- if( iCol<0 ) iCol = iColumn;
- rc = docListOfTerm(v, iCol, &q.pTerms[i], &pRight);
+ rc = docListOfTerm(v, q.pTerms[i].iColumn, &q.pTerms[i], &pRight);
if( rc ){
- queryDestroy(&q);
+ queryClear(&q);
docListDelete(pLeft);
return rc;
}
pLeft = pNew;
}
- queryDestroy(&q);
+ queryClear(&q);
*pResult = pLeft;
return rc;
}
-C Implementation\sof\s"column:"\smodifiers\sin\sFTS1\squeries.\s(CVS\s3411)
-D 2006-09-13T16:02:44
+C Minor\scode\scleanup\sin\sFTS1.\s(CVS\s3412)
+D 2006-09-13T17:17:48
F Makefile.in cabd42d34340f49260bc2a7668c38eba8d4cfd99
F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
F ext/fts1/README.txt 20ac73b006a70bcfd80069bdaf59214b6cf1db5e
F ext/fts1/ft_hash.c 3927bd880e65329bdc6f506555b228b28924921b
F ext/fts1/ft_hash.h 1a35e654a235c2c662d3ca0dfc3138ad60b8b7d5
-F ext/fts1/fts1.c b5d7a61ae136f116427d63b4942540bdde20511e
+F ext/fts1/fts1.c 65aaeb022e4257eec3a6ce10bcf323e77078b10a
F ext/fts1/fts1.h fe8e8f38dd6d2d2645b9b0d6972e80985249575f
F ext/fts1/fts1_hash.c 3196cee866edbebb1c0521e21672e6d599965114
F ext/fts1/fts1_hash.h 957d378355ed29f672cd5add012ce8b088a5e089
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
-P adb780e0dc8bc7dcd1102efbfa4bc17eefdf968e
-R cb518158115dd87ece5a8e7690dc5840
+P 820634f71e3a3499994f82b56b784d22a7e3cdcf
+R 621d72f40c2bc2a8ff0c2901da9a946a
U drh
-Z e9d714f2273a2ad600591f248a85a42b
+Z 31ced45237949ff98b8b01ea025e7b54