/ Hex Artifact Content
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

Artifact e96be827aa8f571031e65e481251dc1981d608bf:


0000: 2f 2a 0a 2a 2a 20 32 30 31 35 20 41 75 67 20 30  /*.** 2015 Aug 0
0010: 34 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 75 74 68  4.**.** The auth
0020: 6f 72 20 64 69 73 63 6c 61 69 6d 73 20 63 6f 70  or disclaims cop
0030: 79 72 69 67 68 74 20 74 6f 20 74 68 69 73 20 73  yright to this s
0040: 6f 75 72 63 65 20 63 6f 64 65 2e 20 20 49 6e 20  ource code.  In 
0050: 70 6c 61 63 65 20 6f 66 0a 2a 2a 20 61 20 6c 65  place of.** a le
0060: 67 61 6c 20 6e 6f 74 69 63 65 2c 20 68 65 72 65  gal notice, here
0070: 20 69 73 20 61 20 62 6c 65 73 73 69 6e 67 3a 0a   is a blessing:.
0080: 2a 2a 0a 2a 2a 20 20 20 20 4d 61 79 20 79 6f 75  **.**    May you
0090: 20 64 6f 20 67 6f 6f 64 20 61 6e 64 20 6e 6f 74   do good and not
00a0: 20 65 76 69 6c 2e 0a 2a 2a 20 20 20 20 4d 61 79   evil..**    May
00b0: 20 79 6f 75 20 66 69 6e 64 20 66 6f 72 67 69 76   you find forgiv
00c0: 65 6e 65 73 73 20 66 6f 72 20 79 6f 75 72 73 65  eness for yourse
00d0: 6c 66 20 61 6e 64 20 66 6f 72 67 69 76 65 20 6f  lf and forgive o
00e0: 74 68 65 72 73 2e 0a 2a 2a 20 20 20 20 4d 61 79  thers..**    May
00f0: 20 79 6f 75 20 73 68 61 72 65 20 66 72 65 65 6c   you share freel
0100: 79 2c 20 6e 65 76 65 72 20 74 61 6b 69 6e 67 20  y, never taking 
0110: 6d 6f 72 65 20 74 68 61 6e 20 79 6f 75 20 67 69  more than you gi
0120: 76 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ve..**.*********
0130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0160: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0170: 2a 2a 2a 2a 2a 0a 2a 2a 0a 2a 2a 20 54 68 69 73  *****.**.** This
0180: 20 66 69 6c 65 20 63 6f 6e 74 61 69 6e 73 20 74   file contains t
0190: 65 73 74 20 63 6f 64 65 20 6f 6e 6c 79 2c 20 69  est code only, i
01a0: 74 20 69 73 20 6e 6f 74 20 69 6e 63 6c 75 64 65  t is not include
01b0: 64 20 69 6e 20 72 65 6c 65 61 73 65 20 0a 2a 2a  d in release .**
01c0: 20 76 65 72 73 69 6f 6e 73 20 6f 66 20 46 54 53   versions of FTS
01d0: 35 2e 20 49 74 20 63 6f 6e 74 61 69 6e 73 20 74  5. It contains t
01e0: 68 65 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f  he implementatio
01f0: 6e 20 6f 66 20 61 6e 20 46 54 53 35 20 61 75 78  n of an FTS5 aux
0200: 69 6c 69 61 72 79 0a 2a 2a 20 66 75 6e 63 74 69  iliary.** functi
0210: 6f 6e 20 76 65 72 79 20 73 69 6d 69 6c 61 72 20  on very similar 
0220: 74 6f 20 74 68 65 20 46 54 53 34 20 66 75 6e 63  to the FTS4 func
0230: 74 69 6f 6e 20 6d 61 74 63 68 69 6e 66 6f 28 29  tion matchinfo()
0240: 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 68 74 74 70  :.**.**     http
0250: 73 3a 2f 2f 77 77 77 2e 73 71 6c 69 74 65 2e 6f  s://www.sqlite.o
0260: 72 67 2f 66 74 73 33 2e 68 74 6d 6c 23 6d 61 74  rg/fts3.html#mat
0270: 63 68 69 6e 66 6f 0a 2a 2a 0a 2a 2a 20 4b 6e 6f  chinfo.**.** Kno
0280: 77 6e 20 64 69 66 66 65 72 65 6e 63 65 73 20 61  wn differences a
0290: 72 65 20 74 68 61 74 3a 0a 2a 2a 0a 2a 2a 20 20  re that:.**.**  
02a0: 31 29 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e  1) this function
02b0: 20 75 73 65 73 20 74 68 65 20 46 54 53 35 20 64   uses the FTS5 d
02c0: 65 66 69 6e 69 74 69 6f 6e 20 6f 66 20 22 6d 61  efinition of "ma
02d0: 74 63 68 61 62 6c 65 20 70 68 72 61 73 65 22 2c  tchable phrase",
02e0: 20 77 68 69 63 68 0a 2a 2a 20 20 20 20 20 65 78   which.**     ex
02f0: 63 6c 75 64 65 73 20 61 6e 79 20 70 68 72 61 73  cludes any phras
0300: 65 73 20 74 68 61 74 20 61 72 65 20 70 61 72 74  es that are part
0310: 20 6f 66 20 61 6e 20 65 78 70 72 65 73 73 69 6f   of an expressio
0320: 6e 20 73 75 62 2d 74 72 65 65 20 74 68 61 74 0a  n sub-tree that.
0330: 2a 2a 20 20 20 20 20 64 6f 65 73 20 6e 6f 74 20  **     does not 
0340: 6d 61 74 63 68 20 74 68 65 20 63 75 72 72 65 6e  match the curren
0350: 74 20 72 6f 77 2e 20 54 68 69 73 20 63 6f 6d 65  t row. This come
0360: 73 20 75 70 20 66 6f 72 20 4d 41 54 43 48 20 71  s up for MATCH q
0370: 75 65 72 69 65 73 20 0a 2a 2a 20 20 20 20 20 73  ueries .**     s
0380: 75 63 68 20 61 73 3a 0a 2a 2a 0a 2a 2a 20 20 20  uch as:.**.**   
0390: 20 20 20 20 20 20 22 61 20 4f 52 20 28 62 20 41        "a OR (b A
03a0: 4e 44 20 63 29 22 0a 2a 2a 0a 2a 2a 20 20 20 20  ND c)".**.**    
03b0: 20 49 6e 20 46 54 53 34 2c 20 69 66 20 61 20 73   In FTS4, if a s
03c0: 69 6e 67 6c 65 20 72 6f 77 20 63 6f 6e 74 61 69  ingle row contai
03d0: 6e 73 20 69 6e 73 74 61 6e 63 65 73 20 6f 66 20  ns instances of 
03e0: 74 6f 6b 65 6e 73 20 22 61 22 20 61 6e 64 20 22  tokens "a" and "
03f0: 63 22 2c 20 0a 2a 2a 20 20 20 20 20 62 75 74 20  c", .**     but 
0400: 6e 6f 74 20 22 62 22 2c 20 61 6c 6c 20 69 6e 73  not "b", all ins
0410: 74 61 6e 63 65 73 20 6f 66 20 22 63 22 20 61 72  tances of "c" ar
0420: 65 20 63 6f 6e 73 69 64 65 72 65 64 20 6d 61 74  e considered mat
0430: 63 68 65 73 2e 20 49 6e 20 46 54 53 35 2c 0a 2a  ches. In FTS5,.*
0440: 2a 20 20 20 20 20 74 68 65 79 20 61 72 65 20 6e  *     they are n
0450: 6f 74 20 28 61 73 20 74 68 65 20 22 62 20 41 4e  ot (as the "b AN
0460: 44 20 63 22 20 73 75 62 2d 74 72 65 65 20 64 6f  D c" sub-tree do
0470: 65 73 20 6e 6f 74 20 6d 61 74 63 68 20 74 68 65  es not match the
0480: 20 63 75 72 72 65 6e 74 0a 2a 2a 20 20 20 20 20   current.**     
0490: 72 6f 77 2e 0a 2a 2a 0a 2a 2a 20 20 32 29 20 46  row..**.**  2) F
04a0: 6f 72 20 74 68 65 20 76 61 6c 75 65 73 20 72 65  or the values re
04b0: 74 75 72 6e 65 64 20 62 79 20 27 78 27 20 74 68  turned by 'x' th
04c0: 61 74 20 61 70 70 6c 79 20 74 6f 20 61 6c 6c 20  at apply to all 
04d0: 72 6f 77 73 20 6f 66 20 74 68 65 20 74 61 62 6c  rows of the tabl
04e0: 65 2c 20 0a 2a 2a 20 20 20 20 20 4e 45 41 52 20  e, .**     NEAR 
04f0: 63 6f 6e 73 74 72 61 69 6e 74 73 20 61 72 65 20  constraints are 
0500: 6e 6f 74 20 63 6f 6e 73 69 64 65 72 65 64 2e 20  not considered. 
0510: 42 75 74 20 66 6f 72 20 74 68 65 20 6e 75 6d 62  But for the numb
0520: 65 72 20 6f 66 20 68 69 74 73 20 69 6e 0a 2a 2a  er of hits in.**
0530: 20 20 20 20 20 74 68 65 20 63 75 72 72 65 6e 74       the current
0540: 20 72 6f 77 2c 20 74 68 65 79 20 61 72 65 2e 0a   row, they are..
0550: 2a 2a 20 20 20 20 20 0a 2a 2a 20 54 68 69 73 20  **     .** This 
0560: 66 69 6c 65 20 65 78 70 6f 72 74 73 20 61 20 73  file exports a s
0570: 69 6e 67 6c 65 20 66 75 6e 63 74 69 6f 6e 20 74  ingle function t
0580: 68 61 74 20 6d 61 79 20 62 65 20 63 61 6c 6c 65  hat may be calle
0590: 64 20 74 6f 20 72 65 67 69 73 74 65 72 20 74 68  d to register th
05a0: 65 0a 2a 2a 20 6d 61 74 63 68 69 6e 66 6f 28 29  e.** matchinfo()
05b0: 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20   implementation 
05c0: 77 69 74 68 20 61 20 64 61 74 61 62 61 73 65 20  with a database 
05d0: 68 61 6e 64 6c 65 3a 0a 2a 2a 0a 2a 2a 20 20 20  handle:.**.**   
05e0: 69 6e 74 20 73 71 6c 69 74 65 33 46 74 73 35 54  int sqlite3Fts5T
05f0: 65 73 74 52 65 67 69 73 74 65 72 4d 61 74 63 68  estRegisterMatch
0600: 69 6e 66 6f 28 73 71 6c 69 74 65 33 20 2a 64 62  info(sqlite3 *db
0610: 29 3b 0a 2a 2f 0a 0a 0a 23 69 66 64 65 66 20 53  );.*/...#ifdef S
0620: 51 4c 49 54 45 5f 54 45 53 54 0a 23 69 66 64 65  QLITE_TEST.#ifde
0630: 66 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f  f SQLITE_ENABLE_
0640: 46 54 53 35 0a 0a 23 69 6e 63 6c 75 64 65 20 22  FTS5..#include "
0650: 66 74 73 35 2e 68 22 0a 23 69 6e 63 6c 75 64 65  fts5.h".#include
0660: 20 3c 74 63 6c 2e 68 3e 0a 23 69 6e 63 6c 75 64   <tcl.h>.#includ
0670: 65 20 3c 61 73 73 65 72 74 2e 68 3e 0a 23 69 6e  e <assert.h>.#in
0680: 63 6c 75 64 65 20 3c 73 74 72 69 6e 67 2e 68 3e  clude <string.h>
0690: 0a 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74  ..typedef struct
06a0: 20 46 74 73 35 4d 61 74 63 68 69 6e 66 6f 43 74   Fts5MatchinfoCt
06b0: 78 20 46 74 73 35 4d 61 74 63 68 69 6e 66 6f 43  x Fts5MatchinfoC
06c0: 74 78 3b 0a 74 79 70 65 64 65 66 20 75 6e 73 69  tx;.typedef unsi
06d0: 67 6e 65 64 20 69 6e 74 20 75 33 32 3b 0a 0a 73  gned int u32;..s
06e0: 74 72 75 63 74 20 46 74 73 35 4d 61 74 63 68 69  truct Fts5Matchi
06f0: 6e 66 6f 43 74 78 20 7b 0a 20 20 69 6e 74 20 6e  nfoCtx {.  int n
0700: 43 6f 6c 3b 20 20 20 20 20 20 20 20 20 20 20 20  Col;            
0710: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75             /* Nu
0720: 6d 62 65 72 20 6f 66 20 63 6f 6c 73 20 69 6e 20  mber of cols in 
0730: 46 54 53 35 20 74 61 62 6c 65 20 2a 2f 0a 20 20  FTS5 table */.  
0740: 69 6e 74 20 6e 50 68 72 61 73 65 3b 20 20 20 20  int nPhrase;    
0750: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0760: 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 70 68 72  /* Number of phr
0770: 61 73 65 73 20 69 6e 20 46 54 53 35 20 71 75 65  ases in FTS5 que
0780: 72 79 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 41  ry */.  char *zA
0790: 72 67 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  rg;             
07a0: 20 20 20 20 20 20 20 20 2f 2a 20 6e 75 6c 2d 74          /* nul-t
07b0: 65 72 6d 27 64 20 63 6f 70 79 20 6f 66 20 32 6e  erm'd copy of 2n
07c0: 64 20 61 72 67 20 2a 2f 0a 20 20 69 6e 74 20 6e  d arg */.  int n
07d0: 52 65 74 3b 20 20 20 20 20 20 20 20 20 20 20 20  Ret;            
07e0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75             /* Nu
07f0: 6d 62 65 72 20 6f 66 20 65 6c 65 6d 65 6e 74 73  mber of elements
0800: 20 69 6e 20 61 52 65 74 5b 5d 20 2a 2f 0a 20 20   in aRet[] */.  
0810: 75 33 32 20 2a 61 52 65 74 3b 20 20 20 20 20 20  u32 *aRet;      
0820: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0830: 2f 2a 20 41 72 72 61 79 20 6f 66 20 33 32 2d 62  /* Array of 32-b
0840: 69 74 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 73  it unsigned ints
0850: 20 74 6f 20 72 65 74 75 72 6e 20 2a 2f 0a 7d 3b   to return */.};
0860: 0a 0a 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e  ..../*.** Return
0870: 20 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 74 68   a pointer to th
0880: 65 20 66 74 73 35 5f 61 70 69 20 70 6f 69 6e 74  e fts5_api point
0890: 65 72 20 66 6f 72 20 64 61 74 61 62 61 73 65 20  er for database 
08a0: 63 6f 6e 6e 65 63 74 69 6f 6e 20 64 62 2e 0a 2a  connection db..*
08b0: 2a 20 49 66 20 61 6e 20 65 72 72 6f 72 20 6f 63  * If an error oc
08c0: 63 75 72 73 2c 20 72 65 74 75 72 6e 20 4e 55 4c  curs, return NUL
08d0: 4c 20 61 6e 64 20 6c 65 61 76 65 20 61 6e 20 65  L and leave an e
08e0: 72 72 6f 72 20 69 6e 20 74 68 65 20 64 61 74 61  rror in the data
08f0: 62 61 73 65 20 0a 2a 2a 20 68 61 6e 64 6c 65 20  base .** handle 
0900: 28 61 63 63 65 73 73 69 62 6c 65 20 75 73 69 6e  (accessible usin
0910: 67 20 73 71 6c 69 74 65 33 5f 65 72 72 63 6f 64  g sqlite3_errcod
0920: 65 28 29 2f 65 72 72 6d 73 67 28 29 29 2e 0a 2a  e()/errmsg())..*
0930: 2f 0a 73 74 61 74 69 63 20 66 74 73 35 5f 61 70  /.static fts5_ap
0940: 69 20 2a 66 74 73 35 5f 61 70 69 5f 66 72 6f 6d  i *fts5_api_from
0950: 5f 64 62 28 73 71 6c 69 74 65 33 20 2a 64 62 29  _db(sqlite3 *db)
0960: 7b 0a 20 20 66 74 73 35 5f 61 70 69 20 2a 70 52  {.  fts5_api *pR
0970: 65 74 20 3d 20 30 3b 0a 20 20 73 71 6c 69 74 65  et = 0;.  sqlite
0980: 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74 20 3d 20  3_stmt *pStmt = 
0990: 30 3b 0a 0a 20 20 69 66 28 20 53 51 4c 49 54 45  0;..  if( SQLITE
09a0: 5f 4f 4b 3d 3d 73 71 6c 69 74 65 33 5f 70 72 65  _OK==sqlite3_pre
09b0: 70 61 72 65 28 64 62 2c 20 22 53 45 4c 45 43 54  pare(db, "SELECT
09c0: 20 66 74 73 35 28 29 22 2c 20 2d 31 2c 20 26 70   fts5()", -1, &p
09d0: 53 74 6d 74 2c 20 30 29 0a 20 20 20 26 26 20 53  Stmt, 0).   && S
09e0: 51 4c 49 54 45 5f 52 4f 57 3d 3d 73 71 6c 69 74  QLITE_ROW==sqlit
09f0: 65 33 5f 73 74 65 70 28 70 53 74 6d 74 29 20 0a  e3_step(pStmt) .
0a00: 20 20 20 26 26 20 73 69 7a 65 6f 66 28 70 52 65     && sizeof(pRe
0a10: 74 29 3d 3d 73 71 6c 69 74 65 33 5f 63 6f 6c 75  t)==sqlite3_colu
0a20: 6d 6e 5f 62 79 74 65 73 28 70 53 74 6d 74 2c 20  mn_bytes(pStmt, 
0a30: 30 29 0a 20 20 29 7b 0a 20 20 20 20 6d 65 6d 63  0).  ){.    memc
0a40: 70 79 28 26 70 52 65 74 2c 20 73 71 6c 69 74 65  py(&pRet, sqlite
0a50: 33 5f 63 6f 6c 75 6d 6e 5f 62 6c 6f 62 28 70 53  3_column_blob(pS
0a60: 74 6d 74 2c 20 30 29 2c 20 73 69 7a 65 6f 66 28  tmt, 0), sizeof(
0a70: 70 52 65 74 29 29 3b 0a 20 20 7d 0a 20 20 73 71  pRet));.  }.  sq
0a80: 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70  lite3_finalize(p
0a90: 53 74 6d 74 29 3b 0a 20 20 72 65 74 75 72 6e 20  Stmt);.  return 
0aa0: 70 52 65 74 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20  pRet;.}.../*.** 
0ab0: 41 72 67 75 6d 65 6e 74 20 66 20 73 68 6f 75 6c  Argument f shoul
0ac0: 64 20 62 65 20 61 20 66 6c 61 67 20 61 63 63 65  d be a flag acce
0ad0: 70 74 65 64 20 62 79 20 6d 61 74 63 68 69 6e 66  pted by matchinf
0ae0: 6f 28 29 20 28 61 20 76 61 6c 69 64 20 63 68 61  o() (a valid cha
0af0: 72 61 63 74 65 72 0a 2a 2a 20 69 6e 20 74 68 65  racter.** in the
0b00: 20 73 74 72 69 6e 67 20 70 61 73 73 65 64 20 61   string passed a
0b10: 73 20 74 68 65 20 73 65 63 6f 6e 64 20 61 72 67  s the second arg
0b20: 75 6d 65 6e 74 29 2e 20 49 66 20 69 74 20 69 73  ument). If it is
0b30: 20 6e 6f 74 2c 20 2d 31 20 69 73 20 0a 2a 2a 20   not, -1 is .** 
0b40: 72 65 74 75 72 6e 65 64 2e 20 4f 74 68 65 72 77  returned. Otherw
0b50: 69 73 65 2c 20 69 66 20 66 20 69 73 20 61 20 76  ise, if f is a v
0b60: 61 6c 69 64 20 6d 61 74 63 68 69 6e 66 6f 20 66  alid matchinfo f
0b70: 6c 61 67 2c 20 74 68 65 20 76 61 6c 75 65 20 72  lag, the value r
0b80: 65 74 75 72 6e 65 64 0a 2a 2a 20 69 73 20 74 68  eturned.** is th
0b90: 65 20 6e 75 6d 62 65 72 20 6f 66 20 33 32 2d 62  e number of 32-b
0ba0: 69 74 20 69 6e 74 65 67 65 72 73 20 61 64 64 65  it integers adde
0bb0: 64 20 74 6f 20 74 68 65 20 6f 75 74 70 75 74 20  d to the output 
0bc0: 61 72 72 61 79 20 69 66 20 74 68 65 0a 2a 2a 20  array if the.** 
0bd0: 74 61 62 6c 65 20 68 61 73 20 6e 43 6f 6c 20 63  table has nCol c
0be0: 6f 6c 75 6d 6e 73 20 61 6e 64 20 74 68 65 20 71  olumns and the q
0bf0: 75 65 72 79 20 6e 50 68 72 61 73 65 20 70 68 72  uery nPhrase phr
0c00: 61 73 65 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ases..*/.static 
0c10: 69 6e 74 20 66 74 73 35 4d 61 74 63 68 69 6e 66  int fts5Matchinf
0c20: 6f 46 6c 61 67 73 69 7a 65 28 69 6e 74 20 6e 43  oFlagsize(int nC
0c30: 6f 6c 2c 20 69 6e 74 20 6e 50 68 72 61 73 65 2c  ol, int nPhrase,
0c40: 20 63 68 61 72 20 66 29 7b 0a 20 20 69 6e 74 20   char f){.  int 
0c50: 72 65 74 20 3d 20 2d 31 3b 0a 20 20 73 77 69 74  ret = -1;.  swit
0c60: 63 68 28 20 66 20 29 7b 0a 20 20 20 20 63 61 73  ch( f ){.    cas
0c70: 65 20 27 70 27 3a 20 72 65 74 20 3d 20 31 3b 20  e 'p': ret = 1; 
0c80: 62 72 65 61 6b 3b 0a 20 20 20 20 63 61 73 65 20  break;.    case 
0c90: 27 63 27 3a 20 72 65 74 20 3d 20 31 3b 20 62 72  'c': ret = 1; br
0ca0: 65 61 6b 3b 0a 20 20 20 20 63 61 73 65 20 27 78  eak;.    case 'x
0cb0: 27 3a 20 72 65 74 20 3d 20 33 20 2a 20 6e 43 6f  ': ret = 3 * nCo
0cc0: 6c 20 2a 20 6e 50 68 72 61 73 65 3b 20 62 72 65  l * nPhrase; bre
0cd0: 61 6b 3b 0a 20 20 20 20 63 61 73 65 20 27 79 27  ak;.    case 'y'
0ce0: 3a 20 72 65 74 20 3d 20 6e 43 6f 6c 20 2a 20 6e  : ret = nCol * n
0cf0: 50 68 72 61 73 65 3b 20 62 72 65 61 6b 3b 0a 20  Phrase; break;. 
0d00: 20 20 20 63 61 73 65 20 27 62 27 3a 20 72 65 74     case 'b': ret
0d10: 20 3d 20 28 28 6e 43 6f 6c 20 2b 20 33 31 29 20   = ((nCol + 31) 
0d20: 2f 20 33 32 29 20 2a 20 6e 50 68 72 61 73 65 3b  / 32) * nPhrase;
0d30: 20 62 72 65 61 6b 3b 0a 20 20 20 20 63 61 73 65   break;.    case
0d40: 20 27 6e 27 3a 20 72 65 74 20 3d 20 31 3b 20 62   'n': ret = 1; b
0d50: 72 65 61 6b 3b 0a 20 20 20 20 63 61 73 65 20 27  reak;.    case '
0d60: 61 27 3a 20 72 65 74 20 3d 20 6e 43 6f 6c 3b 20  a': ret = nCol; 
0d70: 62 72 65 61 6b 3b 0a 20 20 20 20 63 61 73 65 20  break;.    case 
0d80: 27 6c 27 3a 20 72 65 74 20 3d 20 6e 43 6f 6c 3b  'l': ret = nCol;
0d90: 20 62 72 65 61 6b 3b 0a 20 20 20 20 63 61 73 65   break;.    case
0da0: 20 27 73 27 3a 20 72 65 74 20 3d 20 6e 43 6f 6c   's': ret = nCol
0db0: 3b 20 62 72 65 61 6b 3b 0a 20 20 7d 0a 20 20 72  ; break;.  }.  r
0dc0: 65 74 75 72 6e 20 72 65 74 3b 0a 7d 0a 0a 73 74  eturn ret;.}..st
0dd0: 61 74 69 63 20 69 6e 74 20 66 74 73 35 4d 61 74  atic int fts5Mat
0de0: 63 68 69 6e 66 6f 49 74 65 72 28 0a 20 20 63 6f  chinfoIter(.  co
0df0: 6e 73 74 20 46 74 73 35 45 78 74 65 6e 73 69 6f  nst Fts5Extensio
0e00: 6e 41 70 69 20 2a 70 41 70 69 2c 20 20 20 2f 2a  nApi *pApi,   /*
0e10: 20 41 50 49 20 6f 66 66 65 72 65 64 20 62 79 20   API offered by 
0e20: 63 75 72 72 65 6e 74 20 46 54 53 20 76 65 72 73  current FTS vers
0e30: 69 6f 6e 20 2a 2f 0a 20 20 46 74 73 35 43 6f 6e  ion */.  Fts5Con
0e40: 74 65 78 74 20 2a 70 46 74 73 2c 20 20 20 20 20  text *pFts,     
0e50: 20 20 20 20 20 20 20 20 20 2f 2a 20 46 69 72 73           /* Firs
0e60: 74 20 61 72 67 20 74 6f 20 70 61 73 73 20 74 6f  t arg to pass to
0e70: 20 70 41 70 69 20 66 75 6e 63 74 69 6f 6e 73 20   pApi functions 
0e80: 2a 2f 0a 20 20 46 74 73 35 4d 61 74 63 68 69 6e  */.  Fts5Matchin
0e90: 66 6f 43 74 78 20 2a 70 2c 0a 20 20 69 6e 74 28  foCtx *p,.  int(
0ea0: 2a 78 29 28 63 6f 6e 73 74 20 46 74 73 35 45 78  *x)(const Fts5Ex
0eb0: 74 65 6e 73 69 6f 6e 41 70 69 2a 2c 46 74 73 35  tensionApi*,Fts5
0ec0: 43 6f 6e 74 65 78 74 2a 2c 46 74 73 35 4d 61 74  Context*,Fts5Mat
0ed0: 63 68 69 6e 66 6f 43 74 78 2a 2c 63 68 61 72 2c  chinfoCtx*,char,
0ee0: 75 33 32 2a 29 0a 29 7b 0a 20 20 69 6e 74 20 69  u32*).){.  int i
0ef0: 3b 0a 20 20 69 6e 74 20 6e 20 3d 20 30 3b 0a 20  ;.  int n = 0;. 
0f00: 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
0f10: 5f 4f 4b 3b 0a 20 20 63 68 61 72 20 66 3b 0a 20  _OK;.  char f;. 
0f20: 20 66 6f 72 28 69 3d 30 3b 20 28 66 20 3d 20 70   for(i=0; (f = p
0f30: 2d 3e 7a 41 72 67 5b 69 5d 29 3b 20 69 2b 2b 29  ->zArg[i]); i++)
0f40: 7b 0a 20 20 20 20 72 63 20 3d 20 78 28 70 41 70  {.    rc = x(pAp
0f50: 69 2c 20 70 46 74 73 2c 20 70 2c 20 66 2c 20 26  i, pFts, p, f, &
0f60: 70 2d 3e 61 52 65 74 5b 6e 5d 29 3b 0a 20 20 20  p->aRet[n]);.   
0f70: 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
0f80: 4f 4b 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20  OK ) break;.    
0f90: 6e 20 2b 3d 20 66 74 73 35 4d 61 74 63 68 69 6e  n += fts5Matchin
0fa0: 66 6f 46 6c 61 67 73 69 7a 65 28 70 2d 3e 6e 43  foFlagsize(p->nC
0fb0: 6f 6c 2c 20 70 2d 3e 6e 50 68 72 61 73 65 2c 20  ol, p->nPhrase, 
0fc0: 66 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  f);.  }.  return
0fd0: 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69   rc;.}..static i
0fe0: 6e 74 20 66 74 73 35 4d 61 74 63 68 69 6e 66 6f  nt fts5Matchinfo
0ff0: 58 43 62 28 0a 20 20 63 6f 6e 73 74 20 46 74 73  XCb(.  const Fts
1000: 35 45 78 74 65 6e 73 69 6f 6e 41 70 69 20 2a 70  5ExtensionApi *p
1010: 41 70 69 2c 0a 20 20 46 74 73 35 43 6f 6e 74 65  Api,.  Fts5Conte
1020: 78 74 20 2a 70 46 74 73 2c 0a 20 20 76 6f 69 64  xt *pFts,.  void
1030: 20 2a 70 55 73 65 72 44 61 74 61 0a 29 7b 0a 20   *pUserData.){. 
1040: 20 46 74 73 35 50 68 72 61 73 65 49 74 65 72 20   Fts5PhraseIter 
1050: 69 74 65 72 3b 0a 20 20 69 6e 74 20 69 43 6f 6c  iter;.  int iCol
1060: 2c 20 69 4f 66 66 3b 0a 20 20 75 33 32 20 2a 61  , iOff;.  u32 *a
1070: 4f 75 74 20 3d 20 28 75 33 32 2a 29 70 55 73 65  Out = (u32*)pUse
1080: 72 44 61 74 61 3b 0a 20 20 69 6e 74 20 69 50 72  rData;.  int iPr
1090: 65 76 20 3d 20 2d 31 3b 0a 0a 20 20 66 6f 72 28  ev = -1;..  for(
10a0: 70 41 70 69 2d 3e 78 50 68 72 61 73 65 46 69 72  pApi->xPhraseFir
10b0: 73 74 28 70 46 74 73 2c 20 30 2c 20 26 69 74 65  st(pFts, 0, &ite
10c0: 72 2c 20 26 69 43 6f 6c 2c 20 26 69 4f 66 66 29  r, &iCol, &iOff)
10d0: 3b 20 0a 20 20 20 20 20 20 69 4f 66 66 3e 3d 30  ; .      iOff>=0
10e0: 3b 20 0a 20 20 20 20 20 20 70 41 70 69 2d 3e 78  ; .      pApi->x
10f0: 50 68 72 61 73 65 4e 65 78 74 28 70 46 74 73 2c  PhraseNext(pFts,
1100: 20 26 69 74 65 72 2c 20 26 69 43 6f 6c 2c 20 26   &iter, &iCol, &
1110: 69 4f 66 66 29 0a 20 20 29 7b 0a 20 20 20 20 61  iOff).  ){.    a
1120: 4f 75 74 5b 69 43 6f 6c 2a 33 2b 31 5d 2b 2b 3b  Out[iCol*3+1]++;
1130: 0a 20 20 20 20 69 66 28 20 69 43 6f 6c 21 3d 69  .    if( iCol!=i
1140: 50 72 65 76 20 29 20 61 4f 75 74 5b 69 43 6f 6c  Prev ) aOut[iCol
1150: 2a 33 20 2b 20 32 5d 2b 2b 3b 0a 20 20 20 20 69  *3 + 2]++;.    i
1160: 50 72 65 76 20 3d 20 69 43 6f 6c 3b 0a 20 20 7d  Prev = iCol;.  }
1170: 0a 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54  ..  return SQLIT
1180: 45 5f 4f 4b 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  E_OK;.}..static 
1190: 69 6e 74 20 66 74 73 35 4d 61 74 63 68 69 6e 66  int fts5Matchinf
11a0: 6f 47 6c 6f 62 61 6c 43 62 28 0a 20 20 63 6f 6e  oGlobalCb(.  con
11b0: 73 74 20 46 74 73 35 45 78 74 65 6e 73 69 6f 6e  st Fts5Extension
11c0: 41 70 69 20 2a 70 41 70 69 2c 0a 20 20 46 74 73  Api *pApi,.  Fts
11d0: 35 43 6f 6e 74 65 78 74 20 2a 70 46 74 73 2c 0a  5Context *pFts,.
11e0: 20 20 46 74 73 35 4d 61 74 63 68 69 6e 66 6f 43    Fts5MatchinfoC
11f0: 74 78 20 2a 70 2c 0a 20 20 63 68 61 72 20 66 2c  tx *p,.  char f,
1200: 0a 20 20 75 33 32 20 2a 61 4f 75 74 0a 29 7b 0a  .  u32 *aOut.){.
1210: 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
1220: 45 5f 4f 4b 3b 0a 20 20 73 77 69 74 63 68 28 20  E_OK;.  switch( 
1230: 66 20 29 7b 0a 20 20 20 20 63 61 73 65 20 27 70  f ){.    case 'p
1240: 27 3a 0a 20 20 20 20 20 20 61 4f 75 74 5b 30 5d  ':.      aOut[0]
1250: 20 3d 20 70 2d 3e 6e 50 68 72 61 73 65 3b 20 0a   = p->nPhrase; .
1260: 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 0a 20 20        break;..  
1270: 20 20 63 61 73 65 20 27 63 27 3a 0a 20 20 20 20    case 'c':.    
1280: 20 20 61 4f 75 74 5b 30 5d 20 3d 20 70 2d 3e 6e    aOut[0] = p->n
1290: 43 6f 6c 3b 20 0a 20 20 20 20 20 20 62 72 65 61  Col; .      brea
12a0: 6b 3b 0a 0a 20 20 20 20 63 61 73 65 20 27 78 27  k;..    case 'x'
12b0: 3a 20 7b 0a 20 20 20 20 20 20 69 6e 74 20 69 3b  : {.      int i;
12c0: 0a 20 20 20 20 20 20 66 6f 72 28 69 3d 30 3b 20  .      for(i=0; 
12d0: 69 3c 70 2d 3e 6e 50 68 72 61 73 65 20 26 26 20  i<p->nPhrase && 
12e0: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 3b 20 69  rc==SQLITE_OK; i
12f0: 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 76 6f 69  ++){.        voi
1300: 64 20 2a 70 50 74 72 20 3d 20 28 76 6f 69 64 2a  d *pPtr = (void*
1310: 29 26 61 4f 75 74 5b 69 20 2a 20 70 2d 3e 6e 43  )&aOut[i * p->nC
1320: 6f 6c 20 2a 20 33 5d 3b 0a 20 20 20 20 20 20 20  ol * 3];.       
1330: 20 72 63 20 3d 20 70 41 70 69 2d 3e 78 51 75 65   rc = pApi->xQue
1340: 72 79 50 68 72 61 73 65 28 70 46 74 73 2c 20 69  ryPhrase(pFts, i
1350: 2c 20 70 50 74 72 2c 20 66 74 73 35 4d 61 74 63  , pPtr, fts5Matc
1360: 68 69 6e 66 6f 58 43 62 29 3b 0a 20 20 20 20 20  hinfoXCb);.     
1370: 20 7d 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a   }.      break;.
1380: 20 20 20 20 7d 0a 0a 20 20 20 20 63 61 73 65 20      }..    case 
1390: 27 6e 27 3a 20 7b 0a 20 20 20 20 20 20 73 71 6c  'n': {.      sql
13a0: 69 74 65 33 5f 69 6e 74 36 34 20 6e 52 6f 77 3b  ite3_int64 nRow;
13b0: 0a 20 20 20 20 20 20 72 63 20 3d 20 70 41 70 69  .      rc = pApi
13c0: 2d 3e 78 52 6f 77 43 6f 75 6e 74 28 70 46 74 73  ->xRowCount(pFts
13d0: 2c 20 26 6e 52 6f 77 29 3b 0a 20 20 20 20 20 20  , &nRow);.      
13e0: 61 4f 75 74 5b 30 5d 20 3d 20 28 75 33 32 29 6e  aOut[0] = (u32)n
13f0: 52 6f 77 3b 0a 20 20 20 20 20 20 62 72 65 61 6b  Row;.      break
1400: 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 63 61 73  ;.    }..    cas
1410: 65 20 27 61 27 3a 20 7b 0a 20 20 20 20 20 20 73  e 'a': {.      s
1420: 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 6e 52 6f  qlite3_int64 nRo
1430: 77 20 3d 20 30 3b 0a 20 20 20 20 20 20 72 63 20  w = 0;.      rc 
1440: 3d 20 70 41 70 69 2d 3e 78 52 6f 77 43 6f 75 6e  = pApi->xRowCoun
1450: 74 28 70 46 74 73 2c 20 26 6e 52 6f 77 29 3b 0a  t(pFts, &nRow);.
1460: 20 20 20 20 20 20 69 66 28 20 6e 52 6f 77 3d 3d        if( nRow==
1470: 30 20 29 7b 0a 20 20 20 20 20 20 20 20 6d 65 6d  0 ){.        mem
1480: 73 65 74 28 61 4f 75 74 2c 20 30 2c 20 73 69 7a  set(aOut, 0, siz
1490: 65 6f 66 28 75 33 32 29 20 2a 20 70 2d 3e 6e 43  eof(u32) * p->nC
14a0: 6f 6c 29 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65  ol);.      }else
14b0: 7b 0a 20 20 20 20 20 20 20 20 69 6e 74 20 69 3b  {.        int i;
14c0: 0a 20 20 20 20 20 20 20 20 66 6f 72 28 69 3d 30  .        for(i=0
14d0: 3b 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ; rc==SQLITE_OK 
14e0: 26 26 20 69 3c 70 2d 3e 6e 43 6f 6c 3b 20 69 2b  && i<p->nCol; i+
14f0: 2b 29 7b 0a 20 20 20 20 20 20 20 20 20 20 73 71  +){.          sq
1500: 6c 69 74 65 33 5f 69 6e 74 36 34 20 6e 54 6f 6b  lite3_int64 nTok
1510: 65 6e 3b 0a 20 20 20 20 20 20 20 20 20 20 72 63  en;.          rc
1520: 20 3d 20 70 41 70 69 2d 3e 78 43 6f 6c 75 6d 6e   = pApi->xColumn
1530: 54 6f 74 61 6c 53 69 7a 65 28 70 46 74 73 2c 20  TotalSize(pFts, 
1540: 69 2c 20 26 6e 54 6f 6b 65 6e 29 3b 0a 20 20 20  i, &nToken);.   
1550: 20 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53         if( rc==S
1560: 51 4c 49 54 45 5f 4f 4b 29 7b 0a 20 20 20 20 20  QLITE_OK){.     
1570: 20 20 20 20 20 20 20 61 4f 75 74 5b 69 5d 20 3d         aOut[i] =
1580: 20 28 75 33 32 29 28 28 32 2a 6e 54 6f 6b 65 6e   (u32)((2*nToken
1590: 20 2b 20 6e 52 6f 77 29 20 2f 20 28 32 2a 6e 52   + nRow) / (2*nR
15a0: 6f 77 29 29 3b 0a 20 20 20 20 20 20 20 20 20 20  ow));.          
15b0: 7d 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  }.        }.    
15c0: 20 20 7d 0a 20 20 20 20 20 20 62 72 65 61 6b 3b    }.      break;
15d0: 0a 20 20 20 20 7d 0a 0a 20 20 7d 0a 20 20 72 65  .    }..  }.  re
15e0: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74  turn rc;.}..stat
15f0: 69 63 20 69 6e 74 20 66 74 73 35 4d 61 74 63 68  ic int fts5Match
1600: 69 6e 66 6f 4c 6f 63 61 6c 43 62 28 0a 20 20 63  infoLocalCb(.  c
1610: 6f 6e 73 74 20 46 74 73 35 45 78 74 65 6e 73 69  onst Fts5Extensi
1620: 6f 6e 41 70 69 20 2a 70 41 70 69 2c 0a 20 20 46  onApi *pApi,.  F
1630: 74 73 35 43 6f 6e 74 65 78 74 20 2a 70 46 74 73  ts5Context *pFts
1640: 2c 0a 20 20 46 74 73 35 4d 61 74 63 68 69 6e 66  ,.  Fts5Matchinf
1650: 6f 43 74 78 20 2a 70 2c 0a 20 20 63 68 61 72 20  oCtx *p,.  char 
1660: 66 2c 0a 20 20 75 33 32 20 2a 61 4f 75 74 0a 29  f,.  u32 *aOut.)
1670: 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 69 6e 74  {.  int i;.  int
1680: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
1690: 0a 0a 20 20 73 77 69 74 63 68 28 20 66 20 29 7b  ..  switch( f ){
16a0: 0a 20 20 20 20 63 61 73 65 20 27 62 27 3a 20 0a  .    case 'b': .
16b0: 20 20 20 20 63 61 73 65 20 27 78 27 3a 0a 20 20      case 'x':.  
16c0: 20 20 63 61 73 65 20 27 79 27 3a 20 7b 0a 20 20    case 'y': {.  
16d0: 20 20 20 20 69 6e 74 20 6e 4d 75 6c 20 3d 20 28      int nMul = (
16e0: 66 3d 3d 27 78 27 20 3f 20 33 20 3a 20 31 29 3b  f=='x' ? 3 : 1);
16f0: 0a 20 20 20 20 20 20 69 6e 74 20 69 50 68 72 61  .      int iPhra
1700: 73 65 3b 0a 0a 20 20 20 20 20 20 69 66 28 20 66  se;..      if( f
1710: 3d 3d 27 62 27 20 29 7b 0a 20 20 20 20 20 20 20  =='b' ){.       
1720: 20 69 6e 74 20 6e 49 6e 74 20 3d 20 28 28 70 2d   int nInt = ((p-
1730: 3e 6e 43 6f 6c 20 2b 20 33 31 29 20 2f 20 33 32  >nCol + 31) / 32
1740: 29 20 2a 20 70 2d 3e 6e 50 68 72 61 73 65 3b 0a  ) * p->nPhrase;.
1750: 20 20 20 20 20 20 20 20 66 6f 72 28 69 3d 30 3b          for(i=0;
1760: 20 69 3c 6e 49 6e 74 3b 20 69 2b 2b 29 20 61 4f   i<nInt; i++) aO
1770: 75 74 5b 69 5d 20 3d 20 30 3b 0a 20 20 20 20 20  ut[i] = 0;.     
1780: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20   }else{.        
1790: 66 6f 72 28 69 3d 30 3b 20 69 3c 28 70 2d 3e 6e  for(i=0; i<(p->n
17a0: 43 6f 6c 2a 70 2d 3e 6e 50 68 72 61 73 65 29 3b  Col*p->nPhrase);
17b0: 20 69 2b 2b 29 20 61 4f 75 74 5b 69 2a 6e 4d 75   i++) aOut[i*nMu
17c0: 6c 5d 20 3d 20 30 3b 0a 20 20 20 20 20 20 7d 0a  l] = 0;.      }.
17d0: 0a 20 20 20 20 20 20 66 6f 72 28 69 50 68 72 61  .      for(iPhra
17e0: 73 65 3d 30 3b 20 69 50 68 72 61 73 65 3c 70 2d  se=0; iPhrase<p-
17f0: 3e 6e 50 68 72 61 73 65 3b 20 69 50 68 72 61 73  >nPhrase; iPhras
1800: 65 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 46 74  e++){.        Ft
1810: 73 35 50 68 72 61 73 65 49 74 65 72 20 69 74 65  s5PhraseIter ite
1820: 72 3b 0a 20 20 20 20 20 20 20 20 69 6e 74 20 69  r;.        int i
1830: 4f 66 66 2c 20 69 43 6f 6c 3b 0a 20 20 20 20 20  Off, iCol;.     
1840: 20 20 20 66 6f 72 28 70 41 70 69 2d 3e 78 50 68     for(pApi->xPh
1850: 72 61 73 65 46 69 72 73 74 28 70 46 74 73 2c 20  raseFirst(pFts, 
1860: 69 50 68 72 61 73 65 2c 20 26 69 74 65 72 2c 20  iPhrase, &iter, 
1870: 26 69 43 6f 6c 2c 20 26 69 4f 66 66 29 3b 20 0a  &iCol, &iOff); .
1880: 20 20 20 20 20 20 20 20 20 20 20 20 69 4f 66 66              iOff
1890: 3e 3d 30 3b 20 0a 20 20 20 20 20 20 20 20 20 20  >=0; .          
18a0: 20 20 70 41 70 69 2d 3e 78 50 68 72 61 73 65 4e    pApi->xPhraseN
18b0: 65 78 74 28 70 46 74 73 2c 20 26 69 74 65 72 2c  ext(pFts, &iter,
18c0: 20 26 69 43 6f 6c 2c 20 26 69 4f 66 66 29 0a 20   &iCol, &iOff). 
18d0: 20 20 20 20 20 20 20 29 7b 0a 20 20 20 20 20 20         ){.      
18e0: 20 20 20 20 69 66 28 20 66 3d 3d 27 62 27 20 29      if( f=='b' )
18f0: 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 61 4f  {.            aO
1900: 75 74 5b 69 50 68 72 61 73 65 20 2a 20 28 28 70  ut[iPhrase * ((p
1910: 2d 3e 6e 43 6f 6c 2b 33 31 29 2f 33 32 29 20 2b  ->nCol+31)/32) +
1920: 20 69 43 6f 6c 2f 33 32 5d 20 7c 3d 20 28 28 75   iCol/32] |= ((u
1930: 33 32 29 31 20 3c 3c 20 69 43 6f 6c 25 33 32 29  32)1 << iCol%32)
1940: 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 65 6c 73  ;.          }els
1950: 65 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 61  e{.            a
1960: 4f 75 74 5b 6e 4d 75 6c 20 2a 20 28 69 43 6f 6c  Out[nMul * (iCol
1970: 20 2b 20 69 50 68 72 61 73 65 20 2a 20 70 2d 3e   + iPhrase * p->
1980: 6e 43 6f 6c 29 5d 2b 2b 3b 0a 20 20 20 20 20 20  nCol)]++;.      
1990: 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 7d 0a      }.        }.
19a0: 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 62        }..      b
19b0: 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20 20  reak;.    }..   
19c0: 20 63 61 73 65 20 27 6c 27 3a 20 7b 0a 20 20 20   case 'l': {.   
19d0: 20 20 20 66 6f 72 28 69 3d 30 3b 20 72 63 3d 3d     for(i=0; rc==
19e0: 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 69 3c 70  SQLITE_OK && i<p
19f0: 2d 3e 6e 43 6f 6c 3b 20 69 2b 2b 29 7b 0a 20 20  ->nCol; i++){.  
1a00: 20 20 20 20 20 20 69 6e 74 20 6e 54 6f 6b 65 6e        int nToken
1a10: 3b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 70  ;.        rc = p
1a20: 41 70 69 2d 3e 78 43 6f 6c 75 6d 6e 53 69 7a 65  Api->xColumnSize
1a30: 28 70 46 74 73 2c 20 69 2c 20 26 6e 54 6f 6b 65  (pFts, i, &nToke
1a40: 6e 29 3b 0a 20 20 20 20 20 20 20 20 61 4f 75 74  n);.        aOut
1a50: 5b 69 5d 20 3d 20 28 75 33 32 29 6e 54 6f 6b 65  [i] = (u32)nToke
1a60: 6e 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  n;.      }.     
1a70: 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20   break;.    }.. 
1a80: 20 20 20 63 61 73 65 20 27 73 27 3a 20 7b 0a 20     case 's': {. 
1a90: 20 20 20 20 20 69 6e 74 20 6e 49 6e 73 74 3b 0a       int nInst;.
1aa0: 0a 20 20 20 20 20 20 6d 65 6d 73 65 74 28 61 4f  .      memset(aO
1ab0: 75 74 2c 20 30 2c 20 73 69 7a 65 6f 66 28 75 33  ut, 0, sizeof(u3
1ac0: 32 29 20 2a 20 70 2d 3e 6e 43 6f 6c 29 3b 0a 0a  2) * p->nCol);..
1ad0: 20 20 20 20 20 20 72 63 20 3d 20 70 41 70 69 2d        rc = pApi-
1ae0: 3e 78 49 6e 73 74 43 6f 75 6e 74 28 70 46 74 73  >xInstCount(pFts
1af0: 2c 20 26 6e 49 6e 73 74 29 3b 0a 20 20 20 20 20  , &nInst);.     
1b00: 20 66 6f 72 28 69 3d 30 3b 20 72 63 3d 3d 53 51   for(i=0; rc==SQ
1b10: 4c 49 54 45 5f 4f 4b 20 26 26 20 69 3c 6e 49 6e  LITE_OK && i<nIn
1b20: 73 74 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20  st; i++){.      
1b30: 20 20 69 6e 74 20 69 50 68 72 61 73 65 2c 20 69    int iPhrase, i
1b40: 4f 66 66 2c 20 69 43 6f 6c 20 3d 20 30 3b 0a 20  Off, iCol = 0;. 
1b50: 20 20 20 20 20 20 20 69 6e 74 20 69 4e 65 78 74         int iNext
1b60: 50 68 72 61 73 65 3b 0a 20 20 20 20 20 20 20 20  Phrase;.        
1b70: 69 6e 74 20 69 4e 65 78 74 4f 66 66 3b 0a 20 20  int iNextOff;.  
1b80: 20 20 20 20 20 20 75 33 32 20 6e 53 65 71 20 3d        u32 nSeq =
1b90: 20 31 3b 0a 20 20 20 20 20 20 20 20 69 6e 74 20   1;.        int 
1ba0: 6a 3b 0a 0a 20 20 20 20 20 20 20 20 72 63 20 3d  j;..        rc =
1bb0: 20 70 41 70 69 2d 3e 78 49 6e 73 74 28 70 46 74   pApi->xInst(pFt
1bc0: 73 2c 20 69 2c 20 26 69 50 68 72 61 73 65 2c 20  s, i, &iPhrase, 
1bd0: 26 69 43 6f 6c 2c 20 26 69 4f 66 66 29 3b 0a 20  &iCol, &iOff);. 
1be0: 20 20 20 20 20 20 20 69 4e 65 78 74 50 68 72 61         iNextPhra
1bf0: 73 65 20 3d 20 69 50 68 72 61 73 65 2b 31 3b 0a  se = iPhrase+1;.
1c00: 20 20 20 20 20 20 20 20 69 4e 65 78 74 4f 66 66          iNextOff
1c10: 20 3d 20 69 4f 66 66 2b 70 41 70 69 2d 3e 78 50   = iOff+pApi->xP
1c20: 68 72 61 73 65 53 69 7a 65 28 70 46 74 73 2c 20  hraseSize(pFts, 
1c30: 30 29 3b 0a 20 20 20 20 20 20 20 20 66 6f 72 28  0);.        for(
1c40: 6a 3d 69 2b 31 3b 20 72 63 3d 3d 53 51 4c 49 54  j=i+1; rc==SQLIT
1c50: 45 5f 4f 4b 20 26 26 20 6a 3c 6e 49 6e 73 74 3b  E_OK && j<nInst;
1c60: 20 6a 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 20   j++){.         
1c70: 20 69 6e 74 20 69 70 2c 20 69 63 2c 20 69 6f 3b   int ip, ic, io;
1c80: 0a 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20  .          rc = 
1c90: 70 41 70 69 2d 3e 78 49 6e 73 74 28 70 46 74 73  pApi->xInst(pFts
1ca0: 2c 20 6a 2c 20 26 69 70 2c 20 26 69 63 2c 20 26  , j, &ip, &ic, &
1cb0: 69 6f 29 3b 0a 20 20 20 20 20 20 20 20 20 20 69  io);.          i
1cc0: 66 28 20 69 63 21 3d 69 43 6f 6c 20 7c 7c 20 69  f( ic!=iCol || i
1cd0: 6f 3e 69 4e 65 78 74 4f 66 66 20 29 20 62 72 65  o>iNextOff ) bre
1ce0: 61 6b 3b 0a 20 20 20 20 20 20 20 20 20 20 69 66  ak;.          if
1cf0: 28 20 69 70 3d 3d 69 4e 65 78 74 50 68 72 61 73  ( ip==iNextPhras
1d00: 65 20 26 26 20 69 6f 3d 3d 69 4e 65 78 74 4f 66  e && io==iNextOf
1d10: 66 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20  f ){.           
1d20: 20 6e 53 65 71 2b 2b 3b 0a 20 20 20 20 20 20 20   nSeq++;.       
1d30: 20 20 20 20 20 69 4e 65 78 74 50 68 72 61 73 65       iNextPhrase
1d40: 20 3d 20 69 70 2b 31 3b 0a 20 20 20 20 20 20 20   = ip+1;.       
1d50: 20 20 20 20 20 69 4e 65 78 74 4f 66 66 20 3d 20       iNextOff = 
1d60: 69 6f 20 2b 20 70 41 70 69 2d 3e 78 50 68 72 61  io + pApi->xPhra
1d70: 73 65 53 69 7a 65 28 70 46 74 73 2c 20 69 70 29  seSize(pFts, ip)
1d80: 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20  ;.          }.  
1d90: 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 20        }..       
1da0: 20 69 66 28 20 6e 53 65 71 3e 61 4f 75 74 5b 69   if( nSeq>aOut[i
1db0: 43 6f 6c 5d 20 29 20 61 4f 75 74 5b 69 43 6f 6c  Col] ) aOut[iCol
1dc0: 5d 20 3d 20 6e 53 65 71 3b 0a 20 20 20 20 20 20  ] = nSeq;.      
1dd0: 7d 0a 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a  }..      break;.
1de0: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75      }.  }.  retu
1df0: 72 6e 20 72 63 3b 0a 7d 0a 20 0a 73 74 61 74 69  rn rc;.}. .stati
1e00: 63 20 46 74 73 35 4d 61 74 63 68 69 6e 66 6f 43  c Fts5MatchinfoC
1e10: 74 78 20 2a 66 74 73 35 4d 61 74 63 68 69 6e 66  tx *fts5Matchinf
1e20: 6f 4e 65 77 28 0a 20 20 63 6f 6e 73 74 20 46 74  oNew(.  const Ft
1e30: 73 35 45 78 74 65 6e 73 69 6f 6e 41 70 69 20 2a  s5ExtensionApi *
1e40: 70 41 70 69 2c 20 20 20 2f 2a 20 41 50 49 20 6f  pApi,   /* API o
1e50: 66 66 65 72 65 64 20 62 79 20 63 75 72 72 65 6e  ffered by curren
1e60: 74 20 46 54 53 20 76 65 72 73 69 6f 6e 20 2a 2f  t FTS version */
1e70: 0a 20 20 46 74 73 35 43 6f 6e 74 65 78 74 20 2a  .  Fts5Context *
1e80: 70 46 74 73 2c 20 20 20 20 20 20 20 20 20 20 20  pFts,           
1e90: 20 20 20 2f 2a 20 46 69 72 73 74 20 61 72 67 20     /* First arg 
1ea0: 74 6f 20 70 61 73 73 20 74 6f 20 70 41 70 69 20  to pass to pApi 
1eb0: 66 75 6e 63 74 69 6f 6e 73 20 2a 2f 0a 20 20 73  functions */.  s
1ec0: 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74 20 2a  qlite3_context *
1ed0: 70 43 74 78 2c 20 20 20 20 20 20 20 20 20 20 2f  pCtx,          /
1ee0: 2a 20 43 6f 6e 74 65 78 74 20 66 6f 72 20 72 65  * Context for re
1ef0: 74 75 72 6e 69 6e 67 20 65 72 72 6f 72 20 6d 65  turning error me
1f00: 73 73 61 67 65 20 2a 2f 0a 20 20 63 6f 6e 73 74  ssage */.  const
1f10: 20 63 68 61 72 20 2a 7a 41 72 67 20 20 20 20 20   char *zArg     
1f20: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 61             /* Ma
1f30: 74 63 68 69 6e 66 6f 20 66 6c 61 67 20 73 74 72  tchinfo flag str
1f40: 69 6e 67 20 2a 2f 0a 29 7b 0a 20 20 46 74 73 35  ing */.){.  Fts5
1f50: 4d 61 74 63 68 69 6e 66 6f 43 74 78 20 2a 70 3b  MatchinfoCtx *p;
1f60: 0a 20 20 69 6e 74 20 6e 43 6f 6c 3b 0a 20 20 69  .  int nCol;.  i
1f70: 6e 74 20 6e 50 68 72 61 73 65 3b 0a 20 20 69 6e  nt nPhrase;.  in
1f80: 74 20 69 3b 0a 20 20 69 6e 74 20 6e 49 6e 74 3b  t i;.  int nInt;
1f90: 0a 20 20 69 6e 74 20 6e 42 79 74 65 3b 0a 20 20  .  int nByte;.  
1fa0: 69 6e 74 20 72 63 3b 0a 0a 20 20 6e 43 6f 6c 20  int rc;..  nCol 
1fb0: 3d 20 70 41 70 69 2d 3e 78 43 6f 6c 75 6d 6e 43  = pApi->xColumnC
1fc0: 6f 75 6e 74 28 70 46 74 73 29 3b 0a 20 20 6e 50  ount(pFts);.  nP
1fd0: 68 72 61 73 65 20 3d 20 70 41 70 69 2d 3e 78 50  hrase = pApi->xP
1fe0: 68 72 61 73 65 43 6f 75 6e 74 28 70 46 74 73 29  hraseCount(pFts)
1ff0: 3b 0a 0a 20 20 6e 49 6e 74 20 3d 20 30 3b 0a 20  ;..  nInt = 0;. 
2000: 20 66 6f 72 28 69 3d 30 3b 20 7a 41 72 67 5b 69   for(i=0; zArg[i
2010: 5d 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 6e 74  ]; i++){.    int
2020: 20 6e 20 3d 20 66 74 73 35 4d 61 74 63 68 69 6e   n = fts5Matchin
2030: 66 6f 46 6c 61 67 73 69 7a 65 28 6e 43 6f 6c 2c  foFlagsize(nCol,
2040: 20 6e 50 68 72 61 73 65 2c 20 7a 41 72 67 5b 69   nPhrase, zArg[i
2050: 5d 29 3b 0a 20 20 20 20 69 66 28 20 6e 3c 30 20  ]);.    if( n<0 
2060: 29 7b 0a 20 20 20 20 20 20 63 68 61 72 20 2a 7a  ){.      char *z
2070: 45 72 72 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70  Err = sqlite3_mp
2080: 72 69 6e 74 66 28 22 75 6e 72 65 63 6f 67 6e 69  rintf("unrecogni
2090: 7a 65 64 20 6d 61 74 63 68 69 6e 66 6f 20 66 6c  zed matchinfo fl
20a0: 61 67 3a 20 25 63 22 2c 20 7a 41 72 67 5b 69 5d  ag: %c", zArg[i]
20b0: 29 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33  );.      sqlite3
20c0: 5f 72 65 73 75 6c 74 5f 65 72 72 6f 72 28 70 43  _result_error(pC
20d0: 74 78 2c 20 7a 45 72 72 2c 20 2d 31 29 3b 0a 20  tx, zErr, -1);. 
20e0: 20 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65       sqlite3_fre
20f0: 65 28 7a 45 72 72 29 3b 0a 20 20 20 20 20 20 72  e(zErr);.      r
2100: 65 74 75 72 6e 20 30 3b 0a 20 20 20 20 7d 0a 20  eturn 0;.    }. 
2110: 20 20 20 6e 49 6e 74 20 2b 3d 20 6e 3b 0a 20 20     nInt += n;.  
2120: 7d 0a 0a 20 20 6e 42 79 74 65 20 3d 20 73 69 7a  }..  nByte = siz
2130: 65 6f 66 28 46 74 73 35 4d 61 74 63 68 69 6e 66  eof(Fts5Matchinf
2140: 6f 43 74 78 29 20 20 20 20 20 20 20 20 20 20 2f  oCtx)          /
2150: 2a 20 54 68 65 20 73 74 72 75 63 74 20 69 74 73  * The struct its
2160: 65 6c 66 20 2a 2f 0a 20 20 20 20 20 20 20 20 20  elf */.         
2170: 2b 20 73 69 7a 65 6f 66 28 75 33 32 29 20 2a 20  + sizeof(u32) * 
2180: 6e 49 6e 74 20 20 20 20 20 20 20 20 20 20 20 20  nInt            
2190: 20 20 20 2f 2a 20 54 68 65 20 70 2d 3e 61 52 65     /* The p->aRe
21a0: 74 5b 5d 20 61 72 72 61 79 20 2a 2f 0a 20 20 20  t[] array */.   
21b0: 20 20 20 20 20 20 2b 20 28 69 2b 31 29 3b 20 20        + (i+1);  
21c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
21d0: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20           /* The 
21e0: 70 2d 3e 7a 41 72 67 20 73 74 72 69 6e 67 20 2a  p->zArg string *
21f0: 2f 0a 20 20 70 20 3d 20 28 46 74 73 35 4d 61 74  /.  p = (Fts5Mat
2200: 63 68 69 6e 66 6f 43 74 78 2a 29 73 71 6c 69 74  chinfoCtx*)sqlit
2210: 65 33 5f 6d 61 6c 6c 6f 63 28 6e 42 79 74 65 29  e3_malloc(nByte)
2220: 3b 0a 20 20 69 66 28 20 70 3d 3d 30 20 29 7b 0a  ;.  if( p==0 ){.
2230: 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75      sqlite3_resu
2240: 6c 74 5f 65 72 72 6f 72 5f 6e 6f 6d 65 6d 28 70  lt_error_nomem(p
2250: 43 74 78 29 3b 0a 20 20 20 20 72 65 74 75 72 6e  Ctx);.    return
2260: 20 30 3b 0a 20 20 7d 0a 20 20 6d 65 6d 73 65 74   0;.  }.  memset
2270: 28 70 2c 20 30 2c 20 6e 42 79 74 65 29 3b 0a 0a  (p, 0, nByte);..
2280: 20 20 70 2d 3e 6e 43 6f 6c 20 3d 20 6e 43 6f 6c    p->nCol = nCol
2290: 3b 0a 20 20 70 2d 3e 6e 50 68 72 61 73 65 20 3d  ;.  p->nPhrase =
22a0: 20 6e 50 68 72 61 73 65 3b 0a 20 20 70 2d 3e 61   nPhrase;.  p->a
22b0: 52 65 74 20 3d 20 28 75 33 32 2a 29 26 70 5b 31  Ret = (u32*)&p[1
22c0: 5d 3b 0a 20 20 70 2d 3e 6e 52 65 74 20 3d 20 6e  ];.  p->nRet = n
22d0: 49 6e 74 3b 0a 20 20 70 2d 3e 7a 41 72 67 20 3d  Int;.  p->zArg =
22e0: 20 28 63 68 61 72 2a 29 26 70 2d 3e 61 52 65 74   (char*)&p->aRet
22f0: 5b 6e 49 6e 74 5d 3b 0a 20 20 6d 65 6d 63 70 79  [nInt];.  memcpy
2300: 28 70 2d 3e 7a 41 72 67 2c 20 7a 41 72 67 2c 20  (p->zArg, zArg, 
2310: 69 29 3b 0a 0a 20 20 72 63 20 3d 20 66 74 73 35  i);..  rc = fts5
2320: 4d 61 74 63 68 69 6e 66 6f 49 74 65 72 28 70 41  MatchinfoIter(pA
2330: 70 69 2c 20 70 46 74 73 2c 20 70 2c 20 66 74 73  pi, pFts, p, fts
2340: 35 4d 61 74 63 68 69 6e 66 6f 47 6c 6f 62 61 6c  5MatchinfoGlobal
2350: 43 62 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53  Cb);.  if( rc!=S
2360: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
2370: 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 65  sqlite3_result_e
2380: 72 72 6f 72 5f 63 6f 64 65 28 70 43 74 78 2c 20  rror_code(pCtx, 
2390: 72 63 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33  rc);.    sqlite3
23a0: 5f 66 72 65 65 28 70 29 3b 0a 20 20 20 20 70 20  _free(p);.    p 
23b0: 3d 20 30 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75  = 0;.  }..  retu
23c0: 72 6e 20 70 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  rn p;.}..static 
23d0: 76 6f 69 64 20 66 74 73 35 4d 61 74 63 68 69 6e  void fts5Matchin
23e0: 66 6f 46 75 6e 63 28 0a 20 20 63 6f 6e 73 74 20  foFunc(.  const 
23f0: 46 74 73 35 45 78 74 65 6e 73 69 6f 6e 41 70 69  Fts5ExtensionApi
2400: 20 2a 70 41 70 69 2c 20 20 20 2f 2a 20 41 50 49   *pApi,   /* API
2410: 20 6f 66 66 65 72 65 64 20 62 79 20 63 75 72 72   offered by curr
2420: 65 6e 74 20 46 54 53 20 76 65 72 73 69 6f 6e 20  ent FTS version 
2430: 2a 2f 0a 20 20 46 74 73 35 43 6f 6e 74 65 78 74  */.  Fts5Context
2440: 20 2a 70 46 74 73 2c 20 20 20 20 20 20 20 20 20   *pFts,         
2450: 20 20 20 20 20 2f 2a 20 46 69 72 73 74 20 61 72       /* First ar
2460: 67 20 74 6f 20 70 61 73 73 20 74 6f 20 70 41 70  g to pass to pAp
2470: 69 20 66 75 6e 63 74 69 6f 6e 73 20 2a 2f 0a 20  i functions */. 
2480: 20 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74   sqlite3_context
2490: 20 2a 70 43 74 78 2c 20 20 20 20 20 20 20 20 20   *pCtx,         
24a0: 20 2f 2a 20 43 6f 6e 74 65 78 74 20 66 6f 72 20   /* Context for 
24b0: 72 65 74 75 72 6e 69 6e 67 20 72 65 73 75 6c 74  returning result
24c0: 2f 65 72 72 6f 72 20 2a 2f 0a 20 20 69 6e 74 20  /error */.  int 
24d0: 6e 56 61 6c 2c 20 20 20 20 20 20 20 20 20 20 20  nVal,           
24e0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
24f0: 75 6d 62 65 72 20 6f 66 20 76 61 6c 75 65 73 20  umber of values 
2500: 69 6e 20 61 70 56 61 6c 5b 5d 20 61 72 72 61 79  in apVal[] array
2510: 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 76 61   */.  sqlite3_va
2520: 6c 75 65 20 2a 2a 61 70 56 61 6c 20 20 20 20 20  lue **apVal     
2530: 20 20 20 20 20 20 2f 2a 20 41 72 72 61 79 20 6f        /* Array o
2540: 66 20 74 72 61 69 6c 69 6e 67 20 61 72 67 75 6d  f trailing argum
2550: 65 6e 74 73 20 2a 2f 0a 29 7b 0a 20 20 63 6f 6e  ents */.){.  con
2560: 73 74 20 63 68 61 72 20 2a 7a 41 72 67 3b 0a 20  st char *zArg;. 
2570: 20 46 74 73 35 4d 61 74 63 68 69 6e 66 6f 43 74   Fts5MatchinfoCt
2580: 78 20 2a 70 3b 0a 20 20 69 6e 74 20 72 63 20 3d  x *p;.  int rc =
2590: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20 69   SQLITE_OK;..  i
25a0: 66 28 20 6e 56 61 6c 3e 30 20 29 7b 0a 20 20 20  f( nVal>0 ){.   
25b0: 20 7a 41 72 67 20 3d 20 28 63 6f 6e 73 74 20 63   zArg = (const c
25c0: 68 61 72 2a 29 73 71 6c 69 74 65 33 5f 76 61 6c  har*)sqlite3_val
25d0: 75 65 5f 74 65 78 74 28 61 70 56 61 6c 5b 30 5d  ue_text(apVal[0]
25e0: 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  );.  }else{.    
25f0: 7a 41 72 67 20 3d 20 22 70 63 78 22 3b 0a 20 20  zArg = "pcx";.  
2600: 7d 0a 0a 20 20 70 20 3d 20 28 46 74 73 35 4d 61  }..  p = (Fts5Ma
2610: 74 63 68 69 6e 66 6f 43 74 78 2a 29 70 41 70 69  tchinfoCtx*)pApi
2620: 2d 3e 78 47 65 74 41 75 78 64 61 74 61 28 70 46  ->xGetAuxdata(pF
2630: 74 73 2c 20 30 29 3b 0a 20 20 69 66 28 20 70 3d  ts, 0);.  if( p=
2640: 3d 30 20 7c 7c 20 73 71 6c 69 74 65 33 5f 73 74  =0 || sqlite3_st
2650: 72 69 63 6d 70 28 7a 41 72 67 2c 20 70 2d 3e 7a  ricmp(zArg, p->z
2660: 41 72 67 29 20 29 7b 0a 20 20 20 20 70 20 3d 20  Arg) ){.    p = 
2670: 66 74 73 35 4d 61 74 63 68 69 6e 66 6f 4e 65 77  fts5MatchinfoNew
2680: 28 70 41 70 69 2c 20 70 46 74 73 2c 20 70 43 74  (pApi, pFts, pCt
2690: 78 2c 20 7a 41 72 67 29 3b 0a 20 20 20 20 69 66  x, zArg);.    if
26a0: 28 20 70 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  ( p==0 ){.      
26b0: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  rc = SQLITE_NOME
26c0: 4d 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  M;.    }else{.  
26d0: 20 20 20 20 72 63 20 3d 20 70 41 70 69 2d 3e 78      rc = pApi->x
26e0: 53 65 74 41 75 78 64 61 74 61 28 70 46 74 73 2c  SetAuxdata(pFts,
26f0: 20 70 2c 20 73 71 6c 69 74 65 33 5f 66 72 65 65   p, sqlite3_free
2700: 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20  );.    }.  }..  
2710: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
2720: 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 66 74  K ){.    rc = ft
2730: 73 35 4d 61 74 63 68 69 6e 66 6f 49 74 65 72 28  s5MatchinfoIter(
2740: 70 41 70 69 2c 20 70 46 74 73 2c 20 70 2c 20 66  pApi, pFts, p, f
2750: 74 73 35 4d 61 74 63 68 69 6e 66 6f 4c 6f 63 61  ts5MatchinfoLoca
2760: 6c 43 62 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20  lCb);.  }.  if( 
2770: 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc!=SQLITE_OK ){
2780: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73  .    sqlite3_res
2790: 75 6c 74 5f 65 72 72 6f 72 5f 63 6f 64 65 28 70  ult_error_code(p
27a0: 43 74 78 2c 20 72 63 29 3b 0a 20 20 7d 65 6c 73  Ctx, rc);.  }els
27b0: 65 7b 0a 20 20 20 20 2f 2a 20 4e 6f 20 65 72 72  e{.    /* No err
27c0: 6f 72 73 20 68 61 73 20 6f 63 63 75 72 65 64 2c  ors has occured,
27d0: 20 73 6f 20 72 65 74 75 72 6e 20 61 20 63 6f 70   so return a cop
27e0: 79 20 6f 66 20 74 68 65 20 61 72 72 61 79 20 6f  y of the array o
27f0: 66 20 69 6e 74 65 67 65 72 73 2e 20 2a 2f 0a 20  f integers. */. 
2800: 20 20 20 69 6e 74 20 6e 42 79 74 65 20 3d 20 70     int nByte = p
2810: 2d 3e 6e 52 65 74 20 2a 20 73 69 7a 65 6f 66 28  ->nRet * sizeof(
2820: 75 33 32 29 3b 0a 20 20 20 20 73 71 6c 69 74 65  u32);.    sqlite
2830: 33 5f 72 65 73 75 6c 74 5f 62 6c 6f 62 28 70 43  3_result_blob(pC
2840: 74 78 2c 20 28 76 6f 69 64 2a 29 70 2d 3e 61 52  tx, (void*)p->aR
2850: 65 74 2c 20 6e 42 79 74 65 2c 20 53 51 4c 49 54  et, nByte, SQLIT
2860: 45 5f 54 52 41 4e 53 49 45 4e 54 29 3b 0a 20 20  E_TRANSIENT);.  
2870: 7d 0a 7d 0a 0a 69 6e 74 20 73 71 6c 69 74 65 33  }.}..int sqlite3
2880: 46 74 73 35 54 65 73 74 52 65 67 69 73 74 65 72  Fts5TestRegister
2890: 4d 61 74 63 68 69 6e 66 6f 28 73 71 6c 69 74 65  Matchinfo(sqlite
28a0: 33 20 2a 64 62 29 7b 0a 20 20 69 6e 74 20 72 63  3 *db){.  int rc
28b0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
28c0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74            /* Ret
28d0: 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 66 74  urn code */.  ft
28e0: 73 35 5f 61 70 69 20 2a 70 41 70 69 3b 20 20 20  s5_api *pApi;   
28f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
2900: 20 46 54 53 35 20 41 50 49 20 66 75 6e 63 74 69   FTS5 API functi
2910: 6f 6e 73 20 2a 2f 0a 0a 20 20 2f 2a 20 45 78 74  ons */..  /* Ext
2920: 72 61 63 74 20 74 68 65 20 46 54 53 35 20 41 50  ract the FTS5 AP
2930: 49 20 70 6f 69 6e 74 65 72 20 66 72 6f 6d 20 74  I pointer from t
2940: 68 65 20 64 61 74 61 62 61 73 65 20 68 61 6e 64  he database hand
2950: 6c 65 2e 20 54 68 65 20 0a 20 20 2a 2a 20 66 74  le. The .  ** ft
2960: 73 35 5f 61 70 69 5f 66 72 6f 6d 5f 64 62 28 29  s5_api_from_db()
2970: 20 66 75 6e 63 74 69 6f 6e 20 61 62 6f 76 65 20   function above 
2980: 69 73 20 63 6f 70 69 65 64 20 76 65 72 62 61 74  is copied verbat
2990: 69 6d 20 66 72 6f 6d 20 74 68 65 20 0a 20 20 2a  im from the .  *
29a0: 2a 20 46 54 53 35 20 64 6f 63 75 6d 65 6e 74 61  * FTS5 documenta
29b0: 74 69 6f 6e 2e 20 52 65 66 65 72 20 74 68 65 72  tion. Refer ther
29c0: 65 20 66 6f 72 20 64 65 74 61 69 6c 73 2e 20 2a  e for details. *
29d0: 2f 0a 20 20 70 41 70 69 20 3d 20 66 74 73 35 5f  /.  pApi = fts5_
29e0: 61 70 69 5f 66 72 6f 6d 5f 64 62 28 64 62 29 3b  api_from_db(db);
29f0: 0a 0a 20 20 2f 2a 20 49 66 20 66 74 73 35 5f 61  ..  /* If fts5_a
2a00: 70 69 5f 66 72 6f 6d 5f 64 62 28 29 20 72 65 74  pi_from_db() ret
2a10: 75 72 6e 73 20 4e 55 4c 4c 2c 20 74 68 65 6e 20  urns NULL, then 
2a20: 65 69 74 68 65 72 20 46 54 53 35 20 69 73 20 6e  either FTS5 is n
2a30: 6f 74 20 72 65 67 69 73 74 65 72 65 64 0a 20 20  ot registered.  
2a40: 2a 2a 20 77 69 74 68 20 74 68 69 73 20 64 61 74  ** with this dat
2a50: 61 62 61 73 65 20 68 61 6e 64 6c 65 2c 20 6f 72  abase handle, or
2a60: 20 61 6e 20 65 72 72 6f 72 20 28 4f 4f 4d 20 70   an error (OOM p
2a70: 65 72 68 61 70 73 3f 29 20 68 61 73 20 6f 63 63  erhaps?) has occ
2a80: 75 72 72 65 64 2e 0a 20 20 2a 2a 0a 20 20 2a 2a  urred..  **.  **
2a90: 20 41 6c 73 6f 20 63 68 65 63 6b 20 74 68 61 74   Also check that
2aa0: 20 74 68 65 20 66 74 73 35 5f 61 70 69 20 6f 62   the fts5_api ob
2ab0: 6a 65 63 74 20 69 73 20 76 65 72 73 69 6f 6e 20  ject is version 
2ac0: 32 20 6f 72 20 6e 65 77 65 72 2e 20 20 0a 20 20  2 or newer.  .  
2ad0: 2a 2f 20 0a 20 20 69 66 28 20 70 41 70 69 3d 3d  */ .  if( pApi==
2ae0: 30 20 7c 7c 20 70 41 70 69 2d 3e 69 56 65 72 73  0 || pApi->iVers
2af0: 69 6f 6e 3c 31 20 29 7b 0a 20 20 20 20 72 65 74  ion<1 ){.    ret
2b00: 75 72 6e 20 53 51 4c 49 54 45 5f 45 52 52 4f 52  urn SQLITE_ERROR
2b10: 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 52 65 67 69  ;.  }..  /* Regi
2b20: 73 74 65 72 20 74 68 65 20 69 6d 70 6c 65 6d 65  ster the impleme
2b30: 6e 74 61 74 69 6f 6e 20 6f 66 20 6d 61 74 63 68  ntation of match
2b40: 69 6e 66 6f 28 29 20 2a 2f 0a 20 20 72 63 20 3d  info() */.  rc =
2b50: 20 70 41 70 69 2d 3e 78 43 72 65 61 74 65 46 75   pApi->xCreateFu
2b60: 6e 63 74 69 6f 6e 28 70 41 70 69 2c 20 22 6d 61  nction(pApi, "ma
2b70: 74 63 68 69 6e 66 6f 22 2c 20 30 2c 20 66 74 73  tchinfo", 0, fts
2b80: 35 4d 61 74 63 68 69 6e 66 6f 46 75 6e 63 2c 20  5MatchinfoFunc, 
2b90: 30 29 3b 0a 0a 20 20 72 65 74 75 72 6e 20 72 63  0);..  return rc
2ba0: 3b 0a 7d 0a 0a 23 65 6e 64 69 66 20 2f 2a 20 53  ;.}..#endif /* S
2bb0: 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 46 54 53  QLITE_ENABLE_FTS
2bc0: 35 20 2a 2f 0a 23 65 6e 64 69 66 20 2f 2a 20 53  5 */.#endif /* S
2bd0: 51 4c 49 54 45 5f 54 45 53 54 20 2a 2f 0a 0a     QLITE_TEST */..