fts5_expr.c 91 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268
  1. /*
  2. ** 2014 May 31
  3. **
  4. ** The author disclaims copyright to this source code. In place of
  5. ** a legal notice, here is a blessing:
  6. **
  7. ** May you do good and not evil.
  8. ** May you find forgiveness for yourself and forgive others.
  9. ** May you share freely, never taking more than you give.
  10. **
  11. ******************************************************************************
  12. **
  13. */
  14. #include "fts5Int.h"
  15. #include "fts5parse.h"
  16. #ifndef SQLITE_FTS5_MAX_EXPR_DEPTH
  17. # define SQLITE_FTS5_MAX_EXPR_DEPTH 256
  18. #endif
  19. /*
  20. ** All token types in the generated fts5parse.h file are greater than 0.
  21. */
  22. #define FTS5_EOF 0
  23. #define FTS5_LARGEST_INT64 (0xffffffff|(((i64)0x7fffffff)<<32))
  24. typedef struct Fts5ExprTerm Fts5ExprTerm;
  25. /*
  26. ** Functions generated by lemon from fts5parse.y.
  27. */
  28. void *sqlite3Fts5ParserAlloc(void *(*mallocProc)(u64));
  29. void sqlite3Fts5ParserFree(void*, void (*freeProc)(void*));
  30. void sqlite3Fts5Parser(void*, int, Fts5Token, Fts5Parse*);
  31. #ifndef NDEBUG
  32. #include <stdio.h>
  33. void sqlite3Fts5ParserTrace(FILE*, char*);
  34. #endif
  35. int sqlite3Fts5ParserFallback(int);
  36. struct Fts5Expr {
  37. Fts5Index *pIndex;
  38. Fts5Config *pConfig;
  39. Fts5ExprNode *pRoot;
  40. int bDesc; /* Iterate in descending rowid order */
  41. int nPhrase; /* Number of phrases in expression */
  42. Fts5ExprPhrase **apExprPhrase; /* Pointers to phrase objects */
  43. };
  44. /*
  45. ** eType:
  46. ** Expression node type. Usually one of:
  47. **
  48. ** FTS5_AND (nChild, apChild valid)
  49. ** FTS5_OR (nChild, apChild valid)
  50. ** FTS5_NOT (nChild, apChild valid)
  51. ** FTS5_STRING (pNear valid)
  52. ** FTS5_TERM (pNear valid)
  53. **
  54. ** An expression node with eType==0 may also exist. It always matches zero
  55. ** rows. This is created when a phrase containing no tokens is parsed.
  56. ** e.g. "".
  57. **
  58. ** iHeight:
  59. ** Distance from this node to furthest leaf. This is always 0 for nodes
  60. ** of type FTS5_STRING and FTS5_TERM. For all other nodes it is one
  61. ** greater than the largest child value.
  62. */
  63. struct Fts5ExprNode {
  64. int eType; /* Node type */
  65. int bEof; /* True at EOF */
  66. int bNomatch; /* True if entry is not a match */
  67. int iHeight; /* Distance to tree leaf nodes */
  68. /* Next method for this node. */
  69. int (*xNext)(Fts5Expr*, Fts5ExprNode*, int, i64);
  70. i64 iRowid; /* Current rowid */
  71. Fts5ExprNearset *pNear; /* For FTS5_STRING - cluster of phrases */
  72. /* Child nodes. For a NOT node, this array always contains 2 entries. For
  73. ** AND or OR nodes, it contains 2 or more entries. */
  74. int nChild; /* Number of child nodes */
  75. Fts5ExprNode *apChild[1]; /* Array of child nodes */
  76. };
  77. #define Fts5NodeIsString(p) ((p)->eType==FTS5_TERM || (p)->eType==FTS5_STRING)
  78. /*
  79. ** Invoke the xNext method of an Fts5ExprNode object. This macro should be
  80. ** used as if it has the same signature as the xNext() methods themselves.
  81. */
  82. #define fts5ExprNodeNext(a,b,c,d) (b)->xNext((a), (b), (c), (d))
  83. /*
  84. ** An instance of the following structure represents a single search term
  85. ** or term prefix.
  86. */
  87. struct Fts5ExprTerm {
  88. u8 bPrefix; /* True for a prefix term */
  89. u8 bFirst; /* True if token must be first in column */
  90. char *pTerm; /* Term data */
  91. int nQueryTerm; /* Effective size of term in bytes */
  92. int nFullTerm; /* Size of term in bytes incl. tokendata */
  93. Fts5IndexIter *pIter; /* Iterator for this term */
  94. Fts5ExprTerm *pSynonym; /* Pointer to first in list of synonyms */
  95. };
  96. /*
  97. ** A phrase. One or more terms that must appear in a contiguous sequence
  98. ** within a document for it to match.
  99. */
  100. struct Fts5ExprPhrase {
  101. Fts5ExprNode *pNode; /* FTS5_STRING node this phrase is part of */
  102. Fts5Buffer poslist; /* Current position list */
  103. int nTerm; /* Number of entries in aTerm[] */
  104. Fts5ExprTerm aTerm[1]; /* Terms that make up this phrase */
  105. };
  106. /*
  107. ** One or more phrases that must appear within a certain token distance of
  108. ** each other within each matching document.
  109. */
  110. struct Fts5ExprNearset {
  111. int nNear; /* NEAR parameter */
  112. Fts5Colset *pColset; /* Columns to search (NULL -> all columns) */
  113. int nPhrase; /* Number of entries in aPhrase[] array */
  114. Fts5ExprPhrase *apPhrase[1]; /* Array of phrase pointers */
  115. };
  116. /*
  117. ** Parse context.
  118. */
  119. struct Fts5Parse {
  120. Fts5Config *pConfig;
  121. char *zErr;
  122. int rc;
  123. int nPhrase; /* Size of apPhrase array */
  124. Fts5ExprPhrase **apPhrase; /* Array of all phrases */
  125. Fts5ExprNode *pExpr; /* Result of a successful parse */
  126. int bPhraseToAnd; /* Convert "a+b" to "a AND b" */
  127. };
  128. /*
  129. ** Check that the Fts5ExprNode.iHeight variables are set correctly in
  130. ** the expression tree passed as the only argument.
  131. */
  132. #ifndef NDEBUG
  133. static void assert_expr_depth_ok(int rc, Fts5ExprNode *p){
  134. if( rc==SQLITE_OK ){
  135. if( p->eType==FTS5_TERM || p->eType==FTS5_STRING || p->eType==0 ){
  136. assert( p->iHeight==0 );
  137. }else{
  138. int ii;
  139. int iMaxChild = 0;
  140. for(ii=0; ii<p->nChild; ii++){
  141. Fts5ExprNode *pChild = p->apChild[ii];
  142. iMaxChild = MAX(iMaxChild, pChild->iHeight);
  143. assert_expr_depth_ok(SQLITE_OK, pChild);
  144. }
  145. assert( p->iHeight==iMaxChild+1 );
  146. }
  147. }
  148. }
  149. #else
  150. # define assert_expr_depth_ok(rc, p)
  151. #endif
  152. void sqlite3Fts5ParseError(Fts5Parse *pParse, const char *zFmt, ...){
  153. va_list ap;
  154. va_start(ap, zFmt);
  155. if( pParse->rc==SQLITE_OK ){
  156. assert( pParse->zErr==0 );
  157. pParse->zErr = sqlite3_vmprintf(zFmt, ap);
  158. pParse->rc = SQLITE_ERROR;
  159. }
  160. va_end(ap);
  161. }
  162. static int fts5ExprIsspace(char t){
  163. return t==' ' || t=='\t' || t=='\n' || t=='\r';
  164. }
  165. /*
  166. ** Read the first token from the nul-terminated string at *pz.
  167. */
  168. static int fts5ExprGetToken(
  169. Fts5Parse *pParse,
  170. const char **pz, /* IN/OUT: Pointer into buffer */
  171. Fts5Token *pToken
  172. ){
  173. const char *z = *pz;
  174. int tok;
  175. /* Skip past any whitespace */
  176. while( fts5ExprIsspace(*z) ) z++;
  177. pToken->p = z;
  178. pToken->n = 1;
  179. switch( *z ){
  180. case '(': tok = FTS5_LP; break;
  181. case ')': tok = FTS5_RP; break;
  182. case '{': tok = FTS5_LCP; break;
  183. case '}': tok = FTS5_RCP; break;
  184. case ':': tok = FTS5_COLON; break;
  185. case ',': tok = FTS5_COMMA; break;
  186. case '+': tok = FTS5_PLUS; break;
  187. case '*': tok = FTS5_STAR; break;
  188. case '-': tok = FTS5_MINUS; break;
  189. case '^': tok = FTS5_CARET; break;
  190. case '\0': tok = FTS5_EOF; break;
  191. case '"': {
  192. const char *z2;
  193. tok = FTS5_STRING;
  194. for(z2=&z[1]; 1; z2++){
  195. if( z2[0]=='"' ){
  196. z2++;
  197. if( z2[0]!='"' ) break;
  198. }
  199. if( z2[0]=='\0' ){
  200. sqlite3Fts5ParseError(pParse, "unterminated string");
  201. return FTS5_EOF;
  202. }
  203. }
  204. pToken->n = (z2 - z);
  205. break;
  206. }
  207. default: {
  208. const char *z2;
  209. if( sqlite3Fts5IsBareword(z[0])==0 ){
  210. sqlite3Fts5ParseError(pParse, "fts5: syntax error near \"%.1s\"", z);
  211. return FTS5_EOF;
  212. }
  213. tok = FTS5_STRING;
  214. for(z2=&z[1]; sqlite3Fts5IsBareword(*z2); z2++);
  215. pToken->n = (z2 - z);
  216. if( pToken->n==2 && memcmp(pToken->p, "OR", 2)==0 ) tok = FTS5_OR;
  217. if( pToken->n==3 && memcmp(pToken->p, "NOT", 3)==0 ) tok = FTS5_NOT;
  218. if( pToken->n==3 && memcmp(pToken->p, "AND", 3)==0 ) tok = FTS5_AND;
  219. break;
  220. }
  221. }
  222. *pz = &pToken->p[pToken->n];
  223. return tok;
  224. }
  225. static void *fts5ParseAlloc(u64 t){ return sqlite3_malloc64((sqlite3_int64)t);}
  226. static void fts5ParseFree(void *p){ sqlite3_free(p); }
  227. int sqlite3Fts5ExprNew(
  228. Fts5Config *pConfig, /* FTS5 Configuration */
  229. int bPhraseToAnd,
  230. int iCol,
  231. const char *zExpr, /* Expression text */
  232. Fts5Expr **ppNew,
  233. char **pzErr
  234. ){
  235. Fts5Parse sParse;
  236. Fts5Token token;
  237. const char *z = zExpr;
  238. int t; /* Next token type */
  239. void *pEngine;
  240. Fts5Expr *pNew;
  241. *ppNew = 0;
  242. *pzErr = 0;
  243. memset(&sParse, 0, sizeof(sParse));
  244. sParse.bPhraseToAnd = bPhraseToAnd;
  245. pEngine = sqlite3Fts5ParserAlloc(fts5ParseAlloc);
  246. if( pEngine==0 ){ return SQLITE_NOMEM; }
  247. sParse.pConfig = pConfig;
  248. do {
  249. t = fts5ExprGetToken(&sParse, &z, &token);
  250. sqlite3Fts5Parser(pEngine, t, token, &sParse);
  251. }while( sParse.rc==SQLITE_OK && t!=FTS5_EOF );
  252. sqlite3Fts5ParserFree(pEngine, fts5ParseFree);
  253. assert( sParse.pExpr || sParse.rc!=SQLITE_OK );
  254. assert_expr_depth_ok(sParse.rc, sParse.pExpr);
  255. /* If the LHS of the MATCH expression was a user column, apply the
  256. ** implicit column-filter. */
  257. if( sParse.rc==SQLITE_OK && iCol<pConfig->nCol ){
  258. int n = sizeof(Fts5Colset);
  259. Fts5Colset *pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&sParse.rc, n);
  260. if( pColset ){
  261. pColset->nCol = 1;
  262. pColset->aiCol[0] = iCol;
  263. sqlite3Fts5ParseSetColset(&sParse, sParse.pExpr, pColset);
  264. }
  265. }
  266. assert( sParse.rc!=SQLITE_OK || sParse.zErr==0 );
  267. if( sParse.rc==SQLITE_OK ){
  268. *ppNew = pNew = sqlite3_malloc(sizeof(Fts5Expr));
  269. if( pNew==0 ){
  270. sParse.rc = SQLITE_NOMEM;
  271. sqlite3Fts5ParseNodeFree(sParse.pExpr);
  272. }else{
  273. pNew->pRoot = sParse.pExpr;
  274. pNew->pIndex = 0;
  275. pNew->pConfig = pConfig;
  276. pNew->apExprPhrase = sParse.apPhrase;
  277. pNew->nPhrase = sParse.nPhrase;
  278. pNew->bDesc = 0;
  279. sParse.apPhrase = 0;
  280. }
  281. }else{
  282. sqlite3Fts5ParseNodeFree(sParse.pExpr);
  283. }
  284. sqlite3_free(sParse.apPhrase);
  285. if( 0==*pzErr ){
  286. *pzErr = sParse.zErr;
  287. }else{
  288. sqlite3_free(sParse.zErr);
  289. }
  290. return sParse.rc;
  291. }
  292. /*
  293. ** Assuming that buffer z is at least nByte bytes in size and contains a
  294. ** valid utf-8 string, return the number of characters in the string.
  295. */
  296. static int fts5ExprCountChar(const char *z, int nByte){
  297. int nRet = 0;
  298. int ii;
  299. for(ii=0; ii<nByte; ii++){
  300. if( (z[ii] & 0xC0)!=0x80 ) nRet++;
  301. }
  302. return nRet;
  303. }
  304. /*
  305. ** This function is only called when using the special 'trigram' tokenizer.
  306. ** Argument zText contains the text of a LIKE or GLOB pattern matched
  307. ** against column iCol. This function creates and compiles an FTS5 MATCH
  308. ** expression that will match a superset of the rows matched by the LIKE or
  309. ** GLOB. If successful, SQLITE_OK is returned. Otherwise, an SQLite error
  310. ** code.
  311. */
  312. int sqlite3Fts5ExprPattern(
  313. Fts5Config *pConfig, int bGlob, int iCol, const char *zText, Fts5Expr **pp
  314. ){
  315. i64 nText = strlen(zText);
  316. char *zExpr = (char*)sqlite3_malloc64(nText*4 + 1);
  317. int rc = SQLITE_OK;
  318. if( zExpr==0 ){
  319. rc = SQLITE_NOMEM;
  320. }else{
  321. char aSpec[3];
  322. int iOut = 0;
  323. int i = 0;
  324. int iFirst = 0;
  325. if( bGlob==0 ){
  326. aSpec[0] = '_';
  327. aSpec[1] = '%';
  328. aSpec[2] = 0;
  329. }else{
  330. aSpec[0] = '*';
  331. aSpec[1] = '?';
  332. aSpec[2] = '[';
  333. }
  334. while( i<=nText ){
  335. if( i==nText
  336. || zText[i]==aSpec[0] || zText[i]==aSpec[1] || zText[i]==aSpec[2]
  337. ){
  338. if( fts5ExprCountChar(&zText[iFirst], i-iFirst)>=3 ){
  339. int jj;
  340. zExpr[iOut++] = '"';
  341. for(jj=iFirst; jj<i; jj++){
  342. zExpr[iOut++] = zText[jj];
  343. if( zText[jj]=='"' ) zExpr[iOut++] = '"';
  344. }
  345. zExpr[iOut++] = '"';
  346. zExpr[iOut++] = ' ';
  347. }
  348. if( zText[i]==aSpec[2] ){
  349. i += 2;
  350. if( zText[i-1]=='^' ) i++;
  351. while( i<nText && zText[i]!=']' ) i++;
  352. }
  353. iFirst = i+1;
  354. }
  355. i++;
  356. }
  357. if( iOut>0 ){
  358. int bAnd = 0;
  359. if( pConfig->eDetail!=FTS5_DETAIL_FULL ){
  360. bAnd = 1;
  361. if( pConfig->eDetail==FTS5_DETAIL_NONE ){
  362. iCol = pConfig->nCol;
  363. }
  364. }
  365. zExpr[iOut] = '\0';
  366. rc = sqlite3Fts5ExprNew(pConfig, bAnd, iCol, zExpr, pp,pConfig->pzErrmsg);
  367. }else{
  368. *pp = 0;
  369. }
  370. sqlite3_free(zExpr);
  371. }
  372. return rc;
  373. }
  374. /*
  375. ** Free the expression node object passed as the only argument.
  376. */
  377. void sqlite3Fts5ParseNodeFree(Fts5ExprNode *p){
  378. if( p ){
  379. int i;
  380. for(i=0; i<p->nChild; i++){
  381. sqlite3Fts5ParseNodeFree(p->apChild[i]);
  382. }
  383. sqlite3Fts5ParseNearsetFree(p->pNear);
  384. sqlite3_free(p);
  385. }
  386. }
  387. /*
  388. ** Free the expression object passed as the only argument.
  389. */
  390. void sqlite3Fts5ExprFree(Fts5Expr *p){
  391. if( p ){
  392. sqlite3Fts5ParseNodeFree(p->pRoot);
  393. sqlite3_free(p->apExprPhrase);
  394. sqlite3_free(p);
  395. }
  396. }
  397. int sqlite3Fts5ExprAnd(Fts5Expr **pp1, Fts5Expr *p2){
  398. Fts5Parse sParse;
  399. memset(&sParse, 0, sizeof(sParse));
  400. if( *pp1 && p2 ){
  401. Fts5Expr *p1 = *pp1;
  402. int nPhrase = p1->nPhrase + p2->nPhrase;
  403. p1->pRoot = sqlite3Fts5ParseNode(&sParse, FTS5_AND, p1->pRoot, p2->pRoot,0);
  404. p2->pRoot = 0;
  405. if( sParse.rc==SQLITE_OK ){
  406. Fts5ExprPhrase **ap = (Fts5ExprPhrase**)sqlite3_realloc(
  407. p1->apExprPhrase, nPhrase * sizeof(Fts5ExprPhrase*)
  408. );
  409. if( ap==0 ){
  410. sParse.rc = SQLITE_NOMEM;
  411. }else{
  412. int i;
  413. memmove(&ap[p2->nPhrase], ap, p1->nPhrase*sizeof(Fts5ExprPhrase*));
  414. for(i=0; i<p2->nPhrase; i++){
  415. ap[i] = p2->apExprPhrase[i];
  416. }
  417. p1->nPhrase = nPhrase;
  418. p1->apExprPhrase = ap;
  419. }
  420. }
  421. sqlite3_free(p2->apExprPhrase);
  422. sqlite3_free(p2);
  423. }else if( p2 ){
  424. *pp1 = p2;
  425. }
  426. return sParse.rc;
  427. }
  428. /*
  429. ** Argument pTerm must be a synonym iterator. Return the current rowid
  430. ** that it points to.
  431. */
  432. static i64 fts5ExprSynonymRowid(Fts5ExprTerm *pTerm, int bDesc, int *pbEof){
  433. i64 iRet = 0;
  434. int bRetValid = 0;
  435. Fts5ExprTerm *p;
  436. assert( pTerm );
  437. assert( pTerm->pSynonym );
  438. assert( bDesc==0 || bDesc==1 );
  439. for(p=pTerm; p; p=p->pSynonym){
  440. if( 0==sqlite3Fts5IterEof(p->pIter) ){
  441. i64 iRowid = p->pIter->iRowid;
  442. if( bRetValid==0 || (bDesc!=(iRowid<iRet)) ){
  443. iRet = iRowid;
  444. bRetValid = 1;
  445. }
  446. }
  447. }
  448. if( pbEof && bRetValid==0 ) *pbEof = 1;
  449. return iRet;
  450. }
  451. /*
  452. ** Argument pTerm must be a synonym iterator.
  453. */
  454. static int fts5ExprSynonymList(
  455. Fts5ExprTerm *pTerm,
  456. i64 iRowid,
  457. Fts5Buffer *pBuf, /* Use this buffer for space if required */
  458. u8 **pa, int *pn
  459. ){
  460. Fts5PoslistReader aStatic[4];
  461. Fts5PoslistReader *aIter = aStatic;
  462. int nIter = 0;
  463. int nAlloc = 4;
  464. int rc = SQLITE_OK;
  465. Fts5ExprTerm *p;
  466. assert( pTerm->pSynonym );
  467. for(p=pTerm; p; p=p->pSynonym){
  468. Fts5IndexIter *pIter = p->pIter;
  469. if( sqlite3Fts5IterEof(pIter)==0 && pIter->iRowid==iRowid ){
  470. if( pIter->nData==0 ) continue;
  471. if( nIter==nAlloc ){
  472. sqlite3_int64 nByte = sizeof(Fts5PoslistReader) * nAlloc * 2;
  473. Fts5PoslistReader *aNew = (Fts5PoslistReader*)sqlite3_malloc64(nByte);
  474. if( aNew==0 ){
  475. rc = SQLITE_NOMEM;
  476. goto synonym_poslist_out;
  477. }
  478. memcpy(aNew, aIter, sizeof(Fts5PoslistReader) * nIter);
  479. nAlloc = nAlloc*2;
  480. if( aIter!=aStatic ) sqlite3_free(aIter);
  481. aIter = aNew;
  482. }
  483. sqlite3Fts5PoslistReaderInit(pIter->pData, pIter->nData, &aIter[nIter]);
  484. assert( aIter[nIter].bEof==0 );
  485. nIter++;
  486. }
  487. }
  488. if( nIter==1 ){
  489. *pa = (u8*)aIter[0].a;
  490. *pn = aIter[0].n;
  491. }else{
  492. Fts5PoslistWriter writer = {0};
  493. i64 iPrev = -1;
  494. fts5BufferZero(pBuf);
  495. while( 1 ){
  496. int i;
  497. i64 iMin = FTS5_LARGEST_INT64;
  498. for(i=0; i<nIter; i++){
  499. if( aIter[i].bEof==0 ){
  500. if( aIter[i].iPos==iPrev ){
  501. if( sqlite3Fts5PoslistReaderNext(&aIter[i]) ) continue;
  502. }
  503. if( aIter[i].iPos<iMin ){
  504. iMin = aIter[i].iPos;
  505. }
  506. }
  507. }
  508. if( iMin==FTS5_LARGEST_INT64 || rc!=SQLITE_OK ) break;
  509. rc = sqlite3Fts5PoslistWriterAppend(pBuf, &writer, iMin);
  510. iPrev = iMin;
  511. }
  512. if( rc==SQLITE_OK ){
  513. *pa = pBuf->p;
  514. *pn = pBuf->n;
  515. }
  516. }
  517. synonym_poslist_out:
  518. if( aIter!=aStatic ) sqlite3_free(aIter);
  519. return rc;
  520. }
  521. /*
  522. ** All individual term iterators in pPhrase are guaranteed to be valid and
  523. ** pointing to the same rowid when this function is called. This function
  524. ** checks if the current rowid really is a match, and if so populates
  525. ** the pPhrase->poslist buffer accordingly. Output parameter *pbMatch
  526. ** is set to true if this is really a match, or false otherwise.
  527. **
  528. ** SQLITE_OK is returned if an error occurs, or an SQLite error code
  529. ** otherwise. It is not considered an error code if the current rowid is
  530. ** not a match.
  531. */
  532. static int fts5ExprPhraseIsMatch(
  533. Fts5ExprNode *pNode, /* Node pPhrase belongs to */
  534. Fts5ExprPhrase *pPhrase, /* Phrase object to initialize */
  535. int *pbMatch /* OUT: Set to true if really a match */
  536. ){
  537. Fts5PoslistWriter writer = {0};
  538. Fts5PoslistReader aStatic[4];
  539. Fts5PoslistReader *aIter = aStatic;
  540. int i;
  541. int rc = SQLITE_OK;
  542. int bFirst = pPhrase->aTerm[0].bFirst;
  543. fts5BufferZero(&pPhrase->poslist);
  544. /* If the aStatic[] array is not large enough, allocate a large array
  545. ** using sqlite3_malloc(). This approach could be improved upon. */
  546. if( pPhrase->nTerm>ArraySize(aStatic) ){
  547. sqlite3_int64 nByte = sizeof(Fts5PoslistReader) * pPhrase->nTerm;
  548. aIter = (Fts5PoslistReader*)sqlite3_malloc64(nByte);
  549. if( !aIter ) return SQLITE_NOMEM;
  550. }
  551. memset(aIter, 0, sizeof(Fts5PoslistReader) * pPhrase->nTerm);
  552. /* Initialize a term iterator for each term in the phrase */
  553. for(i=0; i<pPhrase->nTerm; i++){
  554. Fts5ExprTerm *pTerm = &pPhrase->aTerm[i];
  555. int n = 0;
  556. int bFlag = 0;
  557. u8 *a = 0;
  558. if( pTerm->pSynonym ){
  559. Fts5Buffer buf = {0, 0, 0};
  560. rc = fts5ExprSynonymList(pTerm, pNode->iRowid, &buf, &a, &n);
  561. if( rc ){
  562. sqlite3_free(a);
  563. goto ismatch_out;
  564. }
  565. if( a==buf.p ) bFlag = 1;
  566. }else{
  567. a = (u8*)pTerm->pIter->pData;
  568. n = pTerm->pIter->nData;
  569. }
  570. sqlite3Fts5PoslistReaderInit(a, n, &aIter[i]);
  571. aIter[i].bFlag = (u8)bFlag;
  572. if( aIter[i].bEof ) goto ismatch_out;
  573. }
  574. while( 1 ){
  575. int bMatch;
  576. i64 iPos = aIter[0].iPos;
  577. do {
  578. bMatch = 1;
  579. for(i=0; i<pPhrase->nTerm; i++){
  580. Fts5PoslistReader *pPos = &aIter[i];
  581. i64 iAdj = iPos + i;
  582. if( pPos->iPos!=iAdj ){
  583. bMatch = 0;
  584. while( pPos->iPos<iAdj ){
  585. if( sqlite3Fts5PoslistReaderNext(pPos) ) goto ismatch_out;
  586. }
  587. if( pPos->iPos>iAdj ) iPos = pPos->iPos-i;
  588. }
  589. }
  590. }while( bMatch==0 );
  591. /* Append position iPos to the output */
  592. if( bFirst==0 || FTS5_POS2OFFSET(iPos)==0 ){
  593. rc = sqlite3Fts5PoslistWriterAppend(&pPhrase->poslist, &writer, iPos);
  594. if( rc!=SQLITE_OK ) goto ismatch_out;
  595. }
  596. for(i=0; i<pPhrase->nTerm; i++){
  597. if( sqlite3Fts5PoslistReaderNext(&aIter[i]) ) goto ismatch_out;
  598. }
  599. }
  600. ismatch_out:
  601. *pbMatch = (pPhrase->poslist.n>0);
  602. for(i=0; i<pPhrase->nTerm; i++){
  603. if( aIter[i].bFlag ) sqlite3_free((u8*)aIter[i].a);
  604. }
  605. if( aIter!=aStatic ) sqlite3_free(aIter);
  606. return rc;
  607. }
  608. typedef struct Fts5LookaheadReader Fts5LookaheadReader;
  609. struct Fts5LookaheadReader {
  610. const u8 *a; /* Buffer containing position list */
  611. int n; /* Size of buffer a[] in bytes */
  612. int i; /* Current offset in position list */
  613. i64 iPos; /* Current position */
  614. i64 iLookahead; /* Next position */
  615. };
  616. #define FTS5_LOOKAHEAD_EOF (((i64)1) << 62)
  617. static int fts5LookaheadReaderNext(Fts5LookaheadReader *p){
  618. p->iPos = p->iLookahead;
  619. if( sqlite3Fts5PoslistNext64(p->a, p->n, &p->i, &p->iLookahead) ){
  620. p->iLookahead = FTS5_LOOKAHEAD_EOF;
  621. }
  622. return (p->iPos==FTS5_LOOKAHEAD_EOF);
  623. }
  624. static int fts5LookaheadReaderInit(
  625. const u8 *a, int n, /* Buffer to read position list from */
  626. Fts5LookaheadReader *p /* Iterator object to initialize */
  627. ){
  628. memset(p, 0, sizeof(Fts5LookaheadReader));
  629. p->a = a;
  630. p->n = n;
  631. fts5LookaheadReaderNext(p);
  632. return fts5LookaheadReaderNext(p);
  633. }
  634. typedef struct Fts5NearTrimmer Fts5NearTrimmer;
  635. struct Fts5NearTrimmer {
  636. Fts5LookaheadReader reader; /* Input iterator */
  637. Fts5PoslistWriter writer; /* Writer context */
  638. Fts5Buffer *pOut; /* Output poslist */
  639. };
  640. /*
  641. ** The near-set object passed as the first argument contains more than
  642. ** one phrase. All phrases currently point to the same row. The
  643. ** Fts5ExprPhrase.poslist buffers are populated accordingly. This function
  644. ** tests if the current row contains instances of each phrase sufficiently
  645. ** close together to meet the NEAR constraint. Non-zero is returned if it
  646. ** does, or zero otherwise.
  647. **
  648. ** If in/out parameter (*pRc) is set to other than SQLITE_OK when this
  649. ** function is called, it is a no-op. Or, if an error (e.g. SQLITE_NOMEM)
  650. ** occurs within this function (*pRc) is set accordingly before returning.
  651. ** The return value is undefined in both these cases.
  652. **
  653. ** If no error occurs and non-zero (a match) is returned, the position-list
  654. ** of each phrase object is edited to contain only those entries that
  655. ** meet the constraint before returning.
  656. */
  657. static int fts5ExprNearIsMatch(int *pRc, Fts5ExprNearset *pNear){
  658. Fts5NearTrimmer aStatic[4];
  659. Fts5NearTrimmer *a = aStatic;
  660. Fts5ExprPhrase **apPhrase = pNear->apPhrase;
  661. int i;
  662. int rc = *pRc;
  663. int bMatch;
  664. assert( pNear->nPhrase>1 );
  665. /* If the aStatic[] array is not large enough, allocate a large array
  666. ** using sqlite3_malloc(). This approach could be improved upon. */
  667. if( pNear->nPhrase>ArraySize(aStatic) ){
  668. sqlite3_int64 nByte = sizeof(Fts5NearTrimmer) * pNear->nPhrase;
  669. a = (Fts5NearTrimmer*)sqlite3Fts5MallocZero(&rc, nByte);
  670. }else{
  671. memset(aStatic, 0, sizeof(aStatic));
  672. }
  673. if( rc!=SQLITE_OK ){
  674. *pRc = rc;
  675. return 0;
  676. }
  677. /* Initialize a lookahead iterator for each phrase. After passing the
  678. ** buffer and buffer size to the lookaside-reader init function, zero
  679. ** the phrase poslist buffer. The new poslist for the phrase (containing
  680. ** the same entries as the original with some entries removed on account
  681. ** of the NEAR constraint) is written over the original even as it is
  682. ** being read. This is safe as the entries for the new poslist are a
  683. ** subset of the old, so it is not possible for data yet to be read to
  684. ** be overwritten. */
  685. for(i=0; i<pNear->nPhrase; i++){
  686. Fts5Buffer *pPoslist = &apPhrase[i]->poslist;
  687. fts5LookaheadReaderInit(pPoslist->p, pPoslist->n, &a[i].reader);
  688. pPoslist->n = 0;
  689. a[i].pOut = pPoslist;
  690. }
  691. while( 1 ){
  692. int iAdv;
  693. i64 iMin;
  694. i64 iMax;
  695. /* This block advances the phrase iterators until they point to a set of
  696. ** entries that together comprise a match. */
  697. iMax = a[0].reader.iPos;
  698. do {
  699. bMatch = 1;
  700. for(i=0; i<pNear->nPhrase; i++){
  701. Fts5LookaheadReader *pPos = &a[i].reader;
  702. iMin = iMax - pNear->apPhrase[i]->nTerm - pNear->nNear;
  703. if( pPos->iPos<iMin || pPos->iPos>iMax ){
  704. bMatch = 0;
  705. while( pPos->iPos<iMin ){
  706. if( fts5LookaheadReaderNext(pPos) ) goto ismatch_out;
  707. }
  708. if( pPos->iPos>iMax ) iMax = pPos->iPos;
  709. }
  710. }
  711. }while( bMatch==0 );
  712. /* Add an entry to each output position list */
  713. for(i=0; i<pNear->nPhrase; i++){
  714. i64 iPos = a[i].reader.iPos;
  715. Fts5PoslistWriter *pWriter = &a[i].writer;
  716. if( a[i].pOut->n==0 || iPos!=pWriter->iPrev ){
  717. sqlite3Fts5PoslistWriterAppend(a[i].pOut, pWriter, iPos);
  718. }
  719. }
  720. iAdv = 0;
  721. iMin = a[0].reader.iLookahead;
  722. for(i=0; i<pNear->nPhrase; i++){
  723. if( a[i].reader.iLookahead < iMin ){
  724. iMin = a[i].reader.iLookahead;
  725. iAdv = i;
  726. }
  727. }
  728. if( fts5LookaheadReaderNext(&a[iAdv].reader) ) goto ismatch_out;
  729. }
  730. ismatch_out: {
  731. int bRet = a[0].pOut->n>0;
  732. *pRc = rc;
  733. if( a!=aStatic ) sqlite3_free(a);
  734. return bRet;
  735. }
  736. }
  737. /*
  738. ** Advance iterator pIter until it points to a value equal to or laster
  739. ** than the initial value of *piLast. If this means the iterator points
  740. ** to a value laster than *piLast, update *piLast to the new lastest value.
  741. **
  742. ** If the iterator reaches EOF, set *pbEof to true before returning. If
  743. ** an error occurs, set *pRc to an error code. If either *pbEof or *pRc
  744. ** are set, return a non-zero value. Otherwise, return zero.
  745. */
  746. static int fts5ExprAdvanceto(
  747. Fts5IndexIter *pIter, /* Iterator to advance */
  748. int bDesc, /* True if iterator is "rowid DESC" */
  749. i64 *piLast, /* IN/OUT: Lastest rowid seen so far */
  750. int *pRc, /* OUT: Error code */
  751. int *pbEof /* OUT: Set to true if EOF */
  752. ){
  753. i64 iLast = *piLast;
  754. i64 iRowid;
  755. iRowid = pIter->iRowid;
  756. if( (bDesc==0 && iLast>iRowid) || (bDesc && iLast<iRowid) ){
  757. int rc = sqlite3Fts5IterNextFrom(pIter, iLast);
  758. if( rc || sqlite3Fts5IterEof(pIter) ){
  759. *pRc = rc;
  760. *pbEof = 1;
  761. return 1;
  762. }
  763. iRowid = pIter->iRowid;
  764. assert( (bDesc==0 && iRowid>=iLast) || (bDesc==1 && iRowid<=iLast) );
  765. }
  766. *piLast = iRowid;
  767. return 0;
  768. }
  769. static int fts5ExprSynonymAdvanceto(
  770. Fts5ExprTerm *pTerm, /* Term iterator to advance */
  771. int bDesc, /* True if iterator is "rowid DESC" */
  772. i64 *piLast, /* IN/OUT: Lastest rowid seen so far */
  773. int *pRc /* OUT: Error code */
  774. ){
  775. int rc = SQLITE_OK;
  776. i64 iLast = *piLast;
  777. Fts5ExprTerm *p;
  778. int bEof = 0;
  779. for(p=pTerm; rc==SQLITE_OK && p; p=p->pSynonym){
  780. if( sqlite3Fts5IterEof(p->pIter)==0 ){
  781. i64 iRowid = p->pIter->iRowid;
  782. if( (bDesc==0 && iLast>iRowid) || (bDesc && iLast<iRowid) ){
  783. rc = sqlite3Fts5IterNextFrom(p->pIter, iLast);
  784. }
  785. }
  786. }
  787. if( rc!=SQLITE_OK ){
  788. *pRc = rc;
  789. bEof = 1;
  790. }else{
  791. *piLast = fts5ExprSynonymRowid(pTerm, bDesc, &bEof);
  792. }
  793. return bEof;
  794. }
  795. static int fts5ExprNearTest(
  796. int *pRc,
  797. Fts5Expr *pExpr, /* Expression that pNear is a part of */
  798. Fts5ExprNode *pNode /* The "NEAR" node (FTS5_STRING) */
  799. ){
  800. Fts5ExprNearset *pNear = pNode->pNear;
  801. int rc = *pRc;
  802. if( pExpr->pConfig->eDetail!=FTS5_DETAIL_FULL ){
  803. Fts5ExprTerm *pTerm;
  804. Fts5ExprPhrase *pPhrase = pNear->apPhrase[0];
  805. pPhrase->poslist.n = 0;
  806. for(pTerm=&pPhrase->aTerm[0]; pTerm; pTerm=pTerm->pSynonym){
  807. Fts5IndexIter *pIter = pTerm->pIter;
  808. if( sqlite3Fts5IterEof(pIter)==0 ){
  809. if( pIter->iRowid==pNode->iRowid && pIter->nData>0 ){
  810. pPhrase->poslist.n = 1;
  811. }
  812. }
  813. }
  814. return pPhrase->poslist.n;
  815. }else{
  816. int i;
  817. /* Check that each phrase in the nearset matches the current row.
  818. ** Populate the pPhrase->poslist buffers at the same time. If any
  819. ** phrase is not a match, break out of the loop early. */
  820. for(i=0; rc==SQLITE_OK && i<pNear->nPhrase; i++){
  821. Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
  822. if( pPhrase->nTerm>1 || pPhrase->aTerm[0].pSynonym
  823. || pNear->pColset || pPhrase->aTerm[0].bFirst
  824. ){
  825. int bMatch = 0;
  826. rc = fts5ExprPhraseIsMatch(pNode, pPhrase, &bMatch);
  827. if( bMatch==0 ) break;
  828. }else{
  829. Fts5IndexIter *pIter = pPhrase->aTerm[0].pIter;
  830. fts5BufferSet(&rc, &pPhrase->poslist, pIter->nData, pIter->pData);
  831. }
  832. }
  833. *pRc = rc;
  834. if( i==pNear->nPhrase && (i==1 || fts5ExprNearIsMatch(pRc, pNear)) ){
  835. return 1;
  836. }
  837. return 0;
  838. }
  839. }
  840. /*
  841. ** Initialize all term iterators in the pNear object. If any term is found
  842. ** to match no documents at all, return immediately without initializing any
  843. ** further iterators.
  844. **
  845. ** If an error occurs, return an SQLite error code. Otherwise, return
  846. ** SQLITE_OK. It is not considered an error if some term matches zero
  847. ** documents.
  848. */
  849. static int fts5ExprNearInitAll(
  850. Fts5Expr *pExpr,
  851. Fts5ExprNode *pNode
  852. ){
  853. Fts5ExprNearset *pNear = pNode->pNear;
  854. int i;
  855. assert( pNode->bNomatch==0 );
  856. for(i=0; i<pNear->nPhrase; i++){
  857. Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
  858. if( pPhrase->nTerm==0 ){
  859. pNode->bEof = 1;
  860. return SQLITE_OK;
  861. }else{
  862. int j;
  863. for(j=0; j<pPhrase->nTerm; j++){
  864. Fts5ExprTerm *pTerm = &pPhrase->aTerm[j];
  865. Fts5ExprTerm *p;
  866. int bHit = 0;
  867. for(p=pTerm; p; p=p->pSynonym){
  868. int rc;
  869. if( p->pIter ){
  870. sqlite3Fts5IterClose(p->pIter);
  871. p->pIter = 0;
  872. }
  873. rc = sqlite3Fts5IndexQuery(
  874. pExpr->pIndex, p->pTerm, p->nQueryTerm,
  875. (pTerm->bPrefix ? FTS5INDEX_QUERY_PREFIX : 0) |
  876. (pExpr->bDesc ? FTS5INDEX_QUERY_DESC : 0),
  877. pNear->pColset,
  878. &p->pIter
  879. );
  880. assert( (rc==SQLITE_OK)==(p->pIter!=0) );
  881. if( rc!=SQLITE_OK ) return rc;
  882. if( 0==sqlite3Fts5IterEof(p->pIter) ){
  883. bHit = 1;
  884. }
  885. }
  886. if( bHit==0 ){
  887. pNode->bEof = 1;
  888. return SQLITE_OK;
  889. }
  890. }
  891. }
  892. }
  893. pNode->bEof = 0;
  894. return SQLITE_OK;
  895. }
  896. /*
  897. ** If pExpr is an ASC iterator, this function returns a value with the
  898. ** same sign as:
  899. **
  900. ** (iLhs - iRhs)
  901. **
  902. ** Otherwise, if this is a DESC iterator, the opposite is returned:
  903. **
  904. ** (iRhs - iLhs)
  905. */
  906. static int fts5RowidCmp(
  907. Fts5Expr *pExpr,
  908. i64 iLhs,
  909. i64 iRhs
  910. ){
  911. assert( pExpr->bDesc==0 || pExpr->bDesc==1 );
  912. if( pExpr->bDesc==0 ){
  913. if( iLhs<iRhs ) return -1;
  914. return (iLhs > iRhs);
  915. }else{
  916. if( iLhs>iRhs ) return -1;
  917. return (iLhs < iRhs);
  918. }
  919. }
  920. static void fts5ExprSetEof(Fts5ExprNode *pNode){
  921. int i;
  922. pNode->bEof = 1;
  923. pNode->bNomatch = 0;
  924. for(i=0; i<pNode->nChild; i++){
  925. fts5ExprSetEof(pNode->apChild[i]);
  926. }
  927. }
  928. static void fts5ExprNodeZeroPoslist(Fts5ExprNode *pNode){
  929. if( pNode->eType==FTS5_STRING || pNode->eType==FTS5_TERM ){
  930. Fts5ExprNearset *pNear = pNode->pNear;
  931. int i;
  932. for(i=0; i<pNear->nPhrase; i++){
  933. Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
  934. pPhrase->poslist.n = 0;
  935. }
  936. }else{
  937. int i;
  938. for(i=0; i<pNode->nChild; i++){
  939. fts5ExprNodeZeroPoslist(pNode->apChild[i]);
  940. }
  941. }
  942. }
  943. /*
  944. ** Compare the values currently indicated by the two nodes as follows:
  945. **
  946. ** res = (*p1) - (*p2)
  947. **
  948. ** Nodes that point to values that come later in the iteration order are
  949. ** considered to be larger. Nodes at EOF are the largest of all.
  950. **
  951. ** This means that if the iteration order is ASC, then numerically larger
  952. ** rowids are considered larger. Or if it is the default DESC, numerically
  953. ** smaller rowids are larger.
  954. */
  955. static int fts5NodeCompare(
  956. Fts5Expr *pExpr,
  957. Fts5ExprNode *p1,
  958. Fts5ExprNode *p2
  959. ){
  960. if( p2->bEof ) return -1;
  961. if( p1->bEof ) return +1;
  962. return fts5RowidCmp(pExpr, p1->iRowid, p2->iRowid);
  963. }
  964. /*
  965. ** All individual term iterators in pNear are guaranteed to be valid when
  966. ** this function is called. This function checks if all term iterators
  967. ** point to the same rowid, and if not, advances them until they do.
  968. ** If an EOF is reached before this happens, *pbEof is set to true before
  969. ** returning.
  970. **
  971. ** SQLITE_OK is returned if an error occurs, or an SQLite error code
  972. ** otherwise. It is not considered an error code if an iterator reaches
  973. ** EOF.
  974. */
  975. static int fts5ExprNodeTest_STRING(
  976. Fts5Expr *pExpr, /* Expression pPhrase belongs to */
  977. Fts5ExprNode *pNode
  978. ){
  979. Fts5ExprNearset *pNear = pNode->pNear;
  980. Fts5ExprPhrase *pLeft = pNear->apPhrase[0];
  981. int rc = SQLITE_OK;
  982. i64 iLast; /* Lastest rowid any iterator points to */
  983. int i, j; /* Phrase and token index, respectively */
  984. int bMatch; /* True if all terms are at the same rowid */
  985. const int bDesc = pExpr->bDesc;
  986. /* Check that this node should not be FTS5_TERM */
  987. assert( pNear->nPhrase>1
  988. || pNear->apPhrase[0]->nTerm>1
  989. || pNear->apPhrase[0]->aTerm[0].pSynonym
  990. || pNear->apPhrase[0]->aTerm[0].bFirst
  991. );
  992. /* Initialize iLast, the "lastest" rowid any iterator points to. If the
  993. ** iterator skips through rowids in the default ascending order, this means
  994. ** the maximum rowid. Or, if the iterator is "ORDER BY rowid DESC", then it
  995. ** means the minimum rowid. */
  996. if( pLeft->aTerm[0].pSynonym ){
  997. iLast = fts5ExprSynonymRowid(&pLeft->aTerm[0], bDesc, 0);
  998. }else{
  999. iLast = pLeft->aTerm[0].pIter->iRowid;
  1000. }
  1001. do {
  1002. bMatch = 1;
  1003. for(i=0; i<pNear->nPhrase; i++){
  1004. Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
  1005. for(j=0; j<pPhrase->nTerm; j++){
  1006. Fts5ExprTerm *pTerm = &pPhrase->aTerm[j];
  1007. if( pTerm->pSynonym ){
  1008. i64 iRowid = fts5ExprSynonymRowid(pTerm, bDesc, 0);
  1009. if( iRowid==iLast ) continue;
  1010. bMatch = 0;
  1011. if( fts5ExprSynonymAdvanceto(pTerm, bDesc, &iLast, &rc) ){
  1012. pNode->bNomatch = 0;
  1013. pNode->bEof = 1;
  1014. return rc;
  1015. }
  1016. }else{
  1017. Fts5IndexIter *pIter = pPhrase->aTerm[j].pIter;
  1018. if( pIter->iRowid==iLast ) continue;
  1019. bMatch = 0;
  1020. if( fts5ExprAdvanceto(pIter, bDesc, &iLast, &rc, &pNode->bEof) ){
  1021. return rc;
  1022. }
  1023. }
  1024. }
  1025. }
  1026. }while( bMatch==0 );
  1027. pNode->iRowid = iLast;
  1028. pNode->bNomatch = ((0==fts5ExprNearTest(&rc, pExpr, pNode)) && rc==SQLITE_OK);
  1029. assert( pNode->bEof==0 || pNode->bNomatch==0 );
  1030. return rc;
  1031. }
  1032. /*
  1033. ** Advance the first term iterator in the first phrase of pNear. Set output
  1034. ** variable *pbEof to true if it reaches EOF or if an error occurs.
  1035. **
  1036. ** Return SQLITE_OK if successful, or an SQLite error code if an error
  1037. ** occurs.
  1038. */
  1039. static int fts5ExprNodeNext_STRING(
  1040. Fts5Expr *pExpr, /* Expression pPhrase belongs to */
  1041. Fts5ExprNode *pNode, /* FTS5_STRING or FTS5_TERM node */
  1042. int bFromValid,
  1043. i64 iFrom
  1044. ){
  1045. Fts5ExprTerm *pTerm = &pNode->pNear->apPhrase[0]->aTerm[0];
  1046. int rc = SQLITE_OK;
  1047. pNode->bNomatch = 0;
  1048. if( pTerm->pSynonym ){
  1049. int bEof = 1;
  1050. Fts5ExprTerm *p;
  1051. /* Find the firstest rowid any synonym points to. */
  1052. i64 iRowid = fts5ExprSynonymRowid(pTerm, pExpr->bDesc, 0);
  1053. /* Advance each iterator that currently points to iRowid. Or, if iFrom
  1054. ** is valid - each iterator that points to a rowid before iFrom. */
  1055. for(p=pTerm; p; p=p->pSynonym){
  1056. if( sqlite3Fts5IterEof(p->pIter)==0 ){
  1057. i64 ii = p->pIter->iRowid;
  1058. if( ii==iRowid
  1059. || (bFromValid && ii!=iFrom && (ii>iFrom)==pExpr->bDesc)
  1060. ){
  1061. if( bFromValid ){
  1062. rc = sqlite3Fts5IterNextFrom(p->pIter, iFrom);
  1063. }else{
  1064. rc = sqlite3Fts5IterNext(p->pIter);
  1065. }
  1066. if( rc!=SQLITE_OK ) break;
  1067. if( sqlite3Fts5IterEof(p->pIter)==0 ){
  1068. bEof = 0;
  1069. }
  1070. }else{
  1071. bEof = 0;
  1072. }
  1073. }
  1074. }
  1075. /* Set the EOF flag if either all synonym iterators are at EOF or an
  1076. ** error has occurred. */
  1077. pNode->bEof = (rc || bEof);
  1078. }else{
  1079. Fts5IndexIter *pIter = pTerm->pIter;
  1080. assert( Fts5NodeIsString(pNode) );
  1081. if( bFromValid ){
  1082. rc = sqlite3Fts5IterNextFrom(pIter, iFrom);
  1083. }else{
  1084. rc = sqlite3Fts5IterNext(pIter);
  1085. }
  1086. pNode->bEof = (rc || sqlite3Fts5IterEof(pIter));
  1087. }
  1088. if( pNode->bEof==0 ){
  1089. assert( rc==SQLITE_OK );
  1090. rc = fts5ExprNodeTest_STRING(pExpr, pNode);
  1091. }
  1092. return rc;
  1093. }
  1094. static int fts5ExprNodeTest_TERM(
  1095. Fts5Expr *pExpr, /* Expression that pNear is a part of */
  1096. Fts5ExprNode *pNode /* The "NEAR" node (FTS5_TERM) */
  1097. ){
  1098. /* As this "NEAR" object is actually a single phrase that consists
  1099. ** of a single term only, grab pointers into the poslist managed by the
  1100. ** fts5_index.c iterator object. This is much faster than synthesizing
  1101. ** a new poslist the way we have to for more complicated phrase or NEAR
  1102. ** expressions. */
  1103. Fts5ExprPhrase *pPhrase = pNode->pNear->apPhrase[0];
  1104. Fts5IndexIter *pIter = pPhrase->aTerm[0].pIter;
  1105. assert( pNode->eType==FTS5_TERM );
  1106. assert( pNode->pNear->nPhrase==1 && pPhrase->nTerm==1 );
  1107. assert( pPhrase->aTerm[0].pSynonym==0 );
  1108. pPhrase->poslist.n = pIter->nData;
  1109. if( pExpr->pConfig->eDetail==FTS5_DETAIL_FULL ){
  1110. pPhrase->poslist.p = (u8*)pIter->pData;
  1111. }
  1112. pNode->iRowid = pIter->iRowid;
  1113. pNode->bNomatch = (pPhrase->poslist.n==0);
  1114. return SQLITE_OK;
  1115. }
  1116. /*
  1117. ** xNext() method for a node of type FTS5_TERM.
  1118. */
  1119. static int fts5ExprNodeNext_TERM(
  1120. Fts5Expr *pExpr,
  1121. Fts5ExprNode *pNode,
  1122. int bFromValid,
  1123. i64 iFrom
  1124. ){
  1125. int rc;
  1126. Fts5IndexIter *pIter = pNode->pNear->apPhrase[0]->aTerm[0].pIter;
  1127. assert( pNode->bEof==0 );
  1128. if( bFromValid ){
  1129. rc = sqlite3Fts5IterNextFrom(pIter, iFrom);
  1130. }else{
  1131. rc = sqlite3Fts5IterNext(pIter);
  1132. }
  1133. if( rc==SQLITE_OK && sqlite3Fts5IterEof(pIter)==0 ){
  1134. rc = fts5ExprNodeTest_TERM(pExpr, pNode);
  1135. }else{
  1136. pNode->bEof = 1;
  1137. pNode->bNomatch = 0;
  1138. }
  1139. return rc;
  1140. }
  1141. static void fts5ExprNodeTest_OR(
  1142. Fts5Expr *pExpr, /* Expression of which pNode is a part */
  1143. Fts5ExprNode *pNode /* Expression node to test */
  1144. ){
  1145. Fts5ExprNode *pNext = pNode->apChild[0];
  1146. int i;
  1147. for(i=1; i<pNode->nChild; i++){
  1148. Fts5ExprNode *pChild = pNode->apChild[i];
  1149. int cmp = fts5NodeCompare(pExpr, pNext, pChild);
  1150. if( cmp>0 || (cmp==0 && pChild->bNomatch==0) ){
  1151. pNext = pChild;
  1152. }
  1153. }
  1154. pNode->iRowid = pNext->iRowid;
  1155. pNode->bEof = pNext->bEof;
  1156. pNode->bNomatch = pNext->bNomatch;
  1157. }
  1158. static int fts5ExprNodeNext_OR(
  1159. Fts5Expr *pExpr,
  1160. Fts5ExprNode *pNode,
  1161. int bFromValid,
  1162. i64 iFrom
  1163. ){
  1164. int i;
  1165. i64 iLast = pNode->iRowid;
  1166. for(i=0; i<pNode->nChild; i++){
  1167. Fts5ExprNode *p1 = pNode->apChild[i];
  1168. assert( p1->bEof || fts5RowidCmp(pExpr, p1->iRowid, iLast)>=0 );
  1169. if( p1->bEof==0 ){
  1170. if( (p1->iRowid==iLast)
  1171. || (bFromValid && fts5RowidCmp(pExpr, p1->iRowid, iFrom)<0)
  1172. ){
  1173. int rc = fts5ExprNodeNext(pExpr, p1, bFromValid, iFrom);
  1174. if( rc!=SQLITE_OK ){
  1175. pNode->bNomatch = 0;
  1176. return rc;
  1177. }
  1178. }
  1179. }
  1180. }
  1181. fts5ExprNodeTest_OR(pExpr, pNode);
  1182. return SQLITE_OK;
  1183. }
  1184. /*
  1185. ** Argument pNode is an FTS5_AND node.
  1186. */
  1187. static int fts5ExprNodeTest_AND(
  1188. Fts5Expr *pExpr, /* Expression pPhrase belongs to */
  1189. Fts5ExprNode *pAnd /* FTS5_AND node to advance */
  1190. ){
  1191. int iChild;
  1192. i64 iLast = pAnd->iRowid;
  1193. int rc = SQLITE_OK;
  1194. int bMatch;
  1195. assert( pAnd->bEof==0 );
  1196. do {
  1197. pAnd->bNomatch = 0;
  1198. bMatch = 1;
  1199. for(iChild=0; iChild<pAnd->nChild; iChild++){
  1200. Fts5ExprNode *pChild = pAnd->apChild[iChild];
  1201. int cmp = fts5RowidCmp(pExpr, iLast, pChild->iRowid);
  1202. if( cmp>0 ){
  1203. /* Advance pChild until it points to iLast or laster */
  1204. rc = fts5ExprNodeNext(pExpr, pChild, 1, iLast);
  1205. if( rc!=SQLITE_OK ){
  1206. pAnd->bNomatch = 0;
  1207. return rc;
  1208. }
  1209. }
  1210. /* If the child node is now at EOF, so is the parent AND node. Otherwise,
  1211. ** the child node is guaranteed to have advanced at least as far as
  1212. ** rowid iLast. So if it is not at exactly iLast, pChild->iRowid is the
  1213. ** new lastest rowid seen so far. */
  1214. assert( pChild->bEof || fts5RowidCmp(pExpr, iLast, pChild->iRowid)<=0 );
  1215. if( pChild->bEof ){
  1216. fts5ExprSetEof(pAnd);
  1217. bMatch = 1;
  1218. break;
  1219. }else if( iLast!=pChild->iRowid ){
  1220. bMatch = 0;
  1221. iLast = pChild->iRowid;
  1222. }
  1223. if( pChild->bNomatch ){
  1224. pAnd->bNomatch = 1;
  1225. }
  1226. }
  1227. }while( bMatch==0 );
  1228. if( pAnd->bNomatch && pAnd!=pExpr->pRoot ){
  1229. fts5ExprNodeZeroPoslist(pAnd);
  1230. }
  1231. pAnd->iRowid = iLast;
  1232. return SQLITE_OK;
  1233. }
  1234. static int fts5ExprNodeNext_AND(
  1235. Fts5Expr *pExpr,
  1236. Fts5ExprNode *pNode,
  1237. int bFromValid,
  1238. i64 iFrom
  1239. ){
  1240. int rc = fts5ExprNodeNext(pExpr, pNode->apChild[0], bFromValid, iFrom);
  1241. if( rc==SQLITE_OK ){
  1242. rc = fts5ExprNodeTest_AND(pExpr, pNode);
  1243. }else{
  1244. pNode->bNomatch = 0;
  1245. }
  1246. return rc;
  1247. }
  1248. static int fts5ExprNodeTest_NOT(
  1249. Fts5Expr *pExpr, /* Expression pPhrase belongs to */
  1250. Fts5ExprNode *pNode /* FTS5_NOT node to advance */
  1251. ){
  1252. int rc = SQLITE_OK;
  1253. Fts5ExprNode *p1 = pNode->apChild[0];
  1254. Fts5ExprNode *p2 = pNode->apChild[1];
  1255. assert( pNode->nChild==2 );
  1256. while( rc==SQLITE_OK && p1->bEof==0 ){
  1257. int cmp = fts5NodeCompare(pExpr, p1, p2);
  1258. if( cmp>0 ){
  1259. rc = fts5ExprNodeNext(pExpr, p2, 1, p1->iRowid);
  1260. cmp = fts5NodeCompare(pExpr, p1, p2);
  1261. }
  1262. assert( rc!=SQLITE_OK || cmp<=0 );
  1263. if( cmp || p2->bNomatch ) break;
  1264. rc = fts5ExprNodeNext(pExpr, p1, 0, 0);
  1265. }
  1266. pNode->bEof = p1->bEof;
  1267. pNode->bNomatch = p1->bNomatch;
  1268. pNode->iRowid = p1->iRowid;
  1269. if( p1->bEof ){
  1270. fts5ExprNodeZeroPoslist(p2);
  1271. }
  1272. return rc;
  1273. }
  1274. static int fts5ExprNodeNext_NOT(
  1275. Fts5Expr *pExpr,
  1276. Fts5ExprNode *pNode,
  1277. int bFromValid,
  1278. i64 iFrom
  1279. ){
  1280. int rc = fts5ExprNodeNext(pExpr, pNode->apChild[0], bFromValid, iFrom);
  1281. if( rc==SQLITE_OK ){
  1282. rc = fts5ExprNodeTest_NOT(pExpr, pNode);
  1283. }
  1284. if( rc!=SQLITE_OK ){
  1285. pNode->bNomatch = 0;
  1286. }
  1287. return rc;
  1288. }
  1289. /*
  1290. ** If pNode currently points to a match, this function returns SQLITE_OK
  1291. ** without modifying it. Otherwise, pNode is advanced until it does point
  1292. ** to a match or EOF is reached.
  1293. */
  1294. static int fts5ExprNodeTest(
  1295. Fts5Expr *pExpr, /* Expression of which pNode is a part */
  1296. Fts5ExprNode *pNode /* Expression node to test */
  1297. ){
  1298. int rc = SQLITE_OK;
  1299. if( pNode->bEof==0 ){
  1300. switch( pNode->eType ){
  1301. case FTS5_STRING: {
  1302. rc = fts5ExprNodeTest_STRING(pExpr, pNode);
  1303. break;
  1304. }
  1305. case FTS5_TERM: {
  1306. rc = fts5ExprNodeTest_TERM(pExpr, pNode);
  1307. break;
  1308. }
  1309. case FTS5_AND: {
  1310. rc = fts5ExprNodeTest_AND(pExpr, pNode);
  1311. break;
  1312. }
  1313. case FTS5_OR: {
  1314. fts5ExprNodeTest_OR(pExpr, pNode);
  1315. break;
  1316. }
  1317. default: assert( pNode->eType==FTS5_NOT ); {
  1318. rc = fts5ExprNodeTest_NOT(pExpr, pNode);
  1319. break;
  1320. }
  1321. }
  1322. }
  1323. return rc;
  1324. }
  1325. /*
  1326. ** Set node pNode, which is part of expression pExpr, to point to the first
  1327. ** match. If there are no matches, set the Node.bEof flag to indicate EOF.
  1328. **
  1329. ** Return an SQLite error code if an error occurs, or SQLITE_OK otherwise.
  1330. ** It is not an error if there are no matches.
  1331. */
  1332. static int fts5ExprNodeFirst(Fts5Expr *pExpr, Fts5ExprNode *pNode){
  1333. int rc = SQLITE_OK;
  1334. pNode->bEof = 0;
  1335. pNode->bNomatch = 0;
  1336. if( Fts5NodeIsString(pNode) ){
  1337. /* Initialize all term iterators in the NEAR object. */
  1338. rc = fts5ExprNearInitAll(pExpr, pNode);
  1339. }else if( pNode->xNext==0 ){
  1340. pNode->bEof = 1;
  1341. }else{
  1342. int i;
  1343. int nEof = 0;
  1344. for(i=0; i<pNode->nChild && rc==SQLITE_OK; i++){
  1345. Fts5ExprNode *pChild = pNode->apChild[i];
  1346. rc = fts5ExprNodeFirst(pExpr, pNode->apChild[i]);
  1347. assert( pChild->bEof==0 || pChild->bEof==1 );
  1348. nEof += pChild->bEof;
  1349. }
  1350. pNode->iRowid = pNode->apChild[0]->iRowid;
  1351. switch( pNode->eType ){
  1352. case FTS5_AND:
  1353. if( nEof>0 ) fts5ExprSetEof(pNode);
  1354. break;
  1355. case FTS5_OR:
  1356. if( pNode->nChild==nEof ) fts5ExprSetEof(pNode);
  1357. break;
  1358. default:
  1359. assert( pNode->eType==FTS5_NOT );
  1360. pNode->bEof = pNode->apChild[0]->bEof;
  1361. break;
  1362. }
  1363. }
  1364. if( rc==SQLITE_OK ){
  1365. rc = fts5ExprNodeTest(pExpr, pNode);
  1366. }
  1367. return rc;
  1368. }
  1369. /*
  1370. ** Begin iterating through the set of documents in index pIdx matched by
  1371. ** the MATCH expression passed as the first argument. If the "bDesc"
  1372. ** parameter is passed a non-zero value, iteration is in descending rowid
  1373. ** order. Or, if it is zero, in ascending order.
  1374. **
  1375. ** If iterating in ascending rowid order (bDesc==0), the first document
  1376. ** visited is that with the smallest rowid that is larger than or equal
  1377. ** to parameter iFirst. Or, if iterating in ascending order (bDesc==1),
  1378. ** then the first document visited must have a rowid smaller than or
  1379. ** equal to iFirst.
  1380. **
  1381. ** Return SQLITE_OK if successful, or an SQLite error code otherwise. It
  1382. ** is not considered an error if the query does not match any documents.
  1383. */
  1384. int sqlite3Fts5ExprFirst(Fts5Expr *p, Fts5Index *pIdx, i64 iFirst, int bDesc){
  1385. Fts5ExprNode *pRoot = p->pRoot;
  1386. int rc; /* Return code */
  1387. p->pIndex = pIdx;
  1388. p->bDesc = bDesc;
  1389. rc = fts5ExprNodeFirst(p, pRoot);
  1390. /* If not at EOF but the current rowid occurs earlier than iFirst in
  1391. ** the iteration order, move to document iFirst or later. */
  1392. if( rc==SQLITE_OK
  1393. && 0==pRoot->bEof
  1394. && fts5RowidCmp(p, pRoot->iRowid, iFirst)<0
  1395. ){
  1396. rc = fts5ExprNodeNext(p, pRoot, 1, iFirst);
  1397. }
  1398. /* If the iterator is not at a real match, skip forward until it is. */
  1399. while( pRoot->bNomatch && rc==SQLITE_OK ){
  1400. assert( pRoot->bEof==0 );
  1401. rc = fts5ExprNodeNext(p, pRoot, 0, 0);
  1402. }
  1403. return rc;
  1404. }
  1405. /*
  1406. ** Move to the next document
  1407. **
  1408. ** Return SQLITE_OK if successful, or an SQLite error code otherwise. It
  1409. ** is not considered an error if the query does not match any documents.
  1410. */
  1411. int sqlite3Fts5ExprNext(Fts5Expr *p, i64 iLast){
  1412. int rc;
  1413. Fts5ExprNode *pRoot = p->pRoot;
  1414. assert( pRoot->bEof==0 && pRoot->bNomatch==0 );
  1415. do {
  1416. rc = fts5ExprNodeNext(p, pRoot, 0, 0);
  1417. assert( pRoot->bNomatch==0 || (rc==SQLITE_OK && pRoot->bEof==0) );
  1418. }while( pRoot->bNomatch );
  1419. if( fts5RowidCmp(p, pRoot->iRowid, iLast)>0 ){
  1420. pRoot->bEof = 1;
  1421. }
  1422. return rc;
  1423. }
  1424. int sqlite3Fts5ExprEof(Fts5Expr *p){
  1425. return p->pRoot->bEof;
  1426. }
  1427. i64 sqlite3Fts5ExprRowid(Fts5Expr *p){
  1428. return p->pRoot->iRowid;
  1429. }
  1430. static int fts5ParseStringFromToken(Fts5Token *pToken, char **pz){
  1431. int rc = SQLITE_OK;
  1432. *pz = sqlite3Fts5Strndup(&rc, pToken->p, pToken->n);
  1433. return rc;
  1434. }
  1435. /*
  1436. ** Free the phrase object passed as the only argument.
  1437. */
  1438. static void fts5ExprPhraseFree(Fts5ExprPhrase *pPhrase){
  1439. if( pPhrase ){
  1440. int i;
  1441. for(i=0; i<pPhrase->nTerm; i++){
  1442. Fts5ExprTerm *pSyn;
  1443. Fts5ExprTerm *pNext;
  1444. Fts5ExprTerm *pTerm = &pPhrase->aTerm[i];
  1445. sqlite3_free(pTerm->pTerm);
  1446. sqlite3Fts5IterClose(pTerm->pIter);
  1447. for(pSyn=pTerm->pSynonym; pSyn; pSyn=pNext){
  1448. pNext = pSyn->pSynonym;
  1449. sqlite3Fts5IterClose(pSyn->pIter);
  1450. fts5BufferFree((Fts5Buffer*)&pSyn[1]);
  1451. sqlite3_free(pSyn);
  1452. }
  1453. }
  1454. if( pPhrase->poslist.nSpace>0 ) fts5BufferFree(&pPhrase->poslist);
  1455. sqlite3_free(pPhrase);
  1456. }
  1457. }
  1458. /*
  1459. ** Set the "bFirst" flag on the first token of the phrase passed as the
  1460. ** only argument.
  1461. */
  1462. void sqlite3Fts5ParseSetCaret(Fts5ExprPhrase *pPhrase){
  1463. if( pPhrase && pPhrase->nTerm ){
  1464. pPhrase->aTerm[0].bFirst = 1;
  1465. }
  1466. }
  1467. /*
  1468. ** If argument pNear is NULL, then a new Fts5ExprNearset object is allocated
  1469. ** and populated with pPhrase. Or, if pNear is not NULL, phrase pPhrase is
  1470. ** appended to it and the results returned.
  1471. **
  1472. ** If an OOM error occurs, both the pNear and pPhrase objects are freed and
  1473. ** NULL returned.
  1474. */
  1475. Fts5ExprNearset *sqlite3Fts5ParseNearset(
  1476. Fts5Parse *pParse, /* Parse context */
  1477. Fts5ExprNearset *pNear, /* Existing nearset, or NULL */
  1478. Fts5ExprPhrase *pPhrase /* Recently parsed phrase */
  1479. ){
  1480. const int SZALLOC = 8;
  1481. Fts5ExprNearset *pRet = 0;
  1482. if( pParse->rc==SQLITE_OK ){
  1483. if( pNear==0 ){
  1484. sqlite3_int64 nByte;
  1485. nByte = sizeof(Fts5ExprNearset) + SZALLOC * sizeof(Fts5ExprPhrase*);
  1486. pRet = sqlite3_malloc64(nByte);
  1487. if( pRet==0 ){
  1488. pParse->rc = SQLITE_NOMEM;
  1489. }else{
  1490. memset(pRet, 0, (size_t)nByte);
  1491. }
  1492. }else if( (pNear->nPhrase % SZALLOC)==0 ){
  1493. int nNew = pNear->nPhrase + SZALLOC;
  1494. sqlite3_int64 nByte;
  1495. nByte = sizeof(Fts5ExprNearset) + nNew * sizeof(Fts5ExprPhrase*);
  1496. pRet = (Fts5ExprNearset*)sqlite3_realloc64(pNear, nByte);
  1497. if( pRet==0 ){
  1498. pParse->rc = SQLITE_NOMEM;
  1499. }
  1500. }else{
  1501. pRet = pNear;
  1502. }
  1503. }
  1504. if( pRet==0 ){
  1505. assert( pParse->rc!=SQLITE_OK );
  1506. sqlite3Fts5ParseNearsetFree(pNear);
  1507. sqlite3Fts5ParsePhraseFree(pPhrase);
  1508. }else{
  1509. if( pRet->nPhrase>0 ){
  1510. Fts5ExprPhrase *pLast = pRet->apPhrase[pRet->nPhrase-1];
  1511. assert( pParse!=0 );
  1512. assert( pParse->apPhrase!=0 );
  1513. assert( pParse->nPhrase>=2 );
  1514. assert( pLast==pParse->apPhrase[pParse->nPhrase-2] );
  1515. if( pPhrase->nTerm==0 ){
  1516. fts5ExprPhraseFree(pPhrase);
  1517. pRet->nPhrase--;
  1518. pParse->nPhrase--;
  1519. pPhrase = pLast;
  1520. }else if( pLast->nTerm==0 ){
  1521. fts5ExprPhraseFree(pLast);
  1522. pParse->apPhrase[pParse->nPhrase-2] = pPhrase;
  1523. pParse->nPhrase--;
  1524. pRet->nPhrase--;
  1525. }
  1526. }
  1527. pRet->apPhrase[pRet->nPhrase++] = pPhrase;
  1528. }
  1529. return pRet;
  1530. }
  1531. typedef struct TokenCtx TokenCtx;
  1532. struct TokenCtx {
  1533. Fts5ExprPhrase *pPhrase;
  1534. Fts5Config *pConfig;
  1535. int rc;
  1536. };
  1537. /*
  1538. ** Callback for tokenizing terms used by ParseTerm().
  1539. */
  1540. static int fts5ParseTokenize(
  1541. void *pContext, /* Pointer to Fts5InsertCtx object */
  1542. int tflags, /* Mask of FTS5_TOKEN_* flags */
  1543. const char *pToken, /* Buffer containing token */
  1544. int nToken, /* Size of token in bytes */
  1545. int iUnused1, /* Start offset of token */
  1546. int iUnused2 /* End offset of token */
  1547. ){
  1548. int rc = SQLITE_OK;
  1549. const int SZALLOC = 8;
  1550. TokenCtx *pCtx = (TokenCtx*)pContext;
  1551. Fts5ExprPhrase *pPhrase = pCtx->pPhrase;
  1552. UNUSED_PARAM2(iUnused1, iUnused2);
  1553. /* If an error has already occurred, this is a no-op */
  1554. if( pCtx->rc!=SQLITE_OK ) return pCtx->rc;
  1555. if( nToken>FTS5_MAX_TOKEN_SIZE ) nToken = FTS5_MAX_TOKEN_SIZE;
  1556. if( pPhrase && pPhrase->nTerm>0 && (tflags & FTS5_TOKEN_COLOCATED) ){
  1557. Fts5ExprTerm *pSyn;
  1558. sqlite3_int64 nByte = sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer) + nToken+1;
  1559. pSyn = (Fts5ExprTerm*)sqlite3_malloc64(nByte);
  1560. if( pSyn==0 ){
  1561. rc = SQLITE_NOMEM;
  1562. }else{
  1563. memset(pSyn, 0, (size_t)nByte);
  1564. pSyn->pTerm = ((char*)pSyn) + sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer);
  1565. pSyn->nFullTerm = pSyn->nQueryTerm = nToken;
  1566. if( pCtx->pConfig->bTokendata ){
  1567. pSyn->nQueryTerm = (int)strlen(pSyn->pTerm);
  1568. }
  1569. memcpy(pSyn->pTerm, pToken, nToken);
  1570. pSyn->pSynonym = pPhrase->aTerm[pPhrase->nTerm-1].pSynonym;
  1571. pPhrase->aTerm[pPhrase->nTerm-1].pSynonym = pSyn;
  1572. }
  1573. }else{
  1574. Fts5ExprTerm *pTerm;
  1575. if( pPhrase==0 || (pPhrase->nTerm % SZALLOC)==0 ){
  1576. Fts5ExprPhrase *pNew;
  1577. int nNew = SZALLOC + (pPhrase ? pPhrase->nTerm : 0);
  1578. pNew = (Fts5ExprPhrase*)sqlite3_realloc64(pPhrase,
  1579. sizeof(Fts5ExprPhrase) + sizeof(Fts5ExprTerm) * nNew
  1580. );
  1581. if( pNew==0 ){
  1582. rc = SQLITE_NOMEM;
  1583. }else{
  1584. if( pPhrase==0 ) memset(pNew, 0, sizeof(Fts5ExprPhrase));
  1585. pCtx->pPhrase = pPhrase = pNew;
  1586. pNew->nTerm = nNew - SZALLOC;
  1587. }
  1588. }
  1589. if( rc==SQLITE_OK ){
  1590. pTerm = &pPhrase->aTerm[pPhrase->nTerm++];
  1591. memset(pTerm, 0, sizeof(Fts5ExprTerm));
  1592. pTerm->pTerm = sqlite3Fts5Strndup(&rc, pToken, nToken);
  1593. pTerm->nFullTerm = pTerm->nQueryTerm = nToken;
  1594. if( pCtx->pConfig->bTokendata && rc==SQLITE_OK ){
  1595. pTerm->nQueryTerm = (int)strlen(pTerm->pTerm);
  1596. }
  1597. }
  1598. }
  1599. pCtx->rc = rc;
  1600. return rc;
  1601. }
  1602. /*
  1603. ** Free the phrase object passed as the only argument.
  1604. */
  1605. void sqlite3Fts5ParsePhraseFree(Fts5ExprPhrase *pPhrase){
  1606. fts5ExprPhraseFree(pPhrase);
  1607. }
  1608. /*
  1609. ** Free the phrase object passed as the second argument.
  1610. */
  1611. void sqlite3Fts5ParseNearsetFree(Fts5ExprNearset *pNear){
  1612. if( pNear ){
  1613. int i;
  1614. for(i=0; i<pNear->nPhrase; i++){
  1615. fts5ExprPhraseFree(pNear->apPhrase[i]);
  1616. }
  1617. sqlite3_free(pNear->pColset);
  1618. sqlite3_free(pNear);
  1619. }
  1620. }
  1621. void sqlite3Fts5ParseFinished(Fts5Parse *pParse, Fts5ExprNode *p){
  1622. assert( pParse->pExpr==0 );
  1623. pParse->pExpr = p;
  1624. }
  1625. static int parseGrowPhraseArray(Fts5Parse *pParse){
  1626. if( (pParse->nPhrase % 8)==0 ){
  1627. sqlite3_int64 nByte = sizeof(Fts5ExprPhrase*) * (pParse->nPhrase + 8);
  1628. Fts5ExprPhrase **apNew;
  1629. apNew = (Fts5ExprPhrase**)sqlite3_realloc64(pParse->apPhrase, nByte);
  1630. if( apNew==0 ){
  1631. pParse->rc = SQLITE_NOMEM;
  1632. return SQLITE_NOMEM;
  1633. }
  1634. pParse->apPhrase = apNew;
  1635. }
  1636. return SQLITE_OK;
  1637. }
  1638. /*
  1639. ** This function is called by the parser to process a string token. The
  1640. ** string may or may not be quoted. In any case it is tokenized and a
  1641. ** phrase object consisting of all tokens returned.
  1642. */
  1643. Fts5ExprPhrase *sqlite3Fts5ParseTerm(
  1644. Fts5Parse *pParse, /* Parse context */
  1645. Fts5ExprPhrase *pAppend, /* Phrase to append to */
  1646. Fts5Token *pToken, /* String to tokenize */
  1647. int bPrefix /* True if there is a trailing "*" */
  1648. ){
  1649. Fts5Config *pConfig = pParse->pConfig;
  1650. TokenCtx sCtx; /* Context object passed to callback */
  1651. int rc; /* Tokenize return code */
  1652. char *z = 0;
  1653. memset(&sCtx, 0, sizeof(TokenCtx));
  1654. sCtx.pPhrase = pAppend;
  1655. sCtx.pConfig = pConfig;
  1656. rc = fts5ParseStringFromToken(pToken, &z);
  1657. if( rc==SQLITE_OK ){
  1658. int flags = FTS5_TOKENIZE_QUERY | (bPrefix ? FTS5_TOKENIZE_PREFIX : 0);
  1659. int n;
  1660. sqlite3Fts5Dequote(z);
  1661. n = (int)strlen(z);
  1662. rc = sqlite3Fts5Tokenize(pConfig, flags, z, n, &sCtx, fts5ParseTokenize);
  1663. }
  1664. sqlite3_free(z);
  1665. if( rc || (rc = sCtx.rc) ){
  1666. pParse->rc = rc;
  1667. fts5ExprPhraseFree(sCtx.pPhrase);
  1668. sCtx.pPhrase = 0;
  1669. }else{
  1670. if( pAppend==0 ){
  1671. if( parseGrowPhraseArray(pParse) ){
  1672. fts5ExprPhraseFree(sCtx.pPhrase);
  1673. return 0;
  1674. }
  1675. pParse->nPhrase++;
  1676. }
  1677. if( sCtx.pPhrase==0 ){
  1678. /* This happens when parsing a token or quoted phrase that contains
  1679. ** no token characters at all. (e.g ... MATCH '""'). */
  1680. sCtx.pPhrase = sqlite3Fts5MallocZero(&pParse->rc, sizeof(Fts5ExprPhrase));
  1681. }else if( sCtx.pPhrase->nTerm ){
  1682. sCtx.pPhrase->aTerm[sCtx.pPhrase->nTerm-1].bPrefix = (u8)bPrefix;
  1683. }
  1684. assert( pParse->apPhrase!=0 );
  1685. pParse->apPhrase[pParse->nPhrase-1] = sCtx.pPhrase;
  1686. }
  1687. return sCtx.pPhrase;
  1688. }
  1689. /*
  1690. ** Create a new FTS5 expression by cloning phrase iPhrase of the
  1691. ** expression passed as the second argument.
  1692. */
  1693. int sqlite3Fts5ExprClonePhrase(
  1694. Fts5Expr *pExpr,
  1695. int iPhrase,
  1696. Fts5Expr **ppNew
  1697. ){
  1698. int rc = SQLITE_OK; /* Return code */
  1699. Fts5ExprPhrase *pOrig = 0; /* The phrase extracted from pExpr */
  1700. Fts5Expr *pNew = 0; /* Expression to return via *ppNew */
  1701. TokenCtx sCtx = {0,0,0}; /* Context object for fts5ParseTokenize */
  1702. if( !pExpr || iPhrase<0 || iPhrase>=pExpr->nPhrase ){
  1703. rc = SQLITE_RANGE;
  1704. }else{
  1705. pOrig = pExpr->apExprPhrase[iPhrase];
  1706. pNew = (Fts5Expr*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5Expr));
  1707. }
  1708. if( rc==SQLITE_OK ){
  1709. pNew->apExprPhrase = (Fts5ExprPhrase**)sqlite3Fts5MallocZero(&rc,
  1710. sizeof(Fts5ExprPhrase*));
  1711. }
  1712. if( rc==SQLITE_OK ){
  1713. pNew->pRoot = (Fts5ExprNode*)sqlite3Fts5MallocZero(&rc,
  1714. sizeof(Fts5ExprNode));
  1715. }
  1716. if( rc==SQLITE_OK ){
  1717. pNew->pRoot->pNear = (Fts5ExprNearset*)sqlite3Fts5MallocZero(&rc,
  1718. sizeof(Fts5ExprNearset) + sizeof(Fts5ExprPhrase*));
  1719. }
  1720. if( rc==SQLITE_OK && ALWAYS(pOrig!=0) ){
  1721. Fts5Colset *pColsetOrig = pOrig->pNode->pNear->pColset;
  1722. if( pColsetOrig ){
  1723. sqlite3_int64 nByte;
  1724. Fts5Colset *pColset;
  1725. nByte = sizeof(Fts5Colset) + (pColsetOrig->nCol-1) * sizeof(int);
  1726. pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&rc, nByte);
  1727. if( pColset ){
  1728. memcpy(pColset, pColsetOrig, (size_t)nByte);
  1729. }
  1730. pNew->pRoot->pNear->pColset = pColset;
  1731. }
  1732. }
  1733. if( rc==SQLITE_OK ){
  1734. if( pOrig->nTerm ){
  1735. int i; /* Used to iterate through phrase terms */
  1736. sCtx.pConfig = pExpr->pConfig;
  1737. for(i=0; rc==SQLITE_OK && i<pOrig->nTerm; i++){
  1738. int tflags = 0;
  1739. Fts5ExprTerm *p;
  1740. for(p=&pOrig->aTerm[i]; p && rc==SQLITE_OK; p=p->pSynonym){
  1741. rc = fts5ParseTokenize((void*)&sCtx,tflags,p->pTerm,p->nFullTerm,0,0);
  1742. tflags = FTS5_TOKEN_COLOCATED;
  1743. }
  1744. if( rc==SQLITE_OK ){
  1745. sCtx.pPhrase->aTerm[i].bPrefix = pOrig->aTerm[i].bPrefix;
  1746. sCtx.pPhrase->aTerm[i].bFirst = pOrig->aTerm[i].bFirst;
  1747. }
  1748. }
  1749. }else{
  1750. /* This happens when parsing a token or quoted phrase that contains
  1751. ** no token characters at all. (e.g ... MATCH '""'). */
  1752. sCtx.pPhrase = sqlite3Fts5MallocZero(&rc, sizeof(Fts5ExprPhrase));
  1753. }
  1754. }
  1755. if( rc==SQLITE_OK && ALWAYS(sCtx.pPhrase) ){
  1756. /* All the allocations succeeded. Put the expression object together. */
  1757. pNew->pIndex = pExpr->pIndex;
  1758. pNew->pConfig = pExpr->pConfig;
  1759. pNew->nPhrase = 1;
  1760. pNew->apExprPhrase[0] = sCtx.pPhrase;
  1761. pNew->pRoot->pNear->apPhrase[0] = sCtx.pPhrase;
  1762. pNew->pRoot->pNear->nPhrase = 1;
  1763. sCtx.pPhrase->pNode = pNew->pRoot;
  1764. if( pOrig->nTerm==1
  1765. && pOrig->aTerm[0].pSynonym==0
  1766. && pOrig->aTerm[0].bFirst==0
  1767. ){
  1768. pNew->pRoot->eType = FTS5_TERM;
  1769. pNew->pRoot->xNext = fts5ExprNodeNext_TERM;
  1770. }else{
  1771. pNew->pRoot->eType = FTS5_STRING;
  1772. pNew->pRoot->xNext = fts5ExprNodeNext_STRING;
  1773. }
  1774. }else{
  1775. sqlite3Fts5ExprFree(pNew);
  1776. fts5ExprPhraseFree(sCtx.pPhrase);
  1777. pNew = 0;
  1778. }
  1779. *ppNew = pNew;
  1780. return rc;
  1781. }
  1782. /*
  1783. ** Token pTok has appeared in a MATCH expression where the NEAR operator
  1784. ** is expected. If token pTok does not contain "NEAR", store an error
  1785. ** in the pParse object.
  1786. */
  1787. void sqlite3Fts5ParseNear(Fts5Parse *pParse, Fts5Token *pTok){
  1788. if( pTok->n!=4 || memcmp("NEAR", pTok->p, 4) ){
  1789. sqlite3Fts5ParseError(
  1790. pParse, "fts5: syntax error near \"%.*s\"", pTok->n, pTok->p
  1791. );
  1792. }
  1793. }
  1794. void sqlite3Fts5ParseSetDistance(
  1795. Fts5Parse *pParse,
  1796. Fts5ExprNearset *pNear,
  1797. Fts5Token *p
  1798. ){
  1799. if( pNear ){
  1800. int nNear = 0;
  1801. int i;
  1802. if( p->n ){
  1803. for(i=0; i<p->n; i++){
  1804. char c = (char)p->p[i];
  1805. if( c<'0' || c>'9' ){
  1806. sqlite3Fts5ParseError(
  1807. pParse, "expected integer, got \"%.*s\"", p->n, p->p
  1808. );
  1809. return;
  1810. }
  1811. nNear = nNear * 10 + (p->p[i] - '0');
  1812. }
  1813. }else{
  1814. nNear = FTS5_DEFAULT_NEARDIST;
  1815. }
  1816. pNear->nNear = nNear;
  1817. }
  1818. }
  1819. /*
  1820. ** The second argument passed to this function may be NULL, or it may be
  1821. ** an existing Fts5Colset object. This function returns a pointer to
  1822. ** a new colset object containing the contents of (p) with new value column
  1823. ** number iCol appended.
  1824. **
  1825. ** If an OOM error occurs, store an error code in pParse and return NULL.
  1826. ** The old colset object (if any) is not freed in this case.
  1827. */
  1828. static Fts5Colset *fts5ParseColset(
  1829. Fts5Parse *pParse, /* Store SQLITE_NOMEM here if required */
  1830. Fts5Colset *p, /* Existing colset object */
  1831. int iCol /* New column to add to colset object */
  1832. ){
  1833. int nCol = p ? p->nCol : 0; /* Num. columns already in colset object */
  1834. Fts5Colset *pNew; /* New colset object to return */
  1835. assert( pParse->rc==SQLITE_OK );
  1836. assert( iCol>=0 && iCol<pParse->pConfig->nCol );
  1837. pNew = sqlite3_realloc64(p, sizeof(Fts5Colset) + sizeof(int)*nCol);
  1838. if( pNew==0 ){
  1839. pParse->rc = SQLITE_NOMEM;
  1840. }else{
  1841. int *aiCol = pNew->aiCol;
  1842. int i, j;
  1843. for(i=0; i<nCol; i++){
  1844. if( aiCol[i]==iCol ) return pNew;
  1845. if( aiCol[i]>iCol ) break;
  1846. }
  1847. for(j=nCol; j>i; j--){
  1848. aiCol[j] = aiCol[j-1];
  1849. }
  1850. aiCol[i] = iCol;
  1851. pNew->nCol = nCol+1;
  1852. #ifndef NDEBUG
  1853. /* Check that the array is in order and contains no duplicate entries. */
  1854. for(i=1; i<pNew->nCol; i++) assert( pNew->aiCol[i]>pNew->aiCol[i-1] );
  1855. #endif
  1856. }
  1857. return pNew;
  1858. }
  1859. /*
  1860. ** Allocate and return an Fts5Colset object specifying the inverse of
  1861. ** the colset passed as the second argument. Free the colset passed
  1862. ** as the second argument before returning.
  1863. */
  1864. Fts5Colset *sqlite3Fts5ParseColsetInvert(Fts5Parse *pParse, Fts5Colset *p){
  1865. Fts5Colset *pRet;
  1866. int nCol = pParse->pConfig->nCol;
  1867. pRet = (Fts5Colset*)sqlite3Fts5MallocZero(&pParse->rc,
  1868. sizeof(Fts5Colset) + sizeof(int)*nCol
  1869. );
  1870. if( pRet ){
  1871. int i;
  1872. int iOld = 0;
  1873. for(i=0; i<nCol; i++){
  1874. if( iOld>=p->nCol || p->aiCol[iOld]!=i ){
  1875. pRet->aiCol[pRet->nCol++] = i;
  1876. }else{
  1877. iOld++;
  1878. }
  1879. }
  1880. }
  1881. sqlite3_free(p);
  1882. return pRet;
  1883. }
  1884. Fts5Colset *sqlite3Fts5ParseColset(
  1885. Fts5Parse *pParse, /* Store SQLITE_NOMEM here if required */
  1886. Fts5Colset *pColset, /* Existing colset object */
  1887. Fts5Token *p
  1888. ){
  1889. Fts5Colset *pRet = 0;
  1890. int iCol;
  1891. char *z; /* Dequoted copy of token p */
  1892. z = sqlite3Fts5Strndup(&pParse->rc, p->p, p->n);
  1893. if( pParse->rc==SQLITE_OK ){
  1894. Fts5Config *pConfig = pParse->pConfig;
  1895. sqlite3Fts5Dequote(z);
  1896. for(iCol=0; iCol<pConfig->nCol; iCol++){
  1897. if( 0==sqlite3_stricmp(pConfig->azCol[iCol], z) ) break;
  1898. }
  1899. if( iCol==pConfig->nCol ){
  1900. sqlite3Fts5ParseError(pParse, "no such column: %s", z);
  1901. }else{
  1902. pRet = fts5ParseColset(pParse, pColset, iCol);
  1903. }
  1904. sqlite3_free(z);
  1905. }
  1906. if( pRet==0 ){
  1907. assert( pParse->rc!=SQLITE_OK );
  1908. sqlite3_free(pColset);
  1909. }
  1910. return pRet;
  1911. }
  1912. /*
  1913. ** If argument pOrig is NULL, or if (*pRc) is set to anything other than
  1914. ** SQLITE_OK when this function is called, NULL is returned.
  1915. **
  1916. ** Otherwise, a copy of (*pOrig) is made into memory obtained from
  1917. ** sqlite3Fts5MallocZero() and a pointer to it returned. If the allocation
  1918. ** fails, (*pRc) is set to SQLITE_NOMEM and NULL is returned.
  1919. */
  1920. static Fts5Colset *fts5CloneColset(int *pRc, Fts5Colset *pOrig){
  1921. Fts5Colset *pRet;
  1922. if( pOrig ){
  1923. sqlite3_int64 nByte = sizeof(Fts5Colset) + (pOrig->nCol-1) * sizeof(int);
  1924. pRet = (Fts5Colset*)sqlite3Fts5MallocZero(pRc, nByte);
  1925. if( pRet ){
  1926. memcpy(pRet, pOrig, (size_t)nByte);
  1927. }
  1928. }else{
  1929. pRet = 0;
  1930. }
  1931. return pRet;
  1932. }
  1933. /*
  1934. ** Remove from colset pColset any columns that are not also in colset pMerge.
  1935. */
  1936. static void fts5MergeColset(Fts5Colset *pColset, Fts5Colset *pMerge){
  1937. int iIn = 0; /* Next input in pColset */
  1938. int iMerge = 0; /* Next input in pMerge */
  1939. int iOut = 0; /* Next output slot in pColset */
  1940. while( iIn<pColset->nCol && iMerge<pMerge->nCol ){
  1941. int iDiff = pColset->aiCol[iIn] - pMerge->aiCol[iMerge];
  1942. if( iDiff==0 ){
  1943. pColset->aiCol[iOut++] = pMerge->aiCol[iMerge];
  1944. iMerge++;
  1945. iIn++;
  1946. }else if( iDiff>0 ){
  1947. iMerge++;
  1948. }else{
  1949. iIn++;
  1950. }
  1951. }
  1952. pColset->nCol = iOut;
  1953. }
  1954. /*
  1955. ** Recursively apply colset pColset to expression node pNode and all of
  1956. ** its decendents. If (*ppFree) is not NULL, it contains a spare copy
  1957. ** of pColset. This function may use the spare copy and set (*ppFree) to
  1958. ** zero, or it may create copies of pColset using fts5CloneColset().
  1959. */
  1960. static void fts5ParseSetColset(
  1961. Fts5Parse *pParse,
  1962. Fts5ExprNode *pNode,
  1963. Fts5Colset *pColset,
  1964. Fts5Colset **ppFree
  1965. ){
  1966. if( pParse->rc==SQLITE_OK ){
  1967. assert( pNode->eType==FTS5_TERM || pNode->eType==FTS5_STRING
  1968. || pNode->eType==FTS5_AND || pNode->eType==FTS5_OR
  1969. || pNode->eType==FTS5_NOT || pNode->eType==FTS5_EOF
  1970. );
  1971. if( pNode->eType==FTS5_STRING || pNode->eType==FTS5_TERM ){
  1972. Fts5ExprNearset *pNear = pNode->pNear;
  1973. if( pNear->pColset ){
  1974. fts5MergeColset(pNear->pColset, pColset);
  1975. if( pNear->pColset->nCol==0 ){
  1976. pNode->eType = FTS5_EOF;
  1977. pNode->xNext = 0;
  1978. }
  1979. }else if( *ppFree ){
  1980. pNear->pColset = pColset;
  1981. *ppFree = 0;
  1982. }else{
  1983. pNear->pColset = fts5CloneColset(&pParse->rc, pColset);
  1984. }
  1985. }else{
  1986. int i;
  1987. assert( pNode->eType!=FTS5_EOF || pNode->nChild==0 );
  1988. for(i=0; i<pNode->nChild; i++){
  1989. fts5ParseSetColset(pParse, pNode->apChild[i], pColset, ppFree);
  1990. }
  1991. }
  1992. }
  1993. }
  1994. /*
  1995. ** Apply colset pColset to expression node pExpr and all of its descendents.
  1996. */
  1997. void sqlite3Fts5ParseSetColset(
  1998. Fts5Parse *pParse,
  1999. Fts5ExprNode *pExpr,
  2000. Fts5Colset *pColset
  2001. ){
  2002. Fts5Colset *pFree = pColset;
  2003. if( pParse->pConfig->eDetail==FTS5_DETAIL_NONE ){
  2004. sqlite3Fts5ParseError(pParse,
  2005. "fts5: column queries are not supported (detail=none)"
  2006. );
  2007. }else{
  2008. fts5ParseSetColset(pParse, pExpr, pColset, &pFree);
  2009. }
  2010. sqlite3_free(pFree);
  2011. }
  2012. static void fts5ExprAssignXNext(Fts5ExprNode *pNode){
  2013. switch( pNode->eType ){
  2014. case FTS5_STRING: {
  2015. Fts5ExprNearset *pNear = pNode->pNear;
  2016. if( pNear->nPhrase==1 && pNear->apPhrase[0]->nTerm==1
  2017. && pNear->apPhrase[0]->aTerm[0].pSynonym==0
  2018. && pNear->apPhrase[0]->aTerm[0].bFirst==0
  2019. ){
  2020. pNode->eType = FTS5_TERM;
  2021. pNode->xNext = fts5ExprNodeNext_TERM;
  2022. }else{
  2023. pNode->xNext = fts5ExprNodeNext_STRING;
  2024. }
  2025. break;
  2026. };
  2027. case FTS5_OR: {
  2028. pNode->xNext = fts5ExprNodeNext_OR;
  2029. break;
  2030. };
  2031. case FTS5_AND: {
  2032. pNode->xNext = fts5ExprNodeNext_AND;
  2033. break;
  2034. };
  2035. default: assert( pNode->eType==FTS5_NOT ); {
  2036. pNode->xNext = fts5ExprNodeNext_NOT;
  2037. break;
  2038. };
  2039. }
  2040. }
  2041. /*
  2042. ** Add pSub as a child of p.
  2043. */
  2044. static void fts5ExprAddChildren(Fts5ExprNode *p, Fts5ExprNode *pSub){
  2045. int ii = p->nChild;
  2046. if( p->eType!=FTS5_NOT && pSub->eType==p->eType ){
  2047. int nByte = sizeof(Fts5ExprNode*) * pSub->nChild;
  2048. memcpy(&p->apChild[p->nChild], pSub->apChild, nByte);
  2049. p->nChild += pSub->nChild;
  2050. sqlite3_free(pSub);
  2051. }else{
  2052. p->apChild[p->nChild++] = pSub;
  2053. }
  2054. for( ; ii<p->nChild; ii++){
  2055. p->iHeight = MAX(p->iHeight, p->apChild[ii]->iHeight + 1);
  2056. }
  2057. }
  2058. /*
  2059. ** This function is used when parsing LIKE or GLOB patterns against
  2060. ** trigram indexes that specify either detail=column or detail=none.
  2061. ** It converts a phrase:
  2062. **
  2063. ** abc + def + ghi
  2064. **
  2065. ** into an AND tree:
  2066. **
  2067. ** abc AND def AND ghi
  2068. */
  2069. static Fts5ExprNode *fts5ParsePhraseToAnd(
  2070. Fts5Parse *pParse,
  2071. Fts5ExprNearset *pNear
  2072. ){
  2073. int nTerm = pNear->apPhrase[0]->nTerm;
  2074. int ii;
  2075. int nByte;
  2076. Fts5ExprNode *pRet;
  2077. assert( pNear->nPhrase==1 );
  2078. assert( pParse->bPhraseToAnd );
  2079. nByte = sizeof(Fts5ExprNode) + nTerm*sizeof(Fts5ExprNode*);
  2080. pRet = (Fts5ExprNode*)sqlite3Fts5MallocZero(&pParse->rc, nByte);
  2081. if( pRet ){
  2082. pRet->eType = FTS5_AND;
  2083. pRet->nChild = nTerm;
  2084. pRet->iHeight = 1;
  2085. fts5ExprAssignXNext(pRet);
  2086. pParse->nPhrase--;
  2087. for(ii=0; ii<nTerm; ii++){
  2088. Fts5ExprPhrase *pPhrase = (Fts5ExprPhrase*)sqlite3Fts5MallocZero(
  2089. &pParse->rc, sizeof(Fts5ExprPhrase)
  2090. );
  2091. if( pPhrase ){
  2092. if( parseGrowPhraseArray(pParse) ){
  2093. fts5ExprPhraseFree(pPhrase);
  2094. }else{
  2095. Fts5ExprTerm *p = &pNear->apPhrase[0]->aTerm[ii];
  2096. Fts5ExprTerm *pTo = &pPhrase->aTerm[0];
  2097. pParse->apPhrase[pParse->nPhrase++] = pPhrase;
  2098. pPhrase->nTerm = 1;
  2099. pTo->pTerm = sqlite3Fts5Strndup(&pParse->rc, p->pTerm, p->nFullTerm);
  2100. pTo->nQueryTerm = p->nQueryTerm;
  2101. pTo->nFullTerm = p->nFullTerm;
  2102. pRet->apChild[ii] = sqlite3Fts5ParseNode(pParse, FTS5_STRING,
  2103. 0, 0, sqlite3Fts5ParseNearset(pParse, 0, pPhrase)
  2104. );
  2105. }
  2106. }
  2107. }
  2108. if( pParse->rc ){
  2109. sqlite3Fts5ParseNodeFree(pRet);
  2110. pRet = 0;
  2111. }else{
  2112. sqlite3Fts5ParseNearsetFree(pNear);
  2113. }
  2114. }
  2115. return pRet;
  2116. }
  2117. /*
  2118. ** Allocate and return a new expression object. If anything goes wrong (i.e.
  2119. ** OOM error), leave an error code in pParse and return NULL.
  2120. */
  2121. Fts5ExprNode *sqlite3Fts5ParseNode(
  2122. Fts5Parse *pParse, /* Parse context */
  2123. int eType, /* FTS5_STRING, AND, OR or NOT */
  2124. Fts5ExprNode *pLeft, /* Left hand child expression */
  2125. Fts5ExprNode *pRight, /* Right hand child expression */
  2126. Fts5ExprNearset *pNear /* For STRING expressions, the near cluster */
  2127. ){
  2128. Fts5ExprNode *pRet = 0;
  2129. if( pParse->rc==SQLITE_OK ){
  2130. int nChild = 0; /* Number of children of returned node */
  2131. sqlite3_int64 nByte; /* Bytes of space to allocate for this node */
  2132. assert( (eType!=FTS5_STRING && !pNear)
  2133. || (eType==FTS5_STRING && !pLeft && !pRight)
  2134. );
  2135. if( eType==FTS5_STRING && pNear==0 ) return 0;
  2136. if( eType!=FTS5_STRING && pLeft==0 ) return pRight;
  2137. if( eType!=FTS5_STRING && pRight==0 ) return pLeft;
  2138. if( eType==FTS5_STRING
  2139. && pParse->bPhraseToAnd
  2140. && pNear->apPhrase[0]->nTerm>1
  2141. ){
  2142. pRet = fts5ParsePhraseToAnd(pParse, pNear);
  2143. }else{
  2144. if( eType==FTS5_NOT ){
  2145. nChild = 2;
  2146. }else if( eType==FTS5_AND || eType==FTS5_OR ){
  2147. nChild = 2;
  2148. if( pLeft->eType==eType ) nChild += pLeft->nChild-1;
  2149. if( pRight->eType==eType ) nChild += pRight->nChild-1;
  2150. }
  2151. nByte = sizeof(Fts5ExprNode) + sizeof(Fts5ExprNode*)*(nChild-1);
  2152. pRet = (Fts5ExprNode*)sqlite3Fts5MallocZero(&pParse->rc, nByte);
  2153. if( pRet ){
  2154. pRet->eType = eType;
  2155. pRet->pNear = pNear;
  2156. fts5ExprAssignXNext(pRet);
  2157. if( eType==FTS5_STRING ){
  2158. int iPhrase;
  2159. for(iPhrase=0; iPhrase<pNear->nPhrase; iPhrase++){
  2160. pNear->apPhrase[iPhrase]->pNode = pRet;
  2161. if( pNear->apPhrase[iPhrase]->nTerm==0 ){
  2162. pRet->xNext = 0;
  2163. pRet->eType = FTS5_EOF;
  2164. }
  2165. }
  2166. if( pParse->pConfig->eDetail!=FTS5_DETAIL_FULL ){
  2167. Fts5ExprPhrase *pPhrase = pNear->apPhrase[0];
  2168. if( pNear->nPhrase!=1
  2169. || pPhrase->nTerm>1
  2170. || (pPhrase->nTerm>0 && pPhrase->aTerm[0].bFirst)
  2171. ){
  2172. sqlite3Fts5ParseError(pParse,
  2173. "fts5: %s queries are not supported (detail!=full)",
  2174. pNear->nPhrase==1 ? "phrase": "NEAR"
  2175. );
  2176. sqlite3Fts5ParseNodeFree(pRet);
  2177. pRet = 0;
  2178. pNear = 0;
  2179. assert( pLeft==0 && pRight==0 );
  2180. }
  2181. }
  2182. }else{
  2183. assert( pNear==0 );
  2184. fts5ExprAddChildren(pRet, pLeft);
  2185. fts5ExprAddChildren(pRet, pRight);
  2186. pLeft = pRight = 0;
  2187. if( pRet->iHeight>SQLITE_FTS5_MAX_EXPR_DEPTH ){
  2188. sqlite3Fts5ParseError(pParse,
  2189. "fts5 expression tree is too large (maximum depth %d)",
  2190. SQLITE_FTS5_MAX_EXPR_DEPTH
  2191. );
  2192. sqlite3Fts5ParseNodeFree(pRet);
  2193. pRet = 0;
  2194. }
  2195. }
  2196. }
  2197. }
  2198. }
  2199. if( pRet==0 ){
  2200. assert( pParse->rc!=SQLITE_OK );
  2201. sqlite3Fts5ParseNodeFree(pLeft);
  2202. sqlite3Fts5ParseNodeFree(pRight);
  2203. sqlite3Fts5ParseNearsetFree(pNear);
  2204. }
  2205. return pRet;
  2206. }
  2207. Fts5ExprNode *sqlite3Fts5ParseImplicitAnd(
  2208. Fts5Parse *pParse, /* Parse context */
  2209. Fts5ExprNode *pLeft, /* Left hand child expression */
  2210. Fts5ExprNode *pRight /* Right hand child expression */
  2211. ){
  2212. Fts5ExprNode *pRet = 0;
  2213. Fts5ExprNode *pPrev;
  2214. if( pParse->rc ){
  2215. sqlite3Fts5ParseNodeFree(pLeft);
  2216. sqlite3Fts5ParseNodeFree(pRight);
  2217. }else{
  2218. assert( pLeft->eType==FTS5_STRING
  2219. || pLeft->eType==FTS5_TERM
  2220. || pLeft->eType==FTS5_EOF
  2221. || pLeft->eType==FTS5_AND
  2222. );
  2223. assert( pRight->eType==FTS5_STRING
  2224. || pRight->eType==FTS5_TERM
  2225. || pRight->eType==FTS5_EOF
  2226. || (pRight->eType==FTS5_AND && pParse->bPhraseToAnd)
  2227. );
  2228. if( pLeft->eType==FTS5_AND ){
  2229. pPrev = pLeft->apChild[pLeft->nChild-1];
  2230. }else{
  2231. pPrev = pLeft;
  2232. }
  2233. assert( pPrev->eType==FTS5_STRING
  2234. || pPrev->eType==FTS5_TERM
  2235. || pPrev->eType==FTS5_EOF
  2236. );
  2237. if( pRight->eType==FTS5_EOF ){
  2238. assert( pParse->apPhrase!=0 );
  2239. assert( pParse->nPhrase>0 );
  2240. assert( pParse->apPhrase[pParse->nPhrase-1]==pRight->pNear->apPhrase[0] );
  2241. sqlite3Fts5ParseNodeFree(pRight);
  2242. pRet = pLeft;
  2243. pParse->nPhrase--;
  2244. }
  2245. else if( pPrev->eType==FTS5_EOF ){
  2246. Fts5ExprPhrase **ap;
  2247. if( pPrev==pLeft ){
  2248. pRet = pRight;
  2249. }else{
  2250. pLeft->apChild[pLeft->nChild-1] = pRight;
  2251. pRet = pLeft;
  2252. }
  2253. ap = &pParse->apPhrase[pParse->nPhrase-1-pRight->pNear->nPhrase];
  2254. assert( ap[0]==pPrev->pNear->apPhrase[0] );
  2255. memmove(ap, &ap[1], sizeof(Fts5ExprPhrase*)*pRight->pNear->nPhrase);
  2256. pParse->nPhrase--;
  2257. sqlite3Fts5ParseNodeFree(pPrev);
  2258. }
  2259. else{
  2260. pRet = sqlite3Fts5ParseNode(pParse, FTS5_AND, pLeft, pRight, 0);
  2261. }
  2262. }
  2263. return pRet;
  2264. }
  2265. #if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG)
  2266. static char *fts5ExprTermPrint(Fts5ExprTerm *pTerm){
  2267. sqlite3_int64 nByte = 0;
  2268. Fts5ExprTerm *p;
  2269. char *zQuoted;
  2270. /* Determine the maximum amount of space required. */
  2271. for(p=pTerm; p; p=p->pSynonym){
  2272. nByte += pTerm->nQueryTerm * 2 + 3 + 2;
  2273. }
  2274. zQuoted = sqlite3_malloc64(nByte);
  2275. if( zQuoted ){
  2276. int i = 0;
  2277. for(p=pTerm; p; p=p->pSynonym){
  2278. char *zIn = p->pTerm;
  2279. char *zEnd = &zIn[p->nQueryTerm];
  2280. zQuoted[i++] = '"';
  2281. while( zIn<zEnd ){
  2282. if( *zIn=='"' ) zQuoted[i++] = '"';
  2283. zQuoted[i++] = *zIn++;
  2284. }
  2285. zQuoted[i++] = '"';
  2286. if( p->pSynonym ) zQuoted[i++] = '|';
  2287. }
  2288. if( pTerm->bPrefix ){
  2289. zQuoted[i++] = ' ';
  2290. zQuoted[i++] = '*';
  2291. }
  2292. zQuoted[i++] = '\0';
  2293. }
  2294. return zQuoted;
  2295. }
  2296. static char *fts5PrintfAppend(char *zApp, const char *zFmt, ...){
  2297. char *zNew;
  2298. va_list ap;
  2299. va_start(ap, zFmt);
  2300. zNew = sqlite3_vmprintf(zFmt, ap);
  2301. va_end(ap);
  2302. if( zApp && zNew ){
  2303. char *zNew2 = sqlite3_mprintf("%s%s", zApp, zNew);
  2304. sqlite3_free(zNew);
  2305. zNew = zNew2;
  2306. }
  2307. sqlite3_free(zApp);
  2308. return zNew;
  2309. }
  2310. /*
  2311. ** Compose a tcl-readable representation of expression pExpr. Return a
  2312. ** pointer to a buffer containing that representation. It is the
  2313. ** responsibility of the caller to at some point free the buffer using
  2314. ** sqlite3_free().
  2315. */
  2316. static char *fts5ExprPrintTcl(
  2317. Fts5Config *pConfig,
  2318. const char *zNearsetCmd,
  2319. Fts5ExprNode *pExpr
  2320. ){
  2321. char *zRet = 0;
  2322. if( pExpr->eType==FTS5_STRING || pExpr->eType==FTS5_TERM ){
  2323. Fts5ExprNearset *pNear = pExpr->pNear;
  2324. int i;
  2325. int iTerm;
  2326. zRet = fts5PrintfAppend(zRet, "%s ", zNearsetCmd);
  2327. if( zRet==0 ) return 0;
  2328. if( pNear->pColset ){
  2329. int *aiCol = pNear->pColset->aiCol;
  2330. int nCol = pNear->pColset->nCol;
  2331. if( nCol==1 ){
  2332. zRet = fts5PrintfAppend(zRet, "-col %d ", aiCol[0]);
  2333. }else{
  2334. zRet = fts5PrintfAppend(zRet, "-col {%d", aiCol[0]);
  2335. for(i=1; i<pNear->pColset->nCol; i++){
  2336. zRet = fts5PrintfAppend(zRet, " %d", aiCol[i]);
  2337. }
  2338. zRet = fts5PrintfAppend(zRet, "} ");
  2339. }
  2340. if( zRet==0 ) return 0;
  2341. }
  2342. if( pNear->nPhrase>1 ){
  2343. zRet = fts5PrintfAppend(zRet, "-near %d ", pNear->nNear);
  2344. if( zRet==0 ) return 0;
  2345. }
  2346. zRet = fts5PrintfAppend(zRet, "--");
  2347. if( zRet==0 ) return 0;
  2348. for(i=0; i<pNear->nPhrase; i++){
  2349. Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
  2350. zRet = fts5PrintfAppend(zRet, " {");
  2351. for(iTerm=0; zRet && iTerm<pPhrase->nTerm; iTerm++){
  2352. Fts5ExprTerm *p = &pPhrase->aTerm[iTerm];
  2353. zRet = fts5PrintfAppend(zRet, "%s%.*s", iTerm==0?"":" ",
  2354. p->nQueryTerm, p->pTerm
  2355. );
  2356. if( pPhrase->aTerm[iTerm].bPrefix ){
  2357. zRet = fts5PrintfAppend(zRet, "*");
  2358. }
  2359. }
  2360. if( zRet ) zRet = fts5PrintfAppend(zRet, "}");
  2361. if( zRet==0 ) return 0;
  2362. }
  2363. }else if( pExpr->eType==0 ){
  2364. zRet = sqlite3_mprintf("{}");
  2365. }else{
  2366. char const *zOp = 0;
  2367. int i;
  2368. switch( pExpr->eType ){
  2369. case FTS5_AND: zOp = "AND"; break;
  2370. case FTS5_NOT: zOp = "NOT"; break;
  2371. default:
  2372. assert( pExpr->eType==FTS5_OR );
  2373. zOp = "OR";
  2374. break;
  2375. }
  2376. zRet = sqlite3_mprintf("%s", zOp);
  2377. for(i=0; zRet && i<pExpr->nChild; i++){
  2378. char *z = fts5ExprPrintTcl(pConfig, zNearsetCmd, pExpr->apChild[i]);
  2379. if( !z ){
  2380. sqlite3_free(zRet);
  2381. zRet = 0;
  2382. }else{
  2383. zRet = fts5PrintfAppend(zRet, " [%z]", z);
  2384. }
  2385. }
  2386. }
  2387. return zRet;
  2388. }
  2389. static char *fts5ExprPrint(Fts5Config *pConfig, Fts5ExprNode *pExpr){
  2390. char *zRet = 0;
  2391. if( pExpr->eType==0 ){
  2392. return sqlite3_mprintf("\"\"");
  2393. }else
  2394. if( pExpr->eType==FTS5_STRING || pExpr->eType==FTS5_TERM ){
  2395. Fts5ExprNearset *pNear = pExpr->pNear;
  2396. int i;
  2397. int iTerm;
  2398. if( pNear->pColset ){
  2399. int ii;
  2400. Fts5Colset *pColset = pNear->pColset;
  2401. if( pColset->nCol>1 ) zRet = fts5PrintfAppend(zRet, "{");
  2402. for(ii=0; ii<pColset->nCol; ii++){
  2403. zRet = fts5PrintfAppend(zRet, "%s%s",
  2404. pConfig->azCol[pColset->aiCol[ii]], ii==pColset->nCol-1 ? "" : " "
  2405. );
  2406. }
  2407. if( zRet ){
  2408. zRet = fts5PrintfAppend(zRet, "%s : ", pColset->nCol>1 ? "}" : "");
  2409. }
  2410. if( zRet==0 ) return 0;
  2411. }
  2412. if( pNear->nPhrase>1 ){
  2413. zRet = fts5PrintfAppend(zRet, "NEAR(");
  2414. if( zRet==0 ) return 0;
  2415. }
  2416. for(i=0; i<pNear->nPhrase; i++){
  2417. Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
  2418. if( i!=0 ){
  2419. zRet = fts5PrintfAppend(zRet, " ");
  2420. if( zRet==0 ) return 0;
  2421. }
  2422. for(iTerm=0; iTerm<pPhrase->nTerm; iTerm++){
  2423. char *zTerm = fts5ExprTermPrint(&pPhrase->aTerm[iTerm]);
  2424. if( zTerm ){
  2425. zRet = fts5PrintfAppend(zRet, "%s%s", iTerm==0?"":" + ", zTerm);
  2426. sqlite3_free(zTerm);
  2427. }
  2428. if( zTerm==0 || zRet==0 ){
  2429. sqlite3_free(zRet);
  2430. return 0;
  2431. }
  2432. }
  2433. }
  2434. if( pNear->nPhrase>1 ){
  2435. zRet = fts5PrintfAppend(zRet, ", %d)", pNear->nNear);
  2436. if( zRet==0 ) return 0;
  2437. }
  2438. }else{
  2439. char const *zOp = 0;
  2440. int i;
  2441. switch( pExpr->eType ){
  2442. case FTS5_AND: zOp = " AND "; break;
  2443. case FTS5_NOT: zOp = " NOT "; break;
  2444. default:
  2445. assert( pExpr->eType==FTS5_OR );
  2446. zOp = " OR ";
  2447. break;
  2448. }
  2449. for(i=0; i<pExpr->nChild; i++){
  2450. char *z = fts5ExprPrint(pConfig, pExpr->apChild[i]);
  2451. if( z==0 ){
  2452. sqlite3_free(zRet);
  2453. zRet = 0;
  2454. }else{
  2455. int e = pExpr->apChild[i]->eType;
  2456. int b = (e!=FTS5_STRING && e!=FTS5_TERM && e!=FTS5_EOF);
  2457. zRet = fts5PrintfAppend(zRet, "%s%s%z%s",
  2458. (i==0 ? "" : zOp),
  2459. (b?"(":""), z, (b?")":"")
  2460. );
  2461. }
  2462. if( zRet==0 ) break;
  2463. }
  2464. }
  2465. return zRet;
  2466. }
  2467. /*
  2468. ** The implementation of user-defined scalar functions fts5_expr() (bTcl==0)
  2469. ** and fts5_expr_tcl() (bTcl!=0).
  2470. */
  2471. static void fts5ExprFunction(
  2472. sqlite3_context *pCtx, /* Function call context */
  2473. int nArg, /* Number of args */
  2474. sqlite3_value **apVal, /* Function arguments */
  2475. int bTcl
  2476. ){
  2477. Fts5Global *pGlobal = (Fts5Global*)sqlite3_user_data(pCtx);
  2478. sqlite3 *db = sqlite3_context_db_handle(pCtx);
  2479. const char *zExpr = 0;
  2480. char *zErr = 0;
  2481. Fts5Expr *pExpr = 0;
  2482. int rc;
  2483. int i;
  2484. const char **azConfig; /* Array of arguments for Fts5Config */
  2485. const char *zNearsetCmd = "nearset";
  2486. int nConfig; /* Size of azConfig[] */
  2487. Fts5Config *pConfig = 0;
  2488. int iArg = 1;
  2489. if( nArg<1 ){
  2490. zErr = sqlite3_mprintf("wrong number of arguments to function %s",
  2491. bTcl ? "fts5_expr_tcl" : "fts5_expr"
  2492. );
  2493. sqlite3_result_error(pCtx, zErr, -1);
  2494. sqlite3_free(zErr);
  2495. return;
  2496. }
  2497. if( bTcl && nArg>1 ){
  2498. zNearsetCmd = (const char*)sqlite3_value_text(apVal[1]);
  2499. iArg = 2;
  2500. }
  2501. nConfig = 3 + (nArg-iArg);
  2502. azConfig = (const char**)sqlite3_malloc64(sizeof(char*) * nConfig);
  2503. if( azConfig==0 ){
  2504. sqlite3_result_error_nomem(pCtx);
  2505. return;
  2506. }
  2507. azConfig[0] = 0;
  2508. azConfig[1] = "main";
  2509. azConfig[2] = "tbl";
  2510. for(i=3; iArg<nArg; iArg++){
  2511. const char *z = (const char*)sqlite3_value_text(apVal[iArg]);
  2512. azConfig[i++] = (z ? z : "");
  2513. }
  2514. zExpr = (const char*)sqlite3_value_text(apVal[0]);
  2515. if( zExpr==0 ) zExpr = "";
  2516. rc = sqlite3Fts5ConfigParse(pGlobal, db, nConfig, azConfig, &pConfig, &zErr);
  2517. if( rc==SQLITE_OK ){
  2518. rc = sqlite3Fts5ExprNew(pConfig, 0, pConfig->nCol, zExpr, &pExpr, &zErr);
  2519. }
  2520. if( rc==SQLITE_OK ){
  2521. char *zText;
  2522. if( pExpr->pRoot->xNext==0 ){
  2523. zText = sqlite3_mprintf("");
  2524. }else if( bTcl ){
  2525. zText = fts5ExprPrintTcl(pConfig, zNearsetCmd, pExpr->pRoot);
  2526. }else{
  2527. zText = fts5ExprPrint(pConfig, pExpr->pRoot);
  2528. }
  2529. if( zText==0 ){
  2530. rc = SQLITE_NOMEM;
  2531. }else{
  2532. sqlite3_result_text(pCtx, zText, -1, SQLITE_TRANSIENT);
  2533. sqlite3_free(zText);
  2534. }
  2535. }
  2536. if( rc!=SQLITE_OK ){
  2537. if( zErr ){
  2538. sqlite3_result_error(pCtx, zErr, -1);
  2539. sqlite3_free(zErr);
  2540. }else{
  2541. sqlite3_result_error_code(pCtx, rc);
  2542. }
  2543. }
  2544. sqlite3_free((void *)azConfig);
  2545. sqlite3Fts5ConfigFree(pConfig);
  2546. sqlite3Fts5ExprFree(pExpr);
  2547. }
  2548. static void fts5ExprFunctionHr(
  2549. sqlite3_context *pCtx, /* Function call context */
  2550. int nArg, /* Number of args */
  2551. sqlite3_value **apVal /* Function arguments */
  2552. ){
  2553. fts5ExprFunction(pCtx, nArg, apVal, 0);
  2554. }
  2555. static void fts5ExprFunctionTcl(
  2556. sqlite3_context *pCtx, /* Function call context */
  2557. int nArg, /* Number of args */
  2558. sqlite3_value **apVal /* Function arguments */
  2559. ){
  2560. fts5ExprFunction(pCtx, nArg, apVal, 1);
  2561. }
  2562. /*
  2563. ** The implementation of an SQLite user-defined-function that accepts a
  2564. ** single integer as an argument. If the integer is an alpha-numeric
  2565. ** unicode code point, 1 is returned. Otherwise 0.
  2566. */
  2567. static void fts5ExprIsAlnum(
  2568. sqlite3_context *pCtx, /* Function call context */
  2569. int nArg, /* Number of args */
  2570. sqlite3_value **apVal /* Function arguments */
  2571. ){
  2572. int iCode;
  2573. u8 aArr[32];
  2574. if( nArg!=1 ){
  2575. sqlite3_result_error(pCtx,
  2576. "wrong number of arguments to function fts5_isalnum", -1
  2577. );
  2578. return;
  2579. }
  2580. memset(aArr, 0, sizeof(aArr));
  2581. sqlite3Fts5UnicodeCatParse("L*", aArr);
  2582. sqlite3Fts5UnicodeCatParse("N*", aArr);
  2583. sqlite3Fts5UnicodeCatParse("Co", aArr);
  2584. iCode = sqlite3_value_int(apVal[0]);
  2585. sqlite3_result_int(pCtx, aArr[sqlite3Fts5UnicodeCategory((u32)iCode)]);
  2586. }
  2587. static void fts5ExprFold(
  2588. sqlite3_context *pCtx, /* Function call context */
  2589. int nArg, /* Number of args */
  2590. sqlite3_value **apVal /* Function arguments */
  2591. ){
  2592. if( nArg!=1 && nArg!=2 ){
  2593. sqlite3_result_error(pCtx,
  2594. "wrong number of arguments to function fts5_fold", -1
  2595. );
  2596. }else{
  2597. int iCode;
  2598. int bRemoveDiacritics = 0;
  2599. iCode = sqlite3_value_int(apVal[0]);
  2600. if( nArg==2 ) bRemoveDiacritics = sqlite3_value_int(apVal[1]);
  2601. sqlite3_result_int(pCtx, sqlite3Fts5UnicodeFold(iCode, bRemoveDiacritics));
  2602. }
  2603. }
  2604. #endif /* if SQLITE_TEST || SQLITE_FTS5_DEBUG */
  2605. /*
  2606. ** This is called during initialization to register the fts5_expr() scalar
  2607. ** UDF with the SQLite handle passed as the only argument.
  2608. */
  2609. int sqlite3Fts5ExprInit(Fts5Global *pGlobal, sqlite3 *db){
  2610. #if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG)
  2611. struct Fts5ExprFunc {
  2612. const char *z;
  2613. void (*x)(sqlite3_context*,int,sqlite3_value**);
  2614. } aFunc[] = {
  2615. { "fts5_expr", fts5ExprFunctionHr },
  2616. { "fts5_expr_tcl", fts5ExprFunctionTcl },
  2617. { "fts5_isalnum", fts5ExprIsAlnum },
  2618. { "fts5_fold", fts5ExprFold },
  2619. };
  2620. int i;
  2621. int rc = SQLITE_OK;
  2622. void *pCtx = (void*)pGlobal;
  2623. for(i=0; rc==SQLITE_OK && i<ArraySize(aFunc); i++){
  2624. struct Fts5ExprFunc *p = &aFunc[i];
  2625. rc = sqlite3_create_function(db, p->z, -1, SQLITE_UTF8, pCtx, p->x, 0, 0);
  2626. }
  2627. #else
  2628. int rc = SQLITE_OK;
  2629. UNUSED_PARAM2(pGlobal,db);
  2630. #endif
  2631. /* Avoid warnings indicating that sqlite3Fts5ParserTrace() and
  2632. ** sqlite3Fts5ParserFallback() are unused */
  2633. #ifndef NDEBUG
  2634. (void)sqlite3Fts5ParserTrace;
  2635. #endif
  2636. (void)sqlite3Fts5ParserFallback;
  2637. return rc;
  2638. }
  2639. /*
  2640. ** Return the number of phrases in expression pExpr.
  2641. */
  2642. int sqlite3Fts5ExprPhraseCount(Fts5Expr *pExpr){
  2643. return (pExpr ? pExpr->nPhrase : 0);
  2644. }
  2645. /*
  2646. ** Return the number of terms in the iPhrase'th phrase in pExpr.
  2647. */
  2648. int sqlite3Fts5ExprPhraseSize(Fts5Expr *pExpr, int iPhrase){
  2649. if( iPhrase<0 || iPhrase>=pExpr->nPhrase ) return 0;
  2650. return pExpr->apExprPhrase[iPhrase]->nTerm;
  2651. }
  2652. /*
  2653. ** This function is used to access the current position list for phrase
  2654. ** iPhrase.
  2655. */
  2656. int sqlite3Fts5ExprPoslist(Fts5Expr *pExpr, int iPhrase, const u8 **pa){
  2657. int nRet;
  2658. Fts5ExprPhrase *pPhrase = pExpr->apExprPhrase[iPhrase];
  2659. Fts5ExprNode *pNode = pPhrase->pNode;
  2660. if( pNode->bEof==0 && pNode->iRowid==pExpr->pRoot->iRowid ){
  2661. *pa = pPhrase->poslist.p;
  2662. nRet = pPhrase->poslist.n;
  2663. }else{
  2664. *pa = 0;
  2665. nRet = 0;
  2666. }
  2667. return nRet;
  2668. }
  2669. struct Fts5PoslistPopulator {
  2670. Fts5PoslistWriter writer;
  2671. int bOk; /* True if ok to populate */
  2672. int bMiss;
  2673. };
  2674. /*
  2675. ** Clear the position lists associated with all phrases in the expression
  2676. ** passed as the first argument. Argument bLive is true if the expression
  2677. ** might be pointing to a real entry, otherwise it has just been reset.
  2678. **
  2679. ** At present this function is only used for detail=col and detail=none
  2680. ** fts5 tables. This implies that all phrases must be at most 1 token
  2681. ** in size, as phrase matches are not supported without detail=full.
  2682. */
  2683. Fts5PoslistPopulator *sqlite3Fts5ExprClearPoslists(Fts5Expr *pExpr, int bLive){
  2684. Fts5PoslistPopulator *pRet;
  2685. pRet = sqlite3_malloc64(sizeof(Fts5PoslistPopulator)*pExpr->nPhrase);
  2686. if( pRet ){
  2687. int i;
  2688. memset(pRet, 0, sizeof(Fts5PoslistPopulator)*pExpr->nPhrase);
  2689. for(i=0; i<pExpr->nPhrase; i++){
  2690. Fts5Buffer *pBuf = &pExpr->apExprPhrase[i]->poslist;
  2691. Fts5ExprNode *pNode = pExpr->apExprPhrase[i]->pNode;
  2692. assert( pExpr->apExprPhrase[i]->nTerm<=1 );
  2693. if( bLive &&
  2694. (pBuf->n==0 || pNode->iRowid!=pExpr->pRoot->iRowid || pNode->bEof)
  2695. ){
  2696. pRet[i].bMiss = 1;
  2697. }else{
  2698. pBuf->n = 0;
  2699. }
  2700. }
  2701. }
  2702. return pRet;
  2703. }
  2704. struct Fts5ExprCtx {
  2705. Fts5Expr *pExpr;
  2706. Fts5PoslistPopulator *aPopulator;
  2707. i64 iOff;
  2708. };
  2709. typedef struct Fts5ExprCtx Fts5ExprCtx;
  2710. /*
  2711. ** TODO: Make this more efficient!
  2712. */
  2713. static int fts5ExprColsetTest(Fts5Colset *pColset, int iCol){
  2714. int i;
  2715. for(i=0; i<pColset->nCol; i++){
  2716. if( pColset->aiCol[i]==iCol ) return 1;
  2717. }
  2718. return 0;
  2719. }
  2720. /*
  2721. ** pToken is a buffer nToken bytes in size that may or may not contain
  2722. ** an embedded 0x00 byte. If it does, return the number of bytes in
  2723. ** the buffer before the 0x00. If it does not, return nToken.
  2724. */
  2725. static int fts5QueryTerm(const char *pToken, int nToken){
  2726. int ii;
  2727. for(ii=0; ii<nToken && pToken[ii]; ii++){}
  2728. return ii;
  2729. }
  2730. static int fts5ExprPopulatePoslistsCb(
  2731. void *pCtx, /* Copy of 2nd argument to xTokenize() */
  2732. int tflags, /* Mask of FTS5_TOKEN_* flags */
  2733. const char *pToken, /* Pointer to buffer containing token */
  2734. int nToken, /* Size of token in bytes */
  2735. int iUnused1, /* Byte offset of token within input text */
  2736. int iUnused2 /* Byte offset of end of token within input text */
  2737. ){
  2738. Fts5ExprCtx *p = (Fts5ExprCtx*)pCtx;
  2739. Fts5Expr *pExpr = p->pExpr;
  2740. int i;
  2741. int nQuery = nToken;
  2742. i64 iRowid = pExpr->pRoot->iRowid;
  2743. UNUSED_PARAM2(iUnused1, iUnused2);
  2744. if( nQuery>FTS5_MAX_TOKEN_SIZE ) nQuery = FTS5_MAX_TOKEN_SIZE;
  2745. if( pExpr->pConfig->bTokendata ){
  2746. nQuery = fts5QueryTerm(pToken, nQuery);
  2747. }
  2748. if( (tflags & FTS5_TOKEN_COLOCATED)==0 ) p->iOff++;
  2749. for(i=0; i<pExpr->nPhrase; i++){
  2750. Fts5ExprTerm *pT;
  2751. if( p->aPopulator[i].bOk==0 ) continue;
  2752. for(pT=&pExpr->apExprPhrase[i]->aTerm[0]; pT; pT=pT->pSynonym){
  2753. if( (pT->nQueryTerm==nQuery || (pT->nQueryTerm<nQuery && pT->bPrefix))
  2754. && memcmp(pT->pTerm, pToken, pT->nQueryTerm)==0
  2755. ){
  2756. int rc = sqlite3Fts5PoslistWriterAppend(
  2757. &pExpr->apExprPhrase[i]->poslist, &p->aPopulator[i].writer, p->iOff
  2758. );
  2759. if( rc==SQLITE_OK && pExpr->pConfig->bTokendata && !pT->bPrefix ){
  2760. int iCol = p->iOff>>32;
  2761. int iTokOff = p->iOff & 0x7FFFFFFF;
  2762. rc = sqlite3Fts5IndexIterWriteTokendata(
  2763. pT->pIter, pToken, nToken, iRowid, iCol, iTokOff
  2764. );
  2765. }
  2766. if( rc ) return rc;
  2767. break;
  2768. }
  2769. }
  2770. }
  2771. return SQLITE_OK;
  2772. }
  2773. int sqlite3Fts5ExprPopulatePoslists(
  2774. Fts5Config *pConfig,
  2775. Fts5Expr *pExpr,
  2776. Fts5PoslistPopulator *aPopulator,
  2777. int iCol,
  2778. const char *z, int n
  2779. ){
  2780. int i;
  2781. Fts5ExprCtx sCtx;
  2782. sCtx.pExpr = pExpr;
  2783. sCtx.aPopulator = aPopulator;
  2784. sCtx.iOff = (((i64)iCol) << 32) - 1;
  2785. for(i=0; i<pExpr->nPhrase; i++){
  2786. Fts5ExprNode *pNode = pExpr->apExprPhrase[i]->pNode;
  2787. Fts5Colset *pColset = pNode->pNear->pColset;
  2788. if( (pColset && 0==fts5ExprColsetTest(pColset, iCol))
  2789. || aPopulator[i].bMiss
  2790. ){
  2791. aPopulator[i].bOk = 0;
  2792. }else{
  2793. aPopulator[i].bOk = 1;
  2794. }
  2795. }
  2796. return sqlite3Fts5Tokenize(pConfig,
  2797. FTS5_TOKENIZE_DOCUMENT, z, n, (void*)&sCtx, fts5ExprPopulatePoslistsCb
  2798. );
  2799. }
  2800. static void fts5ExprClearPoslists(Fts5ExprNode *pNode){
  2801. if( pNode->eType==FTS5_TERM || pNode->eType==FTS5_STRING ){
  2802. pNode->pNear->apPhrase[0]->poslist.n = 0;
  2803. }else{
  2804. int i;
  2805. for(i=0; i<pNode->nChild; i++){
  2806. fts5ExprClearPoslists(pNode->apChild[i]);
  2807. }
  2808. }
  2809. }
  2810. static int fts5ExprCheckPoslists(Fts5ExprNode *pNode, i64 iRowid){
  2811. pNode->iRowid = iRowid;
  2812. pNode->bEof = 0;
  2813. switch( pNode->eType ){
  2814. case 0:
  2815. case FTS5_TERM:
  2816. case FTS5_STRING:
  2817. return (pNode->pNear->apPhrase[0]->poslist.n>0);
  2818. case FTS5_AND: {
  2819. int i;
  2820. for(i=0; i<pNode->nChild; i++){
  2821. if( fts5ExprCheckPoslists(pNode->apChild[i], iRowid)==0 ){
  2822. fts5ExprClearPoslists(pNode);
  2823. return 0;
  2824. }
  2825. }
  2826. break;
  2827. }
  2828. case FTS5_OR: {
  2829. int i;
  2830. int bRet = 0;
  2831. for(i=0; i<pNode->nChild; i++){
  2832. if( fts5ExprCheckPoslists(pNode->apChild[i], iRowid) ){
  2833. bRet = 1;
  2834. }
  2835. }
  2836. return bRet;
  2837. }
  2838. default: {
  2839. assert( pNode->eType==FTS5_NOT );
  2840. if( 0==fts5ExprCheckPoslists(pNode->apChild[0], iRowid)
  2841. || 0!=fts5ExprCheckPoslists(pNode->apChild[1], iRowid)
  2842. ){
  2843. fts5ExprClearPoslists(pNode);
  2844. return 0;
  2845. }
  2846. break;
  2847. }
  2848. }
  2849. return 1;
  2850. }
  2851. void sqlite3Fts5ExprCheckPoslists(Fts5Expr *pExpr, i64 iRowid){
  2852. fts5ExprCheckPoslists(pExpr->pRoot, iRowid);
  2853. }
  2854. /*
  2855. ** This function is only called for detail=columns tables.
  2856. */
  2857. int sqlite3Fts5ExprPhraseCollist(
  2858. Fts5Expr *pExpr,
  2859. int iPhrase,
  2860. const u8 **ppCollist,
  2861. int *pnCollist
  2862. ){
  2863. Fts5ExprPhrase *pPhrase = pExpr->apExprPhrase[iPhrase];
  2864. Fts5ExprNode *pNode = pPhrase->pNode;
  2865. int rc = SQLITE_OK;
  2866. assert( iPhrase>=0 && iPhrase<pExpr->nPhrase );
  2867. assert( pExpr->pConfig->eDetail==FTS5_DETAIL_COLUMNS );
  2868. if( pNode->bEof==0
  2869. && pNode->iRowid==pExpr->pRoot->iRowid
  2870. && pPhrase->poslist.n>0
  2871. ){
  2872. Fts5ExprTerm *pTerm = &pPhrase->aTerm[0];
  2873. if( pTerm->pSynonym ){
  2874. Fts5Buffer *pBuf = (Fts5Buffer*)&pTerm->pSynonym[1];
  2875. rc = fts5ExprSynonymList(
  2876. pTerm, pNode->iRowid, pBuf, (u8**)ppCollist, pnCollist
  2877. );
  2878. }else{
  2879. *ppCollist = pPhrase->aTerm[0].pIter->pData;
  2880. *pnCollist = pPhrase->aTerm[0].pIter->nData;
  2881. }
  2882. }else{
  2883. *ppCollist = 0;
  2884. *pnCollist = 0;
  2885. }
  2886. return rc;
  2887. }
  2888. /*
  2889. ** Does the work of the fts5_api.xQueryToken() API method.
  2890. */
  2891. int sqlite3Fts5ExprQueryToken(
  2892. Fts5Expr *pExpr,
  2893. int iPhrase,
  2894. int iToken,
  2895. const char **ppOut,
  2896. int *pnOut
  2897. ){
  2898. Fts5ExprPhrase *pPhrase = 0;
  2899. if( iPhrase<0 || iPhrase>=pExpr->nPhrase ){
  2900. return SQLITE_RANGE;
  2901. }
  2902. pPhrase = pExpr->apExprPhrase[iPhrase];
  2903. if( iToken<0 || iToken>=pPhrase->nTerm ){
  2904. return SQLITE_RANGE;
  2905. }
  2906. *ppOut = pPhrase->aTerm[iToken].pTerm;
  2907. *pnOut = pPhrase->aTerm[iToken].nFullTerm;
  2908. return SQLITE_OK;
  2909. }
  2910. /*
  2911. ** Does the work of the fts5_api.xInstToken() API method.
  2912. */
  2913. int sqlite3Fts5ExprInstToken(
  2914. Fts5Expr *pExpr,
  2915. i64 iRowid,
  2916. int iPhrase,
  2917. int iCol,
  2918. int iOff,
  2919. int iToken,
  2920. const char **ppOut,
  2921. int *pnOut
  2922. ){
  2923. Fts5ExprPhrase *pPhrase = 0;
  2924. Fts5ExprTerm *pTerm = 0;
  2925. int rc = SQLITE_OK;
  2926. if( iPhrase<0 || iPhrase>=pExpr->nPhrase ){
  2927. return SQLITE_RANGE;
  2928. }
  2929. pPhrase = pExpr->apExprPhrase[iPhrase];
  2930. if( iToken<0 || iToken>=pPhrase->nTerm ){
  2931. return SQLITE_RANGE;
  2932. }
  2933. pTerm = &pPhrase->aTerm[iToken];
  2934. if( pTerm->bPrefix==0 ){
  2935. if( pExpr->pConfig->bTokendata ){
  2936. rc = sqlite3Fts5IterToken(
  2937. pTerm->pIter, iRowid, iCol, iOff+iToken, ppOut, pnOut
  2938. );
  2939. }else{
  2940. *ppOut = pTerm->pTerm;
  2941. *pnOut = pTerm->nFullTerm;
  2942. }
  2943. }
  2944. return rc;
  2945. }
  2946. /*
  2947. ** Clear the token mappings for all Fts5IndexIter objects mannaged by
  2948. ** the expression passed as the only argument.
  2949. */
  2950. void sqlite3Fts5ExprClearTokens(Fts5Expr *pExpr){
  2951. int ii;
  2952. for(ii=0; ii<pExpr->nPhrase; ii++){
  2953. Fts5ExprTerm *pT;
  2954. for(pT=&pExpr->apExprPhrase[ii]->aTerm[0]; pT; pT=pT->pSynonym){
  2955. sqlite3Fts5IndexIterClearTokendata(pT->pIter);
  2956. }
  2957. }
  2958. }