/ Hex Artifact Content
Login

Artifact 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee:


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 45 4e 41 42 4c 45 5f 46 54 53  QLITE_ENABLE_FTS
0630: 35 0a 0a 23 69 6e 63 6c 75 64 65 20 22 66 74 73  5..#include "fts
0640: 35 2e 68 22 0a 23 69 6e 63 6c 75 64 65 20 3c 61  5.h".#include <a
0650: 73 73 65 72 74 2e 68 3e 0a 23 69 6e 63 6c 75 64  ssert.h>.#includ
0660: 65 20 3c 73 74 72 69 6e 67 2e 68 3e 0a 0a 74 79  e <string.h>..ty
0670: 70 65 64 65 66 20 73 74 72 75 63 74 20 46 74 73  pedef struct Fts
0680: 35 4d 61 74 63 68 69 6e 66 6f 43 74 78 20 46 74  5MatchinfoCtx Ft
0690: 73 35 4d 61 74 63 68 69 6e 66 6f 43 74 78 3b 0a  s5MatchinfoCtx;.
06a0: 0a 23 69 66 6e 64 65 66 20 53 51 4c 49 54 45 5f  .#ifndef SQLITE_
06b0: 41 4d 41 4c 47 41 4d 41 54 49 4f 4e 0a 74 79 70  AMALGAMATION.typ
06c0: 65 64 65 66 20 75 6e 73 69 67 6e 65 64 20 69 6e  edef unsigned in
06d0: 74 20 75 33 32 3b 0a 23 65 6e 64 69 66 0a 0a 73  t u32;.#endif..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 69 6e 74 20 66 74 73  /.static int fts
0940: 35 5f 61 70 69 5f 66 72 6f 6d 5f 64 62 28 73 71  5_api_from_db(sq
0950: 6c 69 74 65 33 20 2a 64 62 2c 20 66 74 73 35 5f  lite3 *db, fts5_
0960: 61 70 69 20 2a 2a 70 70 41 70 69 29 7b 0a 20 20  api **ppApi){.  
0970: 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 53  sqlite3_stmt *pS
0980: 74 6d 74 20 3d 20 30 3b 0a 20 20 69 6e 74 20 72  tmt = 0;.  int r
0990: 63 3b 0a 0a 20 20 2a 70 70 41 70 69 20 3d 20 30  c;..  *ppApi = 0
09a0: 3b 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33  ;.  rc = sqlite3
09b0: 5f 70 72 65 70 61 72 65 28 64 62 2c 20 22 53 45  _prepare(db, "SE
09c0: 4c 45 43 54 20 66 74 73 35 28 3f 31 29 22 2c 20  LECT fts5(?1)", 
09d0: 2d 31 2c 20 26 70 53 74 6d 74 2c 20 30 29 3b 0a  -1, &pStmt, 0);.
09e0: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
09f0: 5f 4f 4b 20 29 7b 0a 20 20 20 20 73 71 6c 69 74  _OK ){.    sqlit
0a00: 65 33 5f 62 69 6e 64 5f 70 6f 69 6e 74 65 72 28  e3_bind_pointer(
0a10: 70 53 74 6d 74 2c 20 31 2c 20 28 76 6f 69 64 2a  pStmt, 1, (void*
0a20: 29 70 70 41 70 69 2c 20 22 66 74 73 35 5f 61 70  )ppApi, "fts5_ap
0a30: 69 5f 70 74 72 22 2c 20 30 29 3b 0a 20 20 20 20  i_ptr", 0);.    
0a40: 28 76 6f 69 64 29 73 71 6c 69 74 65 33 5f 73 74  (void)sqlite3_st
0a50: 65 70 28 70 53 74 6d 74 29 3b 0a 20 20 20 20 72  ep(pStmt);.    r
0a60: 63 20 3d 20 73 71 6c 69 74 65 33 5f 66 69 6e 61  c = sqlite3_fina
0a70: 6c 69 7a 65 28 70 53 74 6d 74 29 3b 0a 20 20 7d  lize(pStmt);.  }
0a80: 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ..  return rc;.}
0a90: 0a 0a 0a 2f 2a 0a 2a 2a 20 41 72 67 75 6d 65 6e  .../*.** Argumen
0aa0: 74 20 66 20 73 68 6f 75 6c 64 20 62 65 20 61 20  t f should be a 
0ab0: 66 6c 61 67 20 61 63 63 65 70 74 65 64 20 62 79  flag accepted by
0ac0: 20 6d 61 74 63 68 69 6e 66 6f 28 29 20 28 61 20   matchinfo() (a 
0ad0: 76 61 6c 69 64 20 63 68 61 72 61 63 74 65 72 0a  valid character.
0ae0: 2a 2a 20 69 6e 20 74 68 65 20 73 74 72 69 6e 67  ** in the string
0af0: 20 70 61 73 73 65 64 20 61 73 20 74 68 65 20 73   passed as the s
0b00: 65 63 6f 6e 64 20 61 72 67 75 6d 65 6e 74 29 2e  econd argument).
0b10: 20 49 66 20 69 74 20 69 73 20 6e 6f 74 2c 20 2d   If it is not, -
0b20: 31 20 69 73 20 0a 2a 2a 20 72 65 74 75 72 6e 65  1 is .** returne
0b30: 64 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 69 66  d. Otherwise, if
0b40: 20 66 20 69 73 20 61 20 76 61 6c 69 64 20 6d 61   f is a valid ma
0b50: 74 63 68 69 6e 66 6f 20 66 6c 61 67 2c 20 74 68  tchinfo flag, th
0b60: 65 20 76 61 6c 75 65 20 72 65 74 75 72 6e 65 64  e value returned
0b70: 0a 2a 2a 20 69 73 20 74 68 65 20 6e 75 6d 62 65  .** is the numbe
0b80: 72 20 6f 66 20 33 32 2d 62 69 74 20 69 6e 74 65  r of 32-bit inte
0b90: 67 65 72 73 20 61 64 64 65 64 20 74 6f 20 74 68  gers added to th
0ba0: 65 20 6f 75 74 70 75 74 20 61 72 72 61 79 20 69  e output array i
0bb0: 66 20 74 68 65 0a 2a 2a 20 74 61 62 6c 65 20 68  f the.** table h
0bc0: 61 73 20 6e 43 6f 6c 20 63 6f 6c 75 6d 6e 73 20  as nCol columns 
0bd0: 61 6e 64 20 74 68 65 20 71 75 65 72 79 20 6e 50  and the query nP
0be0: 68 72 61 73 65 20 70 68 72 61 73 65 73 2e 0a 2a  hrase phrases..*
0bf0: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73  /.static int fts
0c00: 35 4d 61 74 63 68 69 6e 66 6f 46 6c 61 67 73 69  5MatchinfoFlagsi
0c10: 7a 65 28 69 6e 74 20 6e 43 6f 6c 2c 20 69 6e 74  ze(int nCol, int
0c20: 20 6e 50 68 72 61 73 65 2c 20 63 68 61 72 20 66   nPhrase, char f
0c30: 29 7b 0a 20 20 69 6e 74 20 72 65 74 20 3d 20 2d  ){.  int ret = -
0c40: 31 3b 0a 20 20 73 77 69 74 63 68 28 20 66 20 29  1;.  switch( f )
0c50: 7b 0a 20 20 20 20 63 61 73 65 20 27 70 27 3a 20  {.    case 'p': 
0c60: 72 65 74 20 3d 20 31 3b 20 62 72 65 61 6b 3b 0a  ret = 1; break;.
0c70: 20 20 20 20 63 61 73 65 20 27 63 27 3a 20 72 65      case 'c': re
0c80: 74 20 3d 20 31 3b 20 62 72 65 61 6b 3b 0a 20 20  t = 1; break;.  
0c90: 20 20 63 61 73 65 20 27 78 27 3a 20 72 65 74 20    case 'x': ret 
0ca0: 3d 20 33 20 2a 20 6e 43 6f 6c 20 2a 20 6e 50 68  = 3 * nCol * nPh
0cb0: 72 61 73 65 3b 20 62 72 65 61 6b 3b 0a 20 20 20  rase; break;.   
0cc0: 20 63 61 73 65 20 27 79 27 3a 20 72 65 74 20 3d   case 'y': ret =
0cd0: 20 6e 43 6f 6c 20 2a 20 6e 50 68 72 61 73 65 3b   nCol * nPhrase;
0ce0: 20 62 72 65 61 6b 3b 0a 20 20 20 20 63 61 73 65   break;.    case
0cf0: 20 27 62 27 3a 20 72 65 74 20 3d 20 28 28 6e 43   'b': ret = ((nC
0d00: 6f 6c 20 2b 20 33 31 29 20 2f 20 33 32 29 20 2a  ol + 31) / 32) *
0d10: 20 6e 50 68 72 61 73 65 3b 20 62 72 65 61 6b 3b   nPhrase; break;
0d20: 0a 20 20 20 20 63 61 73 65 20 27 6e 27 3a 20 72  .    case 'n': r
0d30: 65 74 20 3d 20 31 3b 20 62 72 65 61 6b 3b 0a 20  et = 1; break;. 
0d40: 20 20 20 63 61 73 65 20 27 61 27 3a 20 72 65 74     case 'a': ret
0d50: 20 3d 20 6e 43 6f 6c 3b 20 62 72 65 61 6b 3b 0a   = nCol; break;.
0d60: 20 20 20 20 63 61 73 65 20 27 6c 27 3a 20 72 65      case 'l': re
0d70: 74 20 3d 20 6e 43 6f 6c 3b 20 62 72 65 61 6b 3b  t = nCol; break;
0d80: 0a 20 20 20 20 63 61 73 65 20 27 73 27 3a 20 72  .    case 's': r
0d90: 65 74 20 3d 20 6e 43 6f 6c 3b 20 62 72 65 61 6b  et = nCol; break
0da0: 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72  ;.  }.  return r
0db0: 65 74 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  et;.}..static in
0dc0: 74 20 66 74 73 35 4d 61 74 63 68 69 6e 66 6f 49  t fts5MatchinfoI
0dd0: 74 65 72 28 0a 20 20 63 6f 6e 73 74 20 46 74 73  ter(.  const Fts
0de0: 35 45 78 74 65 6e 73 69 6f 6e 41 70 69 20 2a 70  5ExtensionApi *p
0df0: 41 70 69 2c 20 20 20 2f 2a 20 41 50 49 20 6f 66  Api,   /* API of
0e00: 66 65 72 65 64 20 62 79 20 63 75 72 72 65 6e 74  fered by current
0e10: 20 46 54 53 20 76 65 72 73 69 6f 6e 20 2a 2f 0a   FTS version */.
0e20: 20 20 46 74 73 35 43 6f 6e 74 65 78 74 20 2a 70    Fts5Context *p
0e30: 46 74 73 2c 20 20 20 20 20 20 20 20 20 20 20 20  Fts,            
0e40: 20 20 2f 2a 20 46 69 72 73 74 20 61 72 67 20 74    /* First arg t
0e50: 6f 20 70 61 73 73 20 74 6f 20 70 41 70 69 20 66  o pass to pApi f
0e60: 75 6e 63 74 69 6f 6e 73 20 2a 2f 0a 20 20 46 74  unctions */.  Ft
0e70: 73 35 4d 61 74 63 68 69 6e 66 6f 43 74 78 20 2a  s5MatchinfoCtx *
0e80: 70 2c 0a 20 20 69 6e 74 28 2a 78 29 28 63 6f 6e  p,.  int(*x)(con
0e90: 73 74 20 46 74 73 35 45 78 74 65 6e 73 69 6f 6e  st Fts5Extension
0ea0: 41 70 69 2a 2c 46 74 73 35 43 6f 6e 74 65 78 74  Api*,Fts5Context
0eb0: 2a 2c 46 74 73 35 4d 61 74 63 68 69 6e 66 6f 43  *,Fts5MatchinfoC
0ec0: 74 78 2a 2c 63 68 61 72 2c 75 33 32 2a 29 0a 29  tx*,char,u32*).)
0ed0: 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 69 6e 74  {.  int i;.  int
0ee0: 20 6e 20 3d 20 30 3b 0a 20 20 69 6e 74 20 72 63   n = 0;.  int rc
0ef0: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20   = SQLITE_OK;.  
0f00: 63 68 61 72 20 66 3b 0a 20 20 66 6f 72 28 69 3d  char f;.  for(i=
0f10: 30 3b 20 28 66 20 3d 20 70 2d 3e 7a 41 72 67 5b  0; (f = p->zArg[
0f20: 69 5d 29 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 72  i]); i++){.    r
0f30: 63 20 3d 20 78 28 70 41 70 69 2c 20 70 46 74 73  c = x(pApi, pFts
0f40: 2c 20 70 2c 20 66 2c 20 26 70 2d 3e 61 52 65 74  , p, f, &p->aRet
0f50: 5b 6e 5d 29 3b 0a 20 20 20 20 69 66 28 20 72 63  [n]);.    if( rc
0f60: 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 62 72  !=SQLITE_OK ) br
0f70: 65 61 6b 3b 0a 20 20 20 20 6e 20 2b 3d 20 66 74  eak;.    n += ft
0f80: 73 35 4d 61 74 63 68 69 6e 66 6f 46 6c 61 67 73  s5MatchinfoFlags
0f90: 69 7a 65 28 70 2d 3e 6e 43 6f 6c 2c 20 70 2d 3e  ize(p->nCol, p->
0fa0: 6e 50 68 72 61 73 65 2c 20 66 29 3b 0a 20 20 7d  nPhrase, f);.  }
0fb0: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
0fc0: 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35  .static int fts5
0fd0: 4d 61 74 63 68 69 6e 66 6f 58 43 62 28 0a 20 20  MatchinfoXCb(.  
0fe0: 63 6f 6e 73 74 20 46 74 73 35 45 78 74 65 6e 73  const Fts5Extens
0ff0: 69 6f 6e 41 70 69 20 2a 70 41 70 69 2c 0a 20 20  ionApi *pApi,.  
1000: 46 74 73 35 43 6f 6e 74 65 78 74 20 2a 70 46 74  Fts5Context *pFt
1010: 73 2c 0a 20 20 76 6f 69 64 20 2a 70 55 73 65 72  s,.  void *pUser
1020: 44 61 74 61 0a 29 7b 0a 20 20 46 74 73 35 50 68  Data.){.  Fts5Ph
1030: 72 61 73 65 49 74 65 72 20 69 74 65 72 3b 0a 20  raseIter iter;. 
1040: 20 69 6e 74 20 69 43 6f 6c 2c 20 69 4f 66 66 3b   int iCol, iOff;
1050: 0a 20 20 75 33 32 20 2a 61 4f 75 74 20 3d 20 28  .  u32 *aOut = (
1060: 75 33 32 2a 29 70 55 73 65 72 44 61 74 61 3b 0a  u32*)pUserData;.
1070: 20 20 69 6e 74 20 69 50 72 65 76 20 3d 20 2d 31    int iPrev = -1
1080: 3b 0a 0a 20 20 66 6f 72 28 70 41 70 69 2d 3e 78  ;..  for(pApi->x
1090: 50 68 72 61 73 65 46 69 72 73 74 28 70 46 74 73  PhraseFirst(pFts
10a0: 2c 20 30 2c 20 26 69 74 65 72 2c 20 26 69 43 6f  , 0, &iter, &iCo
10b0: 6c 2c 20 26 69 4f 66 66 29 3b 20 0a 20 20 20 20  l, &iOff); .    
10c0: 20 20 69 43 6f 6c 3e 3d 30 3b 20 0a 20 20 20 20    iCol>=0; .    
10d0: 20 20 70 41 70 69 2d 3e 78 50 68 72 61 73 65 4e    pApi->xPhraseN
10e0: 65 78 74 28 70 46 74 73 2c 20 26 69 74 65 72 2c  ext(pFts, &iter,
10f0: 20 26 69 43 6f 6c 2c 20 26 69 4f 66 66 29 0a 20   &iCol, &iOff). 
1100: 20 29 7b 0a 20 20 20 20 61 4f 75 74 5b 69 43 6f   ){.    aOut[iCo
1110: 6c 2a 33 2b 31 5d 2b 2b 3b 0a 20 20 20 20 69 66  l*3+1]++;.    if
1120: 28 20 69 43 6f 6c 21 3d 69 50 72 65 76 20 29 20  ( iCol!=iPrev ) 
1130: 61 4f 75 74 5b 69 43 6f 6c 2a 33 20 2b 20 32 5d  aOut[iCol*3 + 2]
1140: 2b 2b 3b 0a 20 20 20 20 69 50 72 65 76 20 3d 20  ++;.    iPrev = 
1150: 69 43 6f 6c 3b 0a 20 20 7d 0a 0a 20 20 72 65 74  iCol;.  }..  ret
1160: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
1170: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73  ..static int fts
1180: 35 4d 61 74 63 68 69 6e 66 6f 47 6c 6f 62 61 6c  5MatchinfoGlobal
1190: 43 62 28 0a 20 20 63 6f 6e 73 74 20 46 74 73 35  Cb(.  const Fts5
11a0: 45 78 74 65 6e 73 69 6f 6e 41 70 69 20 2a 70 41  ExtensionApi *pA
11b0: 70 69 2c 0a 20 20 46 74 73 35 43 6f 6e 74 65 78  pi,.  Fts5Contex
11c0: 74 20 2a 70 46 74 73 2c 0a 20 20 46 74 73 35 4d  t *pFts,.  Fts5M
11d0: 61 74 63 68 69 6e 66 6f 43 74 78 20 2a 70 2c 0a  atchinfoCtx *p,.
11e0: 20 20 63 68 61 72 20 66 2c 0a 20 20 75 33 32 20    char f,.  u32 
11f0: 2a 61 4f 75 74 0a 29 7b 0a 20 20 69 6e 74 20 72  *aOut.){.  int r
1200: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  c = SQLITE_OK;. 
1210: 20 73 77 69 74 63 68 28 20 66 20 29 7b 0a 20 20   switch( f ){.  
1220: 20 20 63 61 73 65 20 27 70 27 3a 0a 20 20 20 20    case 'p':.    
1230: 20 20 61 4f 75 74 5b 30 5d 20 3d 20 70 2d 3e 6e    aOut[0] = p->n
1240: 50 68 72 61 73 65 3b 20 0a 20 20 20 20 20 20 62  Phrase; .      b
1250: 72 65 61 6b 3b 0a 0a 20 20 20 20 63 61 73 65 20  reak;..    case 
1260: 27 63 27 3a 0a 20 20 20 20 20 20 61 4f 75 74 5b  'c':.      aOut[
1270: 30 5d 20 3d 20 70 2d 3e 6e 43 6f 6c 3b 20 0a 20  0] = p->nCol; . 
1280: 20 20 20 20 20 62 72 65 61 6b 3b 0a 0a 20 20 20       break;..   
1290: 20 63 61 73 65 20 27 78 27 3a 20 7b 0a 20 20 20   case 'x': {.   
12a0: 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20 20 20     int i;.      
12b0: 66 6f 72 28 69 3d 30 3b 20 69 3c 70 2d 3e 6e 50  for(i=0; i<p->nP
12c0: 68 72 61 73 65 20 26 26 20 72 63 3d 3d 53 51 4c  hrase && rc==SQL
12d0: 49 54 45 5f 4f 4b 3b 20 69 2b 2b 29 7b 0a 20 20  ITE_OK; i++){.  
12e0: 20 20 20 20 20 20 76 6f 69 64 20 2a 70 50 74 72        void *pPtr
12f0: 20 3d 20 28 76 6f 69 64 2a 29 26 61 4f 75 74 5b   = (void*)&aOut[
1300: 69 20 2a 20 70 2d 3e 6e 43 6f 6c 20 2a 20 33 5d  i * p->nCol * 3]
1310: 3b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 70  ;.        rc = p
1320: 41 70 69 2d 3e 78 51 75 65 72 79 50 68 72 61 73  Api->xQueryPhras
1330: 65 28 70 46 74 73 2c 20 69 2c 20 70 50 74 72 2c  e(pFts, i, pPtr,
1340: 20 66 74 73 35 4d 61 74 63 68 69 6e 66 6f 58 43   fts5MatchinfoXC
1350: 62 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  b);.      }.    
1360: 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 0a    break;.    }..
1370: 20 20 20 20 63 61 73 65 20 27 6e 27 3a 20 7b 0a      case 'n': {.
1380: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 69 6e        sqlite3_in
1390: 74 36 34 20 6e 52 6f 77 3b 0a 20 20 20 20 20 20  t64 nRow;.      
13a0: 72 63 20 3d 20 70 41 70 69 2d 3e 78 52 6f 77 43  rc = pApi->xRowC
13b0: 6f 75 6e 74 28 70 46 74 73 2c 20 26 6e 52 6f 77  ount(pFts, &nRow
13c0: 29 3b 0a 20 20 20 20 20 20 61 4f 75 74 5b 30 5d  );.      aOut[0]
13d0: 20 3d 20 28 75 33 32 29 6e 52 6f 77 3b 0a 20 20   = (u32)nRow;.  
13e0: 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d      break;.    }
13f0: 0a 0a 20 20 20 20 63 61 73 65 20 27 61 27 3a 20  ..    case 'a': 
1400: 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f  {.      sqlite3_
1410: 69 6e 74 36 34 20 6e 52 6f 77 20 3d 20 30 3b 0a  int64 nRow = 0;.
1420: 20 20 20 20 20 20 72 63 20 3d 20 70 41 70 69 2d        rc = pApi-
1430: 3e 78 52 6f 77 43 6f 75 6e 74 28 70 46 74 73 2c  >xRowCount(pFts,
1440: 20 26 6e 52 6f 77 29 3b 0a 20 20 20 20 20 20 69   &nRow);.      i
1450: 66 28 20 6e 52 6f 77 3d 3d 30 20 29 7b 0a 20 20  f( nRow==0 ){.  
1460: 20 20 20 20 20 20 6d 65 6d 73 65 74 28 61 4f 75        memset(aOu
1470: 74 2c 20 30 2c 20 73 69 7a 65 6f 66 28 75 33 32  t, 0, sizeof(u32
1480: 29 20 2a 20 70 2d 3e 6e 43 6f 6c 29 3b 0a 20 20  ) * p->nCol);.  
1490: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
14a0: 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20 20 20     int i;.      
14b0: 20 20 66 6f 72 28 69 3d 30 3b 20 72 63 3d 3d 53    for(i=0; rc==S
14c0: 51 4c 49 54 45 5f 4f 4b 20 26 26 20 69 3c 70 2d  QLITE_OK && i<p-
14d0: 3e 6e 43 6f 6c 3b 20 69 2b 2b 29 7b 0a 20 20 20  >nCol; i++){.   
14e0: 20 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 69         sqlite3_i
14f0: 6e 74 36 34 20 6e 54 6f 6b 65 6e 3b 0a 20 20 20  nt64 nToken;.   
1500: 20 20 20 20 20 20 20 72 63 20 3d 20 70 41 70 69         rc = pApi
1510: 2d 3e 78 43 6f 6c 75 6d 6e 54 6f 74 61 6c 53 69  ->xColumnTotalSi
1520: 7a 65 28 70 46 74 73 2c 20 69 2c 20 26 6e 54 6f  ze(pFts, i, &nTo
1530: 6b 65 6e 29 3b 0a 20 20 20 20 20 20 20 20 20 20  ken);.          
1540: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
1550: 4b 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20  K){.            
1560: 61 4f 75 74 5b 69 5d 20 3d 20 28 75 33 32 29 28  aOut[i] = (u32)(
1570: 28 32 2a 6e 54 6f 6b 65 6e 20 2b 20 6e 52 6f 77  (2*nToken + nRow
1580: 29 20 2f 20 28 32 2a 6e 52 6f 77 29 29 3b 0a 20  ) / (2*nRow));. 
1590: 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20           }.     
15a0: 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20     }.      }.   
15b0: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a     break;.    }.
15c0: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63  .  }.  return rc
15d0: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  ;.}..static int 
15e0: 66 74 73 35 4d 61 74 63 68 69 6e 66 6f 4c 6f 63  fts5MatchinfoLoc
15f0: 61 6c 43 62 28 0a 20 20 63 6f 6e 73 74 20 46 74  alCb(.  const Ft
1600: 73 35 45 78 74 65 6e 73 69 6f 6e 41 70 69 20 2a  s5ExtensionApi *
1610: 70 41 70 69 2c 0a 20 20 46 74 73 35 43 6f 6e 74  pApi,.  Fts5Cont
1620: 65 78 74 20 2a 70 46 74 73 2c 0a 20 20 46 74 73  ext *pFts,.  Fts
1630: 35 4d 61 74 63 68 69 6e 66 6f 43 74 78 20 2a 70  5MatchinfoCtx *p
1640: 2c 0a 20 20 63 68 61 72 20 66 2c 0a 20 20 75 33  ,.  char f,.  u3
1650: 32 20 2a 61 4f 75 74 0a 29 7b 0a 20 20 69 6e 74  2 *aOut.){.  int
1660: 20 69 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53   i;.  int rc = S
1670: 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20 73 77 69  QLITE_OK;..  swi
1680: 74 63 68 28 20 66 20 29 7b 0a 20 20 20 20 63 61  tch( f ){.    ca
1690: 73 65 20 27 62 27 3a 20 7b 0a 20 20 20 20 20 20  se 'b': {.      
16a0: 69 6e 74 20 69 50 68 72 61 73 65 3b 0a 20 20 20  int iPhrase;.   
16b0: 20 20 20 69 6e 74 20 6e 49 6e 74 20 3d 20 28 28     int nInt = ((
16c0: 70 2d 3e 6e 43 6f 6c 20 2b 20 33 31 29 20 2f 20  p->nCol + 31) / 
16d0: 33 32 29 20 2a 20 70 2d 3e 6e 50 68 72 61 73 65  32) * p->nPhrase
16e0: 3b 0a 20 20 20 20 20 20 66 6f 72 28 69 3d 30 3b  ;.      for(i=0;
16f0: 20 69 3c 6e 49 6e 74 3b 20 69 2b 2b 29 20 61 4f   i<nInt; i++) aO
1700: 75 74 5b 69 5d 20 3d 20 30 3b 0a 0a 20 20 20 20  ut[i] = 0;..    
1710: 20 20 66 6f 72 28 69 50 68 72 61 73 65 3d 30 3b    for(iPhrase=0;
1720: 20 69 50 68 72 61 73 65 3c 70 2d 3e 6e 50 68 72   iPhrase<p->nPhr
1730: 61 73 65 3b 20 69 50 68 72 61 73 65 2b 2b 29 7b  ase; iPhrase++){
1740: 0a 20 20 20 20 20 20 20 20 46 74 73 35 50 68 72  .        Fts5Phr
1750: 61 73 65 49 74 65 72 20 69 74 65 72 3b 0a 20 20  aseIter iter;.  
1760: 20 20 20 20 20 20 69 6e 74 20 69 43 6f 6c 3b 0a        int iCol;.
1770: 20 20 20 20 20 20 20 20 66 6f 72 28 70 41 70 69          for(pApi
1780: 2d 3e 78 50 68 72 61 73 65 46 69 72 73 74 43 6f  ->xPhraseFirstCo
1790: 6c 75 6d 6e 28 70 46 74 73 2c 20 69 50 68 72 61  lumn(pFts, iPhra
17a0: 73 65 2c 20 26 69 74 65 72 2c 20 26 69 43 6f 6c  se, &iter, &iCol
17b0: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 69  );.            i
17c0: 43 6f 6c 3e 3d 30 3b 20 0a 20 20 20 20 20 20 20  Col>=0; .       
17d0: 20 20 20 20 20 70 41 70 69 2d 3e 78 50 68 72 61       pApi->xPhra
17e0: 73 65 4e 65 78 74 43 6f 6c 75 6d 6e 28 70 46 74  seNextColumn(pFt
17f0: 73 2c 20 26 69 74 65 72 2c 20 26 69 43 6f 6c 29  s, &iter, &iCol)
1800: 0a 20 20 20 20 20 20 20 20 29 7b 0a 20 20 20 20  .        ){.    
1810: 20 20 20 20 20 20 61 4f 75 74 5b 69 50 68 72 61        aOut[iPhra
1820: 73 65 20 2a 20 28 28 70 2d 3e 6e 43 6f 6c 2b 33  se * ((p->nCol+3
1830: 31 29 2f 33 32 29 20 2b 20 69 43 6f 6c 2f 33 32  1)/32) + iCol/32
1840: 5d 20 7c 3d 20 28 28 75 33 32 29 31 20 3c 3c 20  ] |= ((u32)1 << 
1850: 69 43 6f 6c 25 33 32 29 3b 0a 20 20 20 20 20 20  iCol%32);.      
1860: 20 20 7d 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20    }.      }..   
1870: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a     break;.    }.
1880: 0a 20 20 20 20 63 61 73 65 20 27 78 27 3a 0a 20  .    case 'x':. 
1890: 20 20 20 63 61 73 65 20 27 79 27 3a 20 7b 0a 20     case 'y': {. 
18a0: 20 20 20 20 20 69 6e 74 20 6e 4d 75 6c 20 3d 20       int nMul = 
18b0: 28 66 3d 3d 27 78 27 20 3f 20 33 20 3a 20 31 29  (f=='x' ? 3 : 1)
18c0: 3b 0a 20 20 20 20 20 20 69 6e 74 20 69 50 68 72  ;.      int iPhr
18d0: 61 73 65 3b 0a 0a 20 20 20 20 20 20 66 6f 72 28  ase;..      for(
18e0: 69 3d 30 3b 20 69 3c 28 70 2d 3e 6e 43 6f 6c 2a  i=0; i<(p->nCol*
18f0: 70 2d 3e 6e 50 68 72 61 73 65 29 3b 20 69 2b 2b  p->nPhrase); i++
1900: 29 20 61 4f 75 74 5b 69 2a 6e 4d 75 6c 5d 20 3d  ) aOut[i*nMul] =
1910: 20 30 3b 0a 0a 20 20 20 20 20 20 66 6f 72 28 69   0;..      for(i
1920: 50 68 72 61 73 65 3d 30 3b 20 69 50 68 72 61 73  Phrase=0; iPhras
1930: 65 3c 70 2d 3e 6e 50 68 72 61 73 65 3b 20 69 50  e<p->nPhrase; iP
1940: 68 72 61 73 65 2b 2b 29 7b 0a 20 20 20 20 20 20  hrase++){.      
1950: 20 20 46 74 73 35 50 68 72 61 73 65 49 74 65 72    Fts5PhraseIter
1960: 20 69 74 65 72 3b 0a 20 20 20 20 20 20 20 20 69   iter;.        i
1970: 6e 74 20 69 4f 66 66 2c 20 69 43 6f 6c 3b 0a 20  nt iOff, iCol;. 
1980: 20 20 20 20 20 20 20 66 6f 72 28 70 41 70 69 2d         for(pApi-
1990: 3e 78 50 68 72 61 73 65 46 69 72 73 74 28 70 46  >xPhraseFirst(pF
19a0: 74 73 2c 20 69 50 68 72 61 73 65 2c 20 26 69 74  ts, iPhrase, &it
19b0: 65 72 2c 20 26 69 43 6f 6c 2c 20 26 69 4f 66 66  er, &iCol, &iOff
19c0: 29 3b 20 0a 20 20 20 20 20 20 20 20 20 20 20 20  ); .            
19d0: 69 4f 66 66 3e 3d 30 3b 20 0a 20 20 20 20 20 20  iOff>=0; .      
19e0: 20 20 20 20 20 20 70 41 70 69 2d 3e 78 50 68 72        pApi->xPhr
19f0: 61 73 65 4e 65 78 74 28 70 46 74 73 2c 20 26 69  aseNext(pFts, &i
1a00: 74 65 72 2c 20 26 69 43 6f 6c 2c 20 26 69 4f 66  ter, &iCol, &iOf
1a10: 66 29 0a 20 20 20 20 20 20 20 20 29 7b 0a 20 20  f).        ){.  
1a20: 20 20 20 20 20 20 20 20 61 4f 75 74 5b 6e 4d 75          aOut[nMu
1a30: 6c 20 2a 20 28 69 43 6f 6c 20 2b 20 69 50 68 72  l * (iCol + iPhr
1a40: 61 73 65 20 2a 20 70 2d 3e 6e 43 6f 6c 29 5d 2b  ase * p->nCol)]+
1a50: 2b 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20  +;.        }.   
1a60: 20 20 20 7d 0a 0a 20 20 20 20 20 20 62 72 65 61     }..      brea
1a70: 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 63 61  k;.    }..    ca
1a80: 73 65 20 27 6c 27 3a 20 7b 0a 20 20 20 20 20 20  se 'l': {.      
1a90: 66 6f 72 28 69 3d 30 3b 20 72 63 3d 3d 53 51 4c  for(i=0; rc==SQL
1aa0: 49 54 45 5f 4f 4b 20 26 26 20 69 3c 70 2d 3e 6e  ITE_OK && i<p->n
1ab0: 43 6f 6c 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20  Col; i++){.     
1ac0: 20 20 20 69 6e 74 20 6e 54 6f 6b 65 6e 3b 0a 20     int nToken;. 
1ad0: 20 20 20 20 20 20 20 72 63 20 3d 20 70 41 70 69         rc = pApi
1ae0: 2d 3e 78 43 6f 6c 75 6d 6e 53 69 7a 65 28 70 46  ->xColumnSize(pF
1af0: 74 73 2c 20 69 2c 20 26 6e 54 6f 6b 65 6e 29 3b  ts, i, &nToken);
1b00: 0a 20 20 20 20 20 20 20 20 61 4f 75 74 5b 69 5d  .        aOut[i]
1b10: 20 3d 20 28 75 33 32 29 6e 54 6f 6b 65 6e 3b 0a   = (u32)nToken;.
1b20: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 62 72        }.      br
1b30: 65 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20  eak;.    }..    
1b40: 63 61 73 65 20 27 73 27 3a 20 7b 0a 20 20 20 20  case 's': {.    
1b50: 20 20 69 6e 74 20 6e 49 6e 73 74 3b 0a 0a 20 20    int nInst;..  
1b60: 20 20 20 20 6d 65 6d 73 65 74 28 61 4f 75 74 2c      memset(aOut,
1b70: 20 30 2c 20 73 69 7a 65 6f 66 28 75 33 32 29 20   0, sizeof(u32) 
1b80: 2a 20 70 2d 3e 6e 43 6f 6c 29 3b 0a 0a 20 20 20  * p->nCol);..   
1b90: 20 20 20 72 63 20 3d 20 70 41 70 69 2d 3e 78 49     rc = pApi->xI
1ba0: 6e 73 74 43 6f 75 6e 74 28 70 46 74 73 2c 20 26  nstCount(pFts, &
1bb0: 6e 49 6e 73 74 29 3b 0a 20 20 20 20 20 20 66 6f  nInst);.      fo
1bc0: 72 28 69 3d 30 3b 20 72 63 3d 3d 53 51 4c 49 54  r(i=0; rc==SQLIT
1bd0: 45 5f 4f 4b 20 26 26 20 69 3c 6e 49 6e 73 74 3b  E_OK && i<nInst;
1be0: 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 69   i++){.        i
1bf0: 6e 74 20 69 50 68 72 61 73 65 2c 20 69 4f 66 66  nt iPhrase, iOff
1c00: 2c 20 69 43 6f 6c 20 3d 20 30 3b 0a 20 20 20 20  , iCol = 0;.    
1c10: 20 20 20 20 69 6e 74 20 69 4e 65 78 74 50 68 72      int iNextPhr
1c20: 61 73 65 3b 0a 20 20 20 20 20 20 20 20 69 6e 74  ase;.        int
1c30: 20 69 4e 65 78 74 4f 66 66 3b 0a 20 20 20 20 20   iNextOff;.     
1c40: 20 20 20 75 33 32 20 6e 53 65 71 20 3d 20 31 3b     u32 nSeq = 1;
1c50: 0a 20 20 20 20 20 20 20 20 69 6e 74 20 6a 3b 0a  .        int j;.
1c60: 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 70 41  .        rc = pA
1c70: 70 69 2d 3e 78 49 6e 73 74 28 70 46 74 73 2c 20  pi->xInst(pFts, 
1c80: 69 2c 20 26 69 50 68 72 61 73 65 2c 20 26 69 43  i, &iPhrase, &iC
1c90: 6f 6c 2c 20 26 69 4f 66 66 29 3b 0a 20 20 20 20  ol, &iOff);.    
1ca0: 20 20 20 20 69 4e 65 78 74 50 68 72 61 73 65 20      iNextPhrase 
1cb0: 3d 20 69 50 68 72 61 73 65 2b 31 3b 0a 20 20 20  = iPhrase+1;.   
1cc0: 20 20 20 20 20 69 4e 65 78 74 4f 66 66 20 3d 20       iNextOff = 
1cd0: 69 4f 66 66 2b 70 41 70 69 2d 3e 78 50 68 72 61  iOff+pApi->xPhra
1ce0: 73 65 53 69 7a 65 28 70 46 74 73 2c 20 30 29 3b  seSize(pFts, 0);
1cf0: 0a 20 20 20 20 20 20 20 20 66 6f 72 28 6a 3d 69  .        for(j=i
1d00: 2b 31 3b 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  +1; rc==SQLITE_O
1d10: 4b 20 26 26 20 6a 3c 6e 49 6e 73 74 3b 20 6a 2b  K && j<nInst; j+
1d20: 2b 29 7b 0a 20 20 20 20 20 20 20 20 20 20 69 6e  +){.          in
1d30: 74 20 69 70 2c 20 69 63 2c 20 69 6f 3b 0a 20 20  t ip, ic, io;.  
1d40: 20 20 20 20 20 20 20 20 72 63 20 3d 20 70 41 70          rc = pAp
1d50: 69 2d 3e 78 49 6e 73 74 28 70 46 74 73 2c 20 6a  i->xInst(pFts, j
1d60: 2c 20 26 69 70 2c 20 26 69 63 2c 20 26 69 6f 29  , &ip, &ic, &io)
1d70: 3b 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20  ;.          if( 
1d80: 69 63 21 3d 69 43 6f 6c 20 7c 7c 20 69 6f 3e 69  ic!=iCol || io>i
1d90: 4e 65 78 74 4f 66 66 20 29 20 62 72 65 61 6b 3b  NextOff ) break;
1da0: 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20 69  .          if( i
1db0: 70 3d 3d 69 4e 65 78 74 50 68 72 61 73 65 20 26  p==iNextPhrase &
1dc0: 26 20 69 6f 3d 3d 69 4e 65 78 74 4f 66 66 20 29  & io==iNextOff )
1dd0: 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 6e 53  {.            nS
1de0: 65 71 2b 2b 3b 0a 20 20 20 20 20 20 20 20 20 20  eq++;.          
1df0: 20 20 69 4e 65 78 74 50 68 72 61 73 65 20 3d 20    iNextPhrase = 
1e00: 69 70 2b 31 3b 0a 20 20 20 20 20 20 20 20 20 20  ip+1;.          
1e10: 20 20 69 4e 65 78 74 4f 66 66 20 3d 20 69 6f 20    iNextOff = io 
1e20: 2b 20 70 41 70 69 2d 3e 78 50 68 72 61 73 65 53  + pApi->xPhraseS
1e30: 69 7a 65 28 70 46 74 73 2c 20 69 70 29 3b 0a 20  ize(pFts, ip);. 
1e40: 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20           }.     
1e50: 20 20 20 7d 0a 0a 20 20 20 20 20 20 20 20 69 66     }..        if
1e60: 28 20 6e 53 65 71 3e 61 4f 75 74 5b 69 43 6f 6c  ( nSeq>aOut[iCol
1e70: 5d 20 29 20 61 4f 75 74 5b 69 43 6f 6c 5d 20 3d  ] ) aOut[iCol] =
1e80: 20 6e 53 65 71 3b 0a 20 20 20 20 20 20 7d 0a 0a   nSeq;.      }..
1e90: 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20        break;.   
1ea0: 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20   }.  }.  return 
1eb0: 72 63 3b 0a 7d 0a 20 0a 73 74 61 74 69 63 20 46  rc;.}. .static F
1ec0: 74 73 35 4d 61 74 63 68 69 6e 66 6f 43 74 78 20  ts5MatchinfoCtx 
1ed0: 2a 66 74 73 35 4d 61 74 63 68 69 6e 66 6f 4e 65  *fts5MatchinfoNe
1ee0: 77 28 0a 20 20 63 6f 6e 73 74 20 46 74 73 35 45  w(.  const Fts5E
1ef0: 78 74 65 6e 73 69 6f 6e 41 70 69 20 2a 70 41 70  xtensionApi *pAp
1f00: 69 2c 20 20 20 2f 2a 20 41 50 49 20 6f 66 66 65  i,   /* API offe
1f10: 72 65 64 20 62 79 20 63 75 72 72 65 6e 74 20 46  red by current F
1f20: 54 53 20 76 65 72 73 69 6f 6e 20 2a 2f 0a 20 20  TS version */.  
1f30: 46 74 73 35 43 6f 6e 74 65 78 74 20 2a 70 46 74  Fts5Context *pFt
1f40: 73 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  s,              
1f50: 2f 2a 20 46 69 72 73 74 20 61 72 67 20 74 6f 20  /* First arg to 
1f60: 70 61 73 73 20 74 6f 20 70 41 70 69 20 66 75 6e  pass to pApi fun
1f70: 63 74 69 6f 6e 73 20 2a 2f 0a 20 20 73 71 6c 69  ctions */.  sqli
1f80: 74 65 33 5f 63 6f 6e 74 65 78 74 20 2a 70 43 74  te3_context *pCt
1f90: 78 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43  x,          /* C
1fa0: 6f 6e 74 65 78 74 20 66 6f 72 20 72 65 74 75 72  ontext for retur
1fb0: 6e 69 6e 67 20 65 72 72 6f 72 20 6d 65 73 73 61  ning error messa
1fc0: 67 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68  ge */.  const ch
1fd0: 61 72 20 2a 7a 41 72 67 20 20 20 20 20 20 20 20  ar *zArg        
1fe0: 20 20 20 20 20 20 20 20 2f 2a 20 4d 61 74 63 68          /* Match
1ff0: 69 6e 66 6f 20 66 6c 61 67 20 73 74 72 69 6e 67  info flag string
2000: 20 2a 2f 0a 29 7b 0a 20 20 46 74 73 35 4d 61 74   */.){.  Fts5Mat
2010: 63 68 69 6e 66 6f 43 74 78 20 2a 70 3b 0a 20 20  chinfoCtx *p;.  
2020: 69 6e 74 20 6e 43 6f 6c 3b 0a 20 20 69 6e 74 20  int nCol;.  int 
2030: 6e 50 68 72 61 73 65 3b 0a 20 20 69 6e 74 20 69  nPhrase;.  int i
2040: 3b 0a 20 20 69 6e 74 20 6e 49 6e 74 3b 0a 20 20  ;.  int nInt;.  
2050: 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 6e 42  sqlite3_int64 nB
2060: 79 74 65 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 0a  yte;.  int rc;..
2070: 20 20 6e 43 6f 6c 20 3d 20 70 41 70 69 2d 3e 78    nCol = pApi->x
2080: 43 6f 6c 75 6d 6e 43 6f 75 6e 74 28 70 46 74 73  ColumnCount(pFts
2090: 29 3b 0a 20 20 6e 50 68 72 61 73 65 20 3d 20 70  );.  nPhrase = p
20a0: 41 70 69 2d 3e 78 50 68 72 61 73 65 43 6f 75 6e  Api->xPhraseCoun
20b0: 74 28 70 46 74 73 29 3b 0a 0a 20 20 6e 49 6e 74  t(pFts);..  nInt
20c0: 20 3d 20 30 3b 0a 20 20 66 6f 72 28 69 3d 30 3b   = 0;.  for(i=0;
20d0: 20 7a 41 72 67 5b 69 5d 3b 20 69 2b 2b 29 7b 0a   zArg[i]; i++){.
20e0: 20 20 20 20 69 6e 74 20 6e 20 3d 20 66 74 73 35      int n = fts5
20f0: 4d 61 74 63 68 69 6e 66 6f 46 6c 61 67 73 69 7a  MatchinfoFlagsiz
2100: 65 28 6e 43 6f 6c 2c 20 6e 50 68 72 61 73 65 2c  e(nCol, nPhrase,
2110: 20 7a 41 72 67 5b 69 5d 29 3b 0a 20 20 20 20 69   zArg[i]);.    i
2120: 66 28 20 6e 3c 30 20 29 7b 0a 20 20 20 20 20 20  f( n<0 ){.      
2130: 63 68 61 72 20 2a 7a 45 72 72 20 3d 20 73 71 6c  char *zErr = sql
2140: 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 75 6e  ite3_mprintf("un
2150: 72 65 63 6f 67 6e 69 7a 65 64 20 6d 61 74 63 68  recognized match
2160: 69 6e 66 6f 20 66 6c 61 67 3a 20 25 63 22 2c 20  info flag: %c", 
2170: 7a 41 72 67 5b 69 5d 29 3b 0a 20 20 20 20 20 20  zArg[i]);.      
2180: 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 65  sqlite3_result_e
2190: 72 72 6f 72 28 70 43 74 78 2c 20 7a 45 72 72 2c  rror(pCtx, zErr,
21a0: 20 2d 31 29 3b 0a 20 20 20 20 20 20 73 71 6c 69   -1);.      sqli
21b0: 74 65 33 5f 66 72 65 65 28 7a 45 72 72 29 3b 0a  te3_free(zErr);.
21c0: 20 20 20 20 20 20 72 65 74 75 72 6e 20 30 3b 0a        return 0;.
21d0: 20 20 20 20 7d 0a 20 20 20 20 6e 49 6e 74 20 2b      }.    nInt +
21e0: 3d 20 6e 3b 0a 20 20 7d 0a 0a 20 20 6e 42 79 74  = n;.  }..  nByt
21f0: 65 20 3d 20 73 69 7a 65 6f 66 28 46 74 73 35 4d  e = sizeof(Fts5M
2200: 61 74 63 68 69 6e 66 6f 43 74 78 29 20 20 20 20  atchinfoCtx)    
2210: 20 20 20 20 20 20 2f 2a 20 54 68 65 20 73 74 72        /* The str
2220: 75 63 74 20 69 74 73 65 6c 66 20 2a 2f 0a 20 20  uct itself */.  
2230: 20 20 20 20 20 20 20 2b 20 73 69 7a 65 6f 66 28         + sizeof(
2240: 75 33 32 29 20 2a 20 6e 49 6e 74 20 20 20 20 20  u32) * nInt     
2250: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65            /* The
2260: 20 70 2d 3e 61 52 65 74 5b 5d 20 61 72 72 61 79   p->aRet[] array
2270: 20 2a 2f 0a 20 20 20 20 20 20 20 20 20 2b 20 28   */.         + (
2280: 69 2b 31 29 3b 20 20 20 20 20 20 20 20 20 20 20  i+1);           
2290: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
22a0: 2f 2a 20 54 68 65 20 70 2d 3e 7a 41 72 67 20 73  /* The p->zArg s
22b0: 74 72 69 6e 67 20 2a 2f 0a 20 20 70 20 3d 20 28  tring */.  p = (
22c0: 46 74 73 35 4d 61 74 63 68 69 6e 66 6f 43 74 78  Fts5MatchinfoCtx
22d0: 2a 29 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63  *)sqlite3_malloc
22e0: 36 34 28 6e 42 79 74 65 29 3b 0a 20 20 69 66 28  64(nByte);.  if(
22f0: 20 70 3d 3d 30 20 29 7b 0a 20 20 20 20 73 71 6c   p==0 ){.    sql
2300: 69 74 65 33 5f 72 65 73 75 6c 74 5f 65 72 72 6f  ite3_result_erro
2310: 72 5f 6e 6f 6d 65 6d 28 70 43 74 78 29 3b 0a 20  r_nomem(pCtx);. 
2320: 20 20 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 7d     return 0;.  }
2330: 0a 20 20 6d 65 6d 73 65 74 28 70 2c 20 30 2c 20  .  memset(p, 0, 
2340: 6e 42 79 74 65 29 3b 0a 0a 20 20 70 2d 3e 6e 43  nByte);..  p->nC
2350: 6f 6c 20 3d 20 6e 43 6f 6c 3b 0a 20 20 70 2d 3e  ol = nCol;.  p->
2360: 6e 50 68 72 61 73 65 20 3d 20 6e 50 68 72 61 73  nPhrase = nPhras
2370: 65 3b 0a 20 20 70 2d 3e 61 52 65 74 20 3d 20 28  e;.  p->aRet = (
2380: 75 33 32 2a 29 26 70 5b 31 5d 3b 0a 20 20 70 2d  u32*)&p[1];.  p-
2390: 3e 6e 52 65 74 20 3d 20 6e 49 6e 74 3b 0a 20 20  >nRet = nInt;.  
23a0: 70 2d 3e 7a 41 72 67 20 3d 20 28 63 68 61 72 2a  p->zArg = (char*
23b0: 29 26 70 2d 3e 61 52 65 74 5b 6e 49 6e 74 5d 3b  )&p->aRet[nInt];
23c0: 0a 20 20 6d 65 6d 63 70 79 28 70 2d 3e 7a 41 72  .  memcpy(p->zAr
23d0: 67 2c 20 7a 41 72 67 2c 20 69 29 3b 0a 0a 20 20  g, zArg, i);..  
23e0: 72 63 20 3d 20 66 74 73 35 4d 61 74 63 68 69 6e  rc = fts5Matchin
23f0: 66 6f 49 74 65 72 28 70 41 70 69 2c 20 70 46 74  foIter(pApi, pFt
2400: 73 2c 20 70 2c 20 66 74 73 35 4d 61 74 63 68 69  s, p, fts5Matchi
2410: 6e 66 6f 47 6c 6f 62 61 6c 43 62 29 3b 0a 20 20  nfoGlobalCb);.  
2420: 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
2430: 4b 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33  K ){.    sqlite3
2440: 5f 72 65 73 75 6c 74 5f 65 72 72 6f 72 5f 63 6f  _result_error_co
2450: 64 65 28 70 43 74 78 2c 20 72 63 29 3b 0a 20 20  de(pCtx, rc);.  
2460: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70    sqlite3_free(p
2470: 29 3b 0a 20 20 20 20 70 20 3d 20 30 3b 0a 20 20  );.    p = 0;.  
2480: 7d 0a 0a 20 20 72 65 74 75 72 6e 20 70 3b 0a 7d  }..  return p;.}
2490: 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 66 74  ..static void ft
24a0: 73 35 4d 61 74 63 68 69 6e 66 6f 46 75 6e 63 28  s5MatchinfoFunc(
24b0: 0a 20 20 63 6f 6e 73 74 20 46 74 73 35 45 78 74  .  const Fts5Ext
24c0: 65 6e 73 69 6f 6e 41 70 69 20 2a 70 41 70 69 2c  ensionApi *pApi,
24d0: 20 20 20 2f 2a 20 41 50 49 20 6f 66 66 65 72 65     /* API offere
24e0: 64 20 62 79 20 63 75 72 72 65 6e 74 20 46 54 53  d by current FTS
24f0: 20 76 65 72 73 69 6f 6e 20 2a 2f 0a 20 20 46 74   version */.  Ft
2500: 73 35 43 6f 6e 74 65 78 74 20 2a 70 46 74 73 2c  s5Context *pFts,
2510: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
2520: 20 46 69 72 73 74 20 61 72 67 20 74 6f 20 70 61   First arg to pa
2530: 73 73 20 74 6f 20 70 41 70 69 20 66 75 6e 63 74  ss to pApi funct
2540: 69 6f 6e 73 20 2a 2f 0a 20 20 73 71 6c 69 74 65  ions */.  sqlite
2550: 33 5f 63 6f 6e 74 65 78 74 20 2a 70 43 74 78 2c  3_context *pCtx,
2560: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 6e            /* Con
2570: 74 65 78 74 20 66 6f 72 20 72 65 74 75 72 6e 69  text for returni
2580: 6e 67 20 72 65 73 75 6c 74 2f 65 72 72 6f 72 20  ng result/error 
2590: 2a 2f 0a 20 20 69 6e 74 20 6e 56 61 6c 2c 20 20  */.  int nVal,  
25a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
25b0: 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
25c0: 66 20 76 61 6c 75 65 73 20 69 6e 20 61 70 56 61  f values in apVa
25d0: 6c 5b 5d 20 61 72 72 61 79 20 2a 2f 0a 20 20 73  l[] array */.  s
25e0: 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a 61  qlite3_value **a
25f0: 70 56 61 6c 20 20 20 20 20 20 20 20 20 20 20 2f  pVal           /
2600: 2a 20 41 72 72 61 79 20 6f 66 20 74 72 61 69 6c  * Array of trail
2610: 69 6e 67 20 61 72 67 75 6d 65 6e 74 73 20 2a 2f  ing arguments */
2620: 0a 29 7b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72  .){.  const char
2630: 20 2a 7a 41 72 67 3b 0a 20 20 46 74 73 35 4d 61   *zArg;.  Fts5Ma
2640: 74 63 68 69 6e 66 6f 43 74 78 20 2a 70 3b 0a 20  tchinfoCtx *p;. 
2650: 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
2660: 5f 4f 4b 3b 0a 0a 20 20 69 66 28 20 6e 56 61 6c  _OK;..  if( nVal
2670: 3e 30 20 29 7b 0a 20 20 20 20 7a 41 72 67 20 3d  >0 ){.    zArg =
2680: 20 28 63 6f 6e 73 74 20 63 68 61 72 2a 29 73 71   (const char*)sq
2690: 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 65 78 74  lite3_value_text
26a0: 28 61 70 56 61 6c 5b 30 5d 29 3b 0a 20 20 7d 65  (apVal[0]);.  }e
26b0: 6c 73 65 7b 0a 20 20 20 20 7a 41 72 67 20 3d 20  lse{.    zArg = 
26c0: 22 70 63 78 22 3b 0a 20 20 7d 0a 0a 20 20 70 20  "pcx";.  }..  p 
26d0: 3d 20 28 46 74 73 35 4d 61 74 63 68 69 6e 66 6f  = (Fts5Matchinfo
26e0: 43 74 78 2a 29 70 41 70 69 2d 3e 78 47 65 74 41  Ctx*)pApi->xGetA
26f0: 75 78 64 61 74 61 28 70 46 74 73 2c 20 30 29 3b  uxdata(pFts, 0);
2700: 0a 20 20 69 66 28 20 70 3d 3d 30 20 7c 7c 20 73  .  if( p==0 || s
2710: 71 6c 69 74 65 33 5f 73 74 72 69 63 6d 70 28 7a  qlite3_stricmp(z
2720: 41 72 67 2c 20 70 2d 3e 7a 41 72 67 29 20 29 7b  Arg, p->zArg) ){
2730: 0a 20 20 20 20 70 20 3d 20 66 74 73 35 4d 61 74  .    p = fts5Mat
2740: 63 68 69 6e 66 6f 4e 65 77 28 70 41 70 69 2c 20  chinfoNew(pApi, 
2750: 70 46 74 73 2c 20 70 43 74 78 2c 20 7a 41 72 67  pFts, pCtx, zArg
2760: 29 3b 0a 20 20 20 20 69 66 28 20 70 3d 3d 30 20  );.    if( p==0 
2770: 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51  ){.      rc = SQ
2780: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20  LITE_NOMEM;.    
2790: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 72 63 20  }else{.      rc 
27a0: 3d 20 70 41 70 69 2d 3e 78 53 65 74 41 75 78 64  = pApi->xSetAuxd
27b0: 61 74 61 28 70 46 74 73 2c 20 70 2c 20 73 71 6c  ata(pFts, p, sql
27c0: 69 74 65 33 5f 66 72 65 65 29 3b 0a 20 20 20 20  ite3_free);.    
27d0: 7d 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d  }.  }..  if( rc=
27e0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
27f0: 20 20 72 63 20 3d 20 66 74 73 35 4d 61 74 63 68    rc = fts5Match
2800: 69 6e 66 6f 49 74 65 72 28 70 41 70 69 2c 20 70  infoIter(pApi, p
2810: 46 74 73 2c 20 70 2c 20 66 74 73 35 4d 61 74 63  Fts, p, fts5Matc
2820: 68 69 6e 66 6f 4c 6f 63 61 6c 43 62 29 3b 0a 20  hinfoLocalCb);. 
2830: 20 7d 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c   }.  if( rc!=SQL
2840: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 73 71  ITE_OK ){.    sq
2850: 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 65 72 72  lite3_result_err
2860: 6f 72 5f 63 6f 64 65 28 70 43 74 78 2c 20 72 63  or_code(pCtx, rc
2870: 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  );.  }else{.    
2880: 2f 2a 20 4e 6f 20 65 72 72 6f 72 73 20 68 61 73  /* No errors has
2890: 20 6f 63 63 75 72 65 64 2c 20 73 6f 20 72 65 74   occured, so ret
28a0: 75 72 6e 20 61 20 63 6f 70 79 20 6f 66 20 74 68  urn a copy of th
28b0: 65 20 61 72 72 61 79 20 6f 66 20 69 6e 74 65 67  e array of integ
28c0: 65 72 73 2e 20 2a 2f 0a 20 20 20 20 69 6e 74 20  ers. */.    int 
28d0: 6e 42 79 74 65 20 3d 20 70 2d 3e 6e 52 65 74 20  nByte = p->nRet 
28e0: 2a 20 73 69 7a 65 6f 66 28 75 33 32 29 3b 0a 20  * sizeof(u32);. 
28f0: 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c     sqlite3_resul
2900: 74 5f 62 6c 6f 62 28 70 43 74 78 2c 20 28 76 6f  t_blob(pCtx, (vo
2910: 69 64 2a 29 70 2d 3e 61 52 65 74 2c 20 6e 42 79  id*)p->aRet, nBy
2920: 74 65 2c 20 53 51 4c 49 54 45 5f 54 52 41 4e 53  te, SQLITE_TRANS
2930: 49 45 4e 54 29 3b 0a 20 20 7d 0a 7d 0a 0a 69 6e  IENT);.  }.}..in
2940: 74 20 73 71 6c 69 74 65 33 46 74 73 35 54 65 73  t sqlite3Fts5Tes
2950: 74 52 65 67 69 73 74 65 72 4d 61 74 63 68 69 6e  tRegisterMatchin
2960: 66 6f 28 73 71 6c 69 74 65 33 20 2a 64 62 29 7b  fo(sqlite3 *db){
2970: 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20  .  int rc;      
2980: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2990: 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64     /* Return cod
29a0: 65 20 2a 2f 0a 20 20 66 74 73 35 5f 61 70 69 20  e */.  fts5_api 
29b0: 2a 70 41 70 69 3b 20 20 20 20 20 20 20 20 20 20  *pApi;          
29c0: 20 20 20 20 20 20 20 2f 2a 20 46 54 53 35 20 41         /* FTS5 A
29d0: 50 49 20 66 75 6e 63 74 69 6f 6e 73 20 2a 2f 0a  PI functions */.
29e0: 0a 20 20 2f 2a 20 45 78 74 72 61 63 74 20 74 68  .  /* Extract th
29f0: 65 20 46 54 53 35 20 41 50 49 20 70 6f 69 6e 74  e FTS5 API point
2a00: 65 72 20 66 72 6f 6d 20 74 68 65 20 64 61 74 61  er from the data
2a10: 62 61 73 65 20 68 61 6e 64 6c 65 2e 20 54 68 65  base handle. The
2a20: 20 0a 20 20 2a 2a 20 66 74 73 35 5f 61 70 69 5f   .  ** fts5_api_
2a30: 66 72 6f 6d 5f 64 62 28 29 20 66 75 6e 63 74 69  from_db() functi
2a40: 6f 6e 20 61 62 6f 76 65 20 69 73 20 63 6f 70 69  on above is copi
2a50: 65 64 20 76 65 72 62 61 74 69 6d 20 66 72 6f 6d  ed verbatim from
2a60: 20 74 68 65 20 0a 20 20 2a 2a 20 46 54 53 35 20   the .  ** FTS5 
2a70: 64 6f 63 75 6d 65 6e 74 61 74 69 6f 6e 2e 20 52  documentation. R
2a80: 65 66 65 72 20 74 68 65 72 65 20 66 6f 72 20 64  efer there for d
2a90: 65 74 61 69 6c 73 2e 20 2a 2f 0a 20 20 72 63 20  etails. */.  rc 
2aa0: 3d 20 66 74 73 35 5f 61 70 69 5f 66 72 6f 6d 5f  = fts5_api_from_
2ab0: 64 62 28 64 62 2c 20 26 70 41 70 69 29 3b 0a 20  db(db, &pApi);. 
2ac0: 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
2ad0: 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a  OK ) return rc;.
2ae0: 0a 20 20 2f 2a 20 49 66 20 66 74 73 35 5f 61 70  .  /* If fts5_ap
2af0: 69 5f 66 72 6f 6d 5f 64 62 28 29 20 72 65 74 75  i_from_db() retu
2b00: 72 6e 73 20 4e 55 4c 4c 2c 20 74 68 65 6e 20 65  rns NULL, then e
2b10: 69 74 68 65 72 20 46 54 53 35 20 69 73 20 6e 6f  ither FTS5 is no
2b20: 74 20 72 65 67 69 73 74 65 72 65 64 0a 20 20 2a  t registered.  *
2b30: 2a 20 77 69 74 68 20 74 68 69 73 20 64 61 74 61  * with this data
2b40: 62 61 73 65 20 68 61 6e 64 6c 65 2c 20 6f 72 20  base handle, or 
2b50: 61 6e 20 65 72 72 6f 72 20 28 4f 4f 4d 20 70 65  an error (OOM pe
2b60: 72 68 61 70 73 3f 29 20 68 61 73 20 6f 63 63 75  rhaps?) has occu
2b70: 72 72 65 64 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20  rred..  **.  ** 
2b80: 41 6c 73 6f 20 63 68 65 63 6b 20 74 68 61 74 20  Also check that 
2b90: 74 68 65 20 66 74 73 35 5f 61 70 69 20 6f 62 6a  the fts5_api obj
2ba0: 65 63 74 20 69 73 20 76 65 72 73 69 6f 6e 20 32  ect is version 2
2bb0: 20 6f 72 20 6e 65 77 65 72 2e 20 20 0a 20 20 2a   or newer.  .  *
2bc0: 2f 20 0a 20 20 69 66 28 20 70 41 70 69 3d 3d 30  / .  if( pApi==0
2bd0: 20 7c 7c 20 70 41 70 69 2d 3e 69 56 65 72 73 69   || pApi->iVersi
2be0: 6f 6e 3c 32 20 29 7b 0a 20 20 20 20 72 65 74 75  on<2 ){.    retu
2bf0: 72 6e 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b  rn SQLITE_ERROR;
2c00: 0a 20 20 7d 0a 0a 20 20 2f 2a 20 52 65 67 69 73  .  }..  /* Regis
2c10: 74 65 72 20 74 68 65 20 69 6d 70 6c 65 6d 65 6e  ter the implemen
2c20: 74 61 74 69 6f 6e 20 6f 66 20 6d 61 74 63 68 69  tation of matchi
2c30: 6e 66 6f 28 29 20 2a 2f 0a 20 20 72 63 20 3d 20  nfo() */.  rc = 
2c40: 70 41 70 69 2d 3e 78 43 72 65 61 74 65 46 75 6e  pApi->xCreateFun
2c50: 63 74 69 6f 6e 28 70 41 70 69 2c 20 22 6d 61 74  ction(pApi, "mat
2c60: 63 68 69 6e 66 6f 22 2c 20 30 2c 20 66 74 73 35  chinfo", 0, fts5
2c70: 4d 61 74 63 68 69 6e 66 6f 46 75 6e 63 2c 20 30  MatchinfoFunc, 0
2c80: 29 3b 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b  );..  return rc;
2c90: 0a 7d 0a 0a 23 65 6e 64 69 66 20 2f 2a 20 53 51  .}..#endif /* SQ
2ca0: 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 46 54 53 35  LITE_ENABLE_FTS5
2cb0: 20 2a 2f 0a                                       */.