fts5_main.c 117 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870
  1. /*
  2. ** 2014 Jun 09
  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. ** This is an SQLite module implementing full-text search.
  14. */
  15. #include "fts5Int.h"
  16. /*
  17. ** This variable is set to false when running tests for which the on disk
  18. ** structures should not be corrupt. Otherwise, true. If it is false, extra
  19. ** assert() conditions in the fts5 code are activated - conditions that are
  20. ** only true if it is guaranteed that the fts5 database is not corrupt.
  21. */
  22. #ifdef SQLITE_DEBUG
  23. int sqlite3_fts5_may_be_corrupt = 1;
  24. #endif
  25. typedef struct Fts5Auxdata Fts5Auxdata;
  26. typedef struct Fts5Auxiliary Fts5Auxiliary;
  27. typedef struct Fts5Cursor Fts5Cursor;
  28. typedef struct Fts5FullTable Fts5FullTable;
  29. typedef struct Fts5Sorter Fts5Sorter;
  30. typedef struct Fts5TokenizerModule Fts5TokenizerModule;
  31. /*
  32. ** NOTES ON TRANSACTIONS:
  33. **
  34. ** SQLite invokes the following virtual table methods as transactions are
  35. ** opened and closed by the user:
  36. **
  37. ** xBegin(): Start of a new transaction.
  38. ** xSync(): Initial part of two-phase commit.
  39. ** xCommit(): Final part of two-phase commit.
  40. ** xRollback(): Rollback the transaction.
  41. **
  42. ** Anything that is required as part of a commit that may fail is performed
  43. ** in the xSync() callback. Current versions of SQLite ignore any errors
  44. ** returned by xCommit().
  45. **
  46. ** And as sub-transactions are opened/closed:
  47. **
  48. ** xSavepoint(int S): Open savepoint S.
  49. ** xRelease(int S): Commit and close savepoint S.
  50. ** xRollbackTo(int S): Rollback to start of savepoint S.
  51. **
  52. ** During a write-transaction the fts5_index.c module may cache some data
  53. ** in-memory. It is flushed to disk whenever xSync(), xRelease() or
  54. ** xSavepoint() is called. And discarded whenever xRollback() or xRollbackTo()
  55. ** is called.
  56. **
  57. ** Additionally, if SQLITE_DEBUG is defined, an instance of the following
  58. ** structure is used to record the current transaction state. This information
  59. ** is not required, but it is used in the assert() statements executed by
  60. ** function fts5CheckTransactionState() (see below).
  61. */
  62. struct Fts5TransactionState {
  63. int eState; /* 0==closed, 1==open, 2==synced */
  64. int iSavepoint; /* Number of open savepoints (0 -> none) */
  65. };
  66. /*
  67. ** A single object of this type is allocated when the FTS5 module is
  68. ** registered with a database handle. It is used to store pointers to
  69. ** all registered FTS5 extensions - tokenizers and auxiliary functions.
  70. */
  71. struct Fts5Global {
  72. fts5_api api; /* User visible part of object (see fts5.h) */
  73. sqlite3 *db; /* Associated database connection */
  74. i64 iNextId; /* Used to allocate unique cursor ids */
  75. Fts5Auxiliary *pAux; /* First in list of all aux. functions */
  76. Fts5TokenizerModule *pTok; /* First in list of all tokenizer modules */
  77. Fts5TokenizerModule *pDfltTok; /* Default tokenizer module */
  78. Fts5Cursor *pCsr; /* First in list of all open cursors */
  79. u32 aLocaleHdr[4];
  80. };
  81. /*
  82. ** Size of header on fts5_locale() values. And macro to access a buffer
  83. ** containing a copy of the header from an Fts5Config pointer.
  84. */
  85. #define FTS5_LOCALE_HDR_SIZE ((int)sizeof( ((Fts5Global*)0)->aLocaleHdr ))
  86. #define FTS5_LOCALE_HDR(pConfig) ((const u8*)(pConfig->pGlobal->aLocaleHdr))
  87. #define FTS5_INSTTOKEN_SUBTYPE 73
  88. /*
  89. ** Each auxiliary function registered with the FTS5 module is represented
  90. ** by an object of the following type. All such objects are stored as part
  91. ** of the Fts5Global.pAux list.
  92. */
  93. struct Fts5Auxiliary {
  94. Fts5Global *pGlobal; /* Global context for this function */
  95. char *zFunc; /* Function name (nul-terminated) */
  96. void *pUserData; /* User-data pointer */
  97. fts5_extension_function xFunc; /* Callback function */
  98. void (*xDestroy)(void*); /* Destructor function */
  99. Fts5Auxiliary *pNext; /* Next registered auxiliary function */
  100. };
  101. /*
  102. ** Each tokenizer module registered with the FTS5 module is represented
  103. ** by an object of the following type. All such objects are stored as part
  104. ** of the Fts5Global.pTok list.
  105. **
  106. ** bV2Native:
  107. ** True if the tokenizer was registered using xCreateTokenizer_v2(), false
  108. ** for xCreateTokenizer(). If this variable is true, then x2 is populated
  109. ** with the routines as supplied by the caller and x1 contains synthesized
  110. ** wrapper routines. In this case the user-data pointer passed to
  111. ** x1.xCreate should be a pointer to the Fts5TokenizerModule structure,
  112. ** not a copy of pUserData.
  113. **
  114. ** Of course, if bV2Native is false, then x1 contains the real routines and
  115. ** x2 the synthesized ones. In this case a pointer to the Fts5TokenizerModule
  116. ** object should be passed to x2.xCreate.
  117. **
  118. ** The synthesized wrapper routines are necessary for xFindTokenizer(_v2)
  119. ** calls.
  120. */
  121. struct Fts5TokenizerModule {
  122. char *zName; /* Name of tokenizer */
  123. void *pUserData; /* User pointer passed to xCreate() */
  124. int bV2Native; /* True if v2 native tokenizer */
  125. fts5_tokenizer x1; /* Tokenizer functions */
  126. fts5_tokenizer_v2 x2; /* V2 tokenizer functions */
  127. void (*xDestroy)(void*); /* Destructor function */
  128. Fts5TokenizerModule *pNext; /* Next registered tokenizer module */
  129. };
  130. struct Fts5FullTable {
  131. Fts5Table p; /* Public class members from fts5Int.h */
  132. Fts5Storage *pStorage; /* Document store */
  133. Fts5Global *pGlobal; /* Global (connection wide) data */
  134. Fts5Cursor *pSortCsr; /* Sort data from this cursor */
  135. int iSavepoint; /* Successful xSavepoint()+1 */
  136. #ifdef SQLITE_DEBUG
  137. struct Fts5TransactionState ts;
  138. #endif
  139. };
  140. struct Fts5MatchPhrase {
  141. Fts5Buffer *pPoslist; /* Pointer to current poslist */
  142. int nTerm; /* Size of phrase in terms */
  143. };
  144. /*
  145. ** pStmt:
  146. ** SELECT rowid, <fts> FROM <fts> ORDER BY +rank;
  147. **
  148. ** aIdx[]:
  149. ** There is one entry in the aIdx[] array for each phrase in the query,
  150. ** the value of which is the offset within aPoslist[] following the last
  151. ** byte of the position list for the corresponding phrase.
  152. */
  153. struct Fts5Sorter {
  154. sqlite3_stmt *pStmt;
  155. i64 iRowid; /* Current rowid */
  156. const u8 *aPoslist; /* Position lists for current row */
  157. int nIdx; /* Number of entries in aIdx[] */
  158. int aIdx[1]; /* Offsets into aPoslist for current row */
  159. };
  160. /*
  161. ** Virtual-table cursor object.
  162. **
  163. ** iSpecial:
  164. ** If this is a 'special' query (refer to function fts5SpecialMatch()),
  165. ** then this variable contains the result of the query.
  166. **
  167. ** iFirstRowid, iLastRowid:
  168. ** These variables are only used for FTS5_PLAN_MATCH cursors. Assuming the
  169. ** cursor iterates in ascending order of rowids, iFirstRowid is the lower
  170. ** limit of rowids to return, and iLastRowid the upper. In other words, the
  171. ** WHERE clause in the user's query might have been:
  172. **
  173. ** <tbl> MATCH <expr> AND rowid BETWEEN $iFirstRowid AND $iLastRowid
  174. **
  175. ** If the cursor iterates in descending order of rowid, iFirstRowid
  176. ** is the upper limit (i.e. the "first" rowid visited) and iLastRowid
  177. ** the lower.
  178. */
  179. struct Fts5Cursor {
  180. sqlite3_vtab_cursor base; /* Base class used by SQLite core */
  181. Fts5Cursor *pNext; /* Next cursor in Fts5Cursor.pCsr list */
  182. int *aColumnSize; /* Values for xColumnSize() */
  183. i64 iCsrId; /* Cursor id */
  184. /* Zero from this point onwards on cursor reset */
  185. int ePlan; /* FTS5_PLAN_XXX value */
  186. int bDesc; /* True for "ORDER BY rowid DESC" queries */
  187. i64 iFirstRowid; /* Return no rowids earlier than this */
  188. i64 iLastRowid; /* Return no rowids later than this */
  189. sqlite3_stmt *pStmt; /* Statement used to read %_content */
  190. Fts5Expr *pExpr; /* Expression for MATCH queries */
  191. Fts5Sorter *pSorter; /* Sorter for "ORDER BY rank" queries */
  192. int csrflags; /* Mask of cursor flags (see below) */
  193. i64 iSpecial; /* Result of special query */
  194. /* "rank" function. Populated on demand from vtab.xColumn(). */
  195. char *zRank; /* Custom rank function */
  196. char *zRankArgs; /* Custom rank function args */
  197. Fts5Auxiliary *pRank; /* Rank callback (or NULL) */
  198. int nRankArg; /* Number of trailing arguments for rank() */
  199. sqlite3_value **apRankArg; /* Array of trailing arguments */
  200. sqlite3_stmt *pRankArgStmt; /* Origin of objects in apRankArg[] */
  201. /* Auxiliary data storage */
  202. Fts5Auxiliary *pAux; /* Currently executing extension function */
  203. Fts5Auxdata *pAuxdata; /* First in linked list of saved aux-data */
  204. /* Cache used by auxiliary API functions xInst() and xInstCount() */
  205. Fts5PoslistReader *aInstIter; /* One for each phrase */
  206. int nInstAlloc; /* Size of aInst[] array (entries / 3) */
  207. int nInstCount; /* Number of phrase instances */
  208. int *aInst; /* 3 integers per phrase instance */
  209. };
  210. /*
  211. ** Bits that make up the "idxNum" parameter passed indirectly by
  212. ** xBestIndex() to xFilter().
  213. */
  214. #define FTS5_BI_MATCH 0x0001 /* <tbl> MATCH ? */
  215. #define FTS5_BI_RANK 0x0002 /* rank MATCH ? */
  216. #define FTS5_BI_ROWID_EQ 0x0004 /* rowid == ? */
  217. #define FTS5_BI_ROWID_LE 0x0008 /* rowid <= ? */
  218. #define FTS5_BI_ROWID_GE 0x0010 /* rowid >= ? */
  219. #define FTS5_BI_ORDER_RANK 0x0020
  220. #define FTS5_BI_ORDER_ROWID 0x0040
  221. #define FTS5_BI_ORDER_DESC 0x0080
  222. /*
  223. ** Values for Fts5Cursor.csrflags
  224. */
  225. #define FTS5CSR_EOF 0x01
  226. #define FTS5CSR_REQUIRE_CONTENT 0x02
  227. #define FTS5CSR_REQUIRE_DOCSIZE 0x04
  228. #define FTS5CSR_REQUIRE_INST 0x08
  229. #define FTS5CSR_FREE_ZRANK 0x10
  230. #define FTS5CSR_REQUIRE_RESEEK 0x20
  231. #define FTS5CSR_REQUIRE_POSLIST 0x40
  232. #define BitFlagAllTest(x,y) (((x) & (y))==(y))
  233. #define BitFlagTest(x,y) (((x) & (y))!=0)
  234. /*
  235. ** Macros to Set(), Clear() and Test() cursor flags.
  236. */
  237. #define CsrFlagSet(pCsr, flag) ((pCsr)->csrflags |= (flag))
  238. #define CsrFlagClear(pCsr, flag) ((pCsr)->csrflags &= ~(flag))
  239. #define CsrFlagTest(pCsr, flag) ((pCsr)->csrflags & (flag))
  240. struct Fts5Auxdata {
  241. Fts5Auxiliary *pAux; /* Extension to which this belongs */
  242. void *pPtr; /* Pointer value */
  243. void(*xDelete)(void*); /* Destructor */
  244. Fts5Auxdata *pNext; /* Next object in linked list */
  245. };
  246. #ifdef SQLITE_DEBUG
  247. #define FTS5_BEGIN 1
  248. #define FTS5_SYNC 2
  249. #define FTS5_COMMIT 3
  250. #define FTS5_ROLLBACK 4
  251. #define FTS5_SAVEPOINT 5
  252. #define FTS5_RELEASE 6
  253. #define FTS5_ROLLBACKTO 7
  254. static void fts5CheckTransactionState(Fts5FullTable *p, int op, int iSavepoint){
  255. switch( op ){
  256. case FTS5_BEGIN:
  257. assert( p->ts.eState==0 );
  258. p->ts.eState = 1;
  259. p->ts.iSavepoint = -1;
  260. break;
  261. case FTS5_SYNC:
  262. assert( p->ts.eState==1 || p->ts.eState==2 );
  263. p->ts.eState = 2;
  264. break;
  265. case FTS5_COMMIT:
  266. assert( p->ts.eState==2 );
  267. p->ts.eState = 0;
  268. break;
  269. case FTS5_ROLLBACK:
  270. assert( p->ts.eState==1 || p->ts.eState==2 || p->ts.eState==0 );
  271. p->ts.eState = 0;
  272. break;
  273. case FTS5_SAVEPOINT:
  274. assert( p->ts.eState>=1 );
  275. assert( iSavepoint>=0 );
  276. assert( iSavepoint>=p->ts.iSavepoint );
  277. p->ts.iSavepoint = iSavepoint;
  278. break;
  279. case FTS5_RELEASE:
  280. assert( p->ts.eState>=1 );
  281. assert( iSavepoint>=0 );
  282. assert( iSavepoint<=p->ts.iSavepoint );
  283. p->ts.iSavepoint = iSavepoint-1;
  284. break;
  285. case FTS5_ROLLBACKTO:
  286. assert( p->ts.eState>=1 );
  287. assert( iSavepoint>=-1 );
  288. /* The following assert() can fail if another vtab strikes an error
  289. ** within an xSavepoint() call then SQLite calls xRollbackTo() - without
  290. ** having called xSavepoint() on this vtab. */
  291. /* assert( iSavepoint<=p->ts.iSavepoint ); */
  292. p->ts.iSavepoint = iSavepoint;
  293. break;
  294. }
  295. }
  296. #else
  297. # define fts5CheckTransactionState(x,y,z)
  298. #endif
  299. /*
  300. ** Return true if pTab is a contentless table. If parameter bIncludeUnindexed
  301. ** is true, this includes contentless tables that store UNINDEXED columns
  302. ** only.
  303. */
  304. static int fts5IsContentless(Fts5FullTable *pTab, int bIncludeUnindexed){
  305. int eContent = pTab->p.pConfig->eContent;
  306. return (
  307. eContent==FTS5_CONTENT_NONE
  308. || (bIncludeUnindexed && eContent==FTS5_CONTENT_UNINDEXED)
  309. );
  310. }
  311. /*
  312. ** Delete a virtual table handle allocated by fts5InitVtab().
  313. */
  314. static void fts5FreeVtab(Fts5FullTable *pTab){
  315. if( pTab ){
  316. sqlite3Fts5IndexClose(pTab->p.pIndex);
  317. sqlite3Fts5StorageClose(pTab->pStorage);
  318. sqlite3Fts5ConfigFree(pTab->p.pConfig);
  319. sqlite3_free(pTab);
  320. }
  321. }
  322. /*
  323. ** The xDisconnect() virtual table method.
  324. */
  325. static int fts5DisconnectMethod(sqlite3_vtab *pVtab){
  326. fts5FreeVtab((Fts5FullTable*)pVtab);
  327. return SQLITE_OK;
  328. }
  329. /*
  330. ** The xDestroy() virtual table method.
  331. */
  332. static int fts5DestroyMethod(sqlite3_vtab *pVtab){
  333. Fts5Table *pTab = (Fts5Table*)pVtab;
  334. int rc = sqlite3Fts5DropAll(pTab->pConfig);
  335. if( rc==SQLITE_OK ){
  336. fts5FreeVtab((Fts5FullTable*)pVtab);
  337. }
  338. return rc;
  339. }
  340. /*
  341. ** This function is the implementation of both the xConnect and xCreate
  342. ** methods of the FTS3 virtual table.
  343. **
  344. ** The argv[] array contains the following:
  345. **
  346. ** argv[0] -> module name ("fts5")
  347. ** argv[1] -> database name
  348. ** argv[2] -> table name
  349. ** argv[...] -> "column name" and other module argument fields.
  350. */
  351. static int fts5InitVtab(
  352. int bCreate, /* True for xCreate, false for xConnect */
  353. sqlite3 *db, /* The SQLite database connection */
  354. void *pAux, /* Hash table containing tokenizers */
  355. int argc, /* Number of elements in argv array */
  356. const char * const *argv, /* xCreate/xConnect argument array */
  357. sqlite3_vtab **ppVTab, /* Write the resulting vtab structure here */
  358. char **pzErr /* Write any error message here */
  359. ){
  360. Fts5Global *pGlobal = (Fts5Global*)pAux;
  361. const char **azConfig = (const char**)argv;
  362. int rc = SQLITE_OK; /* Return code */
  363. Fts5Config *pConfig = 0; /* Results of parsing argc/argv */
  364. Fts5FullTable *pTab = 0; /* New virtual table object */
  365. /* Allocate the new vtab object and parse the configuration */
  366. pTab = (Fts5FullTable*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5FullTable));
  367. if( rc==SQLITE_OK ){
  368. rc = sqlite3Fts5ConfigParse(pGlobal, db, argc, azConfig, &pConfig, pzErr);
  369. assert( (rc==SQLITE_OK && *pzErr==0) || pConfig==0 );
  370. }
  371. if( rc==SQLITE_OK ){
  372. pConfig->pzErrmsg = pzErr;
  373. pTab->p.pConfig = pConfig;
  374. pTab->pGlobal = pGlobal;
  375. if( bCreate || sqlite3Fts5TokenizerPreload(&pConfig->t) ){
  376. rc = sqlite3Fts5LoadTokenizer(pConfig);
  377. }
  378. }
  379. /* Open the index sub-system */
  380. if( rc==SQLITE_OK ){
  381. rc = sqlite3Fts5IndexOpen(pConfig, bCreate, &pTab->p.pIndex, pzErr);
  382. }
  383. /* Open the storage sub-system */
  384. if( rc==SQLITE_OK ){
  385. rc = sqlite3Fts5StorageOpen(
  386. pConfig, pTab->p.pIndex, bCreate, &pTab->pStorage, pzErr
  387. );
  388. }
  389. /* Call sqlite3_declare_vtab() */
  390. if( rc==SQLITE_OK ){
  391. rc = sqlite3Fts5ConfigDeclareVtab(pConfig);
  392. }
  393. /* Load the initial configuration */
  394. if( rc==SQLITE_OK ){
  395. rc = sqlite3Fts5ConfigLoad(pTab->p.pConfig, pTab->p.pConfig->iCookie-1);
  396. }
  397. if( rc==SQLITE_OK && pConfig->eContent==FTS5_CONTENT_NORMAL ){
  398. rc = sqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, (int)1);
  399. }
  400. if( rc==SQLITE_OK ){
  401. rc = sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
  402. }
  403. if( pConfig ) pConfig->pzErrmsg = 0;
  404. if( rc!=SQLITE_OK ){
  405. fts5FreeVtab(pTab);
  406. pTab = 0;
  407. }else if( bCreate ){
  408. fts5CheckTransactionState(pTab, FTS5_BEGIN, 0);
  409. }
  410. *ppVTab = (sqlite3_vtab*)pTab;
  411. return rc;
  412. }
  413. /*
  414. ** The xConnect() and xCreate() methods for the virtual table. All the
  415. ** work is done in function fts5InitVtab().
  416. */
  417. static int fts5ConnectMethod(
  418. sqlite3 *db, /* Database connection */
  419. void *pAux, /* Pointer to tokenizer hash table */
  420. int argc, /* Number of elements in argv array */
  421. const char * const *argv, /* xCreate/xConnect argument array */
  422. sqlite3_vtab **ppVtab, /* OUT: New sqlite3_vtab object */
  423. char **pzErr /* OUT: sqlite3_malloc'd error message */
  424. ){
  425. return fts5InitVtab(0, db, pAux, argc, argv, ppVtab, pzErr);
  426. }
  427. static int fts5CreateMethod(
  428. sqlite3 *db, /* Database connection */
  429. void *pAux, /* Pointer to tokenizer hash table */
  430. int argc, /* Number of elements in argv array */
  431. const char * const *argv, /* xCreate/xConnect argument array */
  432. sqlite3_vtab **ppVtab, /* OUT: New sqlite3_vtab object */
  433. char **pzErr /* OUT: sqlite3_malloc'd error message */
  434. ){
  435. return fts5InitVtab(1, db, pAux, argc, argv, ppVtab, pzErr);
  436. }
  437. /*
  438. ** The different query plans.
  439. */
  440. #define FTS5_PLAN_MATCH 1 /* (<tbl> MATCH ?) */
  441. #define FTS5_PLAN_SOURCE 2 /* A source cursor for SORTED_MATCH */
  442. #define FTS5_PLAN_SPECIAL 3 /* An internal query */
  443. #define FTS5_PLAN_SORTED_MATCH 4 /* (<tbl> MATCH ? ORDER BY rank) */
  444. #define FTS5_PLAN_SCAN 5 /* No usable constraint */
  445. #define FTS5_PLAN_ROWID 6 /* (rowid = ?) */
  446. /*
  447. ** Set the SQLITE_INDEX_SCAN_UNIQUE flag in pIdxInfo->flags. Unless this
  448. ** extension is currently being used by a version of SQLite too old to
  449. ** support index-info flags. In that case this function is a no-op.
  450. */
  451. static void fts5SetUniqueFlag(sqlite3_index_info *pIdxInfo){
  452. #if SQLITE_VERSION_NUMBER>=3008012
  453. #ifndef SQLITE_CORE
  454. if( sqlite3_libversion_number()>=3008012 )
  455. #endif
  456. {
  457. pIdxInfo->idxFlags |= SQLITE_INDEX_SCAN_UNIQUE;
  458. }
  459. #endif
  460. }
  461. static int fts5UsePatternMatch(
  462. Fts5Config *pConfig,
  463. struct sqlite3_index_constraint *p
  464. ){
  465. assert( FTS5_PATTERN_GLOB==SQLITE_INDEX_CONSTRAINT_GLOB );
  466. assert( FTS5_PATTERN_LIKE==SQLITE_INDEX_CONSTRAINT_LIKE );
  467. if( pConfig->t.ePattern==FTS5_PATTERN_GLOB && p->op==FTS5_PATTERN_GLOB ){
  468. return 1;
  469. }
  470. if( pConfig->t.ePattern==FTS5_PATTERN_LIKE
  471. && (p->op==FTS5_PATTERN_LIKE || p->op==FTS5_PATTERN_GLOB)
  472. ){
  473. return 1;
  474. }
  475. return 0;
  476. }
  477. /*
  478. ** Implementation of the xBestIndex method for FTS5 tables. Within the
  479. ** WHERE constraint, it searches for the following:
  480. **
  481. ** 1. A MATCH constraint against the table column.
  482. ** 2. A MATCH constraint against the "rank" column.
  483. ** 3. A MATCH constraint against some other column.
  484. ** 4. An == constraint against the rowid column.
  485. ** 5. A < or <= constraint against the rowid column.
  486. ** 6. A > or >= constraint against the rowid column.
  487. **
  488. ** Within the ORDER BY, the following are supported:
  489. **
  490. ** 5. ORDER BY rank [ASC|DESC]
  491. ** 6. ORDER BY rowid [ASC|DESC]
  492. **
  493. ** Information for the xFilter call is passed via both the idxNum and
  494. ** idxStr variables. Specifically, idxNum is a bitmask of the following
  495. ** flags used to encode the ORDER BY clause:
  496. **
  497. ** FTS5_BI_ORDER_RANK
  498. ** FTS5_BI_ORDER_ROWID
  499. ** FTS5_BI_ORDER_DESC
  500. **
  501. ** idxStr is used to encode data from the WHERE clause. For each argument
  502. ** passed to the xFilter method, the following is appended to idxStr:
  503. **
  504. ** Match against table column: "m"
  505. ** Match against rank column: "r"
  506. ** Match against other column: "M<column-number>"
  507. ** LIKE against other column: "L<column-number>"
  508. ** GLOB against other column: "G<column-number>"
  509. ** Equality constraint against the rowid: "="
  510. ** A < or <= against the rowid: "<"
  511. ** A > or >= against the rowid: ">"
  512. **
  513. ** This function ensures that there is at most one "r" or "=". And that if
  514. ** there exists an "=" then there is no "<" or ">".
  515. **
  516. ** If an unusable MATCH operator is present in the WHERE clause, then
  517. ** SQLITE_CONSTRAINT is returned.
  518. **
  519. ** Costs are assigned as follows:
  520. **
  521. ** a) If a MATCH operator is present, the cost depends on the other
  522. ** constraints also present. As follows:
  523. **
  524. ** * No other constraints: cost=1000.0
  525. ** * One rowid range constraint: cost=750.0
  526. ** * Both rowid range constraints: cost=500.0
  527. ** * An == rowid constraint: cost=100.0
  528. **
  529. ** b) Otherwise, if there is no MATCH:
  530. **
  531. ** * No other constraints: cost=1000000.0
  532. ** * One rowid range constraint: cost=750000.0
  533. ** * Both rowid range constraints: cost=250000.0
  534. ** * An == rowid constraint: cost=10.0
  535. **
  536. ** Costs are not modified by the ORDER BY clause.
  537. */
  538. static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
  539. Fts5Table *pTab = (Fts5Table*)pVTab;
  540. Fts5Config *pConfig = pTab->pConfig;
  541. const int nCol = pConfig->nCol;
  542. int idxFlags = 0; /* Parameter passed through to xFilter() */
  543. int i;
  544. char *idxStr;
  545. int iIdxStr = 0;
  546. int iCons = 0;
  547. int bSeenEq = 0;
  548. int bSeenGt = 0;
  549. int bSeenLt = 0;
  550. int nSeenMatch = 0;
  551. int bSeenRank = 0;
  552. assert( SQLITE_INDEX_CONSTRAINT_EQ<SQLITE_INDEX_CONSTRAINT_MATCH );
  553. assert( SQLITE_INDEX_CONSTRAINT_GT<SQLITE_INDEX_CONSTRAINT_MATCH );
  554. assert( SQLITE_INDEX_CONSTRAINT_LE<SQLITE_INDEX_CONSTRAINT_MATCH );
  555. assert( SQLITE_INDEX_CONSTRAINT_GE<SQLITE_INDEX_CONSTRAINT_MATCH );
  556. assert( SQLITE_INDEX_CONSTRAINT_LE<SQLITE_INDEX_CONSTRAINT_MATCH );
  557. if( pConfig->bLock ){
  558. pTab->base.zErrMsg = sqlite3_mprintf(
  559. "recursively defined fts5 content table"
  560. );
  561. return SQLITE_ERROR;
  562. }
  563. idxStr = (char*)sqlite3_malloc(pInfo->nConstraint * 8 + 1);
  564. if( idxStr==0 ) return SQLITE_NOMEM;
  565. pInfo->idxStr = idxStr;
  566. pInfo->needToFreeIdxStr = 1;
  567. for(i=0; i<pInfo->nConstraint; i++){
  568. struct sqlite3_index_constraint *p = &pInfo->aConstraint[i];
  569. int iCol = p->iColumn;
  570. if( p->op==SQLITE_INDEX_CONSTRAINT_MATCH
  571. || (p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol>=nCol)
  572. ){
  573. /* A MATCH operator or equivalent */
  574. if( p->usable==0 || iCol<0 ){
  575. /* As there exists an unusable MATCH constraint this is an
  576. ** unusable plan. Return SQLITE_CONSTRAINT. */
  577. idxStr[iIdxStr] = 0;
  578. return SQLITE_CONSTRAINT;
  579. }else{
  580. if( iCol==nCol+1 ){
  581. if( bSeenRank ) continue;
  582. idxStr[iIdxStr++] = 'r';
  583. bSeenRank = 1;
  584. }else{
  585. nSeenMatch++;
  586. idxStr[iIdxStr++] = 'M';
  587. sqlite3_snprintf(6, &idxStr[iIdxStr], "%d", iCol);
  588. idxStr += strlen(&idxStr[iIdxStr]);
  589. assert( idxStr[iIdxStr]=='\0' );
  590. }
  591. pInfo->aConstraintUsage[i].argvIndex = ++iCons;
  592. pInfo->aConstraintUsage[i].omit = 1;
  593. }
  594. }else if( p->usable ){
  595. if( iCol>=0 && iCol<nCol && fts5UsePatternMatch(pConfig, p) ){
  596. assert( p->op==FTS5_PATTERN_LIKE || p->op==FTS5_PATTERN_GLOB );
  597. idxStr[iIdxStr++] = p->op==FTS5_PATTERN_LIKE ? 'L' : 'G';
  598. sqlite3_snprintf(6, &idxStr[iIdxStr], "%d", iCol);
  599. idxStr += strlen(&idxStr[iIdxStr]);
  600. pInfo->aConstraintUsage[i].argvIndex = ++iCons;
  601. assert( idxStr[iIdxStr]=='\0' );
  602. nSeenMatch++;
  603. }else if( bSeenEq==0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol<0 ){
  604. idxStr[iIdxStr++] = '=';
  605. bSeenEq = 1;
  606. pInfo->aConstraintUsage[i].argvIndex = ++iCons;
  607. }
  608. }
  609. }
  610. if( bSeenEq==0 ){
  611. for(i=0; i<pInfo->nConstraint; i++){
  612. struct sqlite3_index_constraint *p = &pInfo->aConstraint[i];
  613. if( p->iColumn<0 && p->usable ){
  614. int op = p->op;
  615. if( op==SQLITE_INDEX_CONSTRAINT_LT || op==SQLITE_INDEX_CONSTRAINT_LE ){
  616. if( bSeenLt ) continue;
  617. idxStr[iIdxStr++] = '<';
  618. pInfo->aConstraintUsage[i].argvIndex = ++iCons;
  619. bSeenLt = 1;
  620. }else
  621. if( op==SQLITE_INDEX_CONSTRAINT_GT || op==SQLITE_INDEX_CONSTRAINT_GE ){
  622. if( bSeenGt ) continue;
  623. idxStr[iIdxStr++] = '>';
  624. pInfo->aConstraintUsage[i].argvIndex = ++iCons;
  625. bSeenGt = 1;
  626. }
  627. }
  628. }
  629. }
  630. idxStr[iIdxStr] = '\0';
  631. /* Set idxFlags flags for the ORDER BY clause
  632. **
  633. ** Note that tokendata=1 tables cannot currently handle "ORDER BY rowid DESC".
  634. */
  635. if( pInfo->nOrderBy==1 ){
  636. int iSort = pInfo->aOrderBy[0].iColumn;
  637. if( iSort==(pConfig->nCol+1) && nSeenMatch>0 ){
  638. idxFlags |= FTS5_BI_ORDER_RANK;
  639. }else if( iSort==-1 && (!pInfo->aOrderBy[0].desc || !pConfig->bTokendata) ){
  640. idxFlags |= FTS5_BI_ORDER_ROWID;
  641. }
  642. if( BitFlagTest(idxFlags, FTS5_BI_ORDER_RANK|FTS5_BI_ORDER_ROWID) ){
  643. pInfo->orderByConsumed = 1;
  644. if( pInfo->aOrderBy[0].desc ){
  645. idxFlags |= FTS5_BI_ORDER_DESC;
  646. }
  647. }
  648. }
  649. /* Calculate the estimated cost based on the flags set in idxFlags. */
  650. if( bSeenEq ){
  651. pInfo->estimatedCost = nSeenMatch ? 1000.0 : 10.0;
  652. if( nSeenMatch==0 ) fts5SetUniqueFlag(pInfo);
  653. }else if( bSeenLt && bSeenGt ){
  654. pInfo->estimatedCost = nSeenMatch ? 5000.0 : 250000.0;
  655. }else if( bSeenLt || bSeenGt ){
  656. pInfo->estimatedCost = nSeenMatch ? 7500.0 : 750000.0;
  657. }else{
  658. pInfo->estimatedCost = nSeenMatch ? 10000.0 : 1000000.0;
  659. }
  660. for(i=1; i<nSeenMatch; i++){
  661. pInfo->estimatedCost *= 0.4;
  662. }
  663. pInfo->idxNum = idxFlags;
  664. return SQLITE_OK;
  665. }
  666. static int fts5NewTransaction(Fts5FullTable *pTab){
  667. Fts5Cursor *pCsr;
  668. for(pCsr=pTab->pGlobal->pCsr; pCsr; pCsr=pCsr->pNext){
  669. if( pCsr->base.pVtab==(sqlite3_vtab*)pTab ) return SQLITE_OK;
  670. }
  671. return sqlite3Fts5StorageReset(pTab->pStorage);
  672. }
  673. /*
  674. ** Implementation of xOpen method.
  675. */
  676. static int fts5OpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){
  677. Fts5FullTable *pTab = (Fts5FullTable*)pVTab;
  678. Fts5Config *pConfig = pTab->p.pConfig;
  679. Fts5Cursor *pCsr = 0; /* New cursor object */
  680. sqlite3_int64 nByte; /* Bytes of space to allocate */
  681. int rc; /* Return code */
  682. rc = fts5NewTransaction(pTab);
  683. if( rc==SQLITE_OK ){
  684. nByte = sizeof(Fts5Cursor) + pConfig->nCol * sizeof(int);
  685. pCsr = (Fts5Cursor*)sqlite3_malloc64(nByte);
  686. if( pCsr ){
  687. Fts5Global *pGlobal = pTab->pGlobal;
  688. memset(pCsr, 0, (size_t)nByte);
  689. pCsr->aColumnSize = (int*)&pCsr[1];
  690. pCsr->pNext = pGlobal->pCsr;
  691. pGlobal->pCsr = pCsr;
  692. pCsr->iCsrId = ++pGlobal->iNextId;
  693. }else{
  694. rc = SQLITE_NOMEM;
  695. }
  696. }
  697. *ppCsr = (sqlite3_vtab_cursor*)pCsr;
  698. return rc;
  699. }
  700. static int fts5StmtType(Fts5Cursor *pCsr){
  701. if( pCsr->ePlan==FTS5_PLAN_SCAN ){
  702. return (pCsr->bDesc) ? FTS5_STMT_SCAN_DESC : FTS5_STMT_SCAN_ASC;
  703. }
  704. return FTS5_STMT_LOOKUP;
  705. }
  706. /*
  707. ** This function is called after the cursor passed as the only argument
  708. ** is moved to point at a different row. It clears all cached data
  709. ** specific to the previous row stored by the cursor object.
  710. */
  711. static void fts5CsrNewrow(Fts5Cursor *pCsr){
  712. CsrFlagSet(pCsr,
  713. FTS5CSR_REQUIRE_CONTENT
  714. | FTS5CSR_REQUIRE_DOCSIZE
  715. | FTS5CSR_REQUIRE_INST
  716. | FTS5CSR_REQUIRE_POSLIST
  717. );
  718. }
  719. static void fts5FreeCursorComponents(Fts5Cursor *pCsr){
  720. Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab);
  721. Fts5Auxdata *pData;
  722. Fts5Auxdata *pNext;
  723. sqlite3_free(pCsr->aInstIter);
  724. sqlite3_free(pCsr->aInst);
  725. if( pCsr->pStmt ){
  726. int eStmt = fts5StmtType(pCsr);
  727. sqlite3Fts5StorageStmtRelease(pTab->pStorage, eStmt, pCsr->pStmt);
  728. }
  729. if( pCsr->pSorter ){
  730. Fts5Sorter *pSorter = pCsr->pSorter;
  731. sqlite3_finalize(pSorter->pStmt);
  732. sqlite3_free(pSorter);
  733. }
  734. if( pCsr->ePlan!=FTS5_PLAN_SOURCE ){
  735. sqlite3Fts5ExprFree(pCsr->pExpr);
  736. }
  737. for(pData=pCsr->pAuxdata; pData; pData=pNext){
  738. pNext = pData->pNext;
  739. if( pData->xDelete ) pData->xDelete(pData->pPtr);
  740. sqlite3_free(pData);
  741. }
  742. sqlite3_finalize(pCsr->pRankArgStmt);
  743. sqlite3_free(pCsr->apRankArg);
  744. if( CsrFlagTest(pCsr, FTS5CSR_FREE_ZRANK) ){
  745. sqlite3_free(pCsr->zRank);
  746. sqlite3_free(pCsr->zRankArgs);
  747. }
  748. sqlite3Fts5IndexCloseReader(pTab->p.pIndex);
  749. memset(&pCsr->ePlan, 0, sizeof(Fts5Cursor) - ((u8*)&pCsr->ePlan - (u8*)pCsr));
  750. }
  751. /*
  752. ** Close the cursor. For additional information see the documentation
  753. ** on the xClose method of the virtual table interface.
  754. */
  755. static int fts5CloseMethod(sqlite3_vtab_cursor *pCursor){
  756. if( pCursor ){
  757. Fts5FullTable *pTab = (Fts5FullTable*)(pCursor->pVtab);
  758. Fts5Cursor *pCsr = (Fts5Cursor*)pCursor;
  759. Fts5Cursor **pp;
  760. fts5FreeCursorComponents(pCsr);
  761. /* Remove the cursor from the Fts5Global.pCsr list */
  762. for(pp=&pTab->pGlobal->pCsr; (*pp)!=pCsr; pp=&(*pp)->pNext);
  763. *pp = pCsr->pNext;
  764. sqlite3_free(pCsr);
  765. }
  766. return SQLITE_OK;
  767. }
  768. static int fts5SorterNext(Fts5Cursor *pCsr){
  769. Fts5Sorter *pSorter = pCsr->pSorter;
  770. int rc;
  771. rc = sqlite3_step(pSorter->pStmt);
  772. if( rc==SQLITE_DONE ){
  773. rc = SQLITE_OK;
  774. CsrFlagSet(pCsr, FTS5CSR_EOF|FTS5CSR_REQUIRE_CONTENT);
  775. }else if( rc==SQLITE_ROW ){
  776. const u8 *a;
  777. const u8 *aBlob;
  778. int nBlob;
  779. int i;
  780. int iOff = 0;
  781. rc = SQLITE_OK;
  782. pSorter->iRowid = sqlite3_column_int64(pSorter->pStmt, 0);
  783. nBlob = sqlite3_column_bytes(pSorter->pStmt, 1);
  784. aBlob = a = sqlite3_column_blob(pSorter->pStmt, 1);
  785. /* nBlob==0 in detail=none mode. */
  786. if( nBlob>0 ){
  787. for(i=0; i<(pSorter->nIdx-1); i++){
  788. int iVal;
  789. a += fts5GetVarint32(a, iVal);
  790. iOff += iVal;
  791. pSorter->aIdx[i] = iOff;
  792. }
  793. pSorter->aIdx[i] = &aBlob[nBlob] - a;
  794. pSorter->aPoslist = a;
  795. }
  796. fts5CsrNewrow(pCsr);
  797. }
  798. return rc;
  799. }
  800. /*
  801. ** Set the FTS5CSR_REQUIRE_RESEEK flag on all FTS5_PLAN_MATCH cursors
  802. ** open on table pTab.
  803. */
  804. static void fts5TripCursors(Fts5FullTable *pTab){
  805. Fts5Cursor *pCsr;
  806. for(pCsr=pTab->pGlobal->pCsr; pCsr; pCsr=pCsr->pNext){
  807. if( pCsr->ePlan==FTS5_PLAN_MATCH
  808. && pCsr->base.pVtab==(sqlite3_vtab*)pTab
  809. ){
  810. CsrFlagSet(pCsr, FTS5CSR_REQUIRE_RESEEK);
  811. }
  812. }
  813. }
  814. /*
  815. ** If the REQUIRE_RESEEK flag is set on the cursor passed as the first
  816. ** argument, close and reopen all Fts5IndexIter iterators that the cursor
  817. ** is using. Then attempt to move the cursor to a rowid equal to or laster
  818. ** (in the cursors sort order - ASC or DESC) than the current rowid.
  819. **
  820. ** If the new rowid is not equal to the old, set output parameter *pbSkip
  821. ** to 1 before returning. Otherwise, leave it unchanged.
  822. **
  823. ** Return SQLITE_OK if successful or if no reseek was required, or an
  824. ** error code if an error occurred.
  825. */
  826. static int fts5CursorReseek(Fts5Cursor *pCsr, int *pbSkip){
  827. int rc = SQLITE_OK;
  828. assert( *pbSkip==0 );
  829. if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_RESEEK) ){
  830. Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab);
  831. int bDesc = pCsr->bDesc;
  832. i64 iRowid = sqlite3Fts5ExprRowid(pCsr->pExpr);
  833. rc = sqlite3Fts5ExprFirst(pCsr->pExpr, pTab->p.pIndex, iRowid, bDesc);
  834. if( rc==SQLITE_OK && iRowid!=sqlite3Fts5ExprRowid(pCsr->pExpr) ){
  835. *pbSkip = 1;
  836. }
  837. CsrFlagClear(pCsr, FTS5CSR_REQUIRE_RESEEK);
  838. fts5CsrNewrow(pCsr);
  839. if( sqlite3Fts5ExprEof(pCsr->pExpr) ){
  840. CsrFlagSet(pCsr, FTS5CSR_EOF);
  841. *pbSkip = 1;
  842. }
  843. }
  844. return rc;
  845. }
  846. /*
  847. ** Advance the cursor to the next row in the table that matches the
  848. ** search criteria.
  849. **
  850. ** Return SQLITE_OK if nothing goes wrong. SQLITE_OK is returned
  851. ** even if we reach end-of-file. The fts5EofMethod() will be called
  852. ** subsequently to determine whether or not an EOF was hit.
  853. */
  854. static int fts5NextMethod(sqlite3_vtab_cursor *pCursor){
  855. Fts5Cursor *pCsr = (Fts5Cursor*)pCursor;
  856. int rc;
  857. assert( (pCsr->ePlan<3)==
  858. (pCsr->ePlan==FTS5_PLAN_MATCH || pCsr->ePlan==FTS5_PLAN_SOURCE)
  859. );
  860. assert( !CsrFlagTest(pCsr, FTS5CSR_EOF) );
  861. /* If this cursor uses FTS5_PLAN_MATCH and this is a tokendata=1 table,
  862. ** clear any token mappings accumulated at the fts5_index.c level. In
  863. ** other cases, specifically FTS5_PLAN_SOURCE and FTS5_PLAN_SORTED_MATCH,
  864. ** we need to retain the mappings for the entire query. */
  865. if( pCsr->ePlan==FTS5_PLAN_MATCH
  866. && ((Fts5Table*)pCursor->pVtab)->pConfig->bTokendata
  867. ){
  868. sqlite3Fts5ExprClearTokens(pCsr->pExpr);
  869. }
  870. if( pCsr->ePlan<3 ){
  871. int bSkip = 0;
  872. if( (rc = fts5CursorReseek(pCsr, &bSkip)) || bSkip ) return rc;
  873. rc = sqlite3Fts5ExprNext(pCsr->pExpr, pCsr->iLastRowid);
  874. CsrFlagSet(pCsr, sqlite3Fts5ExprEof(pCsr->pExpr));
  875. fts5CsrNewrow(pCsr);
  876. }else{
  877. switch( pCsr->ePlan ){
  878. case FTS5_PLAN_SPECIAL: {
  879. CsrFlagSet(pCsr, FTS5CSR_EOF);
  880. rc = SQLITE_OK;
  881. break;
  882. }
  883. case FTS5_PLAN_SORTED_MATCH: {
  884. rc = fts5SorterNext(pCsr);
  885. break;
  886. }
  887. default: {
  888. Fts5Config *pConfig = ((Fts5Table*)pCursor->pVtab)->pConfig;
  889. pConfig->bLock++;
  890. rc = sqlite3_step(pCsr->pStmt);
  891. pConfig->bLock--;
  892. if( rc!=SQLITE_ROW ){
  893. CsrFlagSet(pCsr, FTS5CSR_EOF);
  894. rc = sqlite3_reset(pCsr->pStmt);
  895. if( rc!=SQLITE_OK ){
  896. pCursor->pVtab->zErrMsg = sqlite3_mprintf(
  897. "%s", sqlite3_errmsg(pConfig->db)
  898. );
  899. }
  900. }else{
  901. rc = SQLITE_OK;
  902. CsrFlagSet(pCsr, FTS5CSR_REQUIRE_DOCSIZE);
  903. }
  904. break;
  905. }
  906. }
  907. }
  908. return rc;
  909. }
  910. static int fts5PrepareStatement(
  911. sqlite3_stmt **ppStmt,
  912. Fts5Config *pConfig,
  913. const char *zFmt,
  914. ...
  915. ){
  916. sqlite3_stmt *pRet = 0;
  917. int rc;
  918. char *zSql;
  919. va_list ap;
  920. va_start(ap, zFmt);
  921. zSql = sqlite3_vmprintf(zFmt, ap);
  922. if( zSql==0 ){
  923. rc = SQLITE_NOMEM;
  924. }else{
  925. rc = sqlite3_prepare_v3(pConfig->db, zSql, -1,
  926. SQLITE_PREPARE_PERSISTENT, &pRet, 0);
  927. if( rc!=SQLITE_OK ){
  928. sqlite3Fts5ConfigErrmsg(pConfig, "%s", sqlite3_errmsg(pConfig->db));
  929. }
  930. sqlite3_free(zSql);
  931. }
  932. va_end(ap);
  933. *ppStmt = pRet;
  934. return rc;
  935. }
  936. static int fts5CursorFirstSorted(
  937. Fts5FullTable *pTab,
  938. Fts5Cursor *pCsr,
  939. int bDesc
  940. ){
  941. Fts5Config *pConfig = pTab->p.pConfig;
  942. Fts5Sorter *pSorter;
  943. int nPhrase;
  944. sqlite3_int64 nByte;
  945. int rc;
  946. const char *zRank = pCsr->zRank;
  947. const char *zRankArgs = pCsr->zRankArgs;
  948. nPhrase = sqlite3Fts5ExprPhraseCount(pCsr->pExpr);
  949. nByte = sizeof(Fts5Sorter) + sizeof(int) * (nPhrase-1);
  950. pSorter = (Fts5Sorter*)sqlite3_malloc64(nByte);
  951. if( pSorter==0 ) return SQLITE_NOMEM;
  952. memset(pSorter, 0, (size_t)nByte);
  953. pSorter->nIdx = nPhrase;
  954. /* TODO: It would be better to have some system for reusing statement
  955. ** handles here, rather than preparing a new one for each query. But that
  956. ** is not possible as SQLite reference counts the virtual table objects.
  957. ** And since the statement required here reads from this very virtual
  958. ** table, saving it creates a circular reference.
  959. **
  960. ** If SQLite a built-in statement cache, this wouldn't be a problem. */
  961. rc = fts5PrepareStatement(&pSorter->pStmt, pConfig,
  962. "SELECT rowid, rank FROM %Q.%Q ORDER BY %s(\"%w\"%s%s) %s",
  963. pConfig->zDb, pConfig->zName, zRank, pConfig->zName,
  964. (zRankArgs ? ", " : ""),
  965. (zRankArgs ? zRankArgs : ""),
  966. bDesc ? "DESC" : "ASC"
  967. );
  968. pCsr->pSorter = pSorter;
  969. if( rc==SQLITE_OK ){
  970. assert( pTab->pSortCsr==0 );
  971. pTab->pSortCsr = pCsr;
  972. rc = fts5SorterNext(pCsr);
  973. pTab->pSortCsr = 0;
  974. }
  975. if( rc!=SQLITE_OK ){
  976. sqlite3_finalize(pSorter->pStmt);
  977. sqlite3_free(pSorter);
  978. pCsr->pSorter = 0;
  979. }
  980. return rc;
  981. }
  982. static int fts5CursorFirst(Fts5FullTable *pTab, Fts5Cursor *pCsr, int bDesc){
  983. int rc;
  984. Fts5Expr *pExpr = pCsr->pExpr;
  985. rc = sqlite3Fts5ExprFirst(pExpr, pTab->p.pIndex, pCsr->iFirstRowid, bDesc);
  986. if( sqlite3Fts5ExprEof(pExpr) ){
  987. CsrFlagSet(pCsr, FTS5CSR_EOF);
  988. }
  989. fts5CsrNewrow(pCsr);
  990. return rc;
  991. }
  992. /*
  993. ** Process a "special" query. A special query is identified as one with a
  994. ** MATCH expression that begins with a '*' character. The remainder of
  995. ** the text passed to the MATCH operator are used as the special query
  996. ** parameters.
  997. */
  998. static int fts5SpecialMatch(
  999. Fts5FullTable *pTab,
  1000. Fts5Cursor *pCsr,
  1001. const char *zQuery
  1002. ){
  1003. int rc = SQLITE_OK; /* Return code */
  1004. const char *z = zQuery; /* Special query text */
  1005. int n; /* Number of bytes in text at z */
  1006. while( z[0]==' ' ) z++;
  1007. for(n=0; z[n] && z[n]!=' '; n++);
  1008. assert( pTab->p.base.zErrMsg==0 );
  1009. pCsr->ePlan = FTS5_PLAN_SPECIAL;
  1010. if( n==5 && 0==sqlite3_strnicmp("reads", z, n) ){
  1011. pCsr->iSpecial = sqlite3Fts5IndexReads(pTab->p.pIndex);
  1012. }
  1013. else if( n==2 && 0==sqlite3_strnicmp("id", z, n) ){
  1014. pCsr->iSpecial = pCsr->iCsrId;
  1015. }
  1016. else{
  1017. /* An unrecognized directive. Return an error message. */
  1018. pTab->p.base.zErrMsg = sqlite3_mprintf("unknown special query: %.*s", n, z);
  1019. rc = SQLITE_ERROR;
  1020. }
  1021. return rc;
  1022. }
  1023. /*
  1024. ** Search for an auxiliary function named zName that can be used with table
  1025. ** pTab. If one is found, return a pointer to the corresponding Fts5Auxiliary
  1026. ** structure. Otherwise, if no such function exists, return NULL.
  1027. */
  1028. static Fts5Auxiliary *fts5FindAuxiliary(Fts5FullTable *pTab, const char *zName){
  1029. Fts5Auxiliary *pAux;
  1030. for(pAux=pTab->pGlobal->pAux; pAux; pAux=pAux->pNext){
  1031. if( sqlite3_stricmp(zName, pAux->zFunc)==0 ) return pAux;
  1032. }
  1033. /* No function of the specified name was found. Return 0. */
  1034. return 0;
  1035. }
  1036. static int fts5FindRankFunction(Fts5Cursor *pCsr){
  1037. Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab);
  1038. Fts5Config *pConfig = pTab->p.pConfig;
  1039. int rc = SQLITE_OK;
  1040. Fts5Auxiliary *pAux = 0;
  1041. const char *zRank = pCsr->zRank;
  1042. const char *zRankArgs = pCsr->zRankArgs;
  1043. if( zRankArgs ){
  1044. char *zSql = sqlite3Fts5Mprintf(&rc, "SELECT %s", zRankArgs);
  1045. if( zSql ){
  1046. sqlite3_stmt *pStmt = 0;
  1047. rc = sqlite3_prepare_v3(pConfig->db, zSql, -1,
  1048. SQLITE_PREPARE_PERSISTENT, &pStmt, 0);
  1049. sqlite3_free(zSql);
  1050. assert( rc==SQLITE_OK || pCsr->pRankArgStmt==0 );
  1051. if( rc==SQLITE_OK ){
  1052. if( SQLITE_ROW==sqlite3_step(pStmt) ){
  1053. sqlite3_int64 nByte;
  1054. pCsr->nRankArg = sqlite3_column_count(pStmt);
  1055. nByte = sizeof(sqlite3_value*)*pCsr->nRankArg;
  1056. pCsr->apRankArg = (sqlite3_value**)sqlite3Fts5MallocZero(&rc, nByte);
  1057. if( rc==SQLITE_OK ){
  1058. int i;
  1059. for(i=0; i<pCsr->nRankArg; i++){
  1060. pCsr->apRankArg[i] = sqlite3_column_value(pStmt, i);
  1061. }
  1062. }
  1063. pCsr->pRankArgStmt = pStmt;
  1064. }else{
  1065. rc = sqlite3_finalize(pStmt);
  1066. assert( rc!=SQLITE_OK );
  1067. }
  1068. }
  1069. }
  1070. }
  1071. if( rc==SQLITE_OK ){
  1072. pAux = fts5FindAuxiliary(pTab, zRank);
  1073. if( pAux==0 ){
  1074. assert( pTab->p.base.zErrMsg==0 );
  1075. pTab->p.base.zErrMsg = sqlite3_mprintf("no such function: %s", zRank);
  1076. rc = SQLITE_ERROR;
  1077. }
  1078. }
  1079. pCsr->pRank = pAux;
  1080. return rc;
  1081. }
  1082. static int fts5CursorParseRank(
  1083. Fts5Config *pConfig,
  1084. Fts5Cursor *pCsr,
  1085. sqlite3_value *pRank
  1086. ){
  1087. int rc = SQLITE_OK;
  1088. if( pRank ){
  1089. const char *z = (const char*)sqlite3_value_text(pRank);
  1090. char *zRank = 0;
  1091. char *zRankArgs = 0;
  1092. if( z==0 ){
  1093. if( sqlite3_value_type(pRank)==SQLITE_NULL ) rc = SQLITE_ERROR;
  1094. }else{
  1095. rc = sqlite3Fts5ConfigParseRank(z, &zRank, &zRankArgs);
  1096. }
  1097. if( rc==SQLITE_OK ){
  1098. pCsr->zRank = zRank;
  1099. pCsr->zRankArgs = zRankArgs;
  1100. CsrFlagSet(pCsr, FTS5CSR_FREE_ZRANK);
  1101. }else if( rc==SQLITE_ERROR ){
  1102. pCsr->base.pVtab->zErrMsg = sqlite3_mprintf(
  1103. "parse error in rank function: %s", z
  1104. );
  1105. }
  1106. }else{
  1107. if( pConfig->zRank ){
  1108. pCsr->zRank = (char*)pConfig->zRank;
  1109. pCsr->zRankArgs = (char*)pConfig->zRankArgs;
  1110. }else{
  1111. pCsr->zRank = (char*)FTS5_DEFAULT_RANK;
  1112. pCsr->zRankArgs = 0;
  1113. }
  1114. }
  1115. return rc;
  1116. }
  1117. static i64 fts5GetRowidLimit(sqlite3_value *pVal, i64 iDefault){
  1118. if( pVal ){
  1119. int eType = sqlite3_value_numeric_type(pVal);
  1120. if( eType==SQLITE_INTEGER ){
  1121. return sqlite3_value_int64(pVal);
  1122. }
  1123. }
  1124. return iDefault;
  1125. }
  1126. /*
  1127. ** Set the error message on the virtual table passed as the first argument.
  1128. */
  1129. static void fts5SetVtabError(Fts5FullTable *p, const char *zFormat, ...){
  1130. va_list ap; /* ... printf arguments */
  1131. va_start(ap, zFormat);
  1132. sqlite3_free(p->p.base.zErrMsg);
  1133. p->p.base.zErrMsg = sqlite3_vmprintf(zFormat, ap);
  1134. va_end(ap);
  1135. }
  1136. /*
  1137. ** Arrange for subsequent calls to sqlite3Fts5Tokenize() to use the locale
  1138. ** specified by pLocale/nLocale. The buffer indicated by pLocale must remain
  1139. ** valid until after the final call to sqlite3Fts5Tokenize() that will use
  1140. ** the locale.
  1141. */
  1142. static void sqlite3Fts5SetLocale(
  1143. Fts5Config *pConfig,
  1144. const char *zLocale,
  1145. int nLocale
  1146. ){
  1147. Fts5TokenizerConfig *pT = &pConfig->t;
  1148. pT->pLocale = zLocale;
  1149. pT->nLocale = nLocale;
  1150. }
  1151. /*
  1152. ** Clear any locale configured by an earlier call to sqlite3Fts5SetLocale().
  1153. */
  1154. void sqlite3Fts5ClearLocale(Fts5Config *pConfig){
  1155. sqlite3Fts5SetLocale(pConfig, 0, 0);
  1156. }
  1157. /*
  1158. ** Return true if the value passed as the only argument is an
  1159. ** fts5_locale() value.
  1160. */
  1161. int sqlite3Fts5IsLocaleValue(Fts5Config *pConfig, sqlite3_value *pVal){
  1162. int ret = 0;
  1163. if( sqlite3_value_type(pVal)==SQLITE_BLOB ){
  1164. /* Call sqlite3_value_bytes() after sqlite3_value_blob() in this case.
  1165. ** If the blob was created using zeroblob(), then sqlite3_value_blob()
  1166. ** may call malloc(). If this malloc() fails, then the values returned
  1167. ** by both value_blob() and value_bytes() will be 0. If value_bytes() were
  1168. ** called first, then the NULL pointer returned by value_blob() might
  1169. ** be dereferenced. */
  1170. const u8 *pBlob = sqlite3_value_blob(pVal);
  1171. int nBlob = sqlite3_value_bytes(pVal);
  1172. if( nBlob>FTS5_LOCALE_HDR_SIZE
  1173. && 0==memcmp(pBlob, FTS5_LOCALE_HDR(pConfig), FTS5_LOCALE_HDR_SIZE)
  1174. ){
  1175. ret = 1;
  1176. }
  1177. }
  1178. return ret;
  1179. }
  1180. /*
  1181. ** Value pVal is guaranteed to be an fts5_locale() value, according to
  1182. ** sqlite3Fts5IsLocaleValue(). This function extracts the text and locale
  1183. ** from the value and returns them separately.
  1184. **
  1185. ** If successful, SQLITE_OK is returned and (*ppText) and (*ppLoc) set
  1186. ** to point to buffers containing the text and locale, as utf-8,
  1187. ** respectively. In this case output parameters (*pnText) and (*pnLoc) are
  1188. ** set to the sizes in bytes of these two buffers.
  1189. **
  1190. ** Or, if an error occurs, then an SQLite error code is returned. The final
  1191. ** value of the four output parameters is undefined in this case.
  1192. */
  1193. int sqlite3Fts5DecodeLocaleValue(
  1194. sqlite3_value *pVal,
  1195. const char **ppText,
  1196. int *pnText,
  1197. const char **ppLoc,
  1198. int *pnLoc
  1199. ){
  1200. const char *p = sqlite3_value_blob(pVal);
  1201. int n = sqlite3_value_bytes(pVal);
  1202. int nLoc = 0;
  1203. assert( sqlite3_value_type(pVal)==SQLITE_BLOB );
  1204. assert( n>FTS5_LOCALE_HDR_SIZE );
  1205. for(nLoc=FTS5_LOCALE_HDR_SIZE; p[nLoc]; nLoc++){
  1206. if( nLoc==(n-1) ){
  1207. return SQLITE_MISMATCH;
  1208. }
  1209. }
  1210. *ppLoc = &p[FTS5_LOCALE_HDR_SIZE];
  1211. *pnLoc = nLoc - FTS5_LOCALE_HDR_SIZE;
  1212. *ppText = &p[nLoc+1];
  1213. *pnText = n - nLoc - 1;
  1214. return SQLITE_OK;
  1215. }
  1216. /*
  1217. ** Argument pVal is the text of a full-text search expression. It may or
  1218. ** may not have been wrapped by fts5_locale(). This function extracts
  1219. ** the text of the expression, and sets output variable (*pzText) to
  1220. ** point to a nul-terminated buffer containing the expression.
  1221. **
  1222. ** If pVal was an fts5_locale() value, then sqlite3Fts5SetLocale() is called
  1223. ** to set the tokenizer to use the specified locale.
  1224. **
  1225. ** If output variable (*pbFreeAndReset) is set to true, then the caller
  1226. ** is required to (a) call sqlite3Fts5ClearLocale() to reset the tokenizer
  1227. ** locale, and (b) call sqlite3_free() to free (*pzText).
  1228. */
  1229. static int fts5ExtractExprText(
  1230. Fts5Config *pConfig, /* Fts5 configuration */
  1231. sqlite3_value *pVal, /* Value to extract expression text from */
  1232. char **pzText, /* OUT: nul-terminated buffer of text */
  1233. int *pbFreeAndReset /* OUT: Free (*pzText) and clear locale */
  1234. ){
  1235. int rc = SQLITE_OK;
  1236. if( sqlite3Fts5IsLocaleValue(pConfig, pVal) ){
  1237. const char *pText = 0;
  1238. int nText = 0;
  1239. const char *pLoc = 0;
  1240. int nLoc = 0;
  1241. rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc);
  1242. *pzText = sqlite3Fts5Mprintf(&rc, "%.*s", nText, pText);
  1243. if( rc==SQLITE_OK ){
  1244. sqlite3Fts5SetLocale(pConfig, pLoc, nLoc);
  1245. }
  1246. *pbFreeAndReset = 1;
  1247. }else{
  1248. *pzText = (char*)sqlite3_value_text(pVal);
  1249. *pbFreeAndReset = 0;
  1250. }
  1251. return rc;
  1252. }
  1253. /*
  1254. ** This is the xFilter interface for the virtual table. See
  1255. ** the virtual table xFilter method documentation for additional
  1256. ** information.
  1257. **
  1258. ** There are three possible query strategies:
  1259. **
  1260. ** 1. Full-text search using a MATCH operator.
  1261. ** 2. A by-rowid lookup.
  1262. ** 3. A full-table scan.
  1263. */
  1264. static int fts5FilterMethod(
  1265. sqlite3_vtab_cursor *pCursor, /* The cursor used for this query */
  1266. int idxNum, /* Strategy index */
  1267. const char *idxStr, /* Unused */
  1268. int nVal, /* Number of elements in apVal */
  1269. sqlite3_value **apVal /* Arguments for the indexing scheme */
  1270. ){
  1271. Fts5FullTable *pTab = (Fts5FullTable*)(pCursor->pVtab);
  1272. Fts5Config *pConfig = pTab->p.pConfig;
  1273. Fts5Cursor *pCsr = (Fts5Cursor*)pCursor;
  1274. int rc = SQLITE_OK; /* Error code */
  1275. int bDesc; /* True if ORDER BY [rank|rowid] DESC */
  1276. int bOrderByRank; /* True if ORDER BY rank */
  1277. sqlite3_value *pRank = 0; /* rank MATCH ? expression (or NULL) */
  1278. sqlite3_value *pRowidEq = 0; /* rowid = ? expression (or NULL) */
  1279. sqlite3_value *pRowidLe = 0; /* rowid <= ? expression (or NULL) */
  1280. sqlite3_value *pRowidGe = 0; /* rowid >= ? expression (or NULL) */
  1281. int iCol; /* Column on LHS of MATCH operator */
  1282. char **pzErrmsg = pConfig->pzErrmsg;
  1283. int bPrefixInsttoken = pConfig->bPrefixInsttoken;
  1284. int i;
  1285. int iIdxStr = 0;
  1286. Fts5Expr *pExpr = 0;
  1287. assert( pConfig->bLock==0 );
  1288. if( pCsr->ePlan ){
  1289. fts5FreeCursorComponents(pCsr);
  1290. memset(&pCsr->ePlan, 0, sizeof(Fts5Cursor) - ((u8*)&pCsr->ePlan-(u8*)pCsr));
  1291. }
  1292. assert( pCsr->pStmt==0 );
  1293. assert( pCsr->pExpr==0 );
  1294. assert( pCsr->csrflags==0 );
  1295. assert( pCsr->pRank==0 );
  1296. assert( pCsr->zRank==0 );
  1297. assert( pCsr->zRankArgs==0 );
  1298. assert( pTab->pSortCsr==0 || nVal==0 );
  1299. assert( pzErrmsg==0 || pzErrmsg==&pTab->p.base.zErrMsg );
  1300. pConfig->pzErrmsg = &pTab->p.base.zErrMsg;
  1301. /* Decode the arguments passed through to this function. */
  1302. for(i=0; i<nVal; i++){
  1303. switch( idxStr[iIdxStr++] ){
  1304. case 'r':
  1305. pRank = apVal[i];
  1306. break;
  1307. case 'M': {
  1308. char *zText = 0;
  1309. int bFreeAndReset = 0;
  1310. int bInternal = 0;
  1311. rc = fts5ExtractExprText(pConfig, apVal[i], &zText, &bFreeAndReset);
  1312. if( rc!=SQLITE_OK ) goto filter_out;
  1313. if( zText==0 ) zText = "";
  1314. if( sqlite3_value_subtype(apVal[i])==FTS5_INSTTOKEN_SUBTYPE ){
  1315. pConfig->bPrefixInsttoken = 1;
  1316. }
  1317. iCol = 0;
  1318. do{
  1319. iCol = iCol*10 + (idxStr[iIdxStr]-'0');
  1320. iIdxStr++;
  1321. }while( idxStr[iIdxStr]>='0' && idxStr[iIdxStr]<='9' );
  1322. if( zText[0]=='*' ){
  1323. /* The user has issued a query of the form "MATCH '*...'". This
  1324. ** indicates that the MATCH expression is not a full text query,
  1325. ** but a request for an internal parameter. */
  1326. rc = fts5SpecialMatch(pTab, pCsr, &zText[1]);
  1327. bInternal = 1;
  1328. }else{
  1329. char **pzErr = &pTab->p.base.zErrMsg;
  1330. rc = sqlite3Fts5ExprNew(pConfig, 0, iCol, zText, &pExpr, pzErr);
  1331. if( rc==SQLITE_OK ){
  1332. rc = sqlite3Fts5ExprAnd(&pCsr->pExpr, pExpr);
  1333. pExpr = 0;
  1334. }
  1335. }
  1336. if( bFreeAndReset ){
  1337. sqlite3_free(zText);
  1338. sqlite3Fts5ClearLocale(pConfig);
  1339. }
  1340. if( bInternal || rc!=SQLITE_OK ) goto filter_out;
  1341. break;
  1342. }
  1343. case 'L':
  1344. case 'G': {
  1345. int bGlob = (idxStr[iIdxStr-1]=='G');
  1346. const char *zText = (const char*)sqlite3_value_text(apVal[i]);
  1347. iCol = 0;
  1348. do{
  1349. iCol = iCol*10 + (idxStr[iIdxStr]-'0');
  1350. iIdxStr++;
  1351. }while( idxStr[iIdxStr]>='0' && idxStr[iIdxStr]<='9' );
  1352. if( zText ){
  1353. rc = sqlite3Fts5ExprPattern(pConfig, bGlob, iCol, zText, &pExpr);
  1354. }
  1355. if( rc==SQLITE_OK ){
  1356. rc = sqlite3Fts5ExprAnd(&pCsr->pExpr, pExpr);
  1357. pExpr = 0;
  1358. }
  1359. if( rc!=SQLITE_OK ) goto filter_out;
  1360. break;
  1361. }
  1362. case '=':
  1363. pRowidEq = apVal[i];
  1364. break;
  1365. case '<':
  1366. pRowidLe = apVal[i];
  1367. break;
  1368. default: assert( idxStr[iIdxStr-1]=='>' );
  1369. pRowidGe = apVal[i];
  1370. break;
  1371. }
  1372. }
  1373. bOrderByRank = ((idxNum & FTS5_BI_ORDER_RANK) ? 1 : 0);
  1374. pCsr->bDesc = bDesc = ((idxNum & FTS5_BI_ORDER_DESC) ? 1 : 0);
  1375. /* Set the cursor upper and lower rowid limits. Only some strategies
  1376. ** actually use them. This is ok, as the xBestIndex() method leaves the
  1377. ** sqlite3_index_constraint.omit flag clear for range constraints
  1378. ** on the rowid field. */
  1379. if( pRowidEq ){
  1380. pRowidLe = pRowidGe = pRowidEq;
  1381. }
  1382. if( bDesc ){
  1383. pCsr->iFirstRowid = fts5GetRowidLimit(pRowidLe, LARGEST_INT64);
  1384. pCsr->iLastRowid = fts5GetRowidLimit(pRowidGe, SMALLEST_INT64);
  1385. }else{
  1386. pCsr->iLastRowid = fts5GetRowidLimit(pRowidLe, LARGEST_INT64);
  1387. pCsr->iFirstRowid = fts5GetRowidLimit(pRowidGe, SMALLEST_INT64);
  1388. }
  1389. rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex);
  1390. if( rc!=SQLITE_OK ) goto filter_out;
  1391. if( pTab->pSortCsr ){
  1392. /* If pSortCsr is non-NULL, then this call is being made as part of
  1393. ** processing for a "... MATCH <expr> ORDER BY rank" query (ePlan is
  1394. ** set to FTS5_PLAN_SORTED_MATCH). pSortCsr is the cursor that will
  1395. ** return results to the user for this query. The current cursor
  1396. ** (pCursor) is used to execute the query issued by function
  1397. ** fts5CursorFirstSorted() above. */
  1398. assert( pRowidEq==0 && pRowidLe==0 && pRowidGe==0 && pRank==0 );
  1399. assert( nVal==0 && bOrderByRank==0 && bDesc==0 );
  1400. assert( pCsr->iLastRowid==LARGEST_INT64 );
  1401. assert( pCsr->iFirstRowid==SMALLEST_INT64 );
  1402. if( pTab->pSortCsr->bDesc ){
  1403. pCsr->iLastRowid = pTab->pSortCsr->iFirstRowid;
  1404. pCsr->iFirstRowid = pTab->pSortCsr->iLastRowid;
  1405. }else{
  1406. pCsr->iLastRowid = pTab->pSortCsr->iLastRowid;
  1407. pCsr->iFirstRowid = pTab->pSortCsr->iFirstRowid;
  1408. }
  1409. pCsr->ePlan = FTS5_PLAN_SOURCE;
  1410. pCsr->pExpr = pTab->pSortCsr->pExpr;
  1411. rc = fts5CursorFirst(pTab, pCsr, bDesc);
  1412. }else if( pCsr->pExpr ){
  1413. assert( rc==SQLITE_OK );
  1414. rc = fts5CursorParseRank(pConfig, pCsr, pRank);
  1415. if( rc==SQLITE_OK ){
  1416. if( bOrderByRank ){
  1417. pCsr->ePlan = FTS5_PLAN_SORTED_MATCH;
  1418. rc = fts5CursorFirstSorted(pTab, pCsr, bDesc);
  1419. }else{
  1420. pCsr->ePlan = FTS5_PLAN_MATCH;
  1421. rc = fts5CursorFirst(pTab, pCsr, bDesc);
  1422. }
  1423. }
  1424. }else if( pConfig->zContent==0 ){
  1425. fts5SetVtabError(pTab,"%s: table does not support scanning",pConfig->zName);
  1426. rc = SQLITE_ERROR;
  1427. }else{
  1428. /* This is either a full-table scan (ePlan==FTS5_PLAN_SCAN) or a lookup
  1429. ** by rowid (ePlan==FTS5_PLAN_ROWID). */
  1430. pCsr->ePlan = (pRowidEq ? FTS5_PLAN_ROWID : FTS5_PLAN_SCAN);
  1431. rc = sqlite3Fts5StorageStmt(
  1432. pTab->pStorage, fts5StmtType(pCsr), &pCsr->pStmt, &pTab->p.base.zErrMsg
  1433. );
  1434. if( rc==SQLITE_OK ){
  1435. if( pRowidEq!=0 ){
  1436. assert( pCsr->ePlan==FTS5_PLAN_ROWID );
  1437. sqlite3_bind_value(pCsr->pStmt, 1, pRowidEq);
  1438. }else{
  1439. sqlite3_bind_int64(pCsr->pStmt, 1, pCsr->iFirstRowid);
  1440. sqlite3_bind_int64(pCsr->pStmt, 2, pCsr->iLastRowid);
  1441. }
  1442. rc = fts5NextMethod(pCursor);
  1443. }
  1444. }
  1445. filter_out:
  1446. sqlite3Fts5ExprFree(pExpr);
  1447. pConfig->pzErrmsg = pzErrmsg;
  1448. pConfig->bPrefixInsttoken = bPrefixInsttoken;
  1449. return rc;
  1450. }
  1451. /*
  1452. ** This is the xEof method of the virtual table. SQLite calls this
  1453. ** routine to find out if it has reached the end of a result set.
  1454. */
  1455. static int fts5EofMethod(sqlite3_vtab_cursor *pCursor){
  1456. Fts5Cursor *pCsr = (Fts5Cursor*)pCursor;
  1457. return (CsrFlagTest(pCsr, FTS5CSR_EOF) ? 1 : 0);
  1458. }
  1459. /*
  1460. ** Return the rowid that the cursor currently points to.
  1461. */
  1462. static i64 fts5CursorRowid(Fts5Cursor *pCsr){
  1463. assert( pCsr->ePlan==FTS5_PLAN_MATCH
  1464. || pCsr->ePlan==FTS5_PLAN_SORTED_MATCH
  1465. || pCsr->ePlan==FTS5_PLAN_SOURCE
  1466. || pCsr->ePlan==FTS5_PLAN_SCAN
  1467. || pCsr->ePlan==FTS5_PLAN_ROWID
  1468. );
  1469. if( pCsr->pSorter ){
  1470. return pCsr->pSorter->iRowid;
  1471. }else if( pCsr->ePlan>=FTS5_PLAN_SCAN ){
  1472. return sqlite3_column_int64(pCsr->pStmt, 0);
  1473. }else{
  1474. return sqlite3Fts5ExprRowid(pCsr->pExpr);
  1475. }
  1476. }
  1477. /*
  1478. ** This is the xRowid method. The SQLite core calls this routine to
  1479. ** retrieve the rowid for the current row of the result set. fts5
  1480. ** exposes %_content.rowid as the rowid for the virtual table. The
  1481. ** rowid should be written to *pRowid.
  1482. */
  1483. static int fts5RowidMethod(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){
  1484. Fts5Cursor *pCsr = (Fts5Cursor*)pCursor;
  1485. int ePlan = pCsr->ePlan;
  1486. assert( CsrFlagTest(pCsr, FTS5CSR_EOF)==0 );
  1487. if( ePlan==FTS5_PLAN_SPECIAL ){
  1488. *pRowid = 0;
  1489. }else{
  1490. *pRowid = fts5CursorRowid(pCsr);
  1491. }
  1492. return SQLITE_OK;
  1493. }
  1494. /*
  1495. ** If the cursor requires seeking (bSeekRequired flag is set), seek it.
  1496. ** Return SQLITE_OK if no error occurs, or an SQLite error code otherwise.
  1497. **
  1498. ** If argument bErrormsg is true and an error occurs, an error message may
  1499. ** be left in sqlite3_vtab.zErrMsg.
  1500. */
  1501. static int fts5SeekCursor(Fts5Cursor *pCsr, int bErrormsg){
  1502. int rc = SQLITE_OK;
  1503. /* If the cursor does not yet have a statement handle, obtain one now. */
  1504. if( pCsr->pStmt==0 ){
  1505. Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab);
  1506. int eStmt = fts5StmtType(pCsr);
  1507. rc = sqlite3Fts5StorageStmt(
  1508. pTab->pStorage, eStmt, &pCsr->pStmt, (bErrormsg?&pTab->p.base.zErrMsg:0)
  1509. );
  1510. assert( rc!=SQLITE_OK || pTab->p.base.zErrMsg==0 );
  1511. assert( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_CONTENT) );
  1512. }
  1513. if( rc==SQLITE_OK && CsrFlagTest(pCsr, FTS5CSR_REQUIRE_CONTENT) ){
  1514. Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
  1515. assert( pCsr->pExpr );
  1516. sqlite3_reset(pCsr->pStmt);
  1517. sqlite3_bind_int64(pCsr->pStmt, 1, fts5CursorRowid(pCsr));
  1518. pTab->pConfig->bLock++;
  1519. rc = sqlite3_step(pCsr->pStmt);
  1520. pTab->pConfig->bLock--;
  1521. if( rc==SQLITE_ROW ){
  1522. rc = SQLITE_OK;
  1523. CsrFlagClear(pCsr, FTS5CSR_REQUIRE_CONTENT);
  1524. }else{
  1525. rc = sqlite3_reset(pCsr->pStmt);
  1526. if( rc==SQLITE_OK ){
  1527. rc = FTS5_CORRUPT;
  1528. fts5SetVtabError((Fts5FullTable*)pTab,
  1529. "fts5: missing row %lld from content table %s",
  1530. fts5CursorRowid(pCsr),
  1531. pTab->pConfig->zContent
  1532. );
  1533. }else if( pTab->pConfig->pzErrmsg ){
  1534. fts5SetVtabError((Fts5FullTable*)pTab,
  1535. "%s", sqlite3_errmsg(pTab->pConfig->db)
  1536. );
  1537. }
  1538. }
  1539. }
  1540. return rc;
  1541. }
  1542. /*
  1543. ** This function is called to handle an FTS INSERT command. In other words,
  1544. ** an INSERT statement of the form:
  1545. **
  1546. ** INSERT INTO fts(fts) VALUES($pCmd)
  1547. ** INSERT INTO fts(fts, rank) VALUES($pCmd, $pVal)
  1548. **
  1549. ** Argument pVal is the value assigned to column "fts" by the INSERT
  1550. ** statement. This function returns SQLITE_OK if successful, or an SQLite
  1551. ** error code if an error occurs.
  1552. **
  1553. ** The commands implemented by this function are documented in the "Special
  1554. ** INSERT Directives" section of the documentation. It should be updated if
  1555. ** more commands are added to this function.
  1556. */
  1557. static int fts5SpecialInsert(
  1558. Fts5FullTable *pTab, /* Fts5 table object */
  1559. const char *zCmd, /* Text inserted into table-name column */
  1560. sqlite3_value *pVal /* Value inserted into rank column */
  1561. ){
  1562. Fts5Config *pConfig = pTab->p.pConfig;
  1563. int rc = SQLITE_OK;
  1564. int bError = 0;
  1565. int bLoadConfig = 0;
  1566. if( 0==sqlite3_stricmp("delete-all", zCmd) ){
  1567. if( pConfig->eContent==FTS5_CONTENT_NORMAL ){
  1568. fts5SetVtabError(pTab,
  1569. "'delete-all' may only be used with a "
  1570. "contentless or external content fts5 table"
  1571. );
  1572. rc = SQLITE_ERROR;
  1573. }else{
  1574. rc = sqlite3Fts5StorageDeleteAll(pTab->pStorage);
  1575. }
  1576. bLoadConfig = 1;
  1577. }else if( 0==sqlite3_stricmp("rebuild", zCmd) ){
  1578. if( fts5IsContentless(pTab, 1) ){
  1579. fts5SetVtabError(pTab,
  1580. "'rebuild' may not be used with a contentless fts5 table"
  1581. );
  1582. rc = SQLITE_ERROR;
  1583. }else{
  1584. rc = sqlite3Fts5StorageRebuild(pTab->pStorage);
  1585. }
  1586. bLoadConfig = 1;
  1587. }else if( 0==sqlite3_stricmp("optimize", zCmd) ){
  1588. rc = sqlite3Fts5StorageOptimize(pTab->pStorage);
  1589. }else if( 0==sqlite3_stricmp("merge", zCmd) ){
  1590. int nMerge = sqlite3_value_int(pVal);
  1591. rc = sqlite3Fts5StorageMerge(pTab->pStorage, nMerge);
  1592. }else if( 0==sqlite3_stricmp("integrity-check", zCmd) ){
  1593. int iArg = sqlite3_value_int(pVal);
  1594. rc = sqlite3Fts5StorageIntegrity(pTab->pStorage, iArg);
  1595. #ifdef SQLITE_DEBUG
  1596. }else if( 0==sqlite3_stricmp("prefix-index", zCmd) ){
  1597. pConfig->bPrefixIndex = sqlite3_value_int(pVal);
  1598. #endif
  1599. }else if( 0==sqlite3_stricmp("flush", zCmd) ){
  1600. rc = sqlite3Fts5FlushToDisk(&pTab->p);
  1601. }else{
  1602. rc = sqlite3Fts5FlushToDisk(&pTab->p);
  1603. if( rc==SQLITE_OK ){
  1604. rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex);
  1605. }
  1606. if( rc==SQLITE_OK ){
  1607. rc = sqlite3Fts5ConfigSetValue(pTab->p.pConfig, zCmd, pVal, &bError);
  1608. }
  1609. if( rc==SQLITE_OK ){
  1610. if( bError ){
  1611. rc = SQLITE_ERROR;
  1612. }else{
  1613. rc = sqlite3Fts5StorageConfigValue(pTab->pStorage, zCmd, pVal, 0);
  1614. }
  1615. }
  1616. }
  1617. if( rc==SQLITE_OK && bLoadConfig ){
  1618. pTab->p.pConfig->iCookie--;
  1619. rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex);
  1620. }
  1621. return rc;
  1622. }
  1623. static int fts5SpecialDelete(
  1624. Fts5FullTable *pTab,
  1625. sqlite3_value **apVal
  1626. ){
  1627. int rc = SQLITE_OK;
  1628. int eType1 = sqlite3_value_type(apVal[1]);
  1629. if( eType1==SQLITE_INTEGER ){
  1630. sqlite3_int64 iDel = sqlite3_value_int64(apVal[1]);
  1631. rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, &apVal[2], 0);
  1632. }
  1633. return rc;
  1634. }
  1635. static void fts5StorageInsert(
  1636. int *pRc,
  1637. Fts5FullTable *pTab,
  1638. sqlite3_value **apVal,
  1639. i64 *piRowid
  1640. ){
  1641. int rc = *pRc;
  1642. if( rc==SQLITE_OK ){
  1643. rc = sqlite3Fts5StorageContentInsert(pTab->pStorage, 0, apVal, piRowid);
  1644. }
  1645. if( rc==SQLITE_OK ){
  1646. rc = sqlite3Fts5StorageIndexInsert(pTab->pStorage, apVal, *piRowid);
  1647. }
  1648. *pRc = rc;
  1649. }
  1650. /*
  1651. **
  1652. ** This function is called when the user attempts an UPDATE on a contentless
  1653. ** table. Parameter bRowidModified is true if the UPDATE statement modifies
  1654. ** the rowid value. Parameter apVal[] contains the new values for each user
  1655. ** defined column of the fts5 table. pConfig is the configuration object of the
  1656. ** table being updated (guaranteed to be contentless). The contentless_delete=1
  1657. ** and contentless_unindexed=1 options may or may not be set.
  1658. **
  1659. ** This function returns SQLITE_OK if the UPDATE can go ahead, or an SQLite
  1660. ** error code if it cannot. In this case an error message is also loaded into
  1661. ** pConfig. Output parameter (*pbContent) is set to true if the caller should
  1662. ** update the %_content table only - not the FTS index or any other shadow
  1663. ** table. This occurs when an UPDATE modifies only UNINDEXED columns of the
  1664. ** table.
  1665. **
  1666. ** An UPDATE may proceed if:
  1667. **
  1668. ** * The only columns modified are UNINDEXED columns, or
  1669. **
  1670. ** * The contentless_delete=1 option was specified and all of the indexed
  1671. ** columns (not a subset) have been modified.
  1672. */
  1673. static int fts5ContentlessUpdate(
  1674. Fts5Config *pConfig,
  1675. sqlite3_value **apVal,
  1676. int bRowidModified,
  1677. int *pbContent
  1678. ){
  1679. int ii;
  1680. int bSeenIndex = 0; /* Have seen modified indexed column */
  1681. int bSeenIndexNC = 0; /* Have seen unmodified indexed column */
  1682. int rc = SQLITE_OK;
  1683. for(ii=0; ii<pConfig->nCol; ii++){
  1684. if( pConfig->abUnindexed[ii]==0 ){
  1685. if( sqlite3_value_nochange(apVal[ii]) ){
  1686. bSeenIndexNC++;
  1687. }else{
  1688. bSeenIndex++;
  1689. }
  1690. }
  1691. }
  1692. if( bSeenIndex==0 && bRowidModified==0 ){
  1693. *pbContent = 1;
  1694. }else{
  1695. if( bSeenIndexNC || pConfig->bContentlessDelete==0 ){
  1696. rc = SQLITE_ERROR;
  1697. sqlite3Fts5ConfigErrmsg(pConfig,
  1698. (pConfig->bContentlessDelete ?
  1699. "%s a subset of columns on fts5 contentless-delete table: %s" :
  1700. "%s contentless fts5 table: %s")
  1701. , "cannot UPDATE", pConfig->zName
  1702. );
  1703. }
  1704. }
  1705. return rc;
  1706. }
  1707. /*
  1708. ** This function is the implementation of the xUpdate callback used by
  1709. ** FTS3 virtual tables. It is invoked by SQLite each time a row is to be
  1710. ** inserted, updated or deleted.
  1711. **
  1712. ** A delete specifies a single argument - the rowid of the row to remove.
  1713. **
  1714. ** Update and insert operations pass:
  1715. **
  1716. ** 1. The "old" rowid, or NULL.
  1717. ** 2. The "new" rowid.
  1718. ** 3. Values for each of the nCol matchable columns.
  1719. ** 4. Values for the two hidden columns (<tablename> and "rank").
  1720. */
  1721. static int fts5UpdateMethod(
  1722. sqlite3_vtab *pVtab, /* Virtual table handle */
  1723. int nArg, /* Size of argument array */
  1724. sqlite3_value **apVal, /* Array of arguments */
  1725. sqlite_int64 *pRowid /* OUT: The affected (or effected) rowid */
  1726. ){
  1727. Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
  1728. Fts5Config *pConfig = pTab->p.pConfig;
  1729. int eType0; /* value_type() of apVal[0] */
  1730. int rc = SQLITE_OK; /* Return code */
  1731. int bUpdateOrDelete = 0;
  1732. /* A transaction must be open when this is called. */
  1733. assert( pTab->ts.eState==1 || pTab->ts.eState==2 );
  1734. assert( pVtab->zErrMsg==0 );
  1735. assert( nArg==1 || nArg==(2+pConfig->nCol+2) );
  1736. assert( sqlite3_value_type(apVal[0])==SQLITE_INTEGER
  1737. || sqlite3_value_type(apVal[0])==SQLITE_NULL
  1738. );
  1739. assert( pTab->p.pConfig->pzErrmsg==0 );
  1740. if( pConfig->pgsz==0 ){
  1741. rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex);
  1742. if( rc!=SQLITE_OK ) return rc;
  1743. }
  1744. pTab->p.pConfig->pzErrmsg = &pTab->p.base.zErrMsg;
  1745. /* Put any active cursors into REQUIRE_SEEK state. */
  1746. fts5TripCursors(pTab);
  1747. eType0 = sqlite3_value_type(apVal[0]);
  1748. if( eType0==SQLITE_NULL
  1749. && sqlite3_value_type(apVal[2+pConfig->nCol])!=SQLITE_NULL
  1750. ){
  1751. /* A "special" INSERT op. These are handled separately. */
  1752. const char *z = (const char*)sqlite3_value_text(apVal[2+pConfig->nCol]);
  1753. if( pConfig->eContent!=FTS5_CONTENT_NORMAL
  1754. && 0==sqlite3_stricmp("delete", z)
  1755. ){
  1756. if( pConfig->bContentlessDelete ){
  1757. fts5SetVtabError(pTab,
  1758. "'delete' may not be used with a contentless_delete=1 table"
  1759. );
  1760. rc = SQLITE_ERROR;
  1761. }else{
  1762. rc = fts5SpecialDelete(pTab, apVal);
  1763. bUpdateOrDelete = 1;
  1764. }
  1765. }else{
  1766. rc = fts5SpecialInsert(pTab, z, apVal[2 + pConfig->nCol + 1]);
  1767. }
  1768. }else{
  1769. /* A regular INSERT, UPDATE or DELETE statement. The trick here is that
  1770. ** any conflict on the rowid value must be detected before any
  1771. ** modifications are made to the database file. There are 4 cases:
  1772. **
  1773. ** 1) DELETE
  1774. ** 2) UPDATE (rowid not modified)
  1775. ** 3) UPDATE (rowid modified)
  1776. ** 4) INSERT
  1777. **
  1778. ** Cases 3 and 4 may violate the rowid constraint.
  1779. */
  1780. int eConflict = SQLITE_ABORT;
  1781. if( pConfig->eContent==FTS5_CONTENT_NORMAL || pConfig->bContentlessDelete ){
  1782. eConflict = sqlite3_vtab_on_conflict(pConfig->db);
  1783. }
  1784. assert( eType0==SQLITE_INTEGER || eType0==SQLITE_NULL );
  1785. assert( nArg!=1 || eType0==SQLITE_INTEGER );
  1786. /* DELETE */
  1787. if( nArg==1 ){
  1788. /* It is only possible to DELETE from a contentless table if the
  1789. ** contentless_delete=1 flag is set. */
  1790. if( fts5IsContentless(pTab, 1) && pConfig->bContentlessDelete==0 ){
  1791. fts5SetVtabError(pTab,
  1792. "cannot DELETE from contentless fts5 table: %s", pConfig->zName
  1793. );
  1794. rc = SQLITE_ERROR;
  1795. }else{
  1796. i64 iDel = sqlite3_value_int64(apVal[0]); /* Rowid to delete */
  1797. rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, 0, 0);
  1798. bUpdateOrDelete = 1;
  1799. }
  1800. }
  1801. /* INSERT or UPDATE */
  1802. else{
  1803. int eType1 = sqlite3_value_numeric_type(apVal[1]);
  1804. /* It is an error to write an fts5_locale() value to a table without
  1805. ** the locale=1 option. */
  1806. if( pConfig->bLocale==0 ){
  1807. int ii;
  1808. for(ii=0; ii<pConfig->nCol; ii++){
  1809. sqlite3_value *pVal = apVal[ii+2];
  1810. if( sqlite3Fts5IsLocaleValue(pConfig, pVal) ){
  1811. fts5SetVtabError(pTab, "fts5_locale() requires locale=1");
  1812. rc = SQLITE_MISMATCH;
  1813. goto update_out;
  1814. }
  1815. }
  1816. }
  1817. if( eType0!=SQLITE_INTEGER ){
  1818. /* An INSERT statement. If the conflict-mode is REPLACE, first remove
  1819. ** the current entry (if any). */
  1820. if( eConflict==SQLITE_REPLACE && eType1==SQLITE_INTEGER ){
  1821. i64 iNew = sqlite3_value_int64(apVal[1]); /* Rowid to delete */
  1822. rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0, 0);
  1823. bUpdateOrDelete = 1;
  1824. }
  1825. fts5StorageInsert(&rc, pTab, apVal, pRowid);
  1826. }
  1827. /* UPDATE */
  1828. else{
  1829. Fts5Storage *pStorage = pTab->pStorage;
  1830. i64 iOld = sqlite3_value_int64(apVal[0]); /* Old rowid */
  1831. i64 iNew = sqlite3_value_int64(apVal[1]); /* New rowid */
  1832. int bContent = 0; /* Content only update */
  1833. /* If this is a contentless table (including contentless_unindexed=1
  1834. ** tables), check if the UPDATE may proceed. */
  1835. if( fts5IsContentless(pTab, 1) ){
  1836. rc = fts5ContentlessUpdate(pConfig, &apVal[2], iOld!=iNew, &bContent);
  1837. if( rc!=SQLITE_OK ) goto update_out;
  1838. }
  1839. if( eType1!=SQLITE_INTEGER ){
  1840. rc = SQLITE_MISMATCH;
  1841. }else if( iOld!=iNew ){
  1842. assert( bContent==0 );
  1843. if( eConflict==SQLITE_REPLACE ){
  1844. rc = sqlite3Fts5StorageDelete(pStorage, iOld, 0, 1);
  1845. if( rc==SQLITE_OK ){
  1846. rc = sqlite3Fts5StorageDelete(pStorage, iNew, 0, 0);
  1847. }
  1848. fts5StorageInsert(&rc, pTab, apVal, pRowid);
  1849. }else{
  1850. rc = sqlite3Fts5StorageFindDeleteRow(pStorage, iOld);
  1851. if( rc==SQLITE_OK ){
  1852. rc = sqlite3Fts5StorageContentInsert(pStorage, 0, apVal, pRowid);
  1853. }
  1854. if( rc==SQLITE_OK ){
  1855. rc = sqlite3Fts5StorageDelete(pStorage, iOld, 0, 0);
  1856. }
  1857. if( rc==SQLITE_OK ){
  1858. rc = sqlite3Fts5StorageIndexInsert(pStorage, apVal, *pRowid);
  1859. }
  1860. }
  1861. }else if( bContent ){
  1862. /* This occurs when an UPDATE on a contentless table affects *only*
  1863. ** UNINDEXED columns. This is a no-op for contentless_unindexed=0
  1864. ** tables, or a write to the %_content table only for =1 tables. */
  1865. assert( fts5IsContentless(pTab, 1) );
  1866. rc = sqlite3Fts5StorageFindDeleteRow(pStorage, iOld);
  1867. if( rc==SQLITE_OK ){
  1868. rc = sqlite3Fts5StorageContentInsert(pStorage, 1, apVal, pRowid);
  1869. }
  1870. }else{
  1871. rc = sqlite3Fts5StorageDelete(pStorage, iOld, 0, 1);
  1872. fts5StorageInsert(&rc, pTab, apVal, pRowid);
  1873. }
  1874. bUpdateOrDelete = 1;
  1875. sqlite3Fts5StorageReleaseDeleteRow(pStorage);
  1876. }
  1877. }
  1878. }
  1879. if( rc==SQLITE_OK
  1880. && bUpdateOrDelete
  1881. && pConfig->bSecureDelete
  1882. && pConfig->iVersion==FTS5_CURRENT_VERSION
  1883. ){
  1884. rc = sqlite3Fts5StorageConfigValue(
  1885. pTab->pStorage, "version", 0, FTS5_CURRENT_VERSION_SECUREDELETE
  1886. );
  1887. if( rc==SQLITE_OK ){
  1888. pConfig->iVersion = FTS5_CURRENT_VERSION_SECUREDELETE;
  1889. }
  1890. }
  1891. update_out:
  1892. pTab->p.pConfig->pzErrmsg = 0;
  1893. return rc;
  1894. }
  1895. /*
  1896. ** Implementation of xSync() method.
  1897. */
  1898. static int fts5SyncMethod(sqlite3_vtab *pVtab){
  1899. int rc;
  1900. Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
  1901. fts5CheckTransactionState(pTab, FTS5_SYNC, 0);
  1902. pTab->p.pConfig->pzErrmsg = &pTab->p.base.zErrMsg;
  1903. rc = sqlite3Fts5FlushToDisk(&pTab->p);
  1904. pTab->p.pConfig->pzErrmsg = 0;
  1905. return rc;
  1906. }
  1907. /*
  1908. ** Implementation of xBegin() method.
  1909. */
  1910. static int fts5BeginMethod(sqlite3_vtab *pVtab){
  1911. int rc = fts5NewTransaction((Fts5FullTable*)pVtab);
  1912. if( rc==SQLITE_OK ){
  1913. fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_BEGIN, 0);
  1914. }
  1915. return rc;
  1916. }
  1917. /*
  1918. ** Implementation of xCommit() method. This is a no-op. The contents of
  1919. ** the pending-terms hash-table have already been flushed into the database
  1920. ** by fts5SyncMethod().
  1921. */
  1922. static int fts5CommitMethod(sqlite3_vtab *pVtab){
  1923. UNUSED_PARAM(pVtab); /* Call below is a no-op for NDEBUG builds */
  1924. fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_COMMIT, 0);
  1925. return SQLITE_OK;
  1926. }
  1927. /*
  1928. ** Implementation of xRollback(). Discard the contents of the pending-terms
  1929. ** hash-table. Any changes made to the database are reverted by SQLite.
  1930. */
  1931. static int fts5RollbackMethod(sqlite3_vtab *pVtab){
  1932. int rc;
  1933. Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
  1934. fts5CheckTransactionState(pTab, FTS5_ROLLBACK, 0);
  1935. rc = sqlite3Fts5StorageRollback(pTab->pStorage);
  1936. return rc;
  1937. }
  1938. static int fts5CsrPoslist(Fts5Cursor*, int, const u8**, int*);
  1939. static void *fts5ApiUserData(Fts5Context *pCtx){
  1940. Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
  1941. return pCsr->pAux->pUserData;
  1942. }
  1943. static int fts5ApiColumnCount(Fts5Context *pCtx){
  1944. Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
  1945. return ((Fts5Table*)(pCsr->base.pVtab))->pConfig->nCol;
  1946. }
  1947. static int fts5ApiColumnTotalSize(
  1948. Fts5Context *pCtx,
  1949. int iCol,
  1950. sqlite3_int64 *pnToken
  1951. ){
  1952. Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
  1953. Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab);
  1954. return sqlite3Fts5StorageSize(pTab->pStorage, iCol, pnToken);
  1955. }
  1956. static int fts5ApiRowCount(Fts5Context *pCtx, i64 *pnRow){
  1957. Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
  1958. Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab);
  1959. return sqlite3Fts5StorageRowCount(pTab->pStorage, pnRow);
  1960. }
  1961. /*
  1962. ** Implementation of xTokenize_v2() API.
  1963. */
  1964. static int fts5ApiTokenize_v2(
  1965. Fts5Context *pCtx,
  1966. const char *pText, int nText,
  1967. const char *pLoc, int nLoc,
  1968. void *pUserData,
  1969. int (*xToken)(void*, int, const char*, int, int, int)
  1970. ){
  1971. Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
  1972. Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
  1973. int rc = SQLITE_OK;
  1974. sqlite3Fts5SetLocale(pTab->pConfig, pLoc, nLoc);
  1975. rc = sqlite3Fts5Tokenize(pTab->pConfig,
  1976. FTS5_TOKENIZE_AUX, pText, nText, pUserData, xToken
  1977. );
  1978. sqlite3Fts5SetLocale(pTab->pConfig, 0, 0);
  1979. return rc;
  1980. }
  1981. /*
  1982. ** Implementation of xTokenize() API. This is just xTokenize_v2() with NULL/0
  1983. ** passed as the locale.
  1984. */
  1985. static int fts5ApiTokenize(
  1986. Fts5Context *pCtx,
  1987. const char *pText, int nText,
  1988. void *pUserData,
  1989. int (*xToken)(void*, int, const char*, int, int, int)
  1990. ){
  1991. return fts5ApiTokenize_v2(pCtx, pText, nText, 0, 0, pUserData, xToken);
  1992. }
  1993. static int fts5ApiPhraseCount(Fts5Context *pCtx){
  1994. Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
  1995. return sqlite3Fts5ExprPhraseCount(pCsr->pExpr);
  1996. }
  1997. static int fts5ApiPhraseSize(Fts5Context *pCtx, int iPhrase){
  1998. Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
  1999. return sqlite3Fts5ExprPhraseSize(pCsr->pExpr, iPhrase);
  2000. }
  2001. /*
  2002. ** Argument pStmt is an SQL statement of the type used by Fts5Cursor. This
  2003. ** function extracts the text value of column iCol of the current row.
  2004. ** Additionally, if there is an associated locale, it invokes
  2005. ** sqlite3Fts5SetLocale() to configure the tokenizer. In all cases the caller
  2006. ** should invoke sqlite3Fts5ClearLocale() to clear the locale at some point
  2007. ** after this function returns.
  2008. **
  2009. ** If successful, (*ppText) is set to point to a buffer containing the text
  2010. ** value as utf-8 and SQLITE_OK returned. (*pnText) is set to the size of that
  2011. ** buffer in bytes. It is not guaranteed to be nul-terminated. If an error
  2012. ** occurs, an SQLite error code is returned. The final values of the two
  2013. ** output parameters are undefined in this case.
  2014. */
  2015. static int fts5TextFromStmt(
  2016. Fts5Config *pConfig,
  2017. sqlite3_stmt *pStmt,
  2018. int iCol,
  2019. const char **ppText,
  2020. int *pnText
  2021. ){
  2022. sqlite3_value *pVal = sqlite3_column_value(pStmt, iCol+1);
  2023. const char *pLoc = 0;
  2024. int nLoc = 0;
  2025. int rc = SQLITE_OK;
  2026. if( pConfig->bLocale
  2027. && pConfig->eContent==FTS5_CONTENT_EXTERNAL
  2028. && sqlite3Fts5IsLocaleValue(pConfig, pVal)
  2029. ){
  2030. rc = sqlite3Fts5DecodeLocaleValue(pVal, ppText, pnText, &pLoc, &nLoc);
  2031. }else{
  2032. *ppText = (const char*)sqlite3_value_text(pVal);
  2033. *pnText = sqlite3_value_bytes(pVal);
  2034. if( pConfig->bLocale && pConfig->eContent==FTS5_CONTENT_NORMAL ){
  2035. pLoc = (const char*)sqlite3_column_text(pStmt, iCol+1+pConfig->nCol);
  2036. nLoc = sqlite3_column_bytes(pStmt, iCol+1+pConfig->nCol);
  2037. }
  2038. }
  2039. sqlite3Fts5SetLocale(pConfig, pLoc, nLoc);
  2040. return rc;
  2041. }
  2042. static int fts5ApiColumnText(
  2043. Fts5Context *pCtx,
  2044. int iCol,
  2045. const char **pz,
  2046. int *pn
  2047. ){
  2048. int rc = SQLITE_OK;
  2049. Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
  2050. Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
  2051. assert( pCsr->ePlan!=FTS5_PLAN_SPECIAL );
  2052. if( iCol<0 || iCol>=pTab->pConfig->nCol ){
  2053. rc = SQLITE_RANGE;
  2054. }else if( fts5IsContentless((Fts5FullTable*)(pCsr->base.pVtab), 0) ){
  2055. *pz = 0;
  2056. *pn = 0;
  2057. }else{
  2058. rc = fts5SeekCursor(pCsr, 0);
  2059. if( rc==SQLITE_OK ){
  2060. rc = fts5TextFromStmt(pTab->pConfig, pCsr->pStmt, iCol, pz, pn);
  2061. sqlite3Fts5ClearLocale(pTab->pConfig);
  2062. }
  2063. }
  2064. return rc;
  2065. }
  2066. /*
  2067. ** This is called by various API functions - xInst, xPhraseFirst,
  2068. ** xPhraseFirstColumn etc. - to obtain the position list for phrase iPhrase
  2069. ** of the current row. This function works for both detail=full tables (in
  2070. ** which case the position-list was read from the fts index) or for other
  2071. ** detail= modes if the row content is available.
  2072. */
  2073. static int fts5CsrPoslist(
  2074. Fts5Cursor *pCsr, /* Fts5 cursor object */
  2075. int iPhrase, /* Phrase to find position list for */
  2076. const u8 **pa, /* OUT: Pointer to position list buffer */
  2077. int *pn /* OUT: Size of (*pa) in bytes */
  2078. ){
  2079. Fts5Config *pConfig = ((Fts5Table*)(pCsr->base.pVtab))->pConfig;
  2080. int rc = SQLITE_OK;
  2081. int bLive = (pCsr->pSorter==0);
  2082. if( iPhrase<0 || iPhrase>=sqlite3Fts5ExprPhraseCount(pCsr->pExpr) ){
  2083. rc = SQLITE_RANGE;
  2084. }else if( pConfig->eDetail!=FTS5_DETAIL_FULL
  2085. && fts5IsContentless((Fts5FullTable*)pCsr->base.pVtab, 1)
  2086. ){
  2087. *pa = 0;
  2088. *pn = 0;
  2089. return SQLITE_OK;
  2090. }else if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_POSLIST) ){
  2091. if( pConfig->eDetail!=FTS5_DETAIL_FULL ){
  2092. Fts5PoslistPopulator *aPopulator;
  2093. int i;
  2094. aPopulator = sqlite3Fts5ExprClearPoslists(pCsr->pExpr, bLive);
  2095. if( aPopulator==0 ) rc = SQLITE_NOMEM;
  2096. if( rc==SQLITE_OK ){
  2097. rc = fts5SeekCursor(pCsr, 0);
  2098. }
  2099. for(i=0; i<pConfig->nCol && rc==SQLITE_OK; i++){
  2100. const char *z = 0;
  2101. int n = 0;
  2102. rc = fts5TextFromStmt(pConfig, pCsr->pStmt, i, &z, &n);
  2103. if( rc==SQLITE_OK ){
  2104. rc = sqlite3Fts5ExprPopulatePoslists(
  2105. pConfig, pCsr->pExpr, aPopulator, i, z, n
  2106. );
  2107. }
  2108. sqlite3Fts5ClearLocale(pConfig);
  2109. }
  2110. sqlite3_free(aPopulator);
  2111. if( pCsr->pSorter ){
  2112. sqlite3Fts5ExprCheckPoslists(pCsr->pExpr, pCsr->pSorter->iRowid);
  2113. }
  2114. }
  2115. CsrFlagClear(pCsr, FTS5CSR_REQUIRE_POSLIST);
  2116. }
  2117. if( rc==SQLITE_OK ){
  2118. if( pCsr->pSorter && pConfig->eDetail==FTS5_DETAIL_FULL ){
  2119. Fts5Sorter *pSorter = pCsr->pSorter;
  2120. int i1 = (iPhrase==0 ? 0 : pSorter->aIdx[iPhrase-1]);
  2121. *pn = pSorter->aIdx[iPhrase] - i1;
  2122. *pa = &pSorter->aPoslist[i1];
  2123. }else{
  2124. *pn = sqlite3Fts5ExprPoslist(pCsr->pExpr, iPhrase, pa);
  2125. }
  2126. }else{
  2127. *pa = 0;
  2128. *pn = 0;
  2129. }
  2130. return rc;
  2131. }
  2132. /*
  2133. ** Ensure that the Fts5Cursor.nInstCount and aInst[] variables are populated
  2134. ** correctly for the current view. Return SQLITE_OK if successful, or an
  2135. ** SQLite error code otherwise.
  2136. */
  2137. static int fts5CacheInstArray(Fts5Cursor *pCsr){
  2138. int rc = SQLITE_OK;
  2139. Fts5PoslistReader *aIter; /* One iterator for each phrase */
  2140. int nIter; /* Number of iterators/phrases */
  2141. int nCol = ((Fts5Table*)pCsr->base.pVtab)->pConfig->nCol;
  2142. nIter = sqlite3Fts5ExprPhraseCount(pCsr->pExpr);
  2143. if( pCsr->aInstIter==0 ){
  2144. sqlite3_int64 nByte = sizeof(Fts5PoslistReader) * nIter;
  2145. pCsr->aInstIter = (Fts5PoslistReader*)sqlite3Fts5MallocZero(&rc, nByte);
  2146. }
  2147. aIter = pCsr->aInstIter;
  2148. if( aIter ){
  2149. int nInst = 0; /* Number instances seen so far */
  2150. int i;
  2151. /* Initialize all iterators */
  2152. for(i=0; i<nIter && rc==SQLITE_OK; i++){
  2153. const u8 *a;
  2154. int n;
  2155. rc = fts5CsrPoslist(pCsr, i, &a, &n);
  2156. if( rc==SQLITE_OK ){
  2157. sqlite3Fts5PoslistReaderInit(a, n, &aIter[i]);
  2158. }
  2159. }
  2160. if( rc==SQLITE_OK ){
  2161. while( 1 ){
  2162. int *aInst;
  2163. int iBest = -1;
  2164. for(i=0; i<nIter; i++){
  2165. if( (aIter[i].bEof==0)
  2166. && (iBest<0 || aIter[i].iPos<aIter[iBest].iPos)
  2167. ){
  2168. iBest = i;
  2169. }
  2170. }
  2171. if( iBest<0 ) break;
  2172. nInst++;
  2173. if( nInst>=pCsr->nInstAlloc ){
  2174. int nNewSize = pCsr->nInstAlloc ? pCsr->nInstAlloc*2 : 32;
  2175. aInst = (int*)sqlite3_realloc64(
  2176. pCsr->aInst, nNewSize*sizeof(int)*3
  2177. );
  2178. if( aInst ){
  2179. pCsr->aInst = aInst;
  2180. pCsr->nInstAlloc = nNewSize;
  2181. }else{
  2182. nInst--;
  2183. rc = SQLITE_NOMEM;
  2184. break;
  2185. }
  2186. }
  2187. aInst = &pCsr->aInst[3 * (nInst-1)];
  2188. aInst[0] = iBest;
  2189. aInst[1] = FTS5_POS2COLUMN(aIter[iBest].iPos);
  2190. aInst[2] = FTS5_POS2OFFSET(aIter[iBest].iPos);
  2191. assert( aInst[1]>=0 );
  2192. if( aInst[1]>=nCol ){
  2193. rc = FTS5_CORRUPT;
  2194. break;
  2195. }
  2196. sqlite3Fts5PoslistReaderNext(&aIter[iBest]);
  2197. }
  2198. }
  2199. pCsr->nInstCount = nInst;
  2200. CsrFlagClear(pCsr, FTS5CSR_REQUIRE_INST);
  2201. }
  2202. return rc;
  2203. }
  2204. static int fts5ApiInstCount(Fts5Context *pCtx, int *pnInst){
  2205. Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
  2206. int rc = SQLITE_OK;
  2207. if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_INST)==0
  2208. || SQLITE_OK==(rc = fts5CacheInstArray(pCsr)) ){
  2209. *pnInst = pCsr->nInstCount;
  2210. }
  2211. return rc;
  2212. }
  2213. static int fts5ApiInst(
  2214. Fts5Context *pCtx,
  2215. int iIdx,
  2216. int *piPhrase,
  2217. int *piCol,
  2218. int *piOff
  2219. ){
  2220. Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
  2221. int rc = SQLITE_OK;
  2222. if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_INST)==0
  2223. || SQLITE_OK==(rc = fts5CacheInstArray(pCsr))
  2224. ){
  2225. if( iIdx<0 || iIdx>=pCsr->nInstCount ){
  2226. rc = SQLITE_RANGE;
  2227. }else{
  2228. *piPhrase = pCsr->aInst[iIdx*3];
  2229. *piCol = pCsr->aInst[iIdx*3 + 1];
  2230. *piOff = pCsr->aInst[iIdx*3 + 2];
  2231. }
  2232. }
  2233. return rc;
  2234. }
  2235. static sqlite3_int64 fts5ApiRowid(Fts5Context *pCtx){
  2236. return fts5CursorRowid((Fts5Cursor*)pCtx);
  2237. }
  2238. static int fts5ColumnSizeCb(
  2239. void *pContext, /* Pointer to int */
  2240. int tflags,
  2241. const char *pUnused, /* Buffer containing token */
  2242. int nUnused, /* Size of token in bytes */
  2243. int iUnused1, /* Start offset of token */
  2244. int iUnused2 /* End offset of token */
  2245. ){
  2246. int *pCnt = (int*)pContext;
  2247. UNUSED_PARAM2(pUnused, nUnused);
  2248. UNUSED_PARAM2(iUnused1, iUnused2);
  2249. if( (tflags & FTS5_TOKEN_COLOCATED)==0 ){
  2250. (*pCnt)++;
  2251. }
  2252. return SQLITE_OK;
  2253. }
  2254. static int fts5ApiColumnSize(Fts5Context *pCtx, int iCol, int *pnToken){
  2255. Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
  2256. Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab);
  2257. Fts5Config *pConfig = pTab->p.pConfig;
  2258. int rc = SQLITE_OK;
  2259. if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_DOCSIZE) ){
  2260. if( pConfig->bColumnsize ){
  2261. i64 iRowid = fts5CursorRowid(pCsr);
  2262. rc = sqlite3Fts5StorageDocsize(pTab->pStorage, iRowid, pCsr->aColumnSize);
  2263. }else if( !pConfig->zContent || pConfig->eContent==FTS5_CONTENT_UNINDEXED ){
  2264. int i;
  2265. for(i=0; i<pConfig->nCol; i++){
  2266. if( pConfig->abUnindexed[i]==0 ){
  2267. pCsr->aColumnSize[i] = -1;
  2268. }
  2269. }
  2270. }else{
  2271. int i;
  2272. rc = fts5SeekCursor(pCsr, 0);
  2273. for(i=0; rc==SQLITE_OK && i<pConfig->nCol; i++){
  2274. if( pConfig->abUnindexed[i]==0 ){
  2275. const char *z = 0;
  2276. int n = 0;
  2277. pCsr->aColumnSize[i] = 0;
  2278. rc = fts5TextFromStmt(pConfig, pCsr->pStmt, i, &z, &n);
  2279. if( rc==SQLITE_OK ){
  2280. rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_AUX,
  2281. z, n, (void*)&pCsr->aColumnSize[i], fts5ColumnSizeCb
  2282. );
  2283. }
  2284. sqlite3Fts5ClearLocale(pConfig);
  2285. }
  2286. }
  2287. }
  2288. CsrFlagClear(pCsr, FTS5CSR_REQUIRE_DOCSIZE);
  2289. }
  2290. if( iCol<0 ){
  2291. int i;
  2292. *pnToken = 0;
  2293. for(i=0; i<pConfig->nCol; i++){
  2294. *pnToken += pCsr->aColumnSize[i];
  2295. }
  2296. }else if( iCol<pConfig->nCol ){
  2297. *pnToken = pCsr->aColumnSize[iCol];
  2298. }else{
  2299. *pnToken = 0;
  2300. rc = SQLITE_RANGE;
  2301. }
  2302. return rc;
  2303. }
  2304. /*
  2305. ** Implementation of the xSetAuxdata() method.
  2306. */
  2307. static int fts5ApiSetAuxdata(
  2308. Fts5Context *pCtx, /* Fts5 context */
  2309. void *pPtr, /* Pointer to save as auxdata */
  2310. void(*xDelete)(void*) /* Destructor for pPtr (or NULL) */
  2311. ){
  2312. Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
  2313. Fts5Auxdata *pData;
  2314. /* Search through the cursors list of Fts5Auxdata objects for one that
  2315. ** corresponds to the currently executing auxiliary function. */
  2316. for(pData=pCsr->pAuxdata; pData; pData=pData->pNext){
  2317. if( pData->pAux==pCsr->pAux ) break;
  2318. }
  2319. if( pData ){
  2320. if( pData->xDelete ){
  2321. pData->xDelete(pData->pPtr);
  2322. }
  2323. }else{
  2324. int rc = SQLITE_OK;
  2325. pData = (Fts5Auxdata*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5Auxdata));
  2326. if( pData==0 ){
  2327. if( xDelete ) xDelete(pPtr);
  2328. return rc;
  2329. }
  2330. pData->pAux = pCsr->pAux;
  2331. pData->pNext = pCsr->pAuxdata;
  2332. pCsr->pAuxdata = pData;
  2333. }
  2334. pData->xDelete = xDelete;
  2335. pData->pPtr = pPtr;
  2336. return SQLITE_OK;
  2337. }
  2338. static void *fts5ApiGetAuxdata(Fts5Context *pCtx, int bClear){
  2339. Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
  2340. Fts5Auxdata *pData;
  2341. void *pRet = 0;
  2342. for(pData=pCsr->pAuxdata; pData; pData=pData->pNext){
  2343. if( pData->pAux==pCsr->pAux ) break;
  2344. }
  2345. if( pData ){
  2346. pRet = pData->pPtr;
  2347. if( bClear ){
  2348. pData->pPtr = 0;
  2349. pData->xDelete = 0;
  2350. }
  2351. }
  2352. return pRet;
  2353. }
  2354. static void fts5ApiPhraseNext(
  2355. Fts5Context *pCtx,
  2356. Fts5PhraseIter *pIter,
  2357. int *piCol, int *piOff
  2358. ){
  2359. if( pIter->a>=pIter->b ){
  2360. *piCol = -1;
  2361. *piOff = -1;
  2362. }else{
  2363. int iVal;
  2364. pIter->a += fts5GetVarint32(pIter->a, iVal);
  2365. if( iVal==1 ){
  2366. /* Avoid returning a (*piCol) value that is too large for the table,
  2367. ** even if the position-list is corrupt. The caller might not be
  2368. ** expecting it. */
  2369. int nCol = ((Fts5Table*)(((Fts5Cursor*)pCtx)->base.pVtab))->pConfig->nCol;
  2370. pIter->a += fts5GetVarint32(pIter->a, iVal);
  2371. *piCol = (iVal>=nCol ? nCol-1 : iVal);
  2372. *piOff = 0;
  2373. pIter->a += fts5GetVarint32(pIter->a, iVal);
  2374. }
  2375. *piOff += (iVal-2);
  2376. }
  2377. }
  2378. static int fts5ApiPhraseFirst(
  2379. Fts5Context *pCtx,
  2380. int iPhrase,
  2381. Fts5PhraseIter *pIter,
  2382. int *piCol, int *piOff
  2383. ){
  2384. Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
  2385. int n;
  2386. int rc = fts5CsrPoslist(pCsr, iPhrase, &pIter->a, &n);
  2387. if( rc==SQLITE_OK ){
  2388. assert( pIter->a || n==0 );
  2389. pIter->b = (pIter->a ? &pIter->a[n] : 0);
  2390. *piCol = 0;
  2391. *piOff = 0;
  2392. fts5ApiPhraseNext(pCtx, pIter, piCol, piOff);
  2393. }
  2394. return rc;
  2395. }
  2396. static void fts5ApiPhraseNextColumn(
  2397. Fts5Context *pCtx,
  2398. Fts5PhraseIter *pIter,
  2399. int *piCol
  2400. ){
  2401. Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
  2402. Fts5Config *pConfig = ((Fts5Table*)(pCsr->base.pVtab))->pConfig;
  2403. if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
  2404. if( pIter->a>=pIter->b ){
  2405. *piCol = -1;
  2406. }else{
  2407. int iIncr;
  2408. pIter->a += fts5GetVarint32(&pIter->a[0], iIncr);
  2409. *piCol += (iIncr-2);
  2410. }
  2411. }else{
  2412. while( 1 ){
  2413. int dummy;
  2414. if( pIter->a>=pIter->b ){
  2415. *piCol = -1;
  2416. return;
  2417. }
  2418. if( pIter->a[0]==0x01 ) break;
  2419. pIter->a += fts5GetVarint32(pIter->a, dummy);
  2420. }
  2421. pIter->a += 1 + fts5GetVarint32(&pIter->a[1], *piCol);
  2422. }
  2423. }
  2424. static int fts5ApiPhraseFirstColumn(
  2425. Fts5Context *pCtx,
  2426. int iPhrase,
  2427. Fts5PhraseIter *pIter,
  2428. int *piCol
  2429. ){
  2430. int rc = SQLITE_OK;
  2431. Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
  2432. Fts5Config *pConfig = ((Fts5Table*)(pCsr->base.pVtab))->pConfig;
  2433. if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
  2434. Fts5Sorter *pSorter = pCsr->pSorter;
  2435. int n;
  2436. if( pSorter ){
  2437. int i1 = (iPhrase==0 ? 0 : pSorter->aIdx[iPhrase-1]);
  2438. n = pSorter->aIdx[iPhrase] - i1;
  2439. pIter->a = &pSorter->aPoslist[i1];
  2440. }else{
  2441. rc = sqlite3Fts5ExprPhraseCollist(pCsr->pExpr, iPhrase, &pIter->a, &n);
  2442. }
  2443. if( rc==SQLITE_OK ){
  2444. assert( pIter->a || n==0 );
  2445. pIter->b = (pIter->a ? &pIter->a[n] : 0);
  2446. *piCol = 0;
  2447. fts5ApiPhraseNextColumn(pCtx, pIter, piCol);
  2448. }
  2449. }else{
  2450. int n;
  2451. rc = fts5CsrPoslist(pCsr, iPhrase, &pIter->a, &n);
  2452. if( rc==SQLITE_OK ){
  2453. assert( pIter->a || n==0 );
  2454. pIter->b = (pIter->a ? &pIter->a[n] : 0);
  2455. if( n<=0 ){
  2456. *piCol = -1;
  2457. }else if( pIter->a[0]==0x01 ){
  2458. pIter->a += 1 + fts5GetVarint32(&pIter->a[1], *piCol);
  2459. }else{
  2460. *piCol = 0;
  2461. }
  2462. }
  2463. }
  2464. return rc;
  2465. }
  2466. /*
  2467. ** xQueryToken() API implemenetation.
  2468. */
  2469. static int fts5ApiQueryToken(
  2470. Fts5Context* pCtx,
  2471. int iPhrase,
  2472. int iToken,
  2473. const char **ppOut,
  2474. int *pnOut
  2475. ){
  2476. Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
  2477. return sqlite3Fts5ExprQueryToken(pCsr->pExpr, iPhrase, iToken, ppOut, pnOut);
  2478. }
  2479. /*
  2480. ** xInstToken() API implemenetation.
  2481. */
  2482. static int fts5ApiInstToken(
  2483. Fts5Context *pCtx,
  2484. int iIdx,
  2485. int iToken,
  2486. const char **ppOut, int *pnOut
  2487. ){
  2488. Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
  2489. int rc = SQLITE_OK;
  2490. if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_INST)==0
  2491. || SQLITE_OK==(rc = fts5CacheInstArray(pCsr))
  2492. ){
  2493. if( iIdx<0 || iIdx>=pCsr->nInstCount ){
  2494. rc = SQLITE_RANGE;
  2495. }else{
  2496. int iPhrase = pCsr->aInst[iIdx*3];
  2497. int iCol = pCsr->aInst[iIdx*3 + 1];
  2498. int iOff = pCsr->aInst[iIdx*3 + 2];
  2499. i64 iRowid = fts5CursorRowid(pCsr);
  2500. rc = sqlite3Fts5ExprInstToken(
  2501. pCsr->pExpr, iRowid, iPhrase, iCol, iOff, iToken, ppOut, pnOut
  2502. );
  2503. }
  2504. }
  2505. return rc;
  2506. }
  2507. static int fts5ApiQueryPhrase(Fts5Context*, int, void*,
  2508. int(*)(const Fts5ExtensionApi*, Fts5Context*, void*)
  2509. );
  2510. /*
  2511. ** The xColumnLocale() API.
  2512. */
  2513. static int fts5ApiColumnLocale(
  2514. Fts5Context *pCtx,
  2515. int iCol,
  2516. const char **pzLocale,
  2517. int *pnLocale
  2518. ){
  2519. int rc = SQLITE_OK;
  2520. Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
  2521. Fts5Config *pConfig = ((Fts5Table*)(pCsr->base.pVtab))->pConfig;
  2522. *pzLocale = 0;
  2523. *pnLocale = 0;
  2524. assert( pCsr->ePlan!=FTS5_PLAN_SPECIAL );
  2525. if( iCol<0 || iCol>=pConfig->nCol ){
  2526. rc = SQLITE_RANGE;
  2527. }else if(
  2528. pConfig->abUnindexed[iCol]==0
  2529. && 0==fts5IsContentless((Fts5FullTable*)pCsr->base.pVtab, 1)
  2530. && pConfig->bLocale
  2531. ){
  2532. rc = fts5SeekCursor(pCsr, 0);
  2533. if( rc==SQLITE_OK ){
  2534. const char *zDummy = 0;
  2535. int nDummy = 0;
  2536. rc = fts5TextFromStmt(pConfig, pCsr->pStmt, iCol, &zDummy, &nDummy);
  2537. if( rc==SQLITE_OK ){
  2538. *pzLocale = pConfig->t.pLocale;
  2539. *pnLocale = pConfig->t.nLocale;
  2540. }
  2541. sqlite3Fts5ClearLocale(pConfig);
  2542. }
  2543. }
  2544. return rc;
  2545. }
  2546. static const Fts5ExtensionApi sFts5Api = {
  2547. 4, /* iVersion */
  2548. fts5ApiUserData,
  2549. fts5ApiColumnCount,
  2550. fts5ApiRowCount,
  2551. fts5ApiColumnTotalSize,
  2552. fts5ApiTokenize,
  2553. fts5ApiPhraseCount,
  2554. fts5ApiPhraseSize,
  2555. fts5ApiInstCount,
  2556. fts5ApiInst,
  2557. fts5ApiRowid,
  2558. fts5ApiColumnText,
  2559. fts5ApiColumnSize,
  2560. fts5ApiQueryPhrase,
  2561. fts5ApiSetAuxdata,
  2562. fts5ApiGetAuxdata,
  2563. fts5ApiPhraseFirst,
  2564. fts5ApiPhraseNext,
  2565. fts5ApiPhraseFirstColumn,
  2566. fts5ApiPhraseNextColumn,
  2567. fts5ApiQueryToken,
  2568. fts5ApiInstToken,
  2569. fts5ApiColumnLocale,
  2570. fts5ApiTokenize_v2
  2571. };
  2572. /*
  2573. ** Implementation of API function xQueryPhrase().
  2574. */
  2575. static int fts5ApiQueryPhrase(
  2576. Fts5Context *pCtx,
  2577. int iPhrase,
  2578. void *pUserData,
  2579. int(*xCallback)(const Fts5ExtensionApi*, Fts5Context*, void*)
  2580. ){
  2581. Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
  2582. Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab);
  2583. int rc;
  2584. Fts5Cursor *pNew = 0;
  2585. rc = fts5OpenMethod(pCsr->base.pVtab, (sqlite3_vtab_cursor**)&pNew);
  2586. if( rc==SQLITE_OK ){
  2587. pNew->ePlan = FTS5_PLAN_MATCH;
  2588. pNew->iFirstRowid = SMALLEST_INT64;
  2589. pNew->iLastRowid = LARGEST_INT64;
  2590. pNew->base.pVtab = (sqlite3_vtab*)pTab;
  2591. rc = sqlite3Fts5ExprClonePhrase(pCsr->pExpr, iPhrase, &pNew->pExpr);
  2592. }
  2593. if( rc==SQLITE_OK ){
  2594. for(rc = fts5CursorFirst(pTab, pNew, 0);
  2595. rc==SQLITE_OK && CsrFlagTest(pNew, FTS5CSR_EOF)==0;
  2596. rc = fts5NextMethod((sqlite3_vtab_cursor*)pNew)
  2597. ){
  2598. rc = xCallback(&sFts5Api, (Fts5Context*)pNew, pUserData);
  2599. if( rc!=SQLITE_OK ){
  2600. if( rc==SQLITE_DONE ) rc = SQLITE_OK;
  2601. break;
  2602. }
  2603. }
  2604. }
  2605. fts5CloseMethod((sqlite3_vtab_cursor*)pNew);
  2606. return rc;
  2607. }
  2608. static void fts5ApiInvoke(
  2609. Fts5Auxiliary *pAux,
  2610. Fts5Cursor *pCsr,
  2611. sqlite3_context *context,
  2612. int argc,
  2613. sqlite3_value **argv
  2614. ){
  2615. assert( pCsr->pAux==0 );
  2616. assert( pCsr->ePlan!=FTS5_PLAN_SPECIAL );
  2617. pCsr->pAux = pAux;
  2618. pAux->xFunc(&sFts5Api, (Fts5Context*)pCsr, context, argc, argv);
  2619. pCsr->pAux = 0;
  2620. }
  2621. static Fts5Cursor *fts5CursorFromCsrid(Fts5Global *pGlobal, i64 iCsrId){
  2622. Fts5Cursor *pCsr;
  2623. for(pCsr=pGlobal->pCsr; pCsr; pCsr=pCsr->pNext){
  2624. if( pCsr->iCsrId==iCsrId ) break;
  2625. }
  2626. return pCsr;
  2627. }
  2628. /*
  2629. ** Parameter zFmt is a printf() style formatting string. This function
  2630. ** formats it using the trailing arguments and returns the result as
  2631. ** an error message to the context passed as the first argument.
  2632. */
  2633. static void fts5ResultError(sqlite3_context *pCtx, const char *zFmt, ...){
  2634. char *zErr = 0;
  2635. va_list ap;
  2636. va_start(ap, zFmt);
  2637. zErr = sqlite3_vmprintf(zFmt, ap);
  2638. sqlite3_result_error(pCtx, zErr, -1);
  2639. sqlite3_free(zErr);
  2640. va_end(ap);
  2641. }
  2642. static void fts5ApiCallback(
  2643. sqlite3_context *context,
  2644. int argc,
  2645. sqlite3_value **argv
  2646. ){
  2647. Fts5Auxiliary *pAux;
  2648. Fts5Cursor *pCsr;
  2649. i64 iCsrId;
  2650. assert( argc>=1 );
  2651. pAux = (Fts5Auxiliary*)sqlite3_user_data(context);
  2652. iCsrId = sqlite3_value_int64(argv[0]);
  2653. pCsr = fts5CursorFromCsrid(pAux->pGlobal, iCsrId);
  2654. if( pCsr==0 || (pCsr->ePlan==0 || pCsr->ePlan==FTS5_PLAN_SPECIAL) ){
  2655. fts5ResultError(context, "no such cursor: %lld", iCsrId);
  2656. }else{
  2657. sqlite3_vtab *pTab = pCsr->base.pVtab;
  2658. fts5ApiInvoke(pAux, pCsr, context, argc-1, &argv[1]);
  2659. sqlite3_free(pTab->zErrMsg);
  2660. pTab->zErrMsg = 0;
  2661. }
  2662. }
  2663. /*
  2664. ** Given cursor id iId, return a pointer to the corresponding Fts5Table
  2665. ** object. Or NULL If the cursor id does not exist.
  2666. */
  2667. Fts5Table *sqlite3Fts5TableFromCsrid(
  2668. Fts5Global *pGlobal, /* FTS5 global context for db handle */
  2669. i64 iCsrId /* Id of cursor to find */
  2670. ){
  2671. Fts5Cursor *pCsr;
  2672. pCsr = fts5CursorFromCsrid(pGlobal, iCsrId);
  2673. if( pCsr ){
  2674. return (Fts5Table*)pCsr->base.pVtab;
  2675. }
  2676. return 0;
  2677. }
  2678. /*
  2679. ** Return a "position-list blob" corresponding to the current position of
  2680. ** cursor pCsr via sqlite3_result_blob(). A position-list blob contains
  2681. ** the current position-list for each phrase in the query associated with
  2682. ** cursor pCsr.
  2683. **
  2684. ** A position-list blob begins with (nPhrase-1) varints, where nPhrase is
  2685. ** the number of phrases in the query. Following the varints are the
  2686. ** concatenated position lists for each phrase, in order.
  2687. **
  2688. ** The first varint (if it exists) contains the size of the position list
  2689. ** for phrase 0. The second (same disclaimer) contains the size of position
  2690. ** list 1. And so on. There is no size field for the final position list,
  2691. ** as it can be derived from the total size of the blob.
  2692. */
  2693. static int fts5PoslistBlob(sqlite3_context *pCtx, Fts5Cursor *pCsr){
  2694. int i;
  2695. int rc = SQLITE_OK;
  2696. int nPhrase = sqlite3Fts5ExprPhraseCount(pCsr->pExpr);
  2697. Fts5Buffer val;
  2698. memset(&val, 0, sizeof(Fts5Buffer));
  2699. switch( ((Fts5Table*)(pCsr->base.pVtab))->pConfig->eDetail ){
  2700. case FTS5_DETAIL_FULL:
  2701. /* Append the varints */
  2702. for(i=0; i<(nPhrase-1); i++){
  2703. const u8 *dummy;
  2704. int nByte = sqlite3Fts5ExprPoslist(pCsr->pExpr, i, &dummy);
  2705. sqlite3Fts5BufferAppendVarint(&rc, &val, nByte);
  2706. }
  2707. /* Append the position lists */
  2708. for(i=0; i<nPhrase; i++){
  2709. const u8 *pPoslist;
  2710. int nPoslist;
  2711. nPoslist = sqlite3Fts5ExprPoslist(pCsr->pExpr, i, &pPoslist);
  2712. sqlite3Fts5BufferAppendBlob(&rc, &val, nPoslist, pPoslist);
  2713. }
  2714. break;
  2715. case FTS5_DETAIL_COLUMNS:
  2716. /* Append the varints */
  2717. for(i=0; rc==SQLITE_OK && i<(nPhrase-1); i++){
  2718. const u8 *dummy;
  2719. int nByte;
  2720. rc = sqlite3Fts5ExprPhraseCollist(pCsr->pExpr, i, &dummy, &nByte);
  2721. sqlite3Fts5BufferAppendVarint(&rc, &val, nByte);
  2722. }
  2723. /* Append the position lists */
  2724. for(i=0; rc==SQLITE_OK && i<nPhrase; i++){
  2725. const u8 *pPoslist;
  2726. int nPoslist;
  2727. rc = sqlite3Fts5ExprPhraseCollist(pCsr->pExpr, i, &pPoslist, &nPoslist);
  2728. sqlite3Fts5BufferAppendBlob(&rc, &val, nPoslist, pPoslist);
  2729. }
  2730. break;
  2731. default:
  2732. break;
  2733. }
  2734. sqlite3_result_blob(pCtx, val.p, val.n, sqlite3_free);
  2735. return rc;
  2736. }
  2737. /*
  2738. ** This is the xColumn method, called by SQLite to request a value from
  2739. ** the row that the supplied cursor currently points to.
  2740. */
  2741. static int fts5ColumnMethod(
  2742. sqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */
  2743. sqlite3_context *pCtx, /* Context for sqlite3_result_xxx() calls */
  2744. int iCol /* Index of column to read value from */
  2745. ){
  2746. Fts5FullTable *pTab = (Fts5FullTable*)(pCursor->pVtab);
  2747. Fts5Config *pConfig = pTab->p.pConfig;
  2748. Fts5Cursor *pCsr = (Fts5Cursor*)pCursor;
  2749. int rc = SQLITE_OK;
  2750. assert( CsrFlagTest(pCsr, FTS5CSR_EOF)==0 );
  2751. if( pCsr->ePlan==FTS5_PLAN_SPECIAL ){
  2752. if( iCol==pConfig->nCol ){
  2753. sqlite3_result_int64(pCtx, pCsr->iSpecial);
  2754. }
  2755. }else
  2756. if( iCol==pConfig->nCol ){
  2757. /* User is requesting the value of the special column with the same name
  2758. ** as the table. Return the cursor integer id number. This value is only
  2759. ** useful in that it may be passed as the first argument to an FTS5
  2760. ** auxiliary function. */
  2761. sqlite3_result_int64(pCtx, pCsr->iCsrId);
  2762. }else if( iCol==pConfig->nCol+1 ){
  2763. /* The value of the "rank" column. */
  2764. if( pCsr->ePlan==FTS5_PLAN_SOURCE ){
  2765. fts5PoslistBlob(pCtx, pCsr);
  2766. }else if(
  2767. pCsr->ePlan==FTS5_PLAN_MATCH
  2768. || pCsr->ePlan==FTS5_PLAN_SORTED_MATCH
  2769. ){
  2770. if( pCsr->pRank || SQLITE_OK==(rc = fts5FindRankFunction(pCsr)) ){
  2771. fts5ApiInvoke(pCsr->pRank, pCsr, pCtx, pCsr->nRankArg, pCsr->apRankArg);
  2772. }
  2773. }
  2774. }else{
  2775. if( !sqlite3_vtab_nochange(pCtx) && pConfig->eContent!=FTS5_CONTENT_NONE ){
  2776. pConfig->pzErrmsg = &pTab->p.base.zErrMsg;
  2777. rc = fts5SeekCursor(pCsr, 1);
  2778. if( rc==SQLITE_OK ){
  2779. sqlite3_value *pVal = sqlite3_column_value(pCsr->pStmt, iCol+1);
  2780. if( pConfig->bLocale
  2781. && pConfig->eContent==FTS5_CONTENT_EXTERNAL
  2782. && sqlite3Fts5IsLocaleValue(pConfig, pVal)
  2783. ){
  2784. const char *z = 0;
  2785. int n = 0;
  2786. rc = fts5TextFromStmt(pConfig, pCsr->pStmt, iCol, &z, &n);
  2787. if( rc==SQLITE_OK ){
  2788. sqlite3_result_text(pCtx, z, n, SQLITE_TRANSIENT);
  2789. }
  2790. sqlite3Fts5ClearLocale(pConfig);
  2791. }else{
  2792. sqlite3_result_value(pCtx, pVal);
  2793. }
  2794. }
  2795. pConfig->pzErrmsg = 0;
  2796. }
  2797. }
  2798. return rc;
  2799. }
  2800. /*
  2801. ** This routine implements the xFindFunction method for the FTS3
  2802. ** virtual table.
  2803. */
  2804. static int fts5FindFunctionMethod(
  2805. sqlite3_vtab *pVtab, /* Virtual table handle */
  2806. int nUnused, /* Number of SQL function arguments */
  2807. const char *zName, /* Name of SQL function */
  2808. void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), /* OUT: Result */
  2809. void **ppArg /* OUT: User data for *pxFunc */
  2810. ){
  2811. Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
  2812. Fts5Auxiliary *pAux;
  2813. UNUSED_PARAM(nUnused);
  2814. pAux = fts5FindAuxiliary(pTab, zName);
  2815. if( pAux ){
  2816. *pxFunc = fts5ApiCallback;
  2817. *ppArg = (void*)pAux;
  2818. return 1;
  2819. }
  2820. /* No function of the specified name was found. Return 0. */
  2821. return 0;
  2822. }
  2823. /*
  2824. ** Implementation of FTS5 xRename method. Rename an fts5 table.
  2825. */
  2826. static int fts5RenameMethod(
  2827. sqlite3_vtab *pVtab, /* Virtual table handle */
  2828. const char *zName /* New name of table */
  2829. ){
  2830. int rc;
  2831. Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
  2832. rc = sqlite3Fts5StorageRename(pTab->pStorage, zName);
  2833. return rc;
  2834. }
  2835. int sqlite3Fts5FlushToDisk(Fts5Table *pTab){
  2836. fts5TripCursors((Fts5FullTable*)pTab);
  2837. return sqlite3Fts5StorageSync(((Fts5FullTable*)pTab)->pStorage);
  2838. }
  2839. /*
  2840. ** The xSavepoint() method.
  2841. **
  2842. ** Flush the contents of the pending-terms table to disk.
  2843. */
  2844. static int fts5SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){
  2845. Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
  2846. int rc = SQLITE_OK;
  2847. fts5CheckTransactionState(pTab, FTS5_SAVEPOINT, iSavepoint);
  2848. rc = sqlite3Fts5FlushToDisk((Fts5Table*)pVtab);
  2849. if( rc==SQLITE_OK ){
  2850. pTab->iSavepoint = iSavepoint+1;
  2851. }
  2852. return rc;
  2853. }
  2854. /*
  2855. ** The xRelease() method.
  2856. **
  2857. ** This is a no-op.
  2858. */
  2859. static int fts5ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){
  2860. Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
  2861. int rc = SQLITE_OK;
  2862. fts5CheckTransactionState(pTab, FTS5_RELEASE, iSavepoint);
  2863. if( (iSavepoint+1)<pTab->iSavepoint ){
  2864. rc = sqlite3Fts5FlushToDisk(&pTab->p);
  2865. if( rc==SQLITE_OK ){
  2866. pTab->iSavepoint = iSavepoint;
  2867. }
  2868. }
  2869. return rc;
  2870. }
  2871. /*
  2872. ** The xRollbackTo() method.
  2873. **
  2874. ** Discard the contents of the pending terms table.
  2875. */
  2876. static int fts5RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){
  2877. Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
  2878. int rc = SQLITE_OK;
  2879. fts5CheckTransactionState(pTab, FTS5_ROLLBACKTO, iSavepoint);
  2880. fts5TripCursors(pTab);
  2881. if( (iSavepoint+1)<=pTab->iSavepoint ){
  2882. pTab->p.pConfig->pgsz = 0;
  2883. rc = sqlite3Fts5StorageRollback(pTab->pStorage);
  2884. }
  2885. return rc;
  2886. }
  2887. /*
  2888. ** Register a new auxiliary function with global context pGlobal.
  2889. */
  2890. static int fts5CreateAux(
  2891. fts5_api *pApi, /* Global context (one per db handle) */
  2892. const char *zName, /* Name of new function */
  2893. void *pUserData, /* User data for aux. function */
  2894. fts5_extension_function xFunc, /* Aux. function implementation */
  2895. void(*xDestroy)(void*) /* Destructor for pUserData */
  2896. ){
  2897. Fts5Global *pGlobal = (Fts5Global*)pApi;
  2898. int rc = sqlite3_overload_function(pGlobal->db, zName, -1);
  2899. if( rc==SQLITE_OK ){
  2900. Fts5Auxiliary *pAux;
  2901. sqlite3_int64 nName; /* Size of zName in bytes, including \0 */
  2902. sqlite3_int64 nByte; /* Bytes of space to allocate */
  2903. nName = strlen(zName) + 1;
  2904. nByte = sizeof(Fts5Auxiliary) + nName;
  2905. pAux = (Fts5Auxiliary*)sqlite3_malloc64(nByte);
  2906. if( pAux ){
  2907. memset(pAux, 0, (size_t)nByte);
  2908. pAux->zFunc = (char*)&pAux[1];
  2909. memcpy(pAux->zFunc, zName, nName);
  2910. pAux->pGlobal = pGlobal;
  2911. pAux->pUserData = pUserData;
  2912. pAux->xFunc = xFunc;
  2913. pAux->xDestroy = xDestroy;
  2914. pAux->pNext = pGlobal->pAux;
  2915. pGlobal->pAux = pAux;
  2916. }else{
  2917. rc = SQLITE_NOMEM;
  2918. }
  2919. }
  2920. return rc;
  2921. }
  2922. /*
  2923. ** This function is used by xCreateTokenizer_v2() and xCreateTokenizer().
  2924. ** It allocates and partially populates a new Fts5TokenizerModule object.
  2925. ** The new object is already linked into the Fts5Global context before
  2926. ** returning.
  2927. **
  2928. ** If successful, SQLITE_OK is returned and a pointer to the new
  2929. ** Fts5TokenizerModule object returned via output parameter (*ppNew). All
  2930. ** that is required is for the caller to fill in the methods in
  2931. ** Fts5TokenizerModule.x1 and x2, and to set Fts5TokenizerModule.bV2Native
  2932. ** as appropriate.
  2933. **
  2934. ** If an error occurs, an SQLite error code is returned and the final value
  2935. ** of (*ppNew) undefined.
  2936. */
  2937. static int fts5NewTokenizerModule(
  2938. Fts5Global *pGlobal, /* Global context (one per db handle) */
  2939. const char *zName, /* Name of new function */
  2940. void *pUserData, /* User data for aux. function */
  2941. void(*xDestroy)(void*), /* Destructor for pUserData */
  2942. Fts5TokenizerModule **ppNew
  2943. ){
  2944. int rc = SQLITE_OK;
  2945. Fts5TokenizerModule *pNew;
  2946. sqlite3_int64 nName; /* Size of zName and its \0 terminator */
  2947. sqlite3_int64 nByte; /* Bytes of space to allocate */
  2948. nName = strlen(zName) + 1;
  2949. nByte = sizeof(Fts5TokenizerModule) + nName;
  2950. *ppNew = pNew = (Fts5TokenizerModule*)sqlite3Fts5MallocZero(&rc, nByte);
  2951. if( pNew ){
  2952. pNew->zName = (char*)&pNew[1];
  2953. memcpy(pNew->zName, zName, nName);
  2954. pNew->pUserData = pUserData;
  2955. pNew->xDestroy = xDestroy;
  2956. pNew->pNext = pGlobal->pTok;
  2957. pGlobal->pTok = pNew;
  2958. if( pNew->pNext==0 ){
  2959. pGlobal->pDfltTok = pNew;
  2960. }
  2961. }
  2962. return rc;
  2963. }
  2964. /*
  2965. ** An instance of this type is used as the Fts5Tokenizer object for
  2966. ** wrapper tokenizers - those that provide access to a v1 tokenizer via
  2967. ** the fts5_tokenizer_v2 API, and those that provide access to a v2 tokenizer
  2968. ** via the fts5_tokenizer API.
  2969. */
  2970. typedef struct Fts5VtoVTokenizer Fts5VtoVTokenizer;
  2971. struct Fts5VtoVTokenizer {
  2972. int bV2Native; /* True if v2 native tokenizer */
  2973. fts5_tokenizer x1; /* Tokenizer functions */
  2974. fts5_tokenizer_v2 x2; /* V2 tokenizer functions */
  2975. Fts5Tokenizer *pReal;
  2976. };
  2977. /*
  2978. ** Create a wrapper tokenizer. The context argument pCtx points to the
  2979. ** Fts5TokenizerModule object.
  2980. */
  2981. static int fts5VtoVCreate(
  2982. void *pCtx,
  2983. const char **azArg,
  2984. int nArg,
  2985. Fts5Tokenizer **ppOut
  2986. ){
  2987. Fts5TokenizerModule *pMod = (Fts5TokenizerModule*)pCtx;
  2988. Fts5VtoVTokenizer *pNew = 0;
  2989. int rc = SQLITE_OK;
  2990. pNew = (Fts5VtoVTokenizer*)sqlite3Fts5MallocZero(&rc, sizeof(*pNew));
  2991. if( rc==SQLITE_OK ){
  2992. pNew->x1 = pMod->x1;
  2993. pNew->x2 = pMod->x2;
  2994. pNew->bV2Native = pMod->bV2Native;
  2995. if( pMod->bV2Native ){
  2996. rc = pMod->x2.xCreate(pMod->pUserData, azArg, nArg, &pNew->pReal);
  2997. }else{
  2998. rc = pMod->x1.xCreate(pMod->pUserData, azArg, nArg, &pNew->pReal);
  2999. }
  3000. if( rc!=SQLITE_OK ){
  3001. sqlite3_free(pNew);
  3002. pNew = 0;
  3003. }
  3004. }
  3005. *ppOut = (Fts5Tokenizer*)pNew;
  3006. return rc;
  3007. }
  3008. /*
  3009. ** Delete an Fts5VtoVTokenizer wrapper tokenizer.
  3010. */
  3011. static void fts5VtoVDelete(Fts5Tokenizer *pTok){
  3012. Fts5VtoVTokenizer *p = (Fts5VtoVTokenizer*)pTok;
  3013. if( p ){
  3014. if( p->bV2Native ){
  3015. p->x2.xDelete(p->pReal);
  3016. }else{
  3017. p->x1.xDelete(p->pReal);
  3018. }
  3019. sqlite3_free(p);
  3020. }
  3021. }
  3022. /*
  3023. ** xTokenizer method for a wrapper tokenizer that offers the v1 interface
  3024. ** (no support for locales).
  3025. */
  3026. static int fts5V1toV2Tokenize(
  3027. Fts5Tokenizer *pTok,
  3028. void *pCtx, int flags,
  3029. const char *pText, int nText,
  3030. int (*xToken)(void*, int, const char*, int, int, int)
  3031. ){
  3032. Fts5VtoVTokenizer *p = (Fts5VtoVTokenizer*)pTok;
  3033. assert( p->bV2Native );
  3034. return p->x2.xTokenize(p->pReal, pCtx, flags, pText, nText, 0, 0, xToken);
  3035. }
  3036. /*
  3037. ** xTokenizer method for a wrapper tokenizer that offers the v2 interface
  3038. ** (with locale support).
  3039. */
  3040. static int fts5V2toV1Tokenize(
  3041. Fts5Tokenizer *pTok,
  3042. void *pCtx, int flags,
  3043. const char *pText, int nText,
  3044. const char *pLocale, int nLocale,
  3045. int (*xToken)(void*, int, const char*, int, int, int)
  3046. ){
  3047. Fts5VtoVTokenizer *p = (Fts5VtoVTokenizer*)pTok;
  3048. assert( p->bV2Native==0 );
  3049. UNUSED_PARAM2(pLocale,nLocale);
  3050. return p->x1.xTokenize(p->pReal, pCtx, flags, pText, nText, xToken);
  3051. }
  3052. /*
  3053. ** Register a new tokenizer. This is the implementation of the
  3054. ** fts5_api.xCreateTokenizer_v2() method.
  3055. */
  3056. static int fts5CreateTokenizer_v2(
  3057. fts5_api *pApi, /* Global context (one per db handle) */
  3058. const char *zName, /* Name of new function */
  3059. void *pUserData, /* User data for aux. function */
  3060. fts5_tokenizer_v2 *pTokenizer, /* Tokenizer implementation */
  3061. void(*xDestroy)(void*) /* Destructor for pUserData */
  3062. ){
  3063. Fts5Global *pGlobal = (Fts5Global*)pApi;
  3064. int rc = SQLITE_OK;
  3065. if( pTokenizer->iVersion>2 ){
  3066. rc = SQLITE_ERROR;
  3067. }else{
  3068. Fts5TokenizerModule *pNew = 0;
  3069. rc = fts5NewTokenizerModule(pGlobal, zName, pUserData, xDestroy, &pNew);
  3070. if( pNew ){
  3071. pNew->x2 = *pTokenizer;
  3072. pNew->bV2Native = 1;
  3073. pNew->x1.xCreate = fts5VtoVCreate;
  3074. pNew->x1.xTokenize = fts5V1toV2Tokenize;
  3075. pNew->x1.xDelete = fts5VtoVDelete;
  3076. }
  3077. }
  3078. return rc;
  3079. }
  3080. /*
  3081. ** The fts5_api.xCreateTokenizer() method.
  3082. */
  3083. static int fts5CreateTokenizer(
  3084. fts5_api *pApi, /* Global context (one per db handle) */
  3085. const char *zName, /* Name of new function */
  3086. void *pUserData, /* User data for aux. function */
  3087. fts5_tokenizer *pTokenizer, /* Tokenizer implementation */
  3088. void(*xDestroy)(void*) /* Destructor for pUserData */
  3089. ){
  3090. Fts5TokenizerModule *pNew = 0;
  3091. int rc = SQLITE_OK;
  3092. rc = fts5NewTokenizerModule(
  3093. (Fts5Global*)pApi, zName, pUserData, xDestroy, &pNew
  3094. );
  3095. if( pNew ){
  3096. pNew->x1 = *pTokenizer;
  3097. pNew->x2.xCreate = fts5VtoVCreate;
  3098. pNew->x2.xTokenize = fts5V2toV1Tokenize;
  3099. pNew->x2.xDelete = fts5VtoVDelete;
  3100. }
  3101. return rc;
  3102. }
  3103. /*
  3104. ** Search the global context passed as the first argument for a tokenizer
  3105. ** module named zName. If found, return a pointer to the Fts5TokenizerModule
  3106. ** object. Otherwise, return NULL.
  3107. */
  3108. static Fts5TokenizerModule *fts5LocateTokenizer(
  3109. Fts5Global *pGlobal, /* Global (one per db handle) object */
  3110. const char *zName /* Name of tokenizer module to find */
  3111. ){
  3112. Fts5TokenizerModule *pMod = 0;
  3113. if( zName==0 ){
  3114. pMod = pGlobal->pDfltTok;
  3115. }else{
  3116. for(pMod=pGlobal->pTok; pMod; pMod=pMod->pNext){
  3117. if( sqlite3_stricmp(zName, pMod->zName)==0 ) break;
  3118. }
  3119. }
  3120. return pMod;
  3121. }
  3122. /*
  3123. ** Find a tokenizer. This is the implementation of the
  3124. ** fts5_api.xFindTokenizer_v2() method.
  3125. */
  3126. static int fts5FindTokenizer_v2(
  3127. fts5_api *pApi, /* Global context (one per db handle) */
  3128. const char *zName, /* Name of tokenizer */
  3129. void **ppUserData,
  3130. fts5_tokenizer_v2 **ppTokenizer /* Populate this object */
  3131. ){
  3132. int rc = SQLITE_OK;
  3133. Fts5TokenizerModule *pMod;
  3134. pMod = fts5LocateTokenizer((Fts5Global*)pApi, zName);
  3135. if( pMod ){
  3136. if( pMod->bV2Native ){
  3137. *ppUserData = pMod->pUserData;
  3138. }else{
  3139. *ppUserData = (void*)pMod;
  3140. }
  3141. *ppTokenizer = &pMod->x2;
  3142. }else{
  3143. *ppTokenizer = 0;
  3144. *ppUserData = 0;
  3145. rc = SQLITE_ERROR;
  3146. }
  3147. return rc;
  3148. }
  3149. /*
  3150. ** Find a tokenizer. This is the implementation of the
  3151. ** fts5_api.xFindTokenizer() method.
  3152. */
  3153. static int fts5FindTokenizer(
  3154. fts5_api *pApi, /* Global context (one per db handle) */
  3155. const char *zName, /* Name of new function */
  3156. void **ppUserData,
  3157. fts5_tokenizer *pTokenizer /* Populate this object */
  3158. ){
  3159. int rc = SQLITE_OK;
  3160. Fts5TokenizerModule *pMod;
  3161. pMod = fts5LocateTokenizer((Fts5Global*)pApi, zName);
  3162. if( pMod ){
  3163. if( pMod->bV2Native==0 ){
  3164. *ppUserData = pMod->pUserData;
  3165. }else{
  3166. *ppUserData = (void*)pMod;
  3167. }
  3168. *pTokenizer = pMod->x1;
  3169. }else{
  3170. memset(pTokenizer, 0, sizeof(*pTokenizer));
  3171. *ppUserData = 0;
  3172. rc = SQLITE_ERROR;
  3173. }
  3174. return rc;
  3175. }
  3176. /*
  3177. ** Attempt to instantiate the tokenizer.
  3178. */
  3179. int sqlite3Fts5LoadTokenizer(Fts5Config *pConfig){
  3180. const char **azArg = pConfig->t.azArg;
  3181. const int nArg = pConfig->t.nArg;
  3182. Fts5TokenizerModule *pMod = 0;
  3183. int rc = SQLITE_OK;
  3184. pMod = fts5LocateTokenizer(pConfig->pGlobal, nArg==0 ? 0 : azArg[0]);
  3185. if( pMod==0 ){
  3186. assert( nArg>0 );
  3187. rc = SQLITE_ERROR;
  3188. sqlite3Fts5ConfigErrmsg(pConfig, "no such tokenizer: %s", azArg[0]);
  3189. }else{
  3190. int (*xCreate)(void*, const char**, int, Fts5Tokenizer**) = 0;
  3191. if( pMod->bV2Native ){
  3192. xCreate = pMod->x2.xCreate;
  3193. pConfig->t.pApi2 = &pMod->x2;
  3194. }else{
  3195. pConfig->t.pApi1 = &pMod->x1;
  3196. xCreate = pMod->x1.xCreate;
  3197. }
  3198. rc = xCreate(pMod->pUserData,
  3199. (azArg?&azArg[1]:0), (nArg?nArg-1:0), &pConfig->t.pTok
  3200. );
  3201. if( rc!=SQLITE_OK ){
  3202. if( rc!=SQLITE_NOMEM ){
  3203. sqlite3Fts5ConfigErrmsg(pConfig, "error in tokenizer constructor");
  3204. }
  3205. }else if( pMod->bV2Native==0 ){
  3206. pConfig->t.ePattern = sqlite3Fts5TokenizerPattern(
  3207. pMod->x1.xCreate, pConfig->t.pTok
  3208. );
  3209. }
  3210. }
  3211. if( rc!=SQLITE_OK ){
  3212. pConfig->t.pApi1 = 0;
  3213. pConfig->t.pApi2 = 0;
  3214. pConfig->t.pTok = 0;
  3215. }
  3216. return rc;
  3217. }
  3218. /*
  3219. ** xDestroy callback passed to sqlite3_create_module(). This is invoked
  3220. ** when the db handle is being closed. Free memory associated with
  3221. ** tokenizers and aux functions registered with this db handle.
  3222. */
  3223. static void fts5ModuleDestroy(void *pCtx){
  3224. Fts5TokenizerModule *pTok, *pNextTok;
  3225. Fts5Auxiliary *pAux, *pNextAux;
  3226. Fts5Global *pGlobal = (Fts5Global*)pCtx;
  3227. for(pAux=pGlobal->pAux; pAux; pAux=pNextAux){
  3228. pNextAux = pAux->pNext;
  3229. if( pAux->xDestroy ) pAux->xDestroy(pAux->pUserData);
  3230. sqlite3_free(pAux);
  3231. }
  3232. for(pTok=pGlobal->pTok; pTok; pTok=pNextTok){
  3233. pNextTok = pTok->pNext;
  3234. if( pTok->xDestroy ) pTok->xDestroy(pTok->pUserData);
  3235. sqlite3_free(pTok);
  3236. }
  3237. sqlite3_free(pGlobal);
  3238. }
  3239. /*
  3240. ** Implementation of the fts5() function used by clients to obtain the
  3241. ** API pointer.
  3242. */
  3243. static void fts5Fts5Func(
  3244. sqlite3_context *pCtx, /* Function call context */
  3245. int nArg, /* Number of args */
  3246. sqlite3_value **apArg /* Function arguments */
  3247. ){
  3248. Fts5Global *pGlobal = (Fts5Global*)sqlite3_user_data(pCtx);
  3249. fts5_api **ppApi;
  3250. UNUSED_PARAM(nArg);
  3251. assert( nArg==1 );
  3252. ppApi = (fts5_api**)sqlite3_value_pointer(apArg[0], "fts5_api_ptr");
  3253. if( ppApi ) *ppApi = &pGlobal->api;
  3254. }
  3255. /*
  3256. ** Implementation of fts5_source_id() function.
  3257. */
  3258. static void fts5SourceIdFunc(
  3259. sqlite3_context *pCtx, /* Function call context */
  3260. int nArg, /* Number of args */
  3261. sqlite3_value **apUnused /* Function arguments */
  3262. ){
  3263. assert( nArg==0 );
  3264. UNUSED_PARAM2(nArg, apUnused);
  3265. sqlite3_result_text(pCtx, "--FTS5-SOURCE-ID--", -1, SQLITE_TRANSIENT);
  3266. }
  3267. /*
  3268. ** Implementation of fts5_locale(LOCALE, TEXT) function.
  3269. **
  3270. ** If parameter LOCALE is NULL, or a zero-length string, then a copy of
  3271. ** TEXT is returned. Otherwise, both LOCALE and TEXT are interpreted as
  3272. ** text, and the value returned is a blob consisting of:
  3273. **
  3274. ** * The 4 bytes 0x00, 0xE0, 0xB2, 0xEb (FTS5_LOCALE_HEADER).
  3275. ** * The LOCALE, as utf-8 text, followed by
  3276. ** * 0x00, followed by
  3277. ** * The TEXT, as utf-8 text.
  3278. **
  3279. ** There is no final nul-terminator following the TEXT value.
  3280. */
  3281. static void fts5LocaleFunc(
  3282. sqlite3_context *pCtx, /* Function call context */
  3283. int nArg, /* Number of args */
  3284. sqlite3_value **apArg /* Function arguments */
  3285. ){
  3286. const char *zLocale = 0;
  3287. int nLocale = 0;
  3288. const char *zText = 0;
  3289. int nText = 0;
  3290. assert( nArg==2 );
  3291. UNUSED_PARAM(nArg);
  3292. zLocale = (const char*)sqlite3_value_text(apArg[0]);
  3293. nLocale = sqlite3_value_bytes(apArg[0]);
  3294. zText = (const char*)sqlite3_value_text(apArg[1]);
  3295. nText = sqlite3_value_bytes(apArg[1]);
  3296. if( zLocale==0 || zLocale[0]=='\0' ){
  3297. sqlite3_result_text(pCtx, zText, nText, SQLITE_TRANSIENT);
  3298. }else{
  3299. Fts5Global *p = (Fts5Global*)sqlite3_user_data(pCtx);
  3300. u8 *pBlob = 0;
  3301. u8 *pCsr = 0;
  3302. int nBlob = 0;
  3303. nBlob = FTS5_LOCALE_HDR_SIZE + nLocale + 1 + nText;
  3304. pBlob = (u8*)sqlite3_malloc(nBlob);
  3305. if( pBlob==0 ){
  3306. sqlite3_result_error_nomem(pCtx);
  3307. return;
  3308. }
  3309. pCsr = pBlob;
  3310. memcpy(pCsr, (const u8*)p->aLocaleHdr, FTS5_LOCALE_HDR_SIZE);
  3311. pCsr += FTS5_LOCALE_HDR_SIZE;
  3312. memcpy(pCsr, zLocale, nLocale);
  3313. pCsr += nLocale;
  3314. (*pCsr++) = 0x00;
  3315. if( zText ) memcpy(pCsr, zText, nText);
  3316. assert( &pCsr[nText]==&pBlob[nBlob] );
  3317. sqlite3_result_blob(pCtx, pBlob, nBlob, sqlite3_free);
  3318. }
  3319. }
  3320. /*
  3321. ** Implementation of fts5_insttoken() function.
  3322. */
  3323. static void fts5InsttokenFunc(
  3324. sqlite3_context *pCtx, /* Function call context */
  3325. int nArg, /* Number of args */
  3326. sqlite3_value **apArg /* Function arguments */
  3327. ){
  3328. assert( nArg==1 );
  3329. (void)nArg;
  3330. sqlite3_result_value(pCtx, apArg[0]);
  3331. sqlite3_result_subtype(pCtx, FTS5_INSTTOKEN_SUBTYPE);
  3332. }
  3333. /*
  3334. ** Return true if zName is the extension on one of the shadow tables used
  3335. ** by this module.
  3336. */
  3337. static int fts5ShadowName(const char *zName){
  3338. static const char *azName[] = {
  3339. "config", "content", "data", "docsize", "idx"
  3340. };
  3341. unsigned int i;
  3342. for(i=0; i<sizeof(azName)/sizeof(azName[0]); i++){
  3343. if( sqlite3_stricmp(zName, azName[i])==0 ) return 1;
  3344. }
  3345. return 0;
  3346. }
  3347. /*
  3348. ** Run an integrity check on the FTS5 data structures. Return a string
  3349. ** if anything is found amiss. Return a NULL pointer if everything is
  3350. ** OK.
  3351. */
  3352. static int fts5IntegrityMethod(
  3353. sqlite3_vtab *pVtab, /* the FTS5 virtual table to check */
  3354. const char *zSchema, /* Name of schema in which this table lives */
  3355. const char *zTabname, /* Name of the table itself */
  3356. int isQuick, /* True if this is a quick-check */
  3357. char **pzErr /* Write error message here */
  3358. ){
  3359. Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
  3360. int rc;
  3361. assert( pzErr!=0 && *pzErr==0 );
  3362. UNUSED_PARAM(isQuick);
  3363. assert( pTab->p.pConfig->pzErrmsg==0 );
  3364. pTab->p.pConfig->pzErrmsg = pzErr;
  3365. rc = sqlite3Fts5StorageIntegrity(pTab->pStorage, 0);
  3366. if( *pzErr==0 && rc!=SQLITE_OK ){
  3367. if( (rc&0xff)==SQLITE_CORRUPT ){
  3368. *pzErr = sqlite3_mprintf("malformed inverted index for FTS5 table %s.%s",
  3369. zSchema, zTabname);
  3370. rc = (*pzErr) ? SQLITE_OK : SQLITE_NOMEM;
  3371. }else{
  3372. *pzErr = sqlite3_mprintf("unable to validate the inverted index for"
  3373. " FTS5 table %s.%s: %s",
  3374. zSchema, zTabname, sqlite3_errstr(rc));
  3375. }
  3376. }
  3377. sqlite3Fts5IndexCloseReader(pTab->p.pIndex);
  3378. pTab->p.pConfig->pzErrmsg = 0;
  3379. return rc;
  3380. }
  3381. static int fts5Init(sqlite3 *db){
  3382. static const sqlite3_module fts5Mod = {
  3383. /* iVersion */ 4,
  3384. /* xCreate */ fts5CreateMethod,
  3385. /* xConnect */ fts5ConnectMethod,
  3386. /* xBestIndex */ fts5BestIndexMethod,
  3387. /* xDisconnect */ fts5DisconnectMethod,
  3388. /* xDestroy */ fts5DestroyMethod,
  3389. /* xOpen */ fts5OpenMethod,
  3390. /* xClose */ fts5CloseMethod,
  3391. /* xFilter */ fts5FilterMethod,
  3392. /* xNext */ fts5NextMethod,
  3393. /* xEof */ fts5EofMethod,
  3394. /* xColumn */ fts5ColumnMethod,
  3395. /* xRowid */ fts5RowidMethod,
  3396. /* xUpdate */ fts5UpdateMethod,
  3397. /* xBegin */ fts5BeginMethod,
  3398. /* xSync */ fts5SyncMethod,
  3399. /* xCommit */ fts5CommitMethod,
  3400. /* xRollback */ fts5RollbackMethod,
  3401. /* xFindFunction */ fts5FindFunctionMethod,
  3402. /* xRename */ fts5RenameMethod,
  3403. /* xSavepoint */ fts5SavepointMethod,
  3404. /* xRelease */ fts5ReleaseMethod,
  3405. /* xRollbackTo */ fts5RollbackToMethod,
  3406. /* xShadowName */ fts5ShadowName,
  3407. /* xIntegrity */ fts5IntegrityMethod
  3408. };
  3409. int rc;
  3410. Fts5Global *pGlobal = 0;
  3411. pGlobal = (Fts5Global*)sqlite3_malloc(sizeof(Fts5Global));
  3412. if( pGlobal==0 ){
  3413. rc = SQLITE_NOMEM;
  3414. }else{
  3415. void *p = (void*)pGlobal;
  3416. memset(pGlobal, 0, sizeof(Fts5Global));
  3417. pGlobal->db = db;
  3418. pGlobal->api.iVersion = 3;
  3419. pGlobal->api.xCreateFunction = fts5CreateAux;
  3420. pGlobal->api.xCreateTokenizer = fts5CreateTokenizer;
  3421. pGlobal->api.xFindTokenizer = fts5FindTokenizer;
  3422. pGlobal->api.xCreateTokenizer_v2 = fts5CreateTokenizer_v2;
  3423. pGlobal->api.xFindTokenizer_v2 = fts5FindTokenizer_v2;
  3424. /* Initialize pGlobal->aLocaleHdr[] to a 128-bit pseudo-random vector.
  3425. ** The constants below were generated randomly. */
  3426. sqlite3_randomness(sizeof(pGlobal->aLocaleHdr), pGlobal->aLocaleHdr);
  3427. pGlobal->aLocaleHdr[0] ^= 0xF924976D;
  3428. pGlobal->aLocaleHdr[1] ^= 0x16596E13;
  3429. pGlobal->aLocaleHdr[2] ^= 0x7C80BEAA;
  3430. pGlobal->aLocaleHdr[3] ^= 0x9B03A67F;
  3431. assert( sizeof(pGlobal->aLocaleHdr)==16 );
  3432. rc = sqlite3_create_module_v2(db, "fts5", &fts5Mod, p, fts5ModuleDestroy);
  3433. if( rc==SQLITE_OK ) rc = sqlite3Fts5IndexInit(db);
  3434. if( rc==SQLITE_OK ) rc = sqlite3Fts5ExprInit(pGlobal, db);
  3435. if( rc==SQLITE_OK ) rc = sqlite3Fts5AuxInit(&pGlobal->api);
  3436. if( rc==SQLITE_OK ) rc = sqlite3Fts5TokenizerInit(&pGlobal->api);
  3437. if( rc==SQLITE_OK ) rc = sqlite3Fts5VocabInit(pGlobal, db);
  3438. if( rc==SQLITE_OK ){
  3439. rc = sqlite3_create_function(
  3440. db, "fts5", 1, SQLITE_UTF8, p, fts5Fts5Func, 0, 0
  3441. );
  3442. }
  3443. if( rc==SQLITE_OK ){
  3444. rc = sqlite3_create_function(
  3445. db, "fts5_source_id", 0,
  3446. SQLITE_UTF8|SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS,
  3447. p, fts5SourceIdFunc, 0, 0
  3448. );
  3449. }
  3450. if( rc==SQLITE_OK ){
  3451. rc = sqlite3_create_function(
  3452. db, "fts5_locale", 2,
  3453. SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_RESULT_SUBTYPE|SQLITE_SUBTYPE,
  3454. p, fts5LocaleFunc, 0, 0
  3455. );
  3456. }
  3457. if( rc==SQLITE_OK ){
  3458. rc = sqlite3_create_function(
  3459. db, "fts5_insttoken", 1,
  3460. SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_RESULT_SUBTYPE,
  3461. p, fts5InsttokenFunc, 0, 0
  3462. );
  3463. }
  3464. }
  3465. /* If SQLITE_FTS5_ENABLE_TEST_MI is defined, assume that the file
  3466. ** fts5_test_mi.c is compiled and linked into the executable. And call
  3467. ** its entry point to enable the matchinfo() demo. */
  3468. #ifdef SQLITE_FTS5_ENABLE_TEST_MI
  3469. if( rc==SQLITE_OK ){
  3470. extern int sqlite3Fts5TestRegisterMatchinfo(sqlite3*);
  3471. rc = sqlite3Fts5TestRegisterMatchinfo(db);
  3472. }
  3473. #endif
  3474. return rc;
  3475. }
  3476. /*
  3477. ** The following functions are used to register the module with SQLite. If
  3478. ** this module is being built as part of the SQLite core (SQLITE_CORE is
  3479. ** defined), then sqlite3_open() will call sqlite3Fts5Init() directly.
  3480. **
  3481. ** Or, if this module is being built as a loadable extension,
  3482. ** sqlite3Fts5Init() is omitted and the two standard entry points
  3483. ** sqlite3_fts_init() and sqlite3_fts5_init() defined instead.
  3484. */
  3485. #ifndef SQLITE_CORE
  3486. #ifdef _WIN32
  3487. __declspec(dllexport)
  3488. #endif
  3489. int sqlite3_fts_init(
  3490. sqlite3 *db,
  3491. char **pzErrMsg,
  3492. const sqlite3_api_routines *pApi
  3493. ){
  3494. SQLITE_EXTENSION_INIT2(pApi);
  3495. (void)pzErrMsg; /* Unused parameter */
  3496. return fts5Init(db);
  3497. }
  3498. #ifdef _WIN32
  3499. __declspec(dllexport)
  3500. #endif
  3501. int sqlite3_fts5_init(
  3502. sqlite3 *db,
  3503. char **pzErrMsg,
  3504. const sqlite3_api_routines *pApi
  3505. ){
  3506. SQLITE_EXTENSION_INIT2(pApi);
  3507. (void)pzErrMsg; /* Unused parameter */
  3508. return fts5Init(db);
  3509. }
  3510. #else
  3511. int sqlite3Fts5Init(sqlite3 *db){
  3512. return fts5Init(db);
  3513. }
  3514. #endif