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

Artifact a11a5f262fb3e36f943ce008933528c88f1520ca:


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 2e  row..**.**  2) .
04a0: 2e 2e 0a 2a 2a 20 20 20 20 20 0a 2a 2a 20 54 68  ...**     .** Th
04b0: 69 73 20 66 69 6c 65 20 65 78 70 6f 72 74 73 20  is file exports 
04c0: 61 20 73 69 6e 67 6c 65 20 66 75 6e 63 74 69 6f  a single functio
04d0: 6e 20 74 68 61 74 20 6d 61 79 20 62 65 20 63 61  n that may be ca
04e0: 6c 6c 65 64 20 74 6f 20 72 65 67 69 73 74 65 72  lled to register
04f0: 20 74 68 65 0a 2a 2a 20 6d 61 74 63 68 69 6e 66   the.** matchinf
0500: 6f 28 29 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69  o() implementati
0510: 6f 6e 20 77 69 74 68 20 61 20 64 61 74 61 62 61  on with a databa
0520: 73 65 20 68 61 6e 64 6c 65 3a 0a 2a 2a 0a 2a 2a  se handle:.**.**
0530: 20 20 20 69 6e 74 20 73 71 6c 69 74 65 33 46 74     int sqlite3Ft
0540: 73 35 54 65 73 74 52 65 67 69 73 74 65 72 4d 61  s5TestRegisterMa
0550: 74 63 68 69 6e 66 6f 28 73 71 6c 69 74 65 33 20  tchinfo(sqlite3 
0560: 2a 64 62 29 3b 0a 2a 2f 0a 0a 0a 23 69 66 64 65  *db);.*/...#ifde
0570: 66 20 53 51 4c 49 54 45 5f 54 45 53 54 0a 23 69  f SQLITE_TEST.#i
0580: 66 64 65 66 20 53 51 4c 49 54 45 5f 45 4e 41 42  fdef SQLITE_ENAB
0590: 4c 45 5f 46 54 53 35 0a 0a 23 69 6e 63 6c 75 64  LE_FTS5..#includ
05a0: 65 20 22 66 74 73 35 2e 68 22 0a 23 69 6e 63 6c  e "fts5.h".#incl
05b0: 75 64 65 20 3c 74 63 6c 2e 68 3e 0a 23 69 6e 63  ude <tcl.h>.#inc
05c0: 6c 75 64 65 20 3c 61 73 73 65 72 74 2e 68 3e 0a  lude <assert.h>.
05d0: 23 69 6e 63 6c 75 64 65 20 3c 73 74 72 69 6e 67  #include <string
05e0: 2e 68 3e 0a 0a 74 79 70 65 64 65 66 20 73 74 72  .h>..typedef str
05f0: 75 63 74 20 46 74 73 35 4d 61 74 63 68 69 6e 66  uct Fts5Matchinf
0600: 6f 43 74 78 20 46 74 73 35 4d 61 74 63 68 69 6e  oCtx Fts5Matchin
0610: 66 6f 43 74 78 3b 0a 74 79 70 65 64 65 66 20 75  foCtx;.typedef u
0620: 6e 73 69 67 6e 65 64 20 69 6e 74 20 75 33 32 3b  nsigned int u32;
0630: 0a 0a 73 74 72 75 63 74 20 46 74 73 35 4d 61 74  ..struct Fts5Mat
0640: 63 68 69 6e 66 6f 43 74 78 20 7b 0a 20 20 69 6e  chinfoCtx {.  in
0650: 74 20 6e 43 6f 6c 3b 20 20 20 20 20 20 20 20 20  t nCol;         
0660: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0670: 20 4e 75 6d 62 65 72 20 6f 66 20 63 6f 6c 73 20   Number of cols 
0680: 69 6e 20 46 54 53 35 20 74 61 62 6c 65 20 2a 2f  in FTS5 table */
0690: 0a 20 20 69 6e 74 20 6e 50 68 72 61 73 65 3b 20  .  int nPhrase; 
06a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
06b0: 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20     /* Number of 
06c0: 70 68 72 61 73 65 73 20 69 6e 20 46 54 53 35 20  phrases in FTS5 
06d0: 71 75 65 72 79 20 2a 2f 0a 20 20 63 68 61 72 20  query */.  char 
06e0: 2a 7a 41 72 67 3b 20 20 20 20 20 20 20 20 20 20  *zArg;          
06f0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 6e 75             /* nu
0700: 6c 2d 74 65 72 6d 27 64 20 63 6f 70 79 20 6f 66  l-term'd copy of
0710: 20 32 6e 64 20 61 72 67 20 2a 2f 0a 20 20 69 6e   2nd arg */.  in
0720: 74 20 6e 52 65 74 3b 20 20 20 20 20 20 20 20 20  t nRet;         
0730: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0740: 20 4e 75 6d 62 65 72 20 6f 66 20 65 6c 65 6d 65   Number of eleme
0750: 6e 74 73 20 69 6e 20 61 52 65 74 5b 5d 20 2a 2f  nts in aRet[] */
0760: 0a 20 20 75 33 32 20 2a 61 52 65 74 3b 20 20 20  .  u32 *aRet;   
0770: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0780: 20 20 20 2f 2a 20 41 72 72 61 79 20 6f 66 20 33     /* Array of 3
0790: 32 2d 62 69 74 20 75 6e 73 69 67 6e 65 64 20 69  2-bit unsigned i
07a0: 6e 74 73 20 74 6f 20 72 65 74 75 72 6e 20 2a 2f  nts to return */
07b0: 0a 7d 3b 0a 0a 0a 0a 2f 2a 0a 2a 2a 20 52 65 74  .};..../*.** Ret
07c0: 75 72 6e 20 61 20 70 6f 69 6e 74 65 72 20 74 6f  urn a pointer to
07d0: 20 74 68 65 20 66 74 73 35 5f 61 70 69 20 70 6f   the fts5_api po
07e0: 69 6e 74 65 72 20 66 6f 72 20 64 61 74 61 62 61  inter for databa
07f0: 73 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 64 62  se connection db
0800: 2e 0a 2a 2a 20 49 66 20 61 6e 20 65 72 72 6f 72  ..** If an error
0810: 20 6f 63 63 75 72 73 2c 20 72 65 74 75 72 6e 20   occurs, return 
0820: 4e 55 4c 4c 20 61 6e 64 20 6c 65 61 76 65 20 61  NULL and leave a
0830: 6e 20 65 72 72 6f 72 20 69 6e 20 74 68 65 20 64  n error in the d
0840: 61 74 61 62 61 73 65 20 0a 2a 2a 20 68 61 6e 64  atabase .** hand
0850: 6c 65 20 28 61 63 63 65 73 73 69 62 6c 65 20 75  le (accessible u
0860: 73 69 6e 67 20 73 71 6c 69 74 65 33 5f 65 72 72  sing sqlite3_err
0870: 63 6f 64 65 28 29 2f 65 72 72 6d 73 67 28 29 29  code()/errmsg())
0880: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 66 74 73 35  ..*/.static fts5
0890: 5f 61 70 69 20 2a 66 74 73 35 5f 61 70 69 5f 66  _api *fts5_api_f
08a0: 72 6f 6d 5f 64 62 28 73 71 6c 69 74 65 33 20 2a  rom_db(sqlite3 *
08b0: 64 62 29 7b 0a 20 20 66 74 73 35 5f 61 70 69 20  db){.  fts5_api 
08c0: 2a 70 52 65 74 20 3d 20 30 3b 0a 20 20 73 71 6c  *pRet = 0;.  sql
08d0: 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74  ite3_stmt *pStmt
08e0: 20 3d 20 30 3b 0a 0a 20 20 69 66 28 20 53 51 4c   = 0;..  if( SQL
08f0: 49 54 45 5f 4f 4b 3d 3d 73 71 6c 69 74 65 33 5f  ITE_OK==sqlite3_
0900: 70 72 65 70 61 72 65 28 64 62 2c 20 22 53 45 4c  prepare(db, "SEL
0910: 45 43 54 20 66 74 73 35 28 29 22 2c 20 2d 31 2c  ECT fts5()", -1,
0920: 20 26 70 53 74 6d 74 2c 20 30 29 0a 20 20 20 26   &pStmt, 0).   &
0930: 26 20 53 51 4c 49 54 45 5f 52 4f 57 3d 3d 73 71  & SQLITE_ROW==sq
0940: 6c 69 74 65 33 5f 73 74 65 70 28 70 53 74 6d 74  lite3_step(pStmt
0950: 29 20 0a 20 20 20 26 26 20 73 69 7a 65 6f 66 28  ) .   && sizeof(
0960: 70 52 65 74 29 3d 3d 73 71 6c 69 74 65 33 5f 63  pRet)==sqlite3_c
0970: 6f 6c 75 6d 6e 5f 62 79 74 65 73 28 70 53 74 6d  olumn_bytes(pStm
0980: 74 2c 20 30 29 0a 20 20 29 7b 0a 20 20 20 20 6d  t, 0).  ){.    m
0990: 65 6d 63 70 79 28 26 70 52 65 74 2c 20 73 71 6c  emcpy(&pRet, sql
09a0: 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 62 6c 6f 62  ite3_column_blob
09b0: 28 70 53 74 6d 74 2c 20 30 29 2c 20 73 69 7a 65  (pStmt, 0), size
09c0: 6f 66 28 70 52 65 74 29 29 3b 0a 20 20 7d 0a 20  of(pRet));.  }. 
09d0: 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a   sqlite3_finaliz
09e0: 65 28 70 53 74 6d 74 29 3b 0a 20 20 72 65 74 75  e(pStmt);.  retu
09f0: 72 6e 20 70 52 65 74 3b 0a 7d 0a 0a 0a 2f 2a 0a  rn pRet;.}.../*.
0a00: 2a 2a 20 41 72 67 75 6d 65 6e 74 20 66 20 73 68  ** Argument f sh
0a10: 6f 75 6c 64 20 62 65 20 61 20 66 6c 61 67 20 61  ould be a flag a
0a20: 63 63 65 70 74 65 64 20 62 79 20 6d 61 74 63 68  ccepted by match
0a30: 69 6e 66 6f 28 29 20 28 61 20 76 61 6c 69 64 20  info() (a valid 
0a40: 63 68 61 72 61 63 74 65 72 0a 2a 2a 20 69 6e 20  character.** in 
0a50: 74 68 65 20 73 74 72 69 6e 67 20 70 61 73 73 65  the string passe
0a60: 64 20 61 73 20 74 68 65 20 73 65 63 6f 6e 64 20  d as the second 
0a70: 61 72 67 75 6d 65 6e 74 29 2e 20 49 66 20 69 74  argument). If it
0a80: 20 69 73 20 6e 6f 74 2c 20 30 20 69 73 20 0a 2a   is not, 0 is .*
0a90: 2a 20 72 65 74 75 72 6e 65 64 2e 20 4f 74 68 65  * returned. Othe
0aa0: 72 77 69 73 65 2c 20 69 66 20 66 20 69 73 20 61  rwise, if f is a
0ab0: 20 76 61 6c 69 64 20 6d 61 74 63 68 69 6e 66 6f   valid matchinfo
0ac0: 20 66 6c 61 67 2c 20 74 68 65 20 76 61 6c 75 65   flag, the value
0ad0: 20 72 65 74 75 72 6e 65 64 0a 2a 2a 20 69 73 20   returned.** is 
0ae0: 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 33 32  the number of 32
0af0: 2d 62 69 74 20 69 6e 74 65 67 65 72 73 20 61 64  -bit integers ad
0b00: 64 65 64 20 74 6f 20 74 68 65 20 6f 75 74 70 75  ded to the outpu
0b10: 74 20 61 72 72 61 79 20 69 66 20 74 68 65 0a 2a  t array if the.*
0b20: 2a 20 74 61 62 6c 65 20 68 61 73 20 6e 43 6f 6c  * table has nCol
0b30: 20 63 6f 6c 75 6d 6e 73 20 61 6e 64 20 74 68 65   columns and the
0b40: 20 71 75 65 72 79 20 6e 50 68 72 61 73 65 20 70   query nPhrase p
0b50: 68 72 61 73 65 73 2e 0a 2a 2f 0a 73 74 61 74 69  hrases..*/.stati
0b60: 63 20 69 6e 74 20 66 74 73 35 4d 61 74 63 68 69  c int fts5Matchi
0b70: 6e 66 6f 46 6c 61 67 73 69 7a 65 28 69 6e 74 20  nfoFlagsize(int 
0b80: 6e 43 6f 6c 2c 20 69 6e 74 20 6e 50 68 72 61 73  nCol, int nPhras
0b90: 65 2c 20 63 68 61 72 20 66 29 7b 0a 20 20 69 6e  e, char f){.  in
0ba0: 74 20 72 65 74 20 3d 20 30 3b 0a 20 20 73 77 69  t ret = 0;.  swi
0bb0: 74 63 68 28 20 66 20 29 7b 0a 20 20 20 20 63 61  tch( f ){.    ca
0bc0: 73 65 20 27 70 27 3a 20 72 65 74 20 3d 20 31 3b  se 'p': ret = 1;
0bd0: 20 62 72 65 61 6b 3b 0a 20 20 20 20 63 61 73 65   break;.    case
0be0: 20 27 63 27 3a 20 72 65 74 20 3d 20 31 3b 20 62   'c': ret = 1; b
0bf0: 72 65 61 6b 3b 0a 20 20 20 20 63 61 73 65 20 27  reak;.    case '
0c00: 78 27 3a 20 72 65 74 20 3d 20 33 20 2a 20 6e 43  x': ret = 3 * nC
0c10: 6f 6c 20 2a 20 6e 50 68 72 61 73 65 3b 20 62 72  ol * nPhrase; br
0c20: 65 61 6b 3b 0a 20 20 20 20 63 61 73 65 20 27 79  eak;.    case 'y
0c30: 27 3a 20 72 65 74 20 3d 20 6e 43 6f 6c 20 2a 20  ': ret = nCol * 
0c40: 6e 50 68 72 61 73 65 3b 20 62 72 65 61 6b 3b 0a  nPhrase; break;.
0c50: 20 20 20 20 63 61 73 65 20 27 62 27 3a 20 72 65      case 'b': re
0c60: 74 20 3d 20 28 28 6e 43 6f 6c 20 2b 20 33 31 29  t = ((nCol + 31)
0c70: 20 2f 20 33 32 29 20 2a 20 6e 50 68 72 61 73 65   / 32) * nPhrase
0c80: 3b 20 62 72 65 61 6b 3b 0a 20 20 20 20 63 61 73  ; break;.    cas
0c90: 65 20 27 6e 27 3a 20 72 65 74 20 3d 20 31 3b 20  e 'n': ret = 1; 
0ca0: 62 72 65 61 6b 3b 0a 20 20 20 20 63 61 73 65 20  break;.    case 
0cb0: 27 61 27 3a 20 72 65 74 20 3d 20 6e 43 6f 6c 3b  'a': ret = nCol;
0cc0: 20 62 72 65 61 6b 3b 0a 20 20 20 20 63 61 73 65   break;.    case
0cd0: 20 27 6c 27 3a 20 72 65 74 20 3d 20 6e 43 6f 6c   'l': ret = nCol
0ce0: 3b 20 62 72 65 61 6b 3b 0a 20 20 20 20 63 61 73  ; break;.    cas
0cf0: 65 20 27 73 27 3a 20 72 65 74 20 3d 20 6e 43 6f  e 's': ret = nCo
0d00: 6c 3b 20 62 72 65 61 6b 3b 0a 20 20 7d 0a 20 20  l; break;.  }.  
0d10: 72 65 74 75 72 6e 20 72 65 74 3b 0a 7d 0a 0a 73  return ret;.}..s
0d20: 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 4d 61  tatic int fts5Ma
0d30: 74 63 68 69 6e 66 6f 49 74 65 72 28 0a 20 20 63  tchinfoIter(.  c
0d40: 6f 6e 73 74 20 46 74 73 35 45 78 74 65 6e 73 69  onst Fts5Extensi
0d50: 6f 6e 41 70 69 20 2a 70 41 70 69 2c 20 20 20 2f  onApi *pApi,   /
0d60: 2a 20 41 50 49 20 6f 66 66 65 72 65 64 20 62 79  * API offered by
0d70: 20 63 75 72 72 65 6e 74 20 46 54 53 20 76 65 72   current FTS ver
0d80: 73 69 6f 6e 20 2a 2f 0a 20 20 46 74 73 35 43 6f  sion */.  Fts5Co
0d90: 6e 74 65 78 74 20 2a 70 46 74 73 2c 20 20 20 20  ntext *pFts,    
0da0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 69 72            /* Fir
0db0: 73 74 20 61 72 67 20 74 6f 20 70 61 73 73 20 74  st arg to pass t
0dc0: 6f 20 70 41 70 69 20 66 75 6e 63 74 69 6f 6e 73  o pApi functions
0dd0: 20 2a 2f 0a 20 20 46 74 73 35 4d 61 74 63 68 69   */.  Fts5Matchi
0de0: 6e 66 6f 43 74 78 20 2a 70 2c 0a 20 20 69 6e 74  nfoCtx *p,.  int
0df0: 28 2a 78 29 28 63 6f 6e 73 74 20 46 74 73 35 45  (*x)(const Fts5E
0e00: 78 74 65 6e 73 69 6f 6e 41 70 69 2a 2c 46 74 73  xtensionApi*,Fts
0e10: 35 43 6f 6e 74 65 78 74 2a 2c 46 74 73 35 4d 61  5Context*,Fts5Ma
0e20: 74 63 68 69 6e 66 6f 43 74 78 2a 2c 63 68 61 72  tchinfoCtx*,char
0e30: 2c 75 33 32 2a 29 0a 29 7b 0a 20 20 69 6e 74 20  ,u32*).){.  int 
0e40: 69 3b 0a 20 20 69 6e 74 20 6e 20 3d 20 30 3b 0a  i;.  int n = 0;.
0e50: 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
0e60: 45 5f 4f 4b 3b 0a 20 20 63 68 61 72 20 66 3b 0a  E_OK;.  char f;.
0e70: 20 20 66 6f 72 28 69 3d 30 3b 20 28 66 20 3d 20    for(i=0; (f = 
0e80: 70 2d 3e 7a 41 72 67 5b 69 5d 29 3b 20 69 2b 2b  p->zArg[i]); i++
0e90: 29 7b 0a 20 20 20 20 72 63 20 3d 20 78 28 70 41  ){.    rc = x(pA
0ea0: 70 69 2c 20 70 46 74 73 2c 20 70 2c 20 66 2c 20  pi, pFts, p, f, 
0eb0: 26 70 2d 3e 61 52 65 74 5b 6e 5d 29 3b 0a 20 20  &p->aRet[n]);.  
0ec0: 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
0ed0: 5f 4f 4b 20 29 20 62 72 65 61 6b 3b 0a 20 20 20  _OK ) break;.   
0ee0: 20 6e 20 2b 3d 20 66 74 73 35 4d 61 74 63 68 69   n += fts5Matchi
0ef0: 6e 66 6f 46 6c 61 67 73 69 7a 65 28 70 2d 3e 6e  nfoFlagsize(p->n
0f00: 43 6f 6c 2c 20 70 2d 3e 6e 50 68 72 61 73 65 2c  Col, p->nPhrase,
0f10: 20 66 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72   f);.  }.  retur
0f20: 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  n rc;.}..static 
0f30: 69 6e 74 20 66 74 73 35 4d 61 74 63 68 69 6e 66  int fts5Matchinf
0f40: 6f 58 43 62 28 0a 20 20 63 6f 6e 73 74 20 46 74  oXCb(.  const Ft
0f50: 73 35 45 78 74 65 6e 73 69 6f 6e 41 70 69 20 2a  s5ExtensionApi *
0f60: 70 41 70 69 2c 0a 20 20 46 74 73 35 43 6f 6e 74  pApi,.  Fts5Cont
0f70: 65 78 74 20 2a 70 46 74 73 2c 0a 20 20 76 6f 69  ext *pFts,.  voi
0f80: 64 20 2a 70 55 73 65 72 44 61 74 61 0a 29 7b 0a  d *pUserData.){.
0f90: 20 20 75 33 32 20 2a 61 4f 75 74 20 3d 20 28 75    u32 *aOut = (u
0fa0: 33 32 2a 29 70 55 73 65 72 44 61 74 61 3b 0a 20  32*)pUserData;. 
0fb0: 20 69 6e 74 20 6e 43 6f 6c 20 3d 20 70 41 70 69   int nCol = pApi
0fc0: 2d 3e 78 43 6f 6c 75 6d 6e 43 6f 75 6e 74 28 70  ->xColumnCount(p
0fd0: 46 74 73 29 3b 0a 20 20 69 6e 74 20 6e 49 6e 73  Fts);.  int nIns
0fe0: 74 3b 0a 20 20 69 6e 74 20 69 50 72 65 76 20 3d  t;.  int iPrev =
0ff0: 20 2d 31 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 20   -1;.  int rc;. 
1000: 20 69 6e 74 20 69 3b 0a 0a 20 20 72 63 20 3d 20   int i;..  rc = 
1010: 70 41 70 69 2d 3e 78 49 6e 73 74 43 6f 75 6e 74  pApi->xInstCount
1020: 28 70 46 74 73 2c 20 26 6e 49 6e 73 74 29 3b 0a  (pFts, &nInst);.
1030: 20 20 66 6f 72 28 69 3d 30 3b 20 72 63 3d 3d 53    for(i=0; rc==S
1040: 51 4c 49 54 45 5f 4f 4b 20 26 26 20 69 3c 6e 49  QLITE_OK && i<nI
1050: 6e 73 74 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69  nst; i++){.    i
1060: 6e 74 20 69 50 68 72 61 73 65 2c 20 69 43 6f 6c  nt iPhrase, iCol
1070: 2c 20 69 4f 66 66 3b 0a 20 20 20 20 72 63 20 3d  , iOff;.    rc =
1080: 20 70 41 70 69 2d 3e 78 49 6e 73 74 28 70 46 74   pApi->xInst(pFt
1090: 73 2c 20 69 2c 20 26 69 50 68 72 61 73 65 2c 20  s, i, &iPhrase, 
10a0: 26 69 43 6f 6c 2c 20 26 69 4f 66 66 29 3b 0a 20  &iCol, &iOff);. 
10b0: 20 20 20 61 4f 75 74 5b 69 43 6f 6c 2a 33 20 2b     aOut[iCol*3 +
10c0: 20 31 5d 2b 2b 3b 0a 20 20 20 20 69 66 28 20 69   1]++;.    if( i
10d0: 43 6f 6c 21 3d 69 50 72 65 76 20 29 20 61 4f 75  Col!=iPrev ) aOu
10e0: 74 5b 69 43 6f 6c 2a 33 20 2b 20 32 5d 2b 2b 3b  t[iCol*3 + 2]++;
10f0: 0a 20 20 20 20 69 50 72 65 76 20 3d 20 69 43 6f  .    iPrev = iCo
1100: 6c 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e  l;.  }..  return
1110: 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69   rc;.}..static i
1120: 6e 74 20 66 74 73 35 4d 61 74 63 68 69 6e 66 6f  nt fts5Matchinfo
1130: 47 6c 6f 62 61 6c 43 62 28 0a 20 20 63 6f 6e 73  GlobalCb(.  cons
1140: 74 20 46 74 73 35 45 78 74 65 6e 73 69 6f 6e 41  t Fts5ExtensionA
1150: 70 69 20 2a 70 41 70 69 2c 0a 20 20 46 74 73 35  pi *pApi,.  Fts5
1160: 43 6f 6e 74 65 78 74 20 2a 70 46 74 73 2c 0a 20  Context *pFts,. 
1170: 20 46 74 73 35 4d 61 74 63 68 69 6e 66 6f 43 74   Fts5MatchinfoCt
1180: 78 20 2a 70 2c 0a 20 20 63 68 61 72 20 66 2c 0a  x *p,.  char f,.
1190: 20 20 75 33 32 20 2a 61 4f 75 74 0a 29 7b 0a 20    u32 *aOut.){. 
11a0: 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
11b0: 5f 4f 4b 3b 0a 20 20 73 77 69 74 63 68 28 20 66  _OK;.  switch( f
11c0: 20 29 7b 0a 20 20 20 20 63 61 73 65 20 27 70 27   ){.    case 'p'
11d0: 3a 0a 20 20 20 20 20 20 61 4f 75 74 5b 30 5d 20  :.      aOut[0] 
11e0: 3d 20 70 2d 3e 6e 50 68 72 61 73 65 3b 20 0a 20  = p->nPhrase; . 
11f0: 20 20 20 20 20 62 72 65 61 6b 3b 0a 0a 20 20 20       break;..   
1200: 20 63 61 73 65 20 27 63 27 3a 0a 20 20 20 20 20   case 'c':.     
1210: 20 61 4f 75 74 5b 30 5d 20 3d 20 70 2d 3e 6e 43   aOut[0] = p->nC
1220: 6f 6c 3b 20 0a 20 20 20 20 20 20 62 72 65 61 6b  ol; .      break
1230: 3b 0a 0a 20 20 20 20 63 61 73 65 20 27 78 27 3a  ;..    case 'x':
1240: 20 7b 0a 20 20 20 20 20 20 69 6e 74 20 69 3b 0a   {.      int i;.
1250: 20 20 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69        for(i=0; i
1260: 3c 70 2d 3e 6e 50 68 72 61 73 65 20 26 26 20 72  <p->nPhrase && r
1270: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 3b 20 69 2b  c==SQLITE_OK; i+
1280: 2b 29 7b 0a 20 20 20 20 20 20 20 20 76 6f 69 64  +){.        void
1290: 20 2a 70 50 74 72 20 3d 20 28 76 6f 69 64 2a 29   *pPtr = (void*)
12a0: 26 61 4f 75 74 5b 69 20 2a 20 70 2d 3e 6e 43 6f  &aOut[i * p->nCo
12b0: 6c 20 2a 20 33 5d 3b 0a 20 20 20 20 20 20 20 20  l * 3];.        
12c0: 72 63 20 3d 20 70 41 70 69 2d 3e 78 51 75 65 72  rc = pApi->xQuer
12d0: 79 50 68 72 61 73 65 28 70 46 74 73 2c 20 69 2c  yPhrase(pFts, i,
12e0: 20 70 50 74 72 2c 20 66 74 73 35 4d 61 74 63 68   pPtr, fts5Match
12f0: 69 6e 66 6f 58 43 62 29 3b 0a 20 20 20 20 20 20  infoXCb);.      
1300: 7d 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20  }.      break;. 
1310: 20 20 20 7d 0a 0a 20 20 20 20 63 61 73 65 20 27     }..    case '
1320: 6e 27 3a 20 7b 0a 20 20 20 20 20 20 73 71 6c 69  n': {.      sqli
1330: 74 65 33 5f 69 6e 74 36 34 20 6e 52 6f 77 3b 0a  te3_int64 nRow;.
1340: 20 20 20 20 20 20 72 63 20 3d 20 70 41 70 69 2d        rc = pApi-
1350: 3e 78 52 6f 77 43 6f 75 6e 74 28 70 46 74 73 2c  >xRowCount(pFts,
1360: 20 26 6e 52 6f 77 29 3b 0a 20 20 20 20 20 20 61   &nRow);.      a
1370: 4f 75 74 5b 30 5d 20 3d 20 28 75 33 32 29 6e 52  Out[0] = (u32)nR
1380: 6f 77 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b  ow;.      break;
1390: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 63 61 73 65  .    }..    case
13a0: 20 27 61 27 3a 20 7b 0a 20 20 20 20 20 20 73 71   'a': {.      sq
13b0: 6c 69 74 65 33 5f 69 6e 74 36 34 20 6e 52 6f 77  lite3_int64 nRow
13c0: 20 3d 20 30 3b 0a 20 20 20 20 20 20 72 63 20 3d   = 0;.      rc =
13d0: 20 70 41 70 69 2d 3e 78 52 6f 77 43 6f 75 6e 74   pApi->xRowCount
13e0: 28 70 46 74 73 2c 20 26 6e 52 6f 77 29 3b 0a 20  (pFts, &nRow);. 
13f0: 20 20 20 20 20 69 66 28 20 6e 52 6f 77 3d 3d 30       if( nRow==0
1400: 20 29 7b 0a 20 20 20 20 20 20 20 20 6d 65 6d 73   ){.        mems
1410: 65 74 28 61 4f 75 74 2c 20 30 2c 20 73 69 7a 65  et(aOut, 0, size
1420: 6f 66 28 75 33 32 29 20 2a 20 70 2d 3e 6e 43 6f  of(u32) * p->nCo
1430: 6c 29 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b  l);.      }else{
1440: 0a 20 20 20 20 20 20 20 20 69 6e 74 20 69 3b 0a  .        int i;.
1450: 20 20 20 20 20 20 20 20 66 6f 72 28 69 3d 30 3b          for(i=0;
1460: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26   rc==SQLITE_OK &
1470: 26 20 69 3c 70 2d 3e 6e 43 6f 6c 3b 20 69 2b 2b  & i<p->nCol; i++
1480: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 73 71 6c  ){.          sql
1490: 69 74 65 33 5f 69 6e 74 36 34 20 6e 54 6f 6b 65  ite3_int64 nToke
14a0: 6e 3b 0a 20 20 20 20 20 20 20 20 20 20 72 63 20  n;.          rc 
14b0: 3d 20 70 41 70 69 2d 3e 78 43 6f 6c 75 6d 6e 54  = pApi->xColumnT
14c0: 6f 74 61 6c 53 69 7a 65 28 70 46 74 73 2c 20 69  otalSize(pFts, i
14d0: 2c 20 26 6e 54 6f 6b 65 6e 29 3b 0a 20 20 20 20  , &nToken);.    
14e0: 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51        if( rc==SQ
14f0: 4c 49 54 45 5f 4f 4b 29 7b 0a 20 20 20 20 20 20  LITE_OK){.      
1500: 20 20 20 20 20 20 61 4f 75 74 5b 69 5d 20 3d 20        aOut[i] = 
1510: 28 75 33 32 29 28 28 32 2a 6e 54 6f 6b 65 6e 20  (u32)((2*nToken 
1520: 2b 20 6e 52 6f 77 29 20 2f 20 28 32 2a 6e 52 6f  + nRow) / (2*nRo
1530: 77 29 29 3b 0a 20 20 20 20 20 20 20 20 20 20 7d  w));.          }
1540: 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
1550: 20 7d 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a   }.      break;.
1560: 20 20 20 20 7d 0a 0a 20 20 7d 0a 20 20 72 65 74      }..  }.  ret
1570: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69  urn rc;.}..stati
1580: 63 20 69 6e 74 20 66 74 73 35 4d 61 74 63 68 69  c int fts5Matchi
1590: 6e 66 6f 4c 6f 63 61 6c 43 62 28 0a 20 20 63 6f  nfoLocalCb(.  co
15a0: 6e 73 74 20 46 74 73 35 45 78 74 65 6e 73 69 6f  nst Fts5Extensio
15b0: 6e 41 70 69 20 2a 70 41 70 69 2c 0a 20 20 46 74  nApi *pApi,.  Ft
15c0: 73 35 43 6f 6e 74 65 78 74 20 2a 70 46 74 73 2c  s5Context *pFts,
15d0: 0a 20 20 46 74 73 35 4d 61 74 63 68 69 6e 66 6f  .  Fts5Matchinfo
15e0: 43 74 78 20 2a 70 2c 0a 20 20 63 68 61 72 20 66  Ctx *p,.  char f
15f0: 2c 0a 20 20 75 33 32 20 2a 61 4f 75 74 0a 29 7b  ,.  u32 *aOut.){
1600: 0a 20 20 69 6e 74 20 69 3b 0a 20 20 69 6e 74 20  .  int i;.  int 
1610: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  rc = SQLITE_OK;.
1620: 0a 20 20 73 77 69 74 63 68 28 20 66 20 29 7b 0a  .  switch( f ){.
1630: 20 20 20 20 63 61 73 65 20 27 62 27 3a 20 0a 20      case 'b': . 
1640: 20 20 20 63 61 73 65 20 27 78 27 3a 0a 20 20 20     case 'x':.   
1650: 20 63 61 73 65 20 27 79 27 3a 20 7b 0a 20 20 20   case 'y': {.   
1660: 20 20 20 69 6e 74 20 6e 49 6e 73 74 3b 0a 20 20     int nInst;.  
1670: 20 20 20 20 69 6e 74 20 6e 4d 75 6c 20 3d 20 28      int nMul = (
1680: 66 3d 3d 27 78 27 20 3f 20 33 20 3a 20 31 29 3b  f=='x' ? 3 : 1);
1690: 0a 0a 20 20 20 20 20 20 69 66 28 20 66 3d 3d 27  ..      if( f=='
16a0: 62 27 20 29 7b 0a 20 20 20 20 20 20 20 20 69 6e  b' ){.        in
16b0: 74 20 6e 49 6e 74 20 3d 20 28 28 70 2d 3e 6e 43  t nInt = ((p->nC
16c0: 6f 6c 20 2b 20 33 31 29 20 2f 20 33 32 29 20 2a  ol + 31) / 32) *
16d0: 20 70 2d 3e 6e 50 68 72 61 73 65 3b 0a 20 20 20   p->nPhrase;.   
16e0: 20 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c       for(i=0; i<
16f0: 6e 49 6e 74 3b 20 69 2b 2b 29 20 61 4f 75 74 5b  nInt; i++) aOut[
1700: 69 5d 20 3d 20 30 3b 0a 20 20 20 20 20 20 7d 65  i] = 0;.      }e
1710: 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 66 6f 72  lse{.        for
1720: 28 69 3d 30 3b 20 69 3c 28 70 2d 3e 6e 43 6f 6c  (i=0; i<(p->nCol
1730: 2a 70 2d 3e 6e 50 68 72 61 73 65 29 3b 20 69 2b  *p->nPhrase); i+
1740: 2b 29 20 61 4f 75 74 5b 69 2a 6e 4d 75 6c 5d 20  +) aOut[i*nMul] 
1750: 3d 20 30 3b 0a 20 20 20 20 20 20 7d 0a 0a 20 20  = 0;.      }..  
1760: 20 20 20 20 72 63 20 3d 20 70 41 70 69 2d 3e 78      rc = pApi->x
1770: 49 6e 73 74 43 6f 75 6e 74 28 70 46 74 73 2c 20  InstCount(pFts, 
1780: 26 6e 49 6e 73 74 29 3b 0a 20 20 20 20 20 20 66  &nInst);.      f
1790: 6f 72 28 69 3d 30 3b 20 72 63 3d 3d 53 51 4c 49  or(i=0; rc==SQLI
17a0: 54 45 5f 4f 4b 20 26 26 20 69 3c 6e 49 6e 73 74  TE_OK && i<nInst
17b0: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20  ; i++){.        
17c0: 69 6e 74 20 69 50 68 72 61 73 65 2c 20 69 4f 66  int iPhrase, iOf
17d0: 66 2c 20 69 43 6f 6c 20 3d 20 30 3b 0a 20 20 20  f, iCol = 0;.   
17e0: 20 20 20 20 20 72 63 20 3d 20 70 41 70 69 2d 3e       rc = pApi->
17f0: 78 49 6e 73 74 28 70 46 74 73 2c 20 69 2c 20 26  xInst(pFts, i, &
1800: 69 50 68 72 61 73 65 2c 20 26 69 43 6f 6c 2c 20  iPhrase, &iCol, 
1810: 26 69 4f 66 66 29 3b 0a 20 20 20 20 20 20 20 20  &iOff);.        
1820: 69 66 28 20 66 3d 3d 27 62 27 20 29 7b 0a 20 20  if( f=='b' ){.  
1830: 20 20 20 20 20 20 20 20 61 4f 75 74 5b 69 50 68          aOut[iPh
1840: 72 61 73 65 20 2a 20 28 28 70 2d 3e 6e 43 6f 6c  rase * ((p->nCol
1850: 2b 33 31 29 2f 33 32 29 20 2b 20 69 43 6f 6c 2f  +31)/32) + iCol/
1860: 33 32 5d 20 7c 3d 20 28 28 75 33 32 29 31 20 3c  32] |= ((u32)1 <
1870: 3c 20 28 69 43 6f 6c 25 33 32 29 29 3b 0a 20 20  < (iCol%32));.  
1880: 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20        }else{.   
1890: 20 20 20 20 20 20 20 61 4f 75 74 5b 6e 4d 75 6c         aOut[nMul
18a0: 20 2a 20 28 69 43 6f 6c 20 2b 20 69 50 68 72 61   * (iCol + iPhra
18b0: 73 65 20 2a 20 70 2d 3e 6e 43 6f 6c 29 5d 2b 2b  se * p->nCol)]++
18c0: 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
18d0: 20 20 7d 0a 0a 20 20 20 20 20 20 62 72 65 61 6b    }..      break
18e0: 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 63 61 73  ;.    }..    cas
18f0: 65 20 27 6c 27 3a 20 7b 0a 20 20 20 20 20 20 66  e 'l': {.      f
1900: 6f 72 28 69 3d 30 3b 20 72 63 3d 3d 53 51 4c 49  or(i=0; rc==SQLI
1910: 54 45 5f 4f 4b 20 26 26 20 69 3c 70 2d 3e 6e 43  TE_OK && i<p->nC
1920: 6f 6c 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20  ol; i++){.      
1930: 20 20 69 6e 74 20 6e 54 6f 6b 65 6e 3b 0a 20 20    int nToken;.  
1940: 20 20 20 20 20 20 72 63 20 3d 20 70 41 70 69 2d        rc = pApi-
1950: 3e 78 43 6f 6c 75 6d 6e 53 69 7a 65 28 70 46 74  >xColumnSize(pFt
1960: 73 2c 20 69 2c 20 26 6e 54 6f 6b 65 6e 29 3b 0a  s, i, &nToken);.
1970: 20 20 20 20 20 20 20 20 61 4f 75 74 5b 69 5d 20          aOut[i] 
1980: 3d 20 28 75 33 32 29 6e 54 6f 6b 65 6e 3b 0a 20  = (u32)nToken;. 
1990: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 62 72 65       }.      bre
19a0: 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 63  ak;.    }..    c
19b0: 61 73 65 20 27 73 27 3a 0a 20 20 20 20 20 20 6d  ase 's':.      m
19c0: 65 6d 73 65 74 28 61 4f 75 74 2c 20 30 2c 20 73  emset(aOut, 0, s
19d0: 69 7a 65 6f 66 28 75 33 32 29 20 2a 20 70 2d 3e  izeof(u32) * p->
19e0: 6e 43 6f 6c 29 3b 0a 20 20 20 20 20 20 62 72 65  nCol);.      bre
19f0: 61 6b 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  ak;.  }.  return
1a00: 20 72 63 3b 0a 7d 0a 20 0a 73 74 61 74 69 63 20   rc;.}. .static 
1a10: 46 74 73 35 4d 61 74 63 68 69 6e 66 6f 43 74 78  Fts5MatchinfoCtx
1a20: 20 2a 66 74 73 35 4d 61 74 63 68 69 6e 66 6f 4e   *fts5MatchinfoN
1a30: 65 77 28 0a 20 20 63 6f 6e 73 74 20 46 74 73 35  ew(.  const Fts5
1a40: 45 78 74 65 6e 73 69 6f 6e 41 70 69 20 2a 70 41  ExtensionApi *pA
1a50: 70 69 2c 20 20 20 2f 2a 20 41 50 49 20 6f 66 66  pi,   /* API off
1a60: 65 72 65 64 20 62 79 20 63 75 72 72 65 6e 74 20  ered by current 
1a70: 46 54 53 20 76 65 72 73 69 6f 6e 20 2a 2f 0a 20  FTS version */. 
1a80: 20 46 74 73 35 43 6f 6e 74 65 78 74 20 2a 70 46   Fts5Context *pF
1a90: 74 73 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ts,             
1aa0: 20 2f 2a 20 46 69 72 73 74 20 61 72 67 20 74 6f   /* First arg to
1ab0: 20 70 61 73 73 20 74 6f 20 70 41 70 69 20 66 75   pass to pApi fu
1ac0: 6e 63 74 69 6f 6e 73 20 2a 2f 0a 20 20 73 71 6c  nctions */.  sql
1ad0: 69 74 65 33 5f 63 6f 6e 74 65 78 74 20 2a 70 43  ite3_context *pC
1ae0: 74 78 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20  tx,          /* 
1af0: 43 6f 6e 74 65 78 74 20 66 6f 72 20 72 65 74 75  Context for retu
1b00: 72 6e 69 6e 67 20 65 72 72 6f 72 20 6d 65 73 73  rning error mess
1b10: 61 67 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63  age */.  const c
1b20: 68 61 72 20 2a 7a 41 72 67 20 20 20 20 20 20 20  har *zArg       
1b30: 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 61 74 63           /* Matc
1b40: 68 69 6e 66 6f 20 66 6c 61 67 20 73 74 72 69 6e  hinfo flag strin
1b50: 67 20 2a 2f 0a 29 7b 0a 20 20 46 74 73 35 4d 61  g */.){.  Fts5Ma
1b60: 74 63 68 69 6e 66 6f 43 74 78 20 2a 70 3b 0a 20  tchinfoCtx *p;. 
1b70: 20 69 6e 74 20 6e 43 6f 6c 3b 0a 20 20 69 6e 74   int nCol;.  int
1b80: 20 6e 50 68 72 61 73 65 3b 0a 20 20 69 6e 74 20   nPhrase;.  int 
1b90: 69 3b 0a 20 20 69 6e 74 20 6e 49 6e 74 3b 0a 20  i;.  int nInt;. 
1ba0: 20 69 6e 74 20 6e 42 79 74 65 3b 0a 20 20 69 6e   int nByte;.  in
1bb0: 74 20 72 63 3b 0a 0a 20 20 6e 43 6f 6c 20 3d 20  t rc;..  nCol = 
1bc0: 70 41 70 69 2d 3e 78 43 6f 6c 75 6d 6e 43 6f 75  pApi->xColumnCou
1bd0: 6e 74 28 70 46 74 73 29 3b 0a 20 20 6e 50 68 72  nt(pFts);.  nPhr
1be0: 61 73 65 20 3d 20 70 41 70 69 2d 3e 78 50 68 72  ase = pApi->xPhr
1bf0: 61 73 65 43 6f 75 6e 74 28 70 46 74 73 29 3b 0a  aseCount(pFts);.
1c00: 0a 20 20 6e 49 6e 74 20 3d 20 30 3b 0a 20 20 66  .  nInt = 0;.  f
1c10: 6f 72 28 69 3d 30 3b 20 7a 41 72 67 5b 69 5d 3b  or(i=0; zArg[i];
1c20: 20 69 2b 2b 29 7b 0a 20 20 20 20 69 6e 74 20 6e   i++){.    int n
1c30: 20 3d 20 66 74 73 35 4d 61 74 63 68 69 6e 66 6f   = fts5Matchinfo
1c40: 46 6c 61 67 73 69 7a 65 28 6e 43 6f 6c 2c 20 6e  Flagsize(nCol, n
1c50: 50 68 72 61 73 65 2c 20 7a 41 72 67 5b 69 5d 29  Phrase, zArg[i])
1c60: 3b 0a 20 20 20 20 69 66 28 20 6e 3d 3d 30 20 29  ;.    if( n==0 )
1c70: 7b 0a 20 20 20 20 20 20 63 68 61 72 20 2a 7a 45  {.      char *zE
1c80: 72 72 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72  rr = sqlite3_mpr
1c90: 69 6e 74 66 28 22 75 6e 72 65 63 6f 67 6e 69 7a  intf("unrecogniz
1ca0: 65 64 20 6d 61 74 63 68 69 6e 66 6f 20 66 6c 61  ed matchinfo fla
1cb0: 67 3a 20 25 63 22 2c 20 7a 41 72 67 5b 69 5d 29  g: %c", zArg[i])
1cc0: 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f  ;.      sqlite3_
1cd0: 72 65 73 75 6c 74 5f 65 72 72 6f 72 28 70 43 74  result_error(pCt
1ce0: 78 2c 20 7a 45 72 72 2c 20 2d 31 29 3b 0a 20 20  x, zErr, -1);.  
1cf0: 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65      sqlite3_free
1d00: 28 7a 45 72 72 29 3b 0a 20 20 20 20 20 20 72 65  (zErr);.      re
1d10: 74 75 72 6e 20 30 3b 0a 20 20 20 20 7d 0a 20 20  turn 0;.    }.  
1d20: 20 20 6e 49 6e 74 20 2b 3d 20 6e 3b 0a 20 20 7d    nInt += n;.  }
1d30: 0a 0a 20 20 6e 42 79 74 65 20 3d 20 73 69 7a 65  ..  nByte = size
1d40: 6f 66 28 46 74 73 35 4d 61 74 63 68 69 6e 66 6f  of(Fts5Matchinfo
1d50: 43 74 78 29 20 20 20 20 20 20 20 20 20 20 2f 2a  Ctx)          /*
1d60: 20 54 68 65 20 73 74 72 75 63 74 20 69 74 73 65   The struct itse
1d70: 6c 66 20 2a 2f 0a 20 20 20 20 20 20 20 20 20 2b  lf */.         +
1d80: 20 73 69 7a 65 6f 66 28 75 33 32 29 20 2a 20 6e   sizeof(u32) * n
1d90: 49 6e 74 20 20 20 20 20 20 20 20 20 20 20 20 20  Int             
1da0: 20 20 2f 2a 20 54 68 65 20 70 2d 3e 61 52 65 74    /* The p->aRet
1db0: 5b 5d 20 61 72 72 61 79 20 2a 2f 0a 20 20 20 20  [] array */.    
1dc0: 20 20 20 20 20 2b 20 28 69 2b 31 29 3b 20 20 20       + (i+1);   
1dd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1de0: 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20 70          /* The p
1df0: 2d 3e 7a 41 72 67 20 73 74 72 69 6e 67 20 2a 2f  ->zArg string */
1e00: 0a 20 20 70 20 3d 20 28 46 74 73 35 4d 61 74 63  .  p = (Fts5Matc
1e10: 68 69 6e 66 6f 43 74 78 2a 29 73 71 6c 69 74 65  hinfoCtx*)sqlite
1e20: 33 5f 6d 61 6c 6c 6f 63 28 6e 42 79 74 65 29 3b  3_malloc(nByte);
1e30: 0a 20 20 69 66 28 20 70 3d 3d 30 20 29 7b 0a 20  .  if( p==0 ){. 
1e40: 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c     sqlite3_resul
1e50: 74 5f 65 72 72 6f 72 5f 6e 6f 6d 65 6d 28 70 43  t_error_nomem(pC
1e60: 74 78 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20  tx);.    return 
1e70: 30 3b 0a 20 20 7d 0a 20 20 6d 65 6d 73 65 74 28  0;.  }.  memset(
1e80: 70 2c 20 30 2c 20 6e 42 79 74 65 29 3b 0a 0a 20  p, 0, nByte);.. 
1e90: 20 70 2d 3e 6e 43 6f 6c 20 3d 20 6e 43 6f 6c 3b   p->nCol = nCol;
1ea0: 0a 20 20 70 2d 3e 6e 50 68 72 61 73 65 20 3d 20  .  p->nPhrase = 
1eb0: 6e 50 68 72 61 73 65 3b 0a 20 20 70 2d 3e 61 52  nPhrase;.  p->aR
1ec0: 65 74 20 3d 20 28 75 33 32 2a 29 26 70 5b 31 5d  et = (u32*)&p[1]
1ed0: 3b 0a 20 20 70 2d 3e 6e 52 65 74 20 3d 20 6e 49  ;.  p->nRet = nI
1ee0: 6e 74 3b 0a 20 20 70 2d 3e 7a 41 72 67 20 3d 20  nt;.  p->zArg = 
1ef0: 28 63 68 61 72 2a 29 26 70 2d 3e 61 52 65 74 5b  (char*)&p->aRet[
1f00: 6e 49 6e 74 5d 3b 0a 20 20 6d 65 6d 63 70 79 28  nInt];.  memcpy(
1f10: 70 2d 3e 7a 41 72 67 2c 20 7a 41 72 67 2c 20 69  p->zArg, zArg, i
1f20: 29 3b 0a 0a 20 20 72 63 20 3d 20 66 74 73 35 4d  );..  rc = fts5M
1f30: 61 74 63 68 69 6e 66 6f 49 74 65 72 28 70 41 70  atchinfoIter(pAp
1f40: 69 2c 20 70 46 74 73 2c 20 70 2c 20 66 74 73 35  i, pFts, p, fts5
1f50: 4d 61 74 63 68 69 6e 66 6f 47 6c 6f 62 61 6c 43  MatchinfoGlobalC
1f60: 62 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51  b);.  if( rc!=SQ
1f70: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 73  LITE_OK ){.    s
1f80: 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 65 72  qlite3_result_er
1f90: 72 6f 72 5f 63 6f 64 65 28 70 43 74 78 2c 20 72  ror_code(pCtx, r
1fa0: 63 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f  c);.    sqlite3_
1fb0: 66 72 65 65 28 70 29 3b 0a 20 20 20 20 70 20 3d  free(p);.    p =
1fc0: 20 30 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72   0;.  }..  retur
1fd0: 6e 20 70 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76  n p;.}..static v
1fe0: 6f 69 64 20 66 74 73 35 4d 61 74 63 68 69 6e 66  oid fts5Matchinf
1ff0: 6f 46 75 6e 63 28 0a 20 20 63 6f 6e 73 74 20 46  oFunc(.  const F
2000: 74 73 35 45 78 74 65 6e 73 69 6f 6e 41 70 69 20  ts5ExtensionApi 
2010: 2a 70 41 70 69 2c 20 20 20 2f 2a 20 41 50 49 20  *pApi,   /* API 
2020: 6f 66 66 65 72 65 64 20 62 79 20 63 75 72 72 65  offered by curre
2030: 6e 74 20 46 54 53 20 76 65 72 73 69 6f 6e 20 2a  nt FTS version *
2040: 2f 0a 20 20 46 74 73 35 43 6f 6e 74 65 78 74 20  /.  Fts5Context 
2050: 2a 70 46 74 73 2c 20 20 20 20 20 20 20 20 20 20  *pFts,          
2060: 20 20 20 20 2f 2a 20 46 69 72 73 74 20 61 72 67      /* First arg
2070: 20 74 6f 20 70 61 73 73 20 74 6f 20 70 41 70 69   to pass to pApi
2080: 20 66 75 6e 63 74 69 6f 6e 73 20 2a 2f 0a 20 20   functions */.  
2090: 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74 20  sqlite3_context 
20a0: 2a 70 43 74 78 2c 20 20 20 20 20 20 20 20 20 20  *pCtx,          
20b0: 2f 2a 20 43 6f 6e 74 65 78 74 20 66 6f 72 20 72  /* Context for r
20c0: 65 74 75 72 6e 69 6e 67 20 72 65 73 75 6c 74 2f  eturning result/
20d0: 65 72 72 6f 72 20 2a 2f 0a 20 20 69 6e 74 20 6e  error */.  int n
20e0: 56 61 6c 2c 20 20 20 20 20 20 20 20 20 20 20 20  Val,            
20f0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75             /* Nu
2100: 6d 62 65 72 20 6f 66 20 76 61 6c 75 65 73 20 69  mber of values i
2110: 6e 20 61 70 56 61 6c 5b 5d 20 61 72 72 61 79 20  n apVal[] array 
2120: 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 76 61 6c  */.  sqlite3_val
2130: 75 65 20 2a 2a 61 70 56 61 6c 20 20 20 20 20 20  ue **apVal      
2140: 20 20 20 20 20 2f 2a 20 41 72 72 61 79 20 6f 66       /* Array of
2150: 20 74 72 61 69 6c 69 6e 67 20 61 72 67 75 6d 65   trailing argume
2160: 6e 74 73 20 2a 2f 0a 29 7b 0a 20 20 63 6f 6e 73  nts */.){.  cons
2170: 74 20 63 68 61 72 20 2a 7a 41 72 67 3b 0a 20 20  t char *zArg;.  
2180: 46 74 73 35 4d 61 74 63 68 69 6e 66 6f 43 74 78  Fts5MatchinfoCtx
2190: 20 2a 70 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 0a   *p;.  int rc;..
21a0: 20 20 69 66 28 20 6e 56 61 6c 3e 30 20 29 7b 0a    if( nVal>0 ){.
21b0: 20 20 20 20 7a 41 72 67 20 3d 20 28 63 6f 6e 73      zArg = (cons
21c0: 74 20 63 68 61 72 2a 29 73 71 6c 69 74 65 33 5f  t char*)sqlite3_
21d0: 76 61 6c 75 65 5f 74 65 78 74 28 61 70 56 61 6c  value_text(apVal
21e0: 5b 30 5d 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  [0]);.  }else{. 
21f0: 20 20 20 7a 41 72 67 20 3d 20 22 70 63 78 22 3b     zArg = "pcx";
2200: 0a 20 20 7d 0a 0a 20 20 70 20 3d 20 28 46 74 73  .  }..  p = (Fts
2210: 35 4d 61 74 63 68 69 6e 66 6f 43 74 78 2a 29 70  5MatchinfoCtx*)p
2220: 41 70 69 2d 3e 78 47 65 74 41 75 78 64 61 74 61  Api->xGetAuxdata
2230: 28 70 46 74 73 2c 20 30 29 3b 0a 20 20 69 66 28  (pFts, 0);.  if(
2240: 20 70 3d 3d 30 20 7c 7c 20 73 71 6c 69 74 65 33   p==0 || sqlite3
2250: 5f 73 74 72 69 63 6d 70 28 7a 41 72 67 2c 20 70  _stricmp(zArg, p
2260: 2d 3e 7a 41 72 67 29 20 29 7b 0a 20 20 20 20 70  ->zArg) ){.    p
2270: 20 3d 20 66 74 73 35 4d 61 74 63 68 69 6e 66 6f   = fts5Matchinfo
2280: 4e 65 77 28 70 41 70 69 2c 20 70 46 74 73 2c 20  New(pApi, pFts, 
2290: 70 43 74 78 2c 20 7a 41 72 67 29 3b 0a 20 20 20  pCtx, zArg);.   
22a0: 20 70 41 70 69 2d 3e 78 53 65 74 41 75 78 64 61   pApi->xSetAuxda
22b0: 74 61 28 70 46 74 73 2c 20 70 2c 20 73 71 6c 69  ta(pFts, p, sqli
22c0: 74 65 33 5f 66 72 65 65 29 3b 0a 20 20 20 20 69  te3_free);.    i
22d0: 66 28 20 70 3d 3d 30 20 29 20 72 65 74 75 72 6e  f( p==0 ) return
22e0: 3b 0a 20 20 7d 0a 0a 20 20 72 63 20 3d 20 66 74  ;.  }..  rc = ft
22f0: 73 35 4d 61 74 63 68 69 6e 66 6f 49 74 65 72 28  s5MatchinfoIter(
2300: 70 41 70 69 2c 20 70 46 74 73 2c 20 70 2c 20 66  pApi, pFts, p, f
2310: 74 73 35 4d 61 74 63 68 69 6e 66 6f 4c 6f 63 61  ts5MatchinfoLoca
2320: 6c 43 62 29 3b 0a 20 20 69 66 28 20 72 63 21 3d  lCb);.  if( rc!=
2330: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
2340: 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f   sqlite3_result_
2350: 65 72 72 6f 72 5f 63 6f 64 65 28 70 43 74 78 2c  error_code(pCtx,
2360: 20 72 63 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20   rc);.  }else{. 
2370: 20 20 20 2f 2a 20 4e 6f 20 65 72 72 6f 72 73 20     /* No errors 
2380: 68 61 73 20 6f 63 63 75 72 65 64 2c 20 73 6f 20  has occured, so 
2390: 72 65 74 75 72 6e 20 61 20 63 6f 70 79 20 6f 66  return a copy of
23a0: 20 74 68 65 20 61 72 72 61 79 20 6f 66 20 69 6e   the array of in
23b0: 74 65 67 65 72 73 2e 20 2a 2f 0a 20 20 20 20 69  tegers. */.    i
23c0: 6e 74 20 6e 42 79 74 65 20 3d 20 70 2d 3e 6e 52  nt nByte = p->nR
23d0: 65 74 20 2a 20 73 69 7a 65 6f 66 28 75 33 32 29  et * sizeof(u32)
23e0: 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65  ;.    sqlite3_re
23f0: 73 75 6c 74 5f 62 6c 6f 62 28 70 43 74 78 2c 20  sult_blob(pCtx, 
2400: 28 76 6f 69 64 2a 29 70 2d 3e 61 52 65 74 2c 20  (void*)p->aRet, 
2410: 6e 42 79 74 65 2c 20 53 51 4c 49 54 45 5f 54 52  nByte, SQLITE_TR
2420: 41 4e 53 49 45 4e 54 29 3b 0a 20 20 7d 0a 7d 0a  ANSIENT);.  }.}.
2430: 0a 69 6e 74 20 73 71 6c 69 74 65 33 46 74 73 35  .int sqlite3Fts5
2440: 54 65 73 74 52 65 67 69 73 74 65 72 4d 61 74 63  TestRegisterMatc
2450: 68 69 6e 66 6f 28 73 71 6c 69 74 65 33 20 2a 64  hinfo(sqlite3 *d
2460: 62 29 7b 0a 20 20 69 6e 74 20 72 63 3b 20 20 20  b){.  int rc;   
2470: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2480: 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20        /* Return 
2490: 63 6f 64 65 20 2a 2f 0a 20 20 66 74 73 35 5f 61  code */.  fts5_a
24a0: 70 69 20 2a 70 41 70 69 3b 20 20 20 20 20 20 20  pi *pApi;       
24b0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 54 53            /* FTS
24c0: 35 20 41 50 49 20 66 75 6e 63 74 69 6f 6e 73 20  5 API functions 
24d0: 2a 2f 0a 0a 20 20 2f 2a 20 45 78 74 72 61 63 74  */..  /* Extract
24e0: 20 74 68 65 20 46 54 53 35 20 41 50 49 20 70 6f   the FTS5 API po
24f0: 69 6e 74 65 72 20 66 72 6f 6d 20 74 68 65 20 64  inter from the d
2500: 61 74 61 62 61 73 65 20 68 61 6e 64 6c 65 2e 20  atabase handle. 
2510: 54 68 65 20 0a 20 20 2a 2a 20 66 74 73 35 5f 61  The .  ** fts5_a
2520: 70 69 5f 66 72 6f 6d 5f 64 62 28 29 20 66 75 6e  pi_from_db() fun
2530: 63 74 69 6f 6e 20 61 62 6f 76 65 20 69 73 20 63  ction above is c
2540: 6f 70 69 65 64 20 76 65 72 62 61 74 69 6d 20 66  opied verbatim f
2550: 72 6f 6d 20 74 68 65 20 0a 20 20 2a 2a 20 46 54  rom the .  ** FT
2560: 53 35 20 64 6f 63 75 6d 65 6e 74 61 74 69 6f 6e  S5 documentation
2570: 2e 20 52 65 66 65 72 20 74 68 65 72 65 20 66 6f  . Refer there fo
2580: 72 20 64 65 74 61 69 6c 73 2e 20 2a 2f 0a 20 20  r details. */.  
2590: 70 41 70 69 20 3d 20 66 74 73 35 5f 61 70 69 5f  pApi = fts5_api_
25a0: 66 72 6f 6d 5f 64 62 28 64 62 29 3b 0a 0a 20 20  from_db(db);..  
25b0: 2f 2a 20 49 66 20 66 74 73 35 5f 61 70 69 5f 66  /* If fts5_api_f
25c0: 72 6f 6d 5f 64 62 28 29 20 72 65 74 75 72 6e 73  rom_db() returns
25d0: 20 4e 55 4c 4c 2c 20 74 68 65 6e 20 65 69 74 68   NULL, then eith
25e0: 65 72 20 46 54 53 35 20 69 73 20 6e 6f 74 20 72  er FTS5 is not r
25f0: 65 67 69 73 74 65 72 65 64 0a 20 20 2a 2a 20 77  egistered.  ** w
2600: 69 74 68 20 74 68 69 73 20 64 61 74 61 62 61 73  ith this databas
2610: 65 20 68 61 6e 64 6c 65 2c 20 6f 72 20 61 6e 20  e handle, or an 
2620: 65 72 72 6f 72 20 28 4f 4f 4d 20 70 65 72 68 61  error (OOM perha
2630: 70 73 3f 29 20 68 61 73 20 6f 63 63 75 72 72 65  ps?) has occurre
2640: 64 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20 41 6c 73  d..  **.  ** Als
2650: 6f 20 63 68 65 63 6b 20 74 68 61 74 20 74 68 65  o check that the
2660: 20 66 74 73 35 5f 61 70 69 20 6f 62 6a 65 63 74   fts5_api object
2670: 20 69 73 20 76 65 72 73 69 6f 6e 20 31 20 6f 72   is version 1 or
2680: 20 6e 65 77 65 72 20 28 74 68 65 72 65 20 0a 20   newer (there . 
2690: 20 2a 2a 20 69 73 20 6e 6f 20 61 63 74 75 61 6c   ** is no actual
26a0: 20 76 65 72 73 69 6f 6e 20 6f 66 20 46 54 53 35   version of FTS5
26b0: 20 74 68 61 74 20 77 6f 75 6c 64 20 72 65 74 75   that would retu
26c0: 72 6e 20 61 6e 20 41 50 49 20 6f 62 6a 65 63 74  rn an API object
26d0: 20 6f 66 20 76 65 72 73 69 6f 6e 0a 20 20 2a 2a   of version.  **
26e0: 20 30 2c 20 62 75 74 20 46 54 53 35 20 65 78 74   0, but FTS5 ext
26f0: 65 6e 73 69 6f 6e 73 20 73 68 6f 75 6c 64 20 63  ensions should c
2700: 68 65 63 6b 20 74 68 65 20 41 50 49 20 76 65 72  heck the API ver
2710: 73 69 6f 6e 20 62 65 66 6f 72 65 20 75 73 69 6e  sion before usin
2720: 67 20 69 74 29 2e 20 2a 2f 0a 20 20 69 66 28 20  g it). */.  if( 
2730: 70 41 70 69 3d 3d 30 20 7c 7c 20 70 41 70 69 2d  pApi==0 || pApi-
2740: 3e 69 56 65 72 73 69 6f 6e 3c 31 20 29 7b 0a 20  >iVersion<1 ){. 
2750: 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45     return SQLITE
2760: 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20 2f  _ERROR;.  }..  /
2770: 2a 20 52 65 67 69 73 74 65 72 20 74 68 65 20 69  * Register the i
2780: 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66  mplementation of
2790: 20 6d 61 74 63 68 69 6e 66 6f 28 29 20 2a 2f 0a   matchinfo() */.
27a0: 20 20 72 63 20 3d 20 70 41 70 69 2d 3e 78 43 72    rc = pApi->xCr
27b0: 65 61 74 65 46 75 6e 63 74 69 6f 6e 28 70 41 70  eateFunction(pAp
27c0: 69 2c 20 22 6d 61 74 63 68 69 6e 66 6f 22 2c 20  i, "matchinfo", 
27d0: 30 2c 20 66 74 73 35 4d 61 74 63 68 69 6e 66 6f  0, fts5Matchinfo
27e0: 46 75 6e 63 2c 20 30 29 3b 0a 0a 20 20 72 65 74  Func, 0);..  ret
27f0: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 23 65 6e 64 69  urn rc;.}..#endi
2800: 66 20 2f 2a 20 53 51 4c 49 54 45 5f 45 4e 41 42  f /* SQLITE_ENAB
2810: 4c 45 5f 46 54 53 35 20 2a 2f 0a 23 65 6e 64 69  LE_FTS5 */.#endi
2820: 66 20 2f 2a 20 53 51 4c 49 54 45 5f 54 45 53 54  f /* SQLITE_TEST
2830: 20 2a 2f 0a 0a                                    */..