/ Hex Artifact Content
Login

Artifact f5800895e4d24b7351d44a3858c3a1611bb68dac:


0000: 2f 2a 0a 2a 2a 20 32 30 31 34 20 4a 75 6e 20 30  /*.** 2014 Jun 0
0010: 39 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 75 74 68  9.**.** 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 69 73 20 61 6e 20 53 51 4c 69 74 65 20 6d 6f   is an SQLite mo
0190: 64 75 6c 65 20 69 6d 70 6c 65 6d 65 6e 74 69 6e  dule implementin
01a0: 67 20 66 75 6c 6c 2d 74 65 78 74 20 73 65 61 72  g full-text sear
01b0: 63 68 2e 0a 2a 2f 0a 0a 23 69 66 20 64 65 66 69  ch..*/..#if defi
01c0: 6e 65 64 28 53 51 4c 49 54 45 5f 45 4e 41 42 4c  ned(SQLITE_ENABL
01d0: 45 5f 46 54 53 35 29 0a 0a 23 69 6e 63 6c 75 64  E_FTS5)..#includ
01e0: 65 20 22 66 74 73 35 49 6e 74 2e 68 22 0a 0a 2f  e "fts5Int.h"../
01f0: 2a 0a 2a 2a 20 54 68 69 73 20 76 61 72 69 61 62  *.** This variab
0200: 6c 65 20 69 73 20 73 65 74 20 74 6f 20 74 72 75  le is set to tru
0210: 65 20 77 68 65 6e 20 72 75 6e 6e 69 6e 67 20 63  e when running c
0220: 6f 72 72 75 70 74 69 6f 6e 20 74 65 73 74 73 2e  orruption tests.
0230: 20 4f 74 68 65 72 77 69 73 65 0a 2a 2a 20 66 61   Otherwise.** fa
0240: 6c 73 65 2e 20 49 66 20 69 74 20 69 73 20 66 61  lse. If it is fa
0250: 6c 73 65 2c 20 65 78 74 72 61 20 61 73 73 65 72  lse, extra asser
0260: 74 28 29 20 63 6f 6e 64 69 74 69 6f 6e 73 20 69  t() conditions i
0270: 6e 20 74 68 65 20 66 74 73 35 20 63 6f 64 65 20  n the fts5 code 
0280: 61 72 65 0a 2a 2a 20 61 63 74 69 76 61 74 65 64  are.** activated
0290: 20 2d 20 63 6f 6e 64 69 74 69 6f 6e 73 20 74 68   - conditions th
02a0: 61 74 20 61 72 65 20 6f 6e 6c 79 20 74 72 75 65  at are only true
02b0: 20 69 66 20 69 74 20 69 73 20 67 75 61 72 61 6e   if it is guaran
02c0: 74 65 65 64 20 74 68 61 74 20 74 68 65 0a 2a 2a  teed that the.**
02d0: 20 66 74 73 35 20 64 61 74 61 62 61 73 65 20 69   fts5 database i
02e0: 73 20 6e 6f 74 20 63 6f 72 72 75 70 74 2e 0a 2a  s not corrupt..*
02f0: 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 5f 66 74  /.int sqlite3_ft
0300: 73 35 5f 6d 61 79 5f 62 65 5f 63 6f 72 72 75 70  s5_may_be_corrup
0310: 74 20 3d 20 30 3b 0a 0a 0a 74 79 70 65 64 65 66  t = 0;...typedef
0320: 20 73 74 72 75 63 74 20 46 74 73 35 54 61 62 6c   struct Fts5Tabl
0330: 65 20 46 74 73 35 54 61 62 6c 65 3b 0a 74 79 70  e Fts5Table;.typ
0340: 65 64 65 66 20 73 74 72 75 63 74 20 46 74 73 35  edef struct Fts5
0350: 43 75 72 73 6f 72 20 46 74 73 35 43 75 72 73 6f  Cursor Fts5Curso
0360: 72 3b 0a 74 79 70 65 64 65 66 20 73 74 72 75 63  r;.typedef struc
0370: 74 20 46 74 73 35 47 6c 6f 62 61 6c 20 46 74 73  t Fts5Global Fts
0380: 35 47 6c 6f 62 61 6c 3b 0a 74 79 70 65 64 65 66  5Global;.typedef
0390: 20 73 74 72 75 63 74 20 46 74 73 35 41 75 78 69   struct Fts5Auxi
03a0: 6c 69 61 72 79 20 46 74 73 35 41 75 78 69 6c 69  liary Fts5Auxili
03b0: 61 72 79 3b 0a 74 79 70 65 64 65 66 20 73 74 72  ary;.typedef str
03c0: 75 63 74 20 46 74 73 35 41 75 78 64 61 74 61 20  uct Fts5Auxdata 
03d0: 46 74 73 35 41 75 78 64 61 74 61 3b 0a 0a 74 79  Fts5Auxdata;..ty
03e0: 70 65 64 65 66 20 73 74 72 75 63 74 20 46 74 73  pedef struct Fts
03f0: 35 54 6f 6b 65 6e 69 7a 65 72 4d 6f 64 75 6c 65  5TokenizerModule
0400: 20 46 74 73 35 54 6f 6b 65 6e 69 7a 65 72 4d 6f   Fts5TokenizerMo
0410: 64 75 6c 65 3b 0a 0a 2f 2a 0a 2a 2a 20 4e 4f 54  dule;../*.** NOT
0420: 45 53 20 4f 4e 20 54 52 41 4e 53 41 43 54 49 4f  ES ON TRANSACTIO
0430: 4e 53 3a 20 0a 2a 2a 0a 2a 2a 20 53 51 4c 69 74  NS: .**.** SQLit
0440: 65 20 69 6e 76 6f 6b 65 73 20 74 68 65 20 66 6f  e invokes the fo
0450: 6c 6c 6f 77 69 6e 67 20 76 69 72 74 75 61 6c 20  llowing virtual 
0460: 74 61 62 6c 65 20 6d 65 74 68 6f 64 73 20 61 73  table methods as
0470: 20 74 72 61 6e 73 61 63 74 69 6f 6e 73 20 61 72   transactions ar
0480: 65 20 0a 2a 2a 20 6f 70 65 6e 65 64 20 61 6e 64  e .** opened and
0490: 20 63 6c 6f 73 65 64 20 62 79 20 74 68 65 20 75   closed by the u
04a0: 73 65 72 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 78  ser:.**.**     x
04b0: 42 65 67 69 6e 28 29 3a 20 20 20 20 53 74 61 72  Begin():    Star
04c0: 74 20 6f 66 20 61 20 6e 65 77 20 74 72 61 6e 73  t of a new trans
04d0: 61 63 74 69 6f 6e 2e 0a 2a 2a 20 20 20 20 20 78  action..**     x
04e0: 53 79 6e 63 28 29 3a 20 20 20 20 20 49 6e 69 74  Sync():     Init
04f0: 69 61 6c 20 70 61 72 74 20 6f 66 20 74 77 6f 2d  ial part of two-
0500: 70 68 61 73 65 20 63 6f 6d 6d 69 74 2e 0a 2a 2a  phase commit..**
0510: 20 20 20 20 20 78 43 6f 6d 6d 69 74 28 29 3a 20       xCommit(): 
0520: 20 20 46 69 6e 61 6c 20 70 61 72 74 20 6f 66 20    Final part of 
0530: 74 77 6f 2d 70 68 61 73 65 20 63 6f 6d 6d 69 74  two-phase commit
0540: 2e 0a 2a 2a 20 20 20 20 20 78 52 6f 6c 6c 62 61  ..**     xRollba
0550: 63 6b 28 29 3a 20 52 6f 6c 6c 62 61 63 6b 20 74  ck(): Rollback t
0560: 68 65 20 74 72 61 6e 73 61 63 74 69 6f 6e 2e 0a  he transaction..
0570: 2a 2a 0a 2a 2a 20 41 6e 79 74 68 69 6e 67 20 74  **.** Anything t
0580: 68 61 74 20 69 73 20 72 65 71 75 69 72 65 64 20  hat is required 
0590: 61 73 20 70 61 72 74 20 6f 66 20 61 20 63 6f 6d  as part of a com
05a0: 6d 69 74 20 74 68 61 74 20 6d 61 79 20 66 61 69  mit that may fai
05b0: 6c 20 69 73 20 70 65 72 66 6f 72 6d 65 64 0a 2a  l is performed.*
05c0: 2a 20 69 6e 20 74 68 65 20 78 53 79 6e 63 28 29  * in the xSync()
05d0: 20 63 61 6c 6c 62 61 63 6b 2e 20 43 75 72 72 65   callback. Curre
05e0: 6e 74 20 76 65 72 73 69 6f 6e 73 20 6f 66 20 53  nt versions of S
05f0: 51 4c 69 74 65 20 69 67 6e 6f 72 65 20 61 6e 79  QLite ignore any
0600: 20 65 72 72 6f 72 73 20 0a 2a 2a 20 72 65 74 75   errors .** retu
0610: 72 6e 65 64 20 62 79 20 78 43 6f 6d 6d 69 74 28  rned by xCommit(
0620: 29 2e 0a 2a 2a 0a 2a 2a 20 41 6e 64 20 61 73 20  )..**.** And as 
0630: 73 75 62 2d 74 72 61 6e 73 61 63 74 69 6f 6e 73  sub-transactions
0640: 20 61 72 65 20 6f 70 65 6e 65 64 2f 63 6c 6f 73   are opened/clos
0650: 65 64 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 78 53  ed:.**.**     xS
0660: 61 76 65 70 6f 69 6e 74 28 69 6e 74 20 53 29 3a  avepoint(int S):
0670: 20 20 4f 70 65 6e 20 73 61 76 65 70 6f 69 6e 74    Open savepoint
0680: 20 53 2e 0a 2a 2a 20 20 20 20 20 78 52 65 6c 65   S..**     xRele
0690: 61 73 65 28 69 6e 74 20 53 29 3a 20 20 20 20 43  ase(int S):    C
06a0: 6f 6d 6d 69 74 20 61 6e 64 20 63 6c 6f 73 65 20  ommit and close 
06b0: 73 61 76 65 70 6f 69 6e 74 20 53 2e 0a 2a 2a 20  savepoint S..** 
06c0: 20 20 20 20 78 52 6f 6c 6c 62 61 63 6b 54 6f 28      xRollbackTo(
06d0: 69 6e 74 20 53 29 3a 20 52 6f 6c 6c 62 61 63 6b  int S): Rollback
06e0: 20 74 6f 20 73 74 61 72 74 20 6f 66 20 73 61 76   to start of sav
06f0: 65 70 6f 69 6e 74 20 53 2e 0a 2a 2a 0a 2a 2a 20  epoint S..**.** 
0700: 44 75 72 69 6e 67 20 61 20 77 72 69 74 65 2d 74  During a write-t
0710: 72 61 6e 73 61 63 74 69 6f 6e 20 74 68 65 20 66  ransaction the f
0720: 74 73 35 5f 69 6e 64 65 78 2e 63 20 6d 6f 64 75  ts5_index.c modu
0730: 6c 65 20 6d 61 79 20 63 61 63 68 65 20 73 6f 6d  le may cache som
0740: 65 20 64 61 74 61 20 0a 2a 2a 20 69 6e 2d 6d 65  e data .** in-me
0750: 6d 6f 72 79 2e 20 49 74 20 69 73 20 66 6c 75 73  mory. It is flus
0760: 68 65 64 20 74 6f 20 64 69 73 6b 20 77 68 65 6e  hed to disk when
0770: 65 76 65 72 20 78 53 79 6e 63 28 29 2c 20 78 52  ever xSync(), xR
0780: 65 6c 65 61 73 65 28 29 20 6f 72 0a 2a 2a 20 78  elease() or.** x
0790: 53 61 76 65 70 6f 69 6e 74 28 29 20 69 73 20 63  Savepoint() is c
07a0: 61 6c 6c 65 64 2e 20 41 6e 64 20 64 69 73 63 61  alled. And disca
07b0: 72 64 65 64 20 77 68 65 6e 65 76 65 72 20 78 52  rded whenever xR
07c0: 6f 6c 6c 62 61 63 6b 28 29 20 6f 72 20 78 52 6f  ollback() or xRo
07d0: 6c 6c 62 61 63 6b 54 6f 28 29 20 0a 2a 2a 20 69  llbackTo() .** i
07e0: 73 20 63 61 6c 6c 65 64 2e 0a 2a 2a 0a 2a 2a 20  s called..**.** 
07f0: 41 64 64 69 74 69 6f 6e 61 6c 6c 79 2c 20 69 66  Additionally, if
0800: 20 53 51 4c 49 54 45 5f 44 45 42 55 47 20 69 73   SQLITE_DEBUG is
0810: 20 64 65 66 69 6e 65 64 2c 20 61 6e 20 69 6e 73   defined, an ins
0820: 74 61 6e 63 65 20 6f 66 20 74 68 65 20 66 6f 6c  tance of the fol
0830: 6c 6f 77 69 6e 67 0a 2a 2a 20 73 74 72 75 63 74  lowing.** struct
0840: 75 72 65 20 69 73 20 75 73 65 64 20 74 6f 20 72  ure is used to r
0850: 65 63 6f 72 64 20 74 68 65 20 63 75 72 72 65 6e  ecord the curren
0860: 74 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 73 74  t transaction st
0870: 61 74 65 2e 20 54 68 69 73 20 69 6e 66 6f 72 6d  ate. This inform
0880: 61 74 69 6f 6e 0a 2a 2a 20 69 73 20 6e 6f 74 20  ation.** is not 
0890: 72 65 71 75 69 72 65 64 2c 20 62 75 74 20 69 74  required, but it
08a0: 20 69 73 20 75 73 65 64 20 69 6e 20 74 68 65 20   is used in the 
08b0: 61 73 73 65 72 74 28 29 20 73 74 61 74 65 6d 65  assert() stateme
08c0: 6e 74 73 20 65 78 65 63 75 74 65 64 20 62 79 0a  nts executed by.
08d0: 2a 2a 20 66 75 6e 63 74 69 6f 6e 20 66 74 73 35  ** function fts5
08e0: 43 68 65 63 6b 54 72 61 6e 73 61 63 74 69 6f 6e  CheckTransaction
08f0: 53 74 61 74 65 28 29 20 28 73 65 65 20 62 65 6c  State() (see bel
0900: 6f 77 29 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 46  ow)..*/.struct F
0910: 74 73 35 54 72 61 6e 73 61 63 74 69 6f 6e 53 74  ts5TransactionSt
0920: 61 74 65 20 7b 0a 20 20 69 6e 74 20 65 53 74 61  ate {.  int eSta
0930: 74 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  te;             
0940: 20 20 20 20 20 20 20 20 2f 2a 20 30 3d 3d 63 6c          /* 0==cl
0950: 6f 73 65 64 2c 20 31 3d 3d 6f 70 65 6e 2c 20 32  osed, 1==open, 2
0960: 3d 3d 73 79 6e 63 65 64 20 2a 2f 0a 20 20 69 6e  ==synced */.  in
0970: 74 20 69 53 61 76 65 70 6f 69 6e 74 3b 20 20 20  t iSavepoint;   
0980: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0990: 20 4e 75 6d 62 65 72 20 6f 66 20 6f 70 65 6e 20   Number of open 
09a0: 73 61 76 65 70 6f 69 6e 74 73 20 28 30 20 2d 3e  savepoints (0 ->
09b0: 20 6e 6f 6e 65 29 20 2a 2f 0a 7d 3b 0a 0a 2f 2a   none) */.};../*
09c0: 0a 2a 2a 20 41 20 73 69 6e 67 6c 65 20 6f 62 6a  .** A single obj
09d0: 65 63 74 20 6f 66 20 74 68 69 73 20 74 79 70 65  ect of this type
09e0: 20 69 73 20 61 6c 6c 6f 63 61 74 65 64 20 77 68   is allocated wh
09f0: 65 6e 20 74 68 65 20 46 54 53 35 20 6d 6f 64 75  en the FTS5 modu
0a00: 6c 65 20 69 73 20 0a 2a 2a 20 72 65 67 69 73 74  le is .** regist
0a10: 65 72 65 64 20 77 69 74 68 20 61 20 64 61 74 61  ered with a data
0a20: 62 61 73 65 20 68 61 6e 64 6c 65 2e 20 49 74 20  base handle. It 
0a30: 69 73 20 75 73 65 64 20 74 6f 20 73 74 6f 72 65  is used to store
0a40: 20 70 6f 69 6e 74 65 72 73 20 74 6f 0a 2a 2a 20   pointers to.** 
0a50: 61 6c 6c 20 72 65 67 69 73 74 65 72 65 64 20 46  all registered F
0a60: 54 53 35 20 65 78 74 65 6e 73 69 6f 6e 73 20 2d  TS5 extensions -
0a70: 20 74 6f 6b 65 6e 69 7a 65 72 73 20 61 6e 64 20   tokenizers and 
0a80: 61 75 78 69 6c 69 61 72 79 20 66 75 6e 63 74 69  auxiliary functi
0a90: 6f 6e 73 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 46  ons..*/.struct F
0aa0: 74 73 35 47 6c 6f 62 61 6c 20 7b 0a 20 20 66 74  ts5Global {.  ft
0ab0: 73 35 5f 61 70 69 20 61 70 69 3b 20 20 20 20 20  s5_api api;     
0ac0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0ad0: 20 55 73 65 72 20 76 69 73 69 62 6c 65 20 70 61   User visible pa
0ae0: 72 74 20 6f 66 20 6f 62 6a 65 63 74 20 28 73 65  rt of object (se
0af0: 65 20 66 74 73 35 2e 68 29 20 2a 2f 0a 20 20 73  e fts5.h) */.  s
0b00: 71 6c 69 74 65 33 20 2a 64 62 3b 20 20 20 20 20  qlite3 *db;     
0b10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
0b20: 2a 20 41 73 73 6f 63 69 61 74 65 64 20 64 61 74  * Associated dat
0b30: 61 62 61 73 65 20 63 6f 6e 6e 65 63 74 69 6f 6e  abase connection
0b40: 20 2a 2f 20 0a 20 20 69 36 34 20 69 4e 65 78 74   */ .  i64 iNext
0b50: 49 64 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  Id;             
0b60: 20 20 20 20 20 20 20 2f 2a 20 55 73 65 64 20 74         /* Used t
0b70: 6f 20 61 6c 6c 6f 63 61 74 65 20 75 6e 69 71 75  o allocate uniqu
0b80: 65 20 63 75 72 73 6f 72 20 69 64 73 20 2a 2f 0a  e cursor ids */.
0b90: 20 20 46 74 73 35 41 75 78 69 6c 69 61 72 79 20    Fts5Auxiliary 
0ba0: 2a 70 41 75 78 3b 20 20 20 20 20 20 20 20 20 20  *pAux;          
0bb0: 20 20 2f 2a 20 46 69 72 73 74 20 69 6e 20 6c 69    /* First in li
0bc0: 73 74 20 6f 66 20 61 6c 6c 20 61 75 78 2e 20 66  st of all aux. f
0bd0: 75 6e 63 74 69 6f 6e 73 20 2a 2f 0a 20 20 46 74  unctions */.  Ft
0be0: 73 35 54 6f 6b 65 6e 69 7a 65 72 4d 6f 64 75 6c  s5TokenizerModul
0bf0: 65 20 2a 70 54 6f 6b 3b 20 20 20 20 20 20 2f 2a  e *pTok;      /*
0c00: 20 46 69 72 73 74 20 69 6e 20 6c 69 73 74 20 6f   First in list o
0c10: 66 20 61 6c 6c 20 74 6f 6b 65 6e 69 7a 65 72 20  f all tokenizer 
0c20: 6d 6f 64 75 6c 65 73 20 2a 2f 0a 20 20 46 74 73  modules */.  Fts
0c30: 35 54 6f 6b 65 6e 69 7a 65 72 4d 6f 64 75 6c 65  5TokenizerModule
0c40: 20 2a 70 44 66 6c 74 54 6f 6b 3b 20 20 2f 2a 20   *pDfltTok;  /* 
0c50: 44 65 66 61 75 6c 74 20 74 6f 6b 65 6e 69 7a 65  Default tokenize
0c60: 72 20 6d 6f 64 75 6c 65 20 2a 2f 0a 20 20 46 74  r module */.  Ft
0c70: 73 35 43 75 72 73 6f 72 20 2a 70 43 73 72 3b 20  s5Cursor *pCsr; 
0c80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0c90: 20 46 69 72 73 74 20 69 6e 20 6c 69 73 74 20 6f   First in list o
0ca0: 66 20 61 6c 6c 20 6f 70 65 6e 20 63 75 72 73 6f  f all open curso
0cb0: 72 73 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20  rs */.};../*.** 
0cc0: 45 61 63 68 20 61 75 78 69 6c 69 61 72 79 20 66  Each auxiliary f
0cd0: 75 6e 63 74 69 6f 6e 20 72 65 67 69 73 74 65 72  unction register
0ce0: 65 64 20 77 69 74 68 20 74 68 65 20 46 54 53 35  ed with the FTS5
0cf0: 20 6d 6f 64 75 6c 65 20 69 73 20 72 65 70 72 65   module is repre
0d00: 73 65 6e 74 65 64 0a 2a 2a 20 62 79 20 61 6e 20  sented.** by an 
0d10: 6f 62 6a 65 63 74 20 6f 66 20 74 68 65 20 66 6f  object of the fo
0d20: 6c 6c 6f 77 69 6e 67 20 74 79 70 65 2e 20 41 6c  llowing type. Al
0d30: 6c 20 73 75 63 68 20 6f 62 6a 65 63 74 73 20 61  l such objects a
0d40: 72 65 20 73 74 6f 72 65 64 20 61 73 20 70 61 72  re stored as par
0d50: 74 0a 2a 2a 20 6f 66 20 74 68 65 20 46 74 73 35  t.** of the Fts5
0d60: 47 6c 6f 62 61 6c 2e 70 41 75 78 20 6c 69 73 74  Global.pAux list
0d70: 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 46 74 73 35  ..*/.struct Fts5
0d80: 41 75 78 69 6c 69 61 72 79 20 7b 0a 20 20 46 74  Auxiliary {.  Ft
0d90: 73 35 47 6c 6f 62 61 6c 20 2a 70 47 6c 6f 62 61  s5Global *pGloba
0da0: 6c 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  l;            /*
0db0: 20 47 6c 6f 62 61 6c 20 63 6f 6e 74 65 78 74 20   Global context 
0dc0: 66 6f 72 20 74 68 69 73 20 66 75 6e 63 74 69 6f  for this functio
0dd0: 6e 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 46 75  n */.  char *zFu
0de0: 6e 63 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  nc;             
0df0: 20 20 20 20 20 20 20 2f 2a 20 46 75 6e 63 74 69         /* Functi
0e00: 6f 6e 20 6e 61 6d 65 20 28 6e 75 6c 2d 74 65 72  on name (nul-ter
0e10: 6d 69 6e 61 74 65 64 29 20 2a 2f 0a 20 20 76 6f  minated) */.  vo
0e20: 69 64 20 2a 70 55 73 65 72 44 61 74 61 3b 20 20  id *pUserData;  
0e30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0e40: 20 55 73 65 72 2d 64 61 74 61 20 70 6f 69 6e 74   User-data point
0e50: 65 72 20 2a 2f 0a 20 20 66 74 73 35 5f 65 78 74  er */.  fts5_ext
0e60: 65 6e 73 69 6f 6e 5f 66 75 6e 63 74 69 6f 6e 20  ension_function 
0e70: 78 46 75 6e 63 3b 20 20 2f 2a 20 43 61 6c 6c 62  xFunc;  /* Callb
0e80: 61 63 6b 20 66 75 6e 63 74 69 6f 6e 20 2a 2f 0a  ack function */.
0e90: 20 20 76 6f 69 64 20 28 2a 78 44 65 73 74 72 6f    void (*xDestro
0ea0: 79 29 28 76 6f 69 64 2a 29 3b 20 20 20 20 20 20  y)(void*);      
0eb0: 20 20 2f 2a 20 44 65 73 74 72 75 63 74 6f 72 20    /* Destructor 
0ec0: 66 75 6e 63 74 69 6f 6e 20 2a 2f 0a 20 20 46 74  function */.  Ft
0ed0: 73 35 41 75 78 69 6c 69 61 72 79 20 2a 70 4e 65  s5Auxiliary *pNe
0ee0: 78 74 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a  xt;           /*
0ef0: 20 4e 65 78 74 20 72 65 67 69 73 74 65 72 65 64   Next registered
0f00: 20 61 75 78 69 6c 69 61 72 79 20 66 75 6e 63 74   auxiliary funct
0f10: 69 6f 6e 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a  ion */.};../*.**
0f20: 20 45 61 63 68 20 74 6f 6b 65 6e 69 7a 65 72 20   Each tokenizer 
0f30: 6d 6f 64 75 6c 65 20 72 65 67 69 73 74 65 72 65  module registere
0f40: 64 20 77 69 74 68 20 74 68 65 20 46 54 53 35 20  d with the FTS5 
0f50: 6d 6f 64 75 6c 65 20 69 73 20 72 65 70 72 65 73  module is repres
0f60: 65 6e 74 65 64 0a 2a 2a 20 62 79 20 61 6e 20 6f  ented.** by an o
0f70: 62 6a 65 63 74 20 6f 66 20 74 68 65 20 66 6f 6c  bject of the fol
0f80: 6c 6f 77 69 6e 67 20 74 79 70 65 2e 20 41 6c 6c  lowing type. All
0f90: 20 73 75 63 68 20 6f 62 6a 65 63 74 73 20 61 72   such objects ar
0fa0: 65 20 73 74 6f 72 65 64 20 61 73 20 70 61 72 74  e stored as part
0fb0: 0a 2a 2a 20 6f 66 20 74 68 65 20 46 74 73 35 47  .** of the Fts5G
0fc0: 6c 6f 62 61 6c 2e 70 54 6f 6b 20 6c 69 73 74 2e  lobal.pTok list.
0fd0: 0a 2a 2f 0a 73 74 72 75 63 74 20 46 74 73 35 54  .*/.struct Fts5T
0fe0: 6f 6b 65 6e 69 7a 65 72 4d 6f 64 75 6c 65 20 7b  okenizerModule {
0ff0: 0a 20 20 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 20  .  char *zName; 
1000: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1010: 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 74 6f     /* Name of to
1020: 6b 65 6e 69 7a 65 72 20 2a 2f 0a 20 20 76 6f 69  kenizer */.  voi
1030: 64 20 2a 70 55 73 65 72 44 61 74 61 3b 20 20 20  d *pUserData;   
1040: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1050: 55 73 65 72 20 70 6f 69 6e 74 65 72 20 70 61 73  User pointer pas
1060: 73 65 64 20 74 6f 20 78 43 72 65 61 74 65 28 29  sed to xCreate()
1070: 20 2a 2f 0a 20 20 66 74 73 35 5f 74 6f 6b 65 6e   */.  fts5_token
1080: 69 7a 65 72 20 78 3b 20 20 20 20 20 20 20 20 20  izer x;         
1090: 20 20 20 20 20 20 2f 2a 20 54 6f 6b 65 6e 69 7a        /* Tokeniz
10a0: 65 72 20 66 75 6e 63 74 69 6f 6e 73 20 2a 2f 0a  er functions */.
10b0: 20 20 76 6f 69 64 20 28 2a 78 44 65 73 74 72 6f    void (*xDestro
10c0: 79 29 28 76 6f 69 64 2a 29 3b 20 20 20 20 20 20  y)(void*);      
10d0: 20 20 2f 2a 20 44 65 73 74 72 75 63 74 6f 72 20    /* Destructor 
10e0: 66 75 6e 63 74 69 6f 6e 20 2a 2f 0a 20 20 46 74  function */.  Ft
10f0: 73 35 54 6f 6b 65 6e 69 7a 65 72 4d 6f 64 75 6c  s5TokenizerModul
1100: 65 20 2a 70 4e 65 78 74 3b 20 20 20 20 20 2f 2a  e *pNext;     /*
1110: 20 4e 65 78 74 20 72 65 67 69 73 74 65 72 65 64   Next registered
1120: 20 74 6f 6b 65 6e 69 7a 65 72 20 6d 6f 64 75 6c   tokenizer modul
1130: 65 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 56  e */.};../*.** V
1140: 69 72 74 75 61 6c 2d 74 61 62 6c 65 20 6f 62 6a  irtual-table obj
1150: 65 63 74 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 46  ect..*/.struct F
1160: 74 73 35 54 61 62 6c 65 20 7b 0a 20 20 73 71 6c  ts5Table {.  sql
1170: 69 74 65 33 5f 76 74 61 62 20 62 61 73 65 3b 20  ite3_vtab base; 
1180: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1190: 42 61 73 65 20 63 6c 61 73 73 20 75 73 65 64 20  Base class used 
11a0: 62 79 20 53 51 4c 69 74 65 20 63 6f 72 65 20 2a  by SQLite core *
11b0: 2f 0a 20 20 46 74 73 35 43 6f 6e 66 69 67 20 2a  /.  Fts5Config *
11c0: 70 43 6f 6e 66 69 67 3b 20 20 20 20 20 20 20 20  pConfig;        
11d0: 20 20 20 20 2f 2a 20 56 69 72 74 75 61 6c 20 74      /* Virtual t
11e0: 61 62 6c 65 20 63 6f 6e 66 69 67 75 72 61 74 69  able configurati
11f0: 6f 6e 20 2a 2f 0a 20 20 46 74 73 35 49 6e 64 65  on */.  Fts5Inde
1200: 78 20 2a 70 49 6e 64 65 78 3b 20 20 20 20 20 20  x *pIndex;      
1210: 20 20 20 20 20 20 20 20 2f 2a 20 46 75 6c 6c 2d          /* Full-
1220: 74 65 78 74 20 69 6e 64 65 78 20 2a 2f 0a 20 20  text index */.  
1230: 46 74 73 35 53 74 6f 72 61 67 65 20 2a 70 53 74  Fts5Storage *pSt
1240: 6f 72 61 67 65 3b 20 20 20 20 20 20 20 20 20 20  orage;          
1250: 2f 2a 20 44 6f 63 75 6d 65 6e 74 20 73 74 6f 72  /* Document stor
1260: 65 20 2a 2f 0a 20 20 46 74 73 35 47 6c 6f 62 61  e */.  Fts5Globa
1270: 6c 20 2a 70 47 6c 6f 62 61 6c 3b 20 20 20 20 20  l *pGlobal;     
1280: 20 20 20 20 20 20 20 2f 2a 20 47 6c 6f 62 61 6c         /* Global
1290: 20 28 63 6f 6e 6e 65 63 74 69 6f 6e 20 77 69 64   (connection wid
12a0: 65 29 20 64 61 74 61 20 2a 2f 0a 20 20 46 74 73  e) data */.  Fts
12b0: 35 43 75 72 73 6f 72 20 2a 70 53 6f 72 74 43 73  5Cursor *pSortCs
12c0: 72 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  r;           /* 
12d0: 53 6f 72 74 20 64 61 74 61 20 66 72 6f 6d 20 74  Sort data from t
12e0: 68 69 73 20 63 75 72 73 6f 72 20 2a 2f 0a 23 69  his cursor */.#i
12f0: 66 64 65 66 20 53 51 4c 49 54 45 5f 44 45 42 55  fdef SQLITE_DEBU
1300: 47 0a 20 20 73 74 72 75 63 74 20 46 74 73 35 54  G.  struct Fts5T
1310: 72 61 6e 73 61 63 74 69 6f 6e 53 74 61 74 65 20  ransactionState 
1320: 74 73 3b 0a 23 65 6e 64 69 66 0a 7d 3b 0a 0a 73  ts;.#endif.};..s
1330: 74 72 75 63 74 20 46 74 73 35 4d 61 74 63 68 50  truct Fts5MatchP
1340: 68 72 61 73 65 20 7b 0a 20 20 46 74 73 35 42 75  hrase {.  Fts5Bu
1350: 66 66 65 72 20 2a 70 50 6f 73 6c 69 73 74 3b 20  ffer *pPoslist; 
1360: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 69            /* Poi
1370: 6e 74 65 72 20 74 6f 20 63 75 72 72 65 6e 74 20  nter to current 
1380: 70 6f 73 6c 69 73 74 20 2a 2f 0a 20 20 69 6e 74  poslist */.  int
1390: 20 6e 54 65 72 6d 3b 20 20 20 20 20 20 20 20 20   nTerm;         
13a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
13b0: 53 69 7a 65 20 6f 66 20 70 68 72 61 73 65 20 69  Size of phrase i
13c0: 6e 20 74 65 72 6d 73 20 2a 2f 0a 7d 3b 0a 0a 2f  n terms */.};../
13d0: 2a 0a 2a 2a 20 70 53 74 6d 74 3a 0a 2a 2a 20 20  *.** pStmt:.**  
13e0: 20 53 45 4c 45 43 54 20 72 6f 77 69 64 2c 20 3c   SELECT rowid, <
13f0: 66 74 73 3e 20 46 52 4f 4d 20 3c 66 74 73 3e 20  fts> FROM <fts> 
1400: 4f 52 44 45 52 20 42 59 20 2b 72 61 6e 6b 3b 0a  ORDER BY +rank;.
1410: 2a 2a 0a 2a 2a 20 61 49 64 78 5b 5d 3a 0a 2a 2a  **.** aIdx[]:.**
1420: 20 20 20 54 68 65 72 65 20 69 73 20 6f 6e 65 20     There is one 
1430: 65 6e 74 72 79 20 69 6e 20 74 68 65 20 61 49 64  entry in the aId
1440: 78 5b 5d 20 61 72 72 61 79 20 66 6f 72 20 65 61  x[] array for ea
1450: 63 68 20 70 68 72 61 73 65 20 69 6e 20 74 68 65  ch phrase in the
1460: 20 71 75 65 72 79 2c 0a 2a 2a 20 20 20 74 68 65   query,.**   the
1470: 20 76 61 6c 75 65 20 6f 66 20 77 68 69 63 68 20   value of which 
1480: 69 73 20 74 68 65 20 6f 66 66 73 65 74 20 77 69  is the offset wi
1490: 74 68 69 6e 20 61 50 6f 73 6c 69 73 74 5b 5d 20  thin aPoslist[] 
14a0: 66 6f 6c 6c 6f 77 69 6e 67 20 74 68 65 20 6c 61  following the la
14b0: 73 74 20 0a 2a 2a 20 20 20 62 79 74 65 20 6f 66  st .**   byte of
14c0: 20 74 68 65 20 70 6f 73 69 74 69 6f 6e 20 6c 69   the position li
14d0: 73 74 20 66 6f 72 20 74 68 65 20 63 6f 72 72 65  st for the corre
14e0: 73 70 6f 6e 64 69 6e 67 20 70 68 72 61 73 65 2e  sponding phrase.
14f0: 0a 2a 2f 0a 73 74 72 75 63 74 20 46 74 73 35 53  .*/.struct Fts5S
1500: 6f 72 74 65 72 20 7b 0a 20 20 73 71 6c 69 74 65  orter {.  sqlite
1510: 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74 3b 0a 20  3_stmt *pStmt;. 
1520: 20 69 36 34 20 69 52 6f 77 69 64 3b 20 20 20 20   i64 iRowid;    
1530: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1540: 20 2f 2a 20 43 75 72 72 65 6e 74 20 72 6f 77 69   /* Current rowi
1550: 64 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 75 38 20  d */.  const u8 
1560: 2a 61 50 6f 73 6c 69 73 74 3b 20 20 20 20 20 20  *aPoslist;      
1570: 20 20 20 20 20 20 20 2f 2a 20 50 6f 73 69 74 69         /* Positi
1580: 6f 6e 20 6c 69 73 74 73 20 66 6f 72 20 63 75 72  on lists for cur
1590: 72 65 6e 74 20 72 6f 77 20 2a 2f 0a 20 20 69 6e  rent row */.  in
15a0: 74 20 6e 49 64 78 3b 20 20 20 20 20 20 20 20 20  t nIdx;         
15b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
15c0: 20 4e 75 6d 62 65 72 20 6f 66 20 65 6e 74 72 69   Number of entri
15d0: 65 73 20 69 6e 20 61 49 64 78 5b 5d 20 2a 2f 0a  es in aIdx[] */.
15e0: 20 20 69 6e 74 20 61 49 64 78 5b 30 5d 3b 20 20    int aIdx[0];  
15f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1600: 20 20 2f 2a 20 4f 66 66 73 65 74 73 20 69 6e 74    /* Offsets int
1610: 6f 20 61 50 6f 73 6c 69 73 74 20 66 6f 72 20 63  o aPoslist for c
1620: 75 72 72 65 6e 74 20 72 6f 77 20 2a 2f 0a 7d 3b  urrent row */.};
1630: 0a 0a 0a 2f 2a 0a 2a 2a 20 56 69 72 74 75 61 6c  .../*.** Virtual
1640: 2d 74 61 62 6c 65 20 63 75 72 73 6f 72 20 6f 62  -table cursor ob
1650: 6a 65 63 74 2e 0a 2a 2a 0a 2a 2a 20 69 53 70 65  ject..**.** iSpe
1660: 63 69 61 6c 3a 0a 2a 2a 20 20 20 49 66 20 74 68  cial:.**   If th
1670: 69 73 20 69 73 20 61 20 27 73 70 65 63 69 61 6c  is is a 'special
1680: 27 20 71 75 65 72 79 20 28 72 65 66 65 72 20 74  ' query (refer t
1690: 6f 20 66 75 6e 63 74 69 6f 6e 20 66 74 73 35 53  o function fts5S
16a0: 70 65 63 69 61 6c 4d 61 74 63 68 28 29 29 2c 20  pecialMatch()), 
16b0: 0a 2a 2a 20 20 20 74 68 65 6e 20 74 68 69 73 20  .**   then this 
16c0: 76 61 72 69 61 62 6c 65 20 63 6f 6e 74 61 69 6e  variable contain
16d0: 73 20 74 68 65 20 72 65 73 75 6c 74 20 6f 66 20  s the result of 
16e0: 74 68 65 20 71 75 65 72 79 2e 20 0a 2a 2a 0a 2a  the query. .**.*
16f0: 2a 20 69 46 69 72 73 74 52 6f 77 69 64 2c 20 69  * iFirstRowid, i
1700: 4c 61 73 74 52 6f 77 69 64 3a 0a 2a 2a 20 20 20  LastRowid:.**   
1710: 54 68 65 73 65 20 76 61 72 69 61 62 6c 65 73 20  These variables 
1720: 61 72 65 20 6f 6e 6c 79 20 75 73 65 64 20 66 6f  are only used fo
1730: 72 20 46 54 53 35 5f 50 4c 41 4e 5f 4d 41 54 43  r FTS5_PLAN_MATC
1740: 48 20 63 75 72 73 6f 72 73 2e 20 41 73 73 75 6d  H cursors. Assum
1750: 69 6e 67 20 74 68 65 0a 2a 2a 20 20 20 63 75 72  ing the.**   cur
1760: 73 6f 72 20 69 74 65 72 61 74 65 73 20 69 6e 20  sor iterates in 
1770: 61 73 63 65 6e 64 69 6e 67 20 6f 72 64 65 72 20  ascending order 
1780: 6f 66 20 72 6f 77 69 64 73 2c 20 69 46 69 72 73  of rowids, iFirs
1790: 74 52 6f 77 69 64 20 69 73 20 74 68 65 20 6c 6f  tRowid is the lo
17a0: 77 65 72 0a 2a 2a 20 20 20 6c 69 6d 69 74 20 6f  wer.**   limit o
17b0: 66 20 72 6f 77 69 64 73 20 74 6f 20 72 65 74 75  f rowids to retu
17c0: 72 6e 2c 20 61 6e 64 20 69 4c 61 73 74 52 6f 77  rn, and iLastRow
17d0: 69 64 20 74 68 65 20 75 70 70 65 72 2e 20 49 6e  id the upper. In
17e0: 20 6f 74 68 65 72 20 77 6f 72 64 73 2c 20 74 68   other words, th
17f0: 65 0a 2a 2a 20 20 20 57 48 45 52 45 20 63 6c 61  e.**   WHERE cla
1800: 75 73 65 20 69 6e 20 74 68 65 20 75 73 65 72 27  use in the user'
1810: 73 20 71 75 65 72 79 20 6d 69 67 68 74 20 68 61  s query might ha
1820: 76 65 20 62 65 65 6e 3a 0a 2a 2a 0a 2a 2a 20 20  ve been:.**.**  
1830: 20 20 20 20 20 3c 74 62 6c 3e 20 4d 41 54 43 48       <tbl> MATCH
1840: 20 3c 65 78 70 72 3e 20 41 4e 44 20 72 6f 77 69   <expr> AND rowi
1850: 64 20 42 45 54 57 45 45 4e 20 24 69 46 69 72 73  d BETWEEN $iFirs
1860: 74 52 6f 77 69 64 20 41 4e 44 20 24 69 4c 61 73  tRowid AND $iLas
1870: 74 52 6f 77 69 64 0a 2a 2a 0a 2a 2a 20 20 20 49  tRowid.**.**   I
1880: 66 20 74 68 65 20 63 75 72 73 6f 72 20 69 74 65  f the cursor ite
1890: 72 61 74 65 73 20 69 6e 20 64 65 73 63 65 6e 64  rates in descend
18a0: 69 6e 67 20 6f 72 64 65 72 20 6f 66 20 72 6f 77  ing order of row
18b0: 69 64 2c 20 69 46 69 72 73 74 52 6f 77 69 64 0a  id, iFirstRowid.
18c0: 2a 2a 20 20 20 69 73 20 74 68 65 20 75 70 70 65  **   is the uppe
18d0: 72 20 6c 69 6d 69 74 20 28 69 2e 65 2e 20 74 68  r limit (i.e. th
18e0: 65 20 22 66 69 72 73 74 22 20 72 6f 77 69 64 20  e "first" rowid 
18f0: 76 69 73 69 74 65 64 29 20 61 6e 64 20 69 4c 61  visited) and iLa
1900: 73 74 52 6f 77 69 64 0a 2a 2a 20 20 20 74 68 65  stRowid.**   the
1910: 20 6c 6f 77 65 72 2e 0a 2a 2f 0a 73 74 72 75 63   lower..*/.struc
1920: 74 20 46 74 73 35 43 75 72 73 6f 72 20 7b 0a 20  t Fts5Cursor {. 
1930: 20 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75   sqlite3_vtab_cu
1940: 72 73 6f 72 20 62 61 73 65 3b 20 20 20 20 20 20  rsor base;      
1950: 20 2f 2a 20 42 61 73 65 20 63 6c 61 73 73 20 75   /* Base class u
1960: 73 65 64 20 62 79 20 53 51 4c 69 74 65 20 63 6f  sed by SQLite co
1970: 72 65 20 2a 2f 0a 20 20 69 6e 74 20 65 50 6c 61  re */.  int ePla
1980: 6e 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  n;              
1990: 20 20 20 20 20 20 20 20 2f 2a 20 46 54 53 35 5f          /* FTS5_
19a0: 50 4c 41 4e 5f 58 58 58 20 76 61 6c 75 65 20 2a  PLAN_XXX value *
19b0: 2f 0a 20 20 69 6e 74 20 62 44 65 73 63 3b 20 20  /.  int bDesc;  
19c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
19d0: 20 20 20 20 2f 2a 20 54 72 75 65 20 66 6f 72 20      /* True for 
19e0: 22 4f 52 44 45 52 20 42 59 20 72 6f 77 69 64 20  "ORDER BY rowid 
19f0: 44 45 53 43 22 20 71 75 65 72 69 65 73 20 2a 2f  DESC" queries */
1a00: 0a 20 20 69 36 34 20 69 46 69 72 73 74 52 6f 77  .  i64 iFirstRow
1a10: 69 64 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  id;             
1a20: 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 6e 6f 20     /* Return no 
1a30: 72 6f 77 69 64 73 20 65 61 72 6c 69 65 72 20 74  rowids earlier t
1a40: 68 61 6e 20 74 68 69 73 20 2a 2f 0a 20 20 69 36  han this */.  i6
1a50: 34 20 69 4c 61 73 74 52 6f 77 69 64 3b 20 20 20  4 iLastRowid;   
1a60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1a70: 20 52 65 74 75 72 6e 20 6e 6f 20 72 6f 77 69 64   Return no rowid
1a80: 73 20 6c 61 74 65 72 20 74 68 61 6e 20 74 68 69  s later than thi
1a90: 73 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 73  s */.  sqlite3_s
1aa0: 74 6d 74 20 2a 70 53 74 6d 74 3b 20 20 20 20 20  tmt *pStmt;     
1ab0: 20 20 20 20 20 20 20 2f 2a 20 53 74 61 74 65 6d         /* Statem
1ac0: 65 6e 74 20 75 73 65 64 20 74 6f 20 72 65 61 64  ent used to read
1ad0: 20 25 5f 63 6f 6e 74 65 6e 74 20 2a 2f 0a 20 20   %_content */.  
1ae0: 46 74 73 35 45 78 70 72 20 2a 70 45 78 70 72 3b  Fts5Expr *pExpr;
1af0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1b00: 2f 2a 20 45 78 70 72 65 73 73 69 6f 6e 20 66 6f  /* Expression fo
1b10: 72 20 4d 41 54 43 48 20 71 75 65 72 69 65 73 20  r MATCH queries 
1b20: 2a 2f 0a 20 20 46 74 73 35 53 6f 72 74 65 72 20  */.  Fts5Sorter 
1b30: 2a 70 53 6f 72 74 65 72 3b 20 20 20 20 20 20 20  *pSorter;       
1b40: 20 20 20 20 20 2f 2a 20 53 6f 72 74 65 72 20 66       /* Sorter f
1b50: 6f 72 20 22 4f 52 44 45 52 20 42 59 20 72 61 6e  or "ORDER BY ran
1b60: 6b 22 20 71 75 65 72 69 65 73 20 2a 2f 0a 20 20  k" queries */.  
1b70: 69 6e 74 20 63 73 72 66 6c 61 67 73 3b 20 20 20  int csrflags;   
1b80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1b90: 2f 2a 20 4d 61 73 6b 20 6f 66 20 63 75 72 73 6f  /* Mask of curso
1ba0: 72 20 66 6c 61 67 73 20 28 73 65 65 20 62 65 6c  r flags (see bel
1bb0: 6f 77 29 20 2a 2f 0a 20 20 46 74 73 35 43 75 72  ow) */.  Fts5Cur
1bc0: 73 6f 72 20 2a 70 4e 65 78 74 3b 20 20 20 20 20  sor *pNext;     
1bd0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 65 78 74           /* Next
1be0: 20 63 75 72 73 6f 72 20 69 6e 20 46 74 73 35 43   cursor in Fts5C
1bf0: 75 72 73 6f 72 2e 70 43 73 72 20 6c 69 73 74 20  ursor.pCsr list 
1c00: 2a 2f 0a 20 20 69 36 34 20 69 53 70 65 63 69 61  */.  i64 iSpecia
1c10: 6c 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  l;              
1c20: 20 20 20 20 20 2f 2a 20 52 65 73 75 6c 74 20 6f       /* Result o
1c30: 66 20 73 70 65 63 69 61 6c 20 71 75 65 72 79 20  f special query 
1c40: 2a 2f 0a 0a 20 20 2f 2a 20 22 72 61 6e 6b 22 20  */..  /* "rank" 
1c50: 66 75 6e 63 74 69 6f 6e 2e 20 50 6f 70 75 6c 61  function. Popula
1c60: 74 65 64 20 6f 6e 20 64 65 6d 61 6e 64 20 66 72  ted on demand fr
1c70: 6f 6d 20 76 74 61 62 2e 78 43 6f 6c 75 6d 6e 28  om vtab.xColumn(
1c80: 29 2e 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 52  ). */.  char *zR
1c90: 61 6e 6b 3b 20 20 20 20 20 20 20 20 20 20 20 20  ank;            
1ca0: 20 20 20 20 20 20 20 20 2f 2a 20 43 75 73 74 6f          /* Custo
1cb0: 6d 20 72 61 6e 6b 20 66 75 6e 63 74 69 6f 6e 20  m rank function 
1cc0: 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 52 61 6e 6b  */.  char *zRank
1cd0: 41 72 67 73 3b 20 20 20 20 20 20 20 20 20 20 20  Args;           
1ce0: 20 20 20 20 20 2f 2a 20 43 75 73 74 6f 6d 20 72       /* Custom r
1cf0: 61 6e 6b 20 66 75 6e 63 74 69 6f 6e 20 61 72 67  ank function arg
1d00: 73 20 2a 2f 0a 20 20 46 74 73 35 41 75 78 69 6c  s */.  Fts5Auxil
1d10: 69 61 72 79 20 2a 70 52 61 6e 6b 3b 20 20 20 20  iary *pRank;    
1d20: 20 20 20 20 20 20 20 2f 2a 20 52 61 6e 6b 20 63         /* Rank c
1d30: 61 6c 6c 62 61 63 6b 20 28 6f 72 20 4e 55 4c 4c  allback (or NULL
1d40: 29 20 2a 2f 0a 20 20 69 6e 74 20 6e 52 61 6e 6b  ) */.  int nRank
1d50: 41 72 67 3b 20 20 20 20 20 20 20 20 20 20 20 20  Arg;            
1d60: 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
1d70: 20 6f 66 20 74 72 61 69 6c 69 6e 67 20 61 72 67   of trailing arg
1d80: 75 6d 65 6e 74 73 20 66 6f 72 20 72 61 6e 6b 28  uments for rank(
1d90: 29 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 76  ) */.  sqlite3_v
1da0: 61 6c 75 65 20 2a 2a 61 70 52 61 6e 6b 41 72 67  alue **apRankArg
1db0: 3b 20 20 20 20 20 20 2f 2a 20 41 72 72 61 79 20  ;      /* Array 
1dc0: 6f 66 20 74 72 61 69 6c 69 6e 67 20 61 72 67 75  of trailing argu
1dd0: 6d 65 6e 74 73 20 2a 2f 0a 20 20 73 71 6c 69 74  ments */.  sqlit
1de0: 65 33 5f 73 74 6d 74 20 2a 70 52 61 6e 6b 41 72  e3_stmt *pRankAr
1df0: 67 53 74 6d 74 3b 20 20 20 20 20 2f 2a 20 4f 72  gStmt;     /* Or
1e00: 69 67 69 6e 20 6f 66 20 6f 62 6a 65 63 74 73 20  igin of objects 
1e10: 69 6e 20 61 70 52 61 6e 6b 41 72 67 5b 5d 20 2a  in apRankArg[] *
1e20: 2f 0a 0a 20 20 2f 2a 20 56 61 72 69 61 62 6c 65  /..  /* Variable
1e30: 73 20 75 73 65 64 20 62 79 20 61 75 78 69 6c 69  s used by auxili
1e40: 61 72 79 20 66 75 6e 63 74 69 6f 6e 73 20 2a 2f  ary functions */
1e50: 0a 20 20 69 36 34 20 69 43 73 72 49 64 3b 20 20  .  i64 iCsrId;  
1e60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1e70: 20 20 20 2f 2a 20 43 75 72 73 6f 72 20 69 64 20     /* Cursor id 
1e80: 2a 2f 0a 20 20 46 74 73 35 41 75 78 69 6c 69 61  */.  Fts5Auxilia
1e90: 72 79 20 2a 70 41 75 78 3b 20 20 20 20 20 20 20  ry *pAux;       
1ea0: 20 20 20 20 20 2f 2a 20 43 75 72 72 65 6e 74 6c       /* Currentl
1eb0: 79 20 65 78 65 63 75 74 69 6e 67 20 65 78 74 65  y executing exte
1ec0: 6e 73 69 6f 6e 20 66 75 6e 63 74 69 6f 6e 20 2a  nsion function *
1ed0: 2f 0a 20 20 46 74 73 35 41 75 78 64 61 74 61 20  /.  Fts5Auxdata 
1ee0: 2a 70 41 75 78 64 61 74 61 3b 20 20 20 20 20 20  *pAuxdata;      
1ef0: 20 20 20 20 2f 2a 20 46 69 72 73 74 20 69 6e 20      /* First in 
1f00: 6c 69 6e 6b 65 64 20 6c 69 73 74 20 6f 66 20 73  linked list of s
1f10: 61 76 65 64 20 61 75 78 2d 64 61 74 61 20 2a 2f  aved aux-data */
1f20: 0a 20 20 69 6e 74 20 2a 61 43 6f 6c 75 6d 6e 53  .  int *aColumnS
1f30: 69 7a 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  ize;            
1f40: 20 20 20 2f 2a 20 56 61 6c 75 65 73 20 66 6f 72     /* Values for
1f50: 20 78 43 6f 6c 75 6d 6e 53 69 7a 65 28 29 20 2a   xColumnSize() *
1f60: 2f 0a 0a 20 20 2f 2a 20 43 61 63 68 65 20 75 73  /..  /* Cache us
1f70: 65 64 20 62 79 20 61 75 78 69 6c 69 61 72 79 20  ed by auxiliary 
1f80: 66 75 6e 63 74 69 6f 6e 73 20 78 49 6e 73 74 28  functions xInst(
1f90: 29 20 61 6e 64 20 78 49 6e 73 74 43 6f 75 6e 74  ) and xInstCount
1fa0: 28 29 20 2a 2f 0a 20 20 69 6e 74 20 6e 49 6e 73  () */.  int nIns
1fb0: 74 43 6f 75 6e 74 3b 20 20 20 20 20 20 20 20 20  tCount;         
1fc0: 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65          /* Numbe
1fd0: 72 20 6f 66 20 70 68 72 61 73 65 20 69 6e 73 74  r of phrase inst
1fe0: 61 6e 63 65 73 20 2a 2f 0a 20 20 69 6e 74 20 2a  ances */.  int *
1ff0: 61 49 6e 73 74 3b 20 20 20 20 20 20 20 20 20 20  aInst;          
2000: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 33 20             /* 3 
2010: 69 6e 74 65 67 65 72 73 20 70 65 72 20 70 68 72  integers per phr
2020: 61 73 65 20 69 6e 73 74 61 6e 63 65 20 2a 2f 0a  ase instance */.
2030: 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 42 69 74 73 20 74  };../*.** Bits t
2040: 68 61 74 20 6d 61 6b 65 20 75 70 20 74 68 65 20  hat make up the 
2050: 22 69 64 78 4e 75 6d 22 20 70 61 72 61 6d 65 74  "idxNum" paramet
2060: 65 72 20 70 61 73 73 65 64 20 69 6e 64 69 72 65  er passed indire
2070: 63 74 6c 79 20 62 79 20 0a 2a 2a 20 78 42 65 73  ctly by .** xBes
2080: 74 49 6e 64 65 78 28 29 20 74 6f 20 78 46 69 6c  tIndex() to xFil
2090: 74 65 72 28 29 2e 0a 2a 2f 0a 23 64 65 66 69 6e  ter()..*/.#defin
20a0: 65 20 46 54 53 35 5f 42 49 5f 4d 41 54 43 48 20  e FTS5_BI_MATCH 
20b0: 20 20 20 20 20 20 20 30 78 30 30 30 31 20 20 20         0x0001   
20c0: 20 20 20 20 20 20 2f 2a 20 3c 74 62 6c 3e 20 4d        /* <tbl> M
20d0: 41 54 43 48 20 3f 20 2a 2f 0a 23 64 65 66 69 6e  ATCH ? */.#defin
20e0: 65 20 46 54 53 35 5f 42 49 5f 52 41 4e 4b 20 20  e FTS5_BI_RANK  
20f0: 20 20 20 20 20 20 20 30 78 30 30 30 32 20 20 20         0x0002   
2100: 20 20 20 20 20 20 2f 2a 20 72 61 6e 6b 20 4d 41        /* rank MA
2110: 54 43 48 20 3f 20 2a 2f 0a 23 64 65 66 69 6e 65  TCH ? */.#define
2120: 20 46 54 53 35 5f 42 49 5f 52 4f 57 49 44 5f 45   FTS5_BI_ROWID_E
2130: 51 20 20 20 20 20 30 78 30 30 30 34 20 20 20 20  Q     0x0004    
2140: 20 20 20 20 20 2f 2a 20 72 6f 77 69 64 20 3d 3d       /* rowid ==
2150: 20 3f 20 2a 2f 0a 23 64 65 66 69 6e 65 20 46 54   ? */.#define FT
2160: 53 35 5f 42 49 5f 52 4f 57 49 44 5f 4c 45 20 20  S5_BI_ROWID_LE  
2170: 20 20 20 30 78 30 30 30 38 20 20 20 20 20 20 20     0x0008       
2180: 20 20 2f 2a 20 72 6f 77 69 64 20 3c 3d 20 3f 20    /* rowid <= ? 
2190: 2a 2f 0a 23 64 65 66 69 6e 65 20 46 54 53 35 5f  */.#define FTS5_
21a0: 42 49 5f 52 4f 57 49 44 5f 47 45 20 20 20 20 20  BI_ROWID_GE     
21b0: 30 78 30 30 31 30 20 20 20 20 20 20 20 20 20 2f  0x0010         /
21c0: 2a 20 72 6f 77 69 64 20 3e 3d 20 3f 20 2a 2f 0a  * rowid >= ? */.
21d0: 0a 23 64 65 66 69 6e 65 20 46 54 53 35 5f 42 49  .#define FTS5_BI
21e0: 5f 4f 52 44 45 52 5f 52 41 4e 4b 20 20 20 30 78  _ORDER_RANK   0x
21f0: 30 30 32 30 0a 23 64 65 66 69 6e 65 20 46 54 53  0020.#define FTS
2200: 35 5f 42 49 5f 4f 52 44 45 52 5f 52 4f 57 49 44  5_BI_ORDER_ROWID
2210: 20 20 30 78 30 30 34 30 0a 23 64 65 66 69 6e 65    0x0040.#define
2220: 20 46 54 53 35 5f 42 49 5f 4f 52 44 45 52 5f 44   FTS5_BI_ORDER_D
2230: 45 53 43 20 20 20 30 78 30 30 38 30 0a 0a 2f 2a  ESC   0x0080../*
2240: 0a 2a 2a 20 56 61 6c 75 65 73 20 66 6f 72 20 46  .** Values for F
2250: 74 73 35 43 75 72 73 6f 72 2e 63 73 72 66 6c 61  ts5Cursor.csrfla
2260: 67 73 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 46 54  gs.*/.#define FT
2270: 53 35 43 53 52 5f 52 45 51 55 49 52 45 5f 43 4f  S5CSR_REQUIRE_CO
2280: 4e 54 45 4e 54 20 20 20 30 78 30 31 0a 23 64 65  NTENT   0x01.#de
2290: 66 69 6e 65 20 46 54 53 35 43 53 52 5f 52 45 51  fine FTS5CSR_REQ
22a0: 55 49 52 45 5f 44 4f 43 53 49 5a 45 20 20 20 30  UIRE_DOCSIZE   0
22b0: 78 30 32 0a 23 64 65 66 69 6e 65 20 46 54 53 35  x02.#define FTS5
22c0: 43 53 52 5f 45 4f 46 20 20 20 20 20 20 20 20 20  CSR_EOF         
22d0: 20 20 20 20 20 20 30 78 30 34 0a 23 64 65 66 69        0x04.#defi
22e0: 6e 65 20 46 54 53 35 43 53 52 5f 46 52 45 45 5f  ne FTS5CSR_FREE_
22f0: 5a 52 41 4e 4b 20 20 20 20 20 20 20 20 30 78 30  ZRANK        0x0
2300: 38 0a 23 64 65 66 69 6e 65 20 46 54 53 35 43 53  8.#define FTS5CS
2310: 52 5f 52 45 51 55 49 52 45 5f 52 45 53 45 45 4b  R_REQUIRE_RESEEK
2320: 20 20 20 20 30 78 31 30 0a 0a 23 64 65 66 69 6e      0x10..#defin
2330: 65 20 42 69 74 46 6c 61 67 41 6c 6c 54 65 73 74  e BitFlagAllTest
2340: 28 78 2c 79 29 20 28 28 28 78 29 20 26 20 28 79  (x,y) (((x) & (y
2350: 29 29 3d 3d 28 79 29 29 0a 23 64 65 66 69 6e 65  ))==(y)).#define
2360: 20 42 69 74 46 6c 61 67 54 65 73 74 28 78 2c 79   BitFlagTest(x,y
2370: 29 20 20 20 20 28 28 28 78 29 20 26 20 28 79 29  )    (((x) & (y)
2380: 29 21 3d 30 29 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6e  )!=0)../*.** Con
2390: 73 74 61 6e 74 73 20 66 6f 72 20 74 68 65 20 6c  stants for the l
23a0: 61 72 67 65 73 74 20 61 6e 64 20 73 6d 61 6c 6c  argest and small
23b0: 65 73 74 20 70 6f 73 73 69 62 6c 65 20 36 34 2d  est possible 64-
23c0: 62 69 74 20 73 69 67 6e 65 64 20 69 6e 74 65 67  bit signed integ
23d0: 65 72 73 2e 0a 2a 2a 20 54 68 65 73 65 20 61 72  ers..** These ar
23e0: 65 20 63 6f 70 69 65 64 20 66 72 6f 6d 20 73 71  e copied from sq
23f0: 6c 69 74 65 49 6e 74 2e 68 2e 0a 2a 2f 0a 23 69  liteInt.h..*/.#i
2400: 66 6e 64 65 66 20 53 51 4c 49 54 45 5f 41 4d 41  fndef SQLITE_AMA
2410: 4c 47 41 4d 41 54 49 4f 4e 0a 23 20 64 65 66 69  LGAMATION.# defi
2420: 6e 65 20 4c 41 52 47 45 53 54 5f 49 4e 54 36 34  ne LARGEST_INT64
2430: 20 20 28 30 78 66 66 66 66 66 66 66 66 7c 28 28    (0xffffffff|((
2440: 28 69 36 34 29 30 78 37 66 66 66 66 66 66 66 29  (i64)0x7fffffff)
2450: 3c 3c 33 32 29 29 0a 23 20 64 65 66 69 6e 65 20  <<32)).# define 
2460: 53 4d 41 4c 4c 45 53 54 5f 49 4e 54 36 34 20 28  SMALLEST_INT64 (
2470: 28 28 69 36 34 29 2d 31 29 20 2d 20 4c 41 52 47  ((i64)-1) - LARG
2480: 45 53 54 5f 49 4e 54 36 34 29 0a 23 65 6e 64 69  EST_INT64).#endi
2490: 66 0a 0a 2f 2a 0a 2a 2a 20 4d 61 63 72 6f 73 20  f../*.** Macros 
24a0: 74 6f 20 53 65 74 28 29 2c 20 43 6c 65 61 72 28  to Set(), Clear(
24b0: 29 20 61 6e 64 20 54 65 73 74 28 29 20 63 75 72  ) and Test() cur
24c0: 73 6f 72 20 66 6c 61 67 73 2e 0a 2a 2f 0a 23 64  sor flags..*/.#d
24d0: 65 66 69 6e 65 20 43 73 72 46 6c 61 67 53 65 74  efine CsrFlagSet
24e0: 28 70 43 73 72 2c 20 66 6c 61 67 29 20 20 20 28  (pCsr, flag)   (
24f0: 28 70 43 73 72 29 2d 3e 63 73 72 66 6c 61 67 73  (pCsr)->csrflags
2500: 20 7c 3d 20 28 66 6c 61 67 29 29 0a 23 64 65 66   |= (flag)).#def
2510: 69 6e 65 20 43 73 72 46 6c 61 67 43 6c 65 61 72  ine CsrFlagClear
2520: 28 70 43 73 72 2c 20 66 6c 61 67 29 20 28 28 70  (pCsr, flag) ((p
2530: 43 73 72 29 2d 3e 63 73 72 66 6c 61 67 73 20 26  Csr)->csrflags &
2540: 3d 20 7e 28 66 6c 61 67 29 29 0a 23 64 65 66 69  = ~(flag)).#defi
2550: 6e 65 20 43 73 72 46 6c 61 67 54 65 73 74 28 70  ne CsrFlagTest(p
2560: 43 73 72 2c 20 66 6c 61 67 29 20 20 28 28 70 43  Csr, flag)  ((pC
2570: 73 72 29 2d 3e 63 73 72 66 6c 61 67 73 20 26 20  sr)->csrflags & 
2580: 28 66 6c 61 67 29 29 0a 0a 73 74 72 75 63 74 20  (flag))..struct 
2590: 46 74 73 35 41 75 78 64 61 74 61 20 7b 0a 20 20  Fts5Auxdata {.  
25a0: 46 74 73 35 41 75 78 69 6c 69 61 72 79 20 2a 70  Fts5Auxiliary *p
25b0: 41 75 78 3b 20 20 20 20 20 20 20 20 20 20 20 20  Aux;            
25c0: 2f 2a 20 45 78 74 65 6e 73 69 6f 6e 20 74 6f 20  /* Extension to 
25d0: 77 68 69 63 68 20 74 68 69 73 20 62 65 6c 6f 6e  which this belon
25e0: 67 73 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 50  gs */.  void *pP
25f0: 74 72 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  tr;             
2600: 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74          /* Point
2610: 65 72 20 76 61 6c 75 65 20 2a 2f 0a 20 20 76 6f  er value */.  vo
2620: 69 64 28 2a 78 44 65 6c 65 74 65 29 28 76 6f 69  id(*xDelete)(voi
2630: 64 2a 29 3b 20 20 20 20 20 20 20 20 20 20 2f 2a  d*);          /*
2640: 20 44 65 73 74 72 75 63 74 6f 72 20 2a 2f 0a 20   Destructor */. 
2650: 20 46 74 73 35 41 75 78 64 61 74 61 20 2a 70 4e   Fts5Auxdata *pN
2660: 65 78 74 3b 20 20 20 20 20 20 20 20 20 20 20 20  ext;            
2670: 20 2f 2a 20 4e 65 78 74 20 6f 62 6a 65 63 74 20   /* Next object 
2680: 69 6e 20 6c 69 6e 6b 65 64 20 6c 69 73 74 20 2a  in linked list *
2690: 2f 0a 7d 3b 0a 0a 23 69 66 64 65 66 20 53 51 4c  /.};..#ifdef SQL
26a0: 49 54 45 5f 44 45 42 55 47 0a 23 64 65 66 69 6e  ITE_DEBUG.#defin
26b0: 65 20 46 54 53 35 5f 42 45 47 49 4e 20 20 20 20  e FTS5_BEGIN    
26c0: 20 20 31 0a 23 64 65 66 69 6e 65 20 46 54 53 35    1.#define FTS5
26d0: 5f 53 59 4e 43 20 20 20 20 20 20 20 32 0a 23 64  _SYNC       2.#d
26e0: 65 66 69 6e 65 20 46 54 53 35 5f 43 4f 4d 4d 49  efine FTS5_COMMI
26f0: 54 20 20 20 20 20 33 0a 23 64 65 66 69 6e 65 20  T     3.#define 
2700: 46 54 53 35 5f 52 4f 4c 4c 42 41 43 4b 20 20 20  FTS5_ROLLBACK   
2710: 34 0a 23 64 65 66 69 6e 65 20 46 54 53 35 5f 53  4.#define FTS5_S
2720: 41 56 45 50 4f 49 4e 54 20 20 35 0a 23 64 65 66  AVEPOINT  5.#def
2730: 69 6e 65 20 46 54 53 35 5f 52 45 4c 45 41 53 45  ine FTS5_RELEASE
2740: 20 20 20 20 36 0a 23 64 65 66 69 6e 65 20 46 54      6.#define FT
2750: 53 35 5f 52 4f 4c 4c 42 41 43 4b 54 4f 20 37 0a  S5_ROLLBACKTO 7.
2760: 73 74 61 74 69 63 20 76 6f 69 64 20 66 74 73 35  static void fts5
2770: 43 68 65 63 6b 54 72 61 6e 73 61 63 74 69 6f 6e  CheckTransaction
2780: 53 74 61 74 65 28 46 74 73 35 54 61 62 6c 65 20  State(Fts5Table 
2790: 2a 70 2c 20 69 6e 74 20 6f 70 2c 20 69 6e 74 20  *p, int op, int 
27a0: 69 53 61 76 65 70 6f 69 6e 74 29 7b 0a 20 20 73  iSavepoint){.  s
27b0: 77 69 74 63 68 28 20 6f 70 20 29 7b 0a 20 20 20  witch( op ){.   
27c0: 20 63 61 73 65 20 46 54 53 35 5f 42 45 47 49 4e   case FTS5_BEGIN
27d0: 3a 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20  :.      assert( 
27e0: 70 2d 3e 74 73 2e 65 53 74 61 74 65 3d 3d 30 20  p->ts.eState==0 
27f0: 29 3b 0a 20 20 20 20 20 20 70 2d 3e 74 73 2e 65  );.      p->ts.e
2800: 53 74 61 74 65 20 3d 20 31 3b 0a 20 20 20 20 20  State = 1;.     
2810: 20 70 2d 3e 74 73 2e 69 53 61 76 65 70 6f 69 6e   p->ts.iSavepoin
2820: 74 20 3d 20 2d 31 3b 0a 20 20 20 20 20 20 62 72  t = -1;.      br
2830: 65 61 6b 3b 0a 0a 20 20 20 20 63 61 73 65 20 46  eak;..    case F
2840: 54 53 35 5f 53 59 4e 43 3a 0a 20 20 20 20 20 20  TS5_SYNC:.      
2850: 61 73 73 65 72 74 28 20 70 2d 3e 74 73 2e 65 53  assert( p->ts.eS
2860: 74 61 74 65 3d 3d 31 20 29 3b 0a 20 20 20 20 20  tate==1 );.     
2870: 20 70 2d 3e 74 73 2e 65 53 74 61 74 65 20 3d 20   p->ts.eState = 
2880: 32 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a  2;.      break;.
2890: 0a 20 20 20 20 63 61 73 65 20 46 54 53 35 5f 43  .    case FTS5_C
28a0: 4f 4d 4d 49 54 3a 0a 20 20 20 20 20 20 61 73 73  OMMIT:.      ass
28b0: 65 72 74 28 20 70 2d 3e 74 73 2e 65 53 74 61 74  ert( p->ts.eStat
28c0: 65 3d 3d 32 20 29 3b 0a 20 20 20 20 20 20 70 2d  e==2 );.      p-
28d0: 3e 74 73 2e 65 53 74 61 74 65 20 3d 20 30 3b 0a  >ts.eState = 0;.
28e0: 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 0a 20 20        break;..  
28f0: 20 20 63 61 73 65 20 46 54 53 35 5f 52 4f 4c 4c    case FTS5_ROLL
2900: 42 41 43 4b 3a 0a 20 20 20 20 20 20 61 73 73 65  BACK:.      asse
2910: 72 74 28 20 70 2d 3e 74 73 2e 65 53 74 61 74 65  rt( p->ts.eState
2920: 3d 3d 31 20 7c 7c 20 70 2d 3e 74 73 2e 65 53 74  ==1 || p->ts.eSt
2930: 61 74 65 3d 3d 32 20 7c 7c 20 70 2d 3e 74 73 2e  ate==2 || p->ts.
2940: 65 53 74 61 74 65 3d 3d 30 20 29 3b 0a 20 20 20  eState==0 );.   
2950: 20 20 20 70 2d 3e 74 73 2e 65 53 74 61 74 65 20     p->ts.eState 
2960: 3d 20 30 3b 0a 20 20 20 20 20 20 62 72 65 61 6b  = 0;.      break
2970: 3b 0a 0a 20 20 20 20 63 61 73 65 20 46 54 53 35  ;..    case FTS5
2980: 5f 53 41 56 45 50 4f 49 4e 54 3a 0a 20 20 20 20  _SAVEPOINT:.    
2990: 20 20 61 73 73 65 72 74 28 20 70 2d 3e 74 73 2e    assert( p->ts.
29a0: 65 53 74 61 74 65 3d 3d 31 20 29 3b 0a 20 20 20  eState==1 );.   
29b0: 20 20 20 61 73 73 65 72 74 28 20 69 53 61 76 65     assert( iSave
29c0: 70 6f 69 6e 74 3e 3d 30 20 29 3b 0a 20 20 20 20  point>=0 );.    
29d0: 20 20 61 73 73 65 72 74 28 20 69 53 61 76 65 70    assert( iSavep
29e0: 6f 69 6e 74 3e 70 2d 3e 74 73 2e 69 53 61 76 65  oint>p->ts.iSave
29f0: 70 6f 69 6e 74 20 29 3b 0a 20 20 20 20 20 20 70  point );.      p
2a00: 2d 3e 74 73 2e 69 53 61 76 65 70 6f 69 6e 74 20  ->ts.iSavepoint 
2a10: 3d 20 69 53 61 76 65 70 6f 69 6e 74 3b 0a 20 20  = iSavepoint;.  
2a20: 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20      break;.     
2a30: 20 0a 20 20 20 20 63 61 73 65 20 46 54 53 35 5f   .    case FTS5_
2a40: 52 45 4c 45 41 53 45 3a 0a 20 20 20 20 20 20 61  RELEASE:.      a
2a50: 73 73 65 72 74 28 20 70 2d 3e 74 73 2e 65 53 74  ssert( p->ts.eSt
2a60: 61 74 65 3d 3d 31 20 29 3b 0a 20 20 20 20 20 20  ate==1 );.      
2a70: 61 73 73 65 72 74 28 20 69 53 61 76 65 70 6f 69  assert( iSavepoi
2a80: 6e 74 3e 3d 30 20 29 3b 0a 20 20 20 20 20 20 61  nt>=0 );.      a
2a90: 73 73 65 72 74 28 20 69 53 61 76 65 70 6f 69 6e  ssert( iSavepoin
2aa0: 74 3c 3d 70 2d 3e 74 73 2e 69 53 61 76 65 70 6f  t<=p->ts.iSavepo
2ab0: 69 6e 74 20 29 3b 0a 20 20 20 20 20 20 70 2d 3e  int );.      p->
2ac0: 74 73 2e 69 53 61 76 65 70 6f 69 6e 74 20 3d 20  ts.iSavepoint = 
2ad0: 69 53 61 76 65 70 6f 69 6e 74 2d 31 3b 0a 20 20  iSavepoint-1;.  
2ae0: 20 20 20 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20      break;..    
2af0: 63 61 73 65 20 46 54 53 35 5f 52 4f 4c 4c 42 41  case FTS5_ROLLBA
2b00: 43 4b 54 4f 3a 0a 20 20 20 20 20 20 61 73 73 65  CKTO:.      asse
2b10: 72 74 28 20 70 2d 3e 74 73 2e 65 53 74 61 74 65  rt( p->ts.eState
2b20: 3d 3d 31 20 29 3b 0a 20 20 20 20 20 20 61 73 73  ==1 );.      ass
2b30: 65 72 74 28 20 69 53 61 76 65 70 6f 69 6e 74 3e  ert( iSavepoint>
2b40: 3d 30 20 29 3b 0a 20 20 20 20 20 20 61 73 73 65  =0 );.      asse
2b50: 72 74 28 20 69 53 61 76 65 70 6f 69 6e 74 3c 3d  rt( iSavepoint<=
2b60: 70 2d 3e 74 73 2e 69 53 61 76 65 70 6f 69 6e 74  p->ts.iSavepoint
2b70: 20 29 3b 0a 20 20 20 20 20 20 70 2d 3e 74 73 2e   );.      p->ts.
2b80: 69 53 61 76 65 70 6f 69 6e 74 20 3d 20 69 53 61  iSavepoint = iSa
2b90: 76 65 70 6f 69 6e 74 3b 0a 20 20 20 20 20 20 62  vepoint;.      b
2ba0: 72 65 61 6b 3b 0a 20 20 7d 0a 7d 0a 23 65 6c 73  reak;.  }.}.#els
2bb0: 65 0a 23 20 64 65 66 69 6e 65 20 66 74 73 35 43  e.# define fts5C
2bc0: 68 65 63 6b 54 72 61 6e 73 61 63 74 69 6f 6e 53  heckTransactionS
2bd0: 74 61 74 65 28 78 2c 79 2c 7a 29 0a 23 65 6e 64  tate(x,y,z).#end
2be0: 69 66 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e  if../*.** Return
2bf0: 20 74 72 75 65 20 69 66 20 70 54 61 62 20 69 73   true if pTab is
2c00: 20 61 20 63 6f 6e 74 65 6e 74 6c 65 73 73 20 74   a contentless t
2c10: 61 62 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  able..*/.static 
2c20: 69 6e 74 20 66 74 73 35 49 73 43 6f 6e 74 65 6e  int fts5IsConten
2c30: 74 6c 65 73 73 28 46 74 73 35 54 61 62 6c 65 20  tless(Fts5Table 
2c40: 2a 70 54 61 62 29 7b 0a 20 20 72 65 74 75 72 6e  *pTab){.  return
2c50: 20 70 54 61 62 2d 3e 70 43 6f 6e 66 69 67 2d 3e   pTab->pConfig->
2c60: 65 43 6f 6e 74 65 6e 74 3d 3d 46 54 53 35 5f 43  eContent==FTS5_C
2c70: 4f 4e 54 45 4e 54 5f 4e 4f 4e 45 3b 0a 7d 0a 0a  ONTENT_NONE;.}..
2c80: 2f 2a 0a 2a 2a 20 44 65 6c 65 74 65 20 61 20 76  /*.** Delete a v
2c90: 69 72 74 75 61 6c 20 74 61 62 6c 65 20 68 61 6e  irtual table han
2ca0: 64 6c 65 20 61 6c 6c 6f 63 61 74 65 64 20 62 79  dle allocated by
2cb0: 20 66 74 73 35 49 6e 69 74 56 74 61 62 28 29 2e   fts5InitVtab().
2cc0: 20 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64   .*/.static void
2cd0: 20 66 74 73 35 46 72 65 65 56 74 61 62 28 46 74   fts5FreeVtab(Ft
2ce0: 73 35 54 61 62 6c 65 20 2a 70 54 61 62 29 7b 0a  s5Table *pTab){.
2cf0: 20 20 69 66 28 20 70 54 61 62 20 29 7b 0a 20 20    if( pTab ){.  
2d00: 20 20 73 71 6c 69 74 65 33 46 74 73 35 49 6e 64    sqlite3Fts5Ind
2d10: 65 78 43 6c 6f 73 65 28 70 54 61 62 2d 3e 70 49  exClose(pTab->pI
2d20: 6e 64 65 78 29 3b 0a 20 20 20 20 73 71 6c 69 74  ndex);.    sqlit
2d30: 65 33 46 74 73 35 53 74 6f 72 61 67 65 43 6c 6f  e3Fts5StorageClo
2d40: 73 65 28 70 54 61 62 2d 3e 70 53 74 6f 72 61 67  se(pTab->pStorag
2d50: 65 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 46  e);.    sqlite3F
2d60: 74 73 35 43 6f 6e 66 69 67 46 72 65 65 28 70 54  ts5ConfigFree(pT
2d70: 61 62 2d 3e 70 43 6f 6e 66 69 67 29 3b 0a 20 20  ab->pConfig);.  
2d80: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70    sqlite3_free(p
2d90: 54 61 62 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a  Tab);.  }.}../*.
2da0: 2a 2a 20 54 68 65 20 78 44 69 73 63 6f 6e 6e 65  ** The xDisconne
2db0: 63 74 28 29 20 76 69 72 74 75 61 6c 20 74 61 62  ct() virtual tab
2dc0: 6c 65 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74  le method..*/.st
2dd0: 61 74 69 63 20 69 6e 74 20 66 74 73 35 44 69 73  atic int fts5Dis
2de0: 63 6f 6e 6e 65 63 74 4d 65 74 68 6f 64 28 73 71  connectMethod(sq
2df0: 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56 74 61  lite3_vtab *pVta
2e00: 62 29 7b 0a 20 20 66 74 73 35 46 72 65 65 56 74  b){.  fts5FreeVt
2e10: 61 62 28 28 46 74 73 35 54 61 62 6c 65 2a 29 70  ab((Fts5Table*)p
2e20: 56 74 61 62 29 3b 0a 20 20 72 65 74 75 72 6e 20  Vtab);.  return 
2e30: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a  SQLITE_OK;.}../*
2e40: 0a 2a 2a 20 54 68 65 20 78 44 65 73 74 72 6f 79  .** The xDestroy
2e50: 28 29 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65  () virtual table
2e60: 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74   method..*/.stat
2e70: 69 63 20 69 6e 74 20 66 74 73 35 44 65 73 74 72  ic int fts5Destr
2e80: 6f 79 4d 65 74 68 6f 64 28 73 71 6c 69 74 65 33  oyMethod(sqlite3
2e90: 5f 76 74 61 62 20 2a 70 56 74 61 62 29 7b 0a 20  _vtab *pVtab){. 
2ea0: 20 46 74 73 35 54 61 62 6c 65 20 2a 70 54 61 62   Fts5Table *pTab
2eb0: 20 3d 20 28 46 74 73 35 54 61 62 6c 65 2a 29 70   = (Fts5Table*)p
2ec0: 56 74 61 62 3b 0a 20 20 69 6e 74 20 72 63 20 3d  Vtab;.  int rc =
2ed0: 20 73 71 6c 69 74 65 33 46 74 73 35 44 72 6f 70   sqlite3Fts5Drop
2ee0: 41 6c 6c 28 70 54 61 62 2d 3e 70 43 6f 6e 66 69  All(pTab->pConfi
2ef0: 67 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51  g);.  if( rc==SQ
2f00: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 66  LITE_OK ){.    f
2f10: 74 73 35 46 72 65 65 56 74 61 62 28 28 46 74 73  ts5FreeVtab((Fts
2f20: 35 54 61 62 6c 65 2a 29 70 56 74 61 62 29 3b 0a  5Table*)pVtab);.
2f30: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b    }.  return rc;
2f40: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66  .}../*.** This f
2f50: 75 6e 63 74 69 6f 6e 20 69 73 20 74 68 65 20 69  unction is the i
2f60: 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66  mplementation of
2f70: 20 62 6f 74 68 20 74 68 65 20 78 43 6f 6e 6e 65   both the xConne
2f80: 63 74 20 61 6e 64 20 78 43 72 65 61 74 65 0a 2a  ct and xCreate.*
2f90: 2a 20 6d 65 74 68 6f 64 73 20 6f 66 20 74 68 65  * methods of the
2fa0: 20 46 54 53 33 20 76 69 72 74 75 61 6c 20 74 61   FTS3 virtual ta
2fb0: 62 6c 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61  ble..**.** The a
2fc0: 72 67 76 5b 5d 20 61 72 72 61 79 20 63 6f 6e 74  rgv[] array cont
2fd0: 61 69 6e 73 20 74 68 65 20 66 6f 6c 6c 6f 77 69  ains the followi
2fe0: 6e 67 3a 0a 2a 2a 0a 2a 2a 20 20 20 61 72 67 76  ng:.**.**   argv
2ff0: 5b 30 5d 20 20 20 2d 3e 20 6d 6f 64 75 6c 65 20  [0]   -> module 
3000: 6e 61 6d 65 20 20 28 22 66 74 73 35 22 29 0a 2a  name  ("fts5").*
3010: 2a 20 20 20 61 72 67 76 5b 31 5d 20 20 20 2d 3e  *   argv[1]   ->
3020: 20 64 61 74 61 62 61 73 65 20 6e 61 6d 65 0a 2a   database name.*
3030: 2a 20 20 20 61 72 67 76 5b 32 5d 20 20 20 2d 3e  *   argv[2]   ->
3040: 20 74 61 62 6c 65 20 6e 61 6d 65 0a 2a 2a 20 20   table name.**  
3050: 20 61 72 67 76 5b 2e 2e 2e 5d 20 2d 3e 20 22 63   argv[...] -> "c
3060: 6f 6c 75 6d 6e 20 6e 61 6d 65 22 20 61 6e 64 20  olumn name" and 
3070: 6f 74 68 65 72 20 6d 6f 64 75 6c 65 20 61 72 67  other module arg
3080: 75 6d 65 6e 74 20 66 69 65 6c 64 73 2e 0a 2a 2f  ument fields..*/
3090: 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35  .static int fts5
30a0: 49 6e 69 74 56 74 61 62 28 0a 20 20 69 6e 74 20  InitVtab(.  int 
30b0: 62 43 72 65 61 74 65 2c 20 20 20 20 20 20 20 20  bCreate,        
30c0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
30d0: 72 75 65 20 66 6f 72 20 78 43 72 65 61 74 65 2c  rue for xCreate,
30e0: 20 66 61 6c 73 65 20 66 6f 72 20 78 43 6f 6e 6e   false for xConn
30f0: 65 63 74 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33  ect */.  sqlite3
3100: 20 2a 64 62 2c 20 20 20 20 20 20 20 20 20 20 20   *db,           
3110: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20           /* The 
3120: 53 51 4c 69 74 65 20 64 61 74 61 62 61 73 65 20  SQLite database 
3130: 63 6f 6e 6e 65 63 74 69 6f 6e 20 2a 2f 0a 20 20  connection */.  
3140: 76 6f 69 64 20 2a 70 41 75 78 2c 20 20 20 20 20  void *pAux,     
3150: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3160: 2f 2a 20 48 61 73 68 20 74 61 62 6c 65 20 63 6f  /* Hash table co
3170: 6e 74 61 69 6e 69 6e 67 20 74 6f 6b 65 6e 69 7a  ntaining tokeniz
3180: 65 72 73 20 2a 2f 0a 20 20 69 6e 74 20 61 72 67  ers */.  int arg
3190: 63 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  c,              
31a0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
31b0: 65 72 20 6f 66 20 65 6c 65 6d 65 6e 74 73 20 69  er of elements i
31c0: 6e 20 61 72 67 76 20 61 72 72 61 79 20 2a 2f 0a  n argv array */.
31d0: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 20 63    const char * c
31e0: 6f 6e 73 74 20 2a 61 72 67 76 2c 20 20 20 20 20  onst *argv,     
31f0: 20 20 2f 2a 20 78 43 72 65 61 74 65 2f 78 43 6f    /* xCreate/xCo
3200: 6e 6e 65 63 74 20 61 72 67 75 6d 65 6e 74 20 61  nnect argument a
3210: 72 72 61 79 20 2a 2f 0a 20 20 73 71 6c 69 74 65  rray */.  sqlite
3220: 33 5f 76 74 61 62 20 2a 2a 70 70 56 54 61 62 2c  3_vtab **ppVTab,
3230: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 57 72 69            /* Wri
3240: 74 65 20 74 68 65 20 72 65 73 75 6c 74 69 6e 67  te the resulting
3250: 20 76 74 61 62 20 73 74 72 75 63 74 75 72 65 20   vtab structure 
3260: 68 65 72 65 20 2a 2f 0a 20 20 63 68 61 72 20 2a  here */.  char *
3270: 2a 70 7a 45 72 72 20 20 20 20 20 20 20 20 20 20  *pzErr          
3280: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 57 72 69            /* Wri
3290: 74 65 20 61 6e 79 20 65 72 72 6f 72 20 6d 65 73  te any error mes
32a0: 73 61 67 65 20 68 65 72 65 20 2a 2f 0a 29 7b 0a  sage here */.){.
32b0: 20 20 46 74 73 35 47 6c 6f 62 61 6c 20 2a 70 47    Fts5Global *pG
32c0: 6c 6f 62 61 6c 20 3d 20 28 46 74 73 35 47 6c 6f  lobal = (Fts5Glo
32d0: 62 61 6c 2a 29 70 41 75 78 3b 0a 20 20 63 6f 6e  bal*)pAux;.  con
32e0: 73 74 20 63 68 61 72 20 2a 2a 61 7a 43 6f 6e 66  st char **azConf
32f0: 69 67 20 3d 20 28 63 6f 6e 73 74 20 63 68 61 72  ig = (const char
3300: 2a 2a 29 61 72 67 76 3b 0a 20 20 69 6e 74 20 72  **)argv;.  int r
3310: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 20 20  c = SQLITE_OK;  
3320: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65             /* Re
3330: 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 46  turn code */.  F
3340: 74 73 35 43 6f 6e 66 69 67 20 2a 70 43 6f 6e 66  ts5Config *pConf
3350: 69 67 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f  ig;            /
3360: 2a 20 52 65 73 75 6c 74 73 20 6f 66 20 70 61 72  * Results of par
3370: 73 69 6e 67 20 61 72 67 63 2f 61 72 67 76 20 2a  sing argc/argv *
3380: 2f 0a 20 20 46 74 73 35 54 61 62 6c 65 20 2a 70  /.  Fts5Table *p
3390: 54 61 62 20 3d 20 30 3b 20 20 20 20 20 20 20 20  Tab = 0;        
33a0: 20 20 20 20 2f 2a 20 4e 65 77 20 76 69 72 74 75      /* New virtu
33b0: 61 6c 20 74 61 62 6c 65 20 6f 62 6a 65 63 74 20  al table object 
33c0: 2a 2f 0a 0a 20 20 2f 2a 20 41 6c 6c 6f 63 61 74  */..  /* Allocat
33d0: 65 20 74 68 65 20 6e 65 77 20 76 74 61 62 20 6f  e the new vtab o
33e0: 62 6a 65 63 74 20 61 6e 64 20 70 61 72 73 65 20  bject and parse 
33f0: 74 68 65 20 63 6f 6e 66 69 67 75 72 61 74 69 6f  the configuratio
3400: 6e 20 2a 2f 0a 20 20 70 54 61 62 20 3d 20 28 46  n */.  pTab = (F
3410: 74 73 35 54 61 62 6c 65 2a 29 73 71 6c 69 74 65  ts5Table*)sqlite
3420: 33 46 74 73 35 4d 61 6c 6c 6f 63 5a 65 72 6f 28  3Fts5MallocZero(
3430: 26 72 63 2c 20 73 69 7a 65 6f 66 28 46 74 73 35  &rc, sizeof(Fts5
3440: 54 61 62 6c 65 29 29 3b 0a 20 20 69 66 28 20 72  Table));.  if( r
3450: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
3460: 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
3470: 46 74 73 35 43 6f 6e 66 69 67 50 61 72 73 65 28  Fts5ConfigParse(
3480: 70 47 6c 6f 62 61 6c 2c 20 64 62 2c 20 61 72 67  pGlobal, db, arg
3490: 63 2c 20 61 7a 43 6f 6e 66 69 67 2c 20 26 70 43  c, azConfig, &pC
34a0: 6f 6e 66 69 67 2c 20 70 7a 45 72 72 29 3b 0a 20  onfig, pzErr);. 
34b0: 20 20 20 61 73 73 65 72 74 28 20 28 72 63 3d 3d     assert( (rc==
34c0: 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 2a 70 7a  SQLITE_OK && *pz
34d0: 45 72 72 3d 3d 30 29 20 7c 7c 20 70 43 6f 6e 66  Err==0) || pConf
34e0: 69 67 3d 3d 30 20 29 3b 0a 20 20 7d 0a 20 20 69  ig==0 );.  }.  i
34f0: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
3500: 20 29 7b 0a 20 20 20 20 70 54 61 62 2d 3e 70 43   ){.    pTab->pC
3510: 6f 6e 66 69 67 20 3d 20 70 43 6f 6e 66 69 67 3b  onfig = pConfig;
3520: 0a 20 20 20 20 70 54 61 62 2d 3e 70 47 6c 6f 62  .    pTab->pGlob
3530: 61 6c 20 3d 20 70 47 6c 6f 62 61 6c 3b 0a 20 20  al = pGlobal;.  
3540: 7d 0a 0a 20 20 2f 2a 20 4f 70 65 6e 20 74 68 65  }..  /* Open the
3550: 20 69 6e 64 65 78 20 73 75 62 2d 73 79 73 74 65   index sub-syste
3560: 6d 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d 53  m */.  if( rc==S
3570: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
3580: 72 63 20 3d 20 73 71 6c 69 74 65 33 46 74 73 35  rc = sqlite3Fts5
3590: 49 6e 64 65 78 4f 70 65 6e 28 70 43 6f 6e 66 69  IndexOpen(pConfi
35a0: 67 2c 20 62 43 72 65 61 74 65 2c 20 26 70 54 61  g, bCreate, &pTa
35b0: 62 2d 3e 70 49 6e 64 65 78 2c 20 70 7a 45 72 72  b->pIndex, pzErr
35c0: 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 4f 70 65  );.  }..  /* Ope
35d0: 6e 20 74 68 65 20 73 74 6f 72 61 67 65 20 73 75  n the storage su
35e0: 62 2d 73 79 73 74 65 6d 20 2a 2f 0a 20 20 69 66  b-system */.  if
35f0: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
3600: 29 7b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69  ){.    rc = sqli
3610: 74 65 33 46 74 73 35 53 74 6f 72 61 67 65 4f 70  te3Fts5StorageOp
3620: 65 6e 28 0a 20 20 20 20 20 20 20 20 70 43 6f 6e  en(.        pCon
3630: 66 69 67 2c 20 70 54 61 62 2d 3e 70 49 6e 64 65  fig, pTab->pInde
3640: 78 2c 20 62 43 72 65 61 74 65 2c 20 26 70 54 61  x, bCreate, &pTa
3650: 62 2d 3e 70 53 74 6f 72 61 67 65 2c 20 70 7a 45  b->pStorage, pzE
3660: 72 72 0a 20 20 20 20 29 3b 0a 20 20 7d 0a 0a 20  rr.    );.  }.. 
3670: 20 2f 2a 20 43 61 6c 6c 20 73 71 6c 69 74 65 33   /* Call sqlite3
3680: 5f 64 65 63 6c 61 72 65 5f 76 74 61 62 28 29 20  _declare_vtab() 
3690: 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  */.  if( rc==SQL
36a0: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63  ITE_OK ){.    rc
36b0: 20 3d 20 73 71 6c 69 74 65 33 46 74 73 35 43 6f   = sqlite3Fts5Co
36c0: 6e 66 69 67 44 65 63 6c 61 72 65 56 74 61 62 28  nfigDeclareVtab(
36d0: 70 43 6f 6e 66 69 67 29 3b 0a 20 20 7d 0a 0a 20  pConfig);.  }.. 
36e0: 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
36f0: 4f 4b 20 29 7b 0a 20 20 20 20 66 74 73 35 46 72  OK ){.    fts5Fr
3700: 65 65 56 74 61 62 28 70 54 61 62 29 3b 0a 20 20  eeVtab(pTab);.  
3710: 20 20 70 54 61 62 20 3d 20 30 3b 0a 20 20 7d 65    pTab = 0;.  }e
3720: 6c 73 65 20 69 66 28 20 62 43 72 65 61 74 65 20  lse if( bCreate 
3730: 29 7b 0a 20 20 20 20 66 74 73 35 43 68 65 63 6b  ){.    fts5Check
3740: 54 72 61 6e 73 61 63 74 69 6f 6e 53 74 61 74 65  TransactionState
3750: 28 70 54 61 62 2c 20 46 54 53 35 5f 42 45 47 49  (pTab, FTS5_BEGI
3760: 4e 2c 20 30 29 3b 0a 20 20 7d 0a 20 20 2a 70 70  N, 0);.  }.  *pp
3770: 56 54 61 62 20 3d 20 28 73 71 6c 69 74 65 33 5f  VTab = (sqlite3_
3780: 76 74 61 62 2a 29 70 54 61 62 3b 0a 20 20 72 65  vtab*)pTab;.  re
3790: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
37a0: 2a 20 54 68 65 20 78 43 6f 6e 6e 65 63 74 28 29  * The xConnect()
37b0: 20 61 6e 64 20 78 43 72 65 61 74 65 28 29 20 6d   and xCreate() m
37c0: 65 74 68 6f 64 73 20 66 6f 72 20 74 68 65 20 76  ethods for the v
37d0: 69 72 74 75 61 6c 20 74 61 62 6c 65 2e 20 41 6c  irtual table. Al
37e0: 6c 20 74 68 65 0a 2a 2a 20 77 6f 72 6b 20 69 73  l the.** work is
37f0: 20 64 6f 6e 65 20 69 6e 20 66 75 6e 63 74 69 6f   done in functio
3800: 6e 20 66 74 73 35 49 6e 69 74 56 74 61 62 28 29  n fts5InitVtab()
3810: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
3820: 66 74 73 35 43 6f 6e 6e 65 63 74 4d 65 74 68 6f  fts5ConnectMetho
3830: 64 28 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62  d(.  sqlite3 *db
3840: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
3850: 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65       /* Database
3860: 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 2a 2f 0a 20   connection */. 
3870: 20 76 6f 69 64 20 2a 70 41 75 78 2c 20 20 20 20   void *pAux,    
3880: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3890: 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 74   /* Pointer to t
38a0: 6f 6b 65 6e 69 7a 65 72 20 68 61 73 68 20 74 61  okenizer hash ta
38b0: 62 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 61 72 67  ble */.  int arg
38c0: 63 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  c,              
38d0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
38e0: 65 72 20 6f 66 20 65 6c 65 6d 65 6e 74 73 20 69  er of elements i
38f0: 6e 20 61 72 67 76 20 61 72 72 61 79 20 2a 2f 0a  n argv array */.
3900: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 20 63    const char * c
3910: 6f 6e 73 74 20 2a 61 72 67 76 2c 20 20 20 20 20  onst *argv,     
3920: 20 20 2f 2a 20 78 43 72 65 61 74 65 2f 78 43 6f    /* xCreate/xCo
3930: 6e 6e 65 63 74 20 61 72 67 75 6d 65 6e 74 20 61  nnect argument a
3940: 72 72 61 79 20 2a 2f 0a 20 20 73 71 6c 69 74 65  rray */.  sqlite
3950: 33 5f 76 74 61 62 20 2a 2a 70 70 56 74 61 62 2c  3_vtab **ppVtab,
3960: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54            /* OUT
3970: 3a 20 4e 65 77 20 73 71 6c 69 74 65 33 5f 76 74  : New sqlite3_vt
3980: 61 62 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 63  ab object */.  c
3990: 68 61 72 20 2a 2a 70 7a 45 72 72 20 20 20 20 20  har **pzErr     
39a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
39b0: 2a 20 4f 55 54 3a 20 73 71 6c 69 74 65 33 5f 6d  * OUT: sqlite3_m
39c0: 61 6c 6c 6f 63 27 64 20 65 72 72 6f 72 20 6d 65  alloc'd error me
39d0: 73 73 61 67 65 20 2a 2f 0a 29 7b 0a 20 20 72 65  ssage */.){.  re
39e0: 74 75 72 6e 20 66 74 73 35 49 6e 69 74 56 74 61  turn fts5InitVta
39f0: 62 28 30 2c 20 64 62 2c 20 70 41 75 78 2c 20 61  b(0, db, pAux, a
3a00: 72 67 63 2c 20 61 72 67 76 2c 20 70 70 56 74 61  rgc, argv, ppVta
3a10: 62 2c 20 70 7a 45 72 72 29 3b 0a 7d 0a 73 74 61  b, pzErr);.}.sta
3a20: 74 69 63 20 69 6e 74 20 66 74 73 35 43 72 65 61  tic int fts5Crea
3a30: 74 65 4d 65 74 68 6f 64 28 0a 20 20 73 71 6c 69  teMethod(.  sqli
3a40: 74 65 33 20 2a 64 62 2c 20 20 20 20 20 20 20 20  te3 *db,        
3a50: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44              /* D
3a60: 61 74 61 62 61 73 65 20 63 6f 6e 6e 65 63 74 69  atabase connecti
3a70: 6f 6e 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 41  on */.  void *pA
3a80: 75 78 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ux,             
3a90: 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74          /* Point
3aa0: 65 72 20 74 6f 20 74 6f 6b 65 6e 69 7a 65 72 20  er to tokenizer 
3ab0: 68 61 73 68 20 74 61 62 6c 65 20 2a 2f 0a 20 20  hash table */.  
3ac0: 69 6e 74 20 61 72 67 63 2c 20 20 20 20 20 20 20  int argc,       
3ad0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3ae0: 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 65 6c 65  /* Number of ele
3af0: 6d 65 6e 74 73 20 69 6e 20 61 72 67 76 20 61 72  ments in argv ar
3b00: 72 61 79 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63  ray */.  const c
3b10: 68 61 72 20 2a 20 63 6f 6e 73 74 20 2a 61 72 67  har * const *arg
3b20: 76 2c 20 20 20 20 20 20 20 2f 2a 20 78 43 72 65  v,       /* xCre
3b30: 61 74 65 2f 78 43 6f 6e 6e 65 63 74 20 61 72 67  ate/xConnect arg
3b40: 75 6d 65 6e 74 20 61 72 72 61 79 20 2a 2f 0a 20  ument array */. 
3b50: 20 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 2a   sqlite3_vtab **
3b60: 70 70 56 74 61 62 2c 20 20 20 20 20 20 20 20 20  ppVtab,         
3b70: 20 2f 2a 20 4f 55 54 3a 20 4e 65 77 20 73 71 6c   /* OUT: New sql
3b80: 69 74 65 33 5f 76 74 61 62 20 6f 62 6a 65 63 74  ite3_vtab object
3b90: 20 2a 2f 0a 20 20 63 68 61 72 20 2a 2a 70 7a 45   */.  char **pzE
3ba0: 72 72 20 20 20 20 20 20 20 20 20 20 20 20 20 20  rr              
3bb0: 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 73 71        /* OUT: sq
3bc0: 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 27 64 20 65  lite3_malloc'd e
3bd0: 72 72 6f 72 20 6d 65 73 73 61 67 65 20 2a 2f 0a  rror message */.
3be0: 29 7b 0a 20 20 72 65 74 75 72 6e 20 66 74 73 35  ){.  return fts5
3bf0: 49 6e 69 74 56 74 61 62 28 31 2c 20 64 62 2c 20  InitVtab(1, db, 
3c00: 70 41 75 78 2c 20 61 72 67 63 2c 20 61 72 67 76  pAux, argc, argv
3c10: 2c 20 70 70 56 74 61 62 2c 20 70 7a 45 72 72 29  , ppVtab, pzErr)
3c20: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 64  ;.}../*.** The d
3c30: 69 66 66 65 72 65 6e 74 20 71 75 65 72 79 20 70  ifferent query p
3c40: 6c 61 6e 73 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65  lans..*/.#define
3c50: 20 46 54 53 35 5f 50 4c 41 4e 5f 53 43 41 4e 20   FTS5_PLAN_SCAN 
3c60: 20 20 20 20 20 20 20 20 20 20 31 20 20 20 20 20            1     
3c70: 20 20 2f 2a 20 4e 6f 20 75 73 61 62 6c 65 20 63    /* No usable c
3c80: 6f 6e 73 74 72 61 69 6e 74 20 2a 2f 0a 23 64 65  onstraint */.#de
3c90: 66 69 6e 65 20 46 54 53 35 5f 50 4c 41 4e 5f 4d  fine FTS5_PLAN_M
3ca0: 41 54 43 48 20 20 20 20 20 20 20 20 20 20 32 20  ATCH          2 
3cb0: 20 20 20 20 20 20 2f 2a 20 28 3c 74 62 6c 3e 20        /* (<tbl> 
3cc0: 4d 41 54 43 48 20 3f 29 20 2a 2f 0a 23 64 65 66  MATCH ?) */.#def
3cd0: 69 6e 65 20 46 54 53 35 5f 50 4c 41 4e 5f 53 4f  ine FTS5_PLAN_SO
3ce0: 52 54 45 44 5f 4d 41 54 43 48 20 20 20 33 20 20  RTED_MATCH   3  
3cf0: 20 20 20 20 20 2f 2a 20 28 3c 74 62 6c 3e 20 4d       /* (<tbl> M
3d00: 41 54 43 48 20 3f 20 4f 52 44 45 52 20 42 59 20  ATCH ? ORDER BY 
3d10: 72 61 6e 6b 29 20 2a 2f 0a 23 64 65 66 69 6e 65  rank) */.#define
3d20: 20 46 54 53 35 5f 50 4c 41 4e 5f 52 4f 57 49 44   FTS5_PLAN_ROWID
3d30: 20 20 20 20 20 20 20 20 20 20 34 20 20 20 20 20            4     
3d40: 20 20 2f 2a 20 28 72 6f 77 69 64 20 3d 20 3f 29    /* (rowid = ?)
3d50: 20 2a 2f 0a 23 64 65 66 69 6e 65 20 46 54 53 35   */.#define FTS5
3d60: 5f 50 4c 41 4e 5f 53 4f 55 52 43 45 20 20 20 20  _PLAN_SOURCE    
3d70: 20 20 20 20 20 35 20 20 20 20 20 20 20 2f 2a 20       5       /* 
3d80: 41 20 73 6f 75 72 63 65 20 63 75 72 73 6f 72 20  A source cursor 
3d90: 66 6f 72 20 53 4f 52 54 45 44 5f 4d 41 54 43 48  for SORTED_MATCH
3da0: 20 2a 2f 0a 23 64 65 66 69 6e 65 20 46 54 53 35   */.#define FTS5
3db0: 5f 50 4c 41 4e 5f 53 50 45 43 49 41 4c 20 20 20  _PLAN_SPECIAL   
3dc0: 20 20 20 20 20 36 20 20 20 20 20 20 20 2f 2a 20       6       /* 
3dd0: 41 6e 20 69 6e 74 65 72 6e 61 6c 20 71 75 65 72  An internal quer
3de0: 79 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c  y */../*.** Impl
3df0: 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68  ementation of th
3e00: 65 20 78 42 65 73 74 49 6e 64 65 78 20 6d 65 74  e xBestIndex met
3e10: 68 6f 64 20 66 6f 72 20 46 54 53 35 20 74 61 62  hod for FTS5 tab
3e20: 6c 65 73 2e 20 57 69 74 68 69 6e 20 74 68 65 20  les. Within the 
3e30: 0a 2a 2a 20 57 48 45 52 45 20 63 6f 6e 73 74 72  .** WHERE constr
3e40: 61 69 6e 74 2c 20 69 74 20 73 65 61 72 63 68 65  aint, it searche
3e50: 73 20 66 6f 72 20 74 68 65 20 66 6f 6c 6c 6f 77  s for the follow
3e60: 69 6e 67 3a 0a 2a 2a 0a 2a 2a 20 20 20 31 2e 20  ing:.**.**   1. 
3e70: 41 20 4d 41 54 43 48 20 63 6f 6e 73 74 72 61 69  A MATCH constrai
3e80: 6e 74 20 61 67 61 69 6e 73 74 20 74 68 65 20 73  nt against the s
3e90: 70 65 63 69 61 6c 20 63 6f 6c 75 6d 6e 2e 0a 2a  pecial column..*
3ea0: 2a 20 20 20 32 2e 20 41 20 4d 41 54 43 48 20 63  *   2. A MATCH c
3eb0: 6f 6e 73 74 72 61 69 6e 74 20 61 67 61 69 6e 73  onstraint agains
3ec0: 74 20 74 68 65 20 22 72 61 6e 6b 22 20 63 6f 6c  t the "rank" col
3ed0: 75 6d 6e 2e 0a 2a 2a 20 20 20 33 2e 20 41 6e 20  umn..**   3. An 
3ee0: 3d 3d 20 63 6f 6e 73 74 72 61 69 6e 74 20 61 67  == constraint ag
3ef0: 61 69 6e 73 74 20 74 68 65 20 72 6f 77 69 64 20  ainst the rowid 
3f00: 63 6f 6c 75 6d 6e 2e 0a 2a 2a 20 20 20 34 2e 20  column..**   4. 
3f10: 41 20 3c 20 6f 72 20 3c 3d 20 63 6f 6e 73 74 72  A < or <= constr
3f20: 61 69 6e 74 20 61 67 61 69 6e 73 74 20 74 68 65  aint against the
3f30: 20 72 6f 77 69 64 20 63 6f 6c 75 6d 6e 2e 0a 2a   rowid column..*
3f40: 2a 20 20 20 35 2e 20 41 20 3e 20 6f 72 20 3e 3d  *   5. A > or >=
3f50: 20 63 6f 6e 73 74 72 61 69 6e 74 20 61 67 61 69   constraint agai
3f60: 6e 73 74 20 74 68 65 20 72 6f 77 69 64 20 63 6f  nst the rowid co
3f70: 6c 75 6d 6e 2e 0a 2a 2a 0a 2a 2a 20 57 69 74 68  lumn..**.** With
3f80: 69 6e 20 74 68 65 20 4f 52 44 45 52 20 42 59 2c  in the ORDER BY,
3f90: 20 65 69 74 68 65 72 3a 0a 2a 2a 0a 2a 2a 20 20   either:.**.**  
3fa0: 20 35 2e 20 4f 52 44 45 52 20 42 59 20 72 61 6e   5. ORDER BY ran
3fb0: 6b 20 5b 41 53 43 7c 44 45 53 43 5d 0a 2a 2a 20  k [ASC|DESC].** 
3fc0: 20 20 36 2e 20 4f 52 44 45 52 20 42 59 20 72 6f    6. ORDER BY ro
3fd0: 77 69 64 20 5b 41 53 43 7c 44 45 53 43 5d 0a 2a  wid [ASC|DESC].*
3fe0: 2a 0a 2a 2a 20 43 6f 73 74 73 20 61 72 65 20 61  *.** Costs are a
3ff0: 73 73 69 67 6e 65 64 20 61 73 20 66 6f 6c 6c 6f  ssigned as follo
4000: 77 73 3a 0a 2a 2a 0a 2a 2a 20 20 61 29 20 49 66  ws:.**.**  a) If
4010: 20 61 6e 20 75 6e 75 73 61 62 6c 65 20 4d 41 54   an unusable MAT
4020: 43 48 20 6f 70 65 72 61 74 6f 72 20 69 73 20 70  CH operator is p
4030: 72 65 73 65 6e 74 20 69 6e 20 74 68 65 20 57 48  resent in the WH
4040: 45 52 45 20 63 6c 61 75 73 65 2c 20 74 68 65 0a  ERE clause, the.
4050: 2a 2a 20 20 20 20 20 63 6f 73 74 20 69 73 20 75  **     cost is u
4060: 6e 63 6f 6e 64 69 74 69 6f 6e 61 6c 6c 79 20 73  nconditionally s
4070: 65 74 20 74 6f 20 31 65 35 30 20 28 61 20 72 65  et to 1e50 (a re
4080: 61 6c 6c 79 20 62 69 67 20 6e 75 6d 62 65 72 29  ally big number)
4090: 2e 0a 2a 2a 0a 2a 2a 20 20 61 29 20 49 66 20 61  ..**.**  a) If a
40a0: 20 4d 41 54 43 48 20 6f 70 65 72 61 74 6f 72 20   MATCH operator 
40b0: 69 73 20 70 72 65 73 65 6e 74 2c 20 74 68 65 20  is present, the 
40c0: 63 6f 73 74 20 64 65 70 65 6e 64 73 20 6f 6e 20  cost depends on 
40d0: 74 68 65 20 6f 74 68 65 72 0a 2a 2a 20 20 20 20  the other.**    
40e0: 20 63 6f 6e 73 74 72 61 69 6e 74 73 20 61 6c 73   constraints als
40f0: 6f 20 70 72 65 73 65 6e 74 2e 20 41 73 20 66 6f  o present. As fo
4100: 6c 6c 6f 77 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 20  llows:.**.**    
4110: 20 20 20 2a 20 4e 6f 20 6f 74 68 65 72 20 63 6f     * No other co
4120: 6e 73 74 72 61 69 6e 74 73 3a 20 20 20 20 20 20  nstraints:      
4130: 20 20 20 63 6f 73 74 3d 31 30 30 30 2e 30 0a 2a     cost=1000.0.*
4140: 2a 20 20 20 20 20 20 20 2a 20 4f 6e 65 20 72 6f  *       * One ro
4150: 77 69 64 20 72 61 6e 67 65 20 63 6f 6e 73 74 72  wid range constr
4160: 61 69 6e 74 3a 20 20 20 63 6f 73 74 3d 37 35 30  aint:   cost=750
4170: 2e 30 0a 2a 2a 20 20 20 20 20 20 20 2a 20 42 6f  .0.**       * Bo
4180: 74 68 20 72 6f 77 69 64 20 72 61 6e 67 65 20 63  th rowid range c
4190: 6f 6e 73 74 72 61 69 6e 74 73 3a 20 63 6f 73 74  onstraints: cost
41a0: 3d 35 30 30 2e 30 0a 2a 2a 20 20 20 20 20 20 20  =500.0.**       
41b0: 2a 20 41 6e 20 3d 3d 20 72 6f 77 69 64 20 63 6f  * An == rowid co
41c0: 6e 73 74 72 61 69 6e 74 3a 20 20 20 20 20 20 20  nstraint:       
41d0: 63 6f 73 74 3d 31 30 30 2e 30 0a 2a 2a 0a 2a 2a  cost=100.0.**.**
41e0: 20 20 62 29 20 4f 74 68 65 72 77 69 73 65 2c 20    b) Otherwise, 
41f0: 69 66 20 74 68 65 72 65 20 69 73 20 6e 6f 20 4d  if there is no M
4200: 41 54 43 48 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20  ATCH:.**.**     
4210: 20 20 2a 20 4e 6f 20 6f 74 68 65 72 20 63 6f 6e    * No other con
4220: 73 74 72 61 69 6e 74 73 3a 20 20 20 20 20 20 20  straints:       
4230: 20 20 63 6f 73 74 3d 31 30 30 30 30 30 30 2e 30    cost=1000000.0
4240: 0a 2a 2a 20 20 20 20 20 20 20 2a 20 4f 6e 65 20  .**       * One 
4250: 72 6f 77 69 64 20 72 61 6e 67 65 20 63 6f 6e 73  rowid range cons
4260: 74 72 61 69 6e 74 3a 20 20 20 63 6f 73 74 3d 37  traint:   cost=7
4270: 35 30 30 30 30 2e 30 0a 2a 2a 20 20 20 20 20 20  50000.0.**      
4280: 20 2a 20 42 6f 74 68 20 72 6f 77 69 64 20 72 61   * Both rowid ra
4290: 6e 67 65 20 63 6f 6e 73 74 72 61 69 6e 74 73 3a  nge constraints:
42a0: 20 63 6f 73 74 3d 32 35 30 30 30 30 2e 30 0a 2a   cost=250000.0.*
42b0: 2a 20 20 20 20 20 20 20 2a 20 41 6e 20 3d 3d 20  *       * An == 
42c0: 72 6f 77 69 64 20 63 6f 6e 73 74 72 61 69 6e 74  rowid constraint
42d0: 3a 20 20 20 20 20 20 20 63 6f 73 74 3d 31 30 2e  :       cost=10.
42e0: 30 0a 2a 2a 0a 2a 2a 20 43 6f 73 74 73 20 61 72  0.**.** Costs ar
42f0: 65 20 6e 6f 74 20 6d 6f 64 69 66 69 65 64 20 62  e not modified b
4300: 79 20 74 68 65 20 4f 52 44 45 52 20 42 59 20 63  y the ORDER BY c
4310: 6c 61 75 73 65 2e 0a 2a 2f 0a 73 74 61 74 69 63  lause..*/.static
4320: 20 69 6e 74 20 66 74 73 35 42 65 73 74 49 6e 64   int fts5BestInd
4330: 65 78 4d 65 74 68 6f 64 28 73 71 6c 69 74 65 33  exMethod(sqlite3
4340: 5f 76 74 61 62 20 2a 70 56 54 61 62 2c 20 73 71  _vtab *pVTab, sq
4350: 6c 69 74 65 33 5f 69 6e 64 65 78 5f 69 6e 66 6f  lite3_index_info
4360: 20 2a 70 49 6e 66 6f 29 7b 0a 20 20 46 74 73 35   *pInfo){.  Fts5
4370: 54 61 62 6c 65 20 2a 70 54 61 62 20 3d 20 28 46  Table *pTab = (F
4380: 74 73 35 54 61 62 6c 65 2a 29 70 56 54 61 62 3b  ts5Table*)pVTab;
4390: 0a 20 20 46 74 73 35 43 6f 6e 66 69 67 20 2a 70  .  Fts5Config *p
43a0: 43 6f 6e 66 69 67 20 3d 20 70 54 61 62 2d 3e 70  Config = pTab->p
43b0: 43 6f 6e 66 69 67 3b 0a 20 20 69 6e 74 20 69 64  Config;.  int id
43c0: 78 46 6c 61 67 73 20 3d 20 30 3b 20 20 20 20 20  xFlags = 0;     
43d0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 61 72            /* Par
43e0: 61 6d 65 74 65 72 20 70 61 73 73 65 64 20 74 68  ameter passed th
43f0: 72 6f 75 67 68 20 74 6f 20 78 46 69 6c 74 65 72  rough to xFilter
4400: 28 29 20 2a 2f 0a 20 20 69 6e 74 20 62 48 61 73  () */.  int bHas
4410: 4d 61 74 63 68 3b 0a 20 20 69 6e 74 20 69 4e 65  Match;.  int iNe
4420: 78 74 3b 0a 20 20 69 6e 74 20 69 3b 0a 0a 20 20  xt;.  int i;..  
4430: 73 74 72 75 63 74 20 43 6f 6e 73 74 72 61 69 6e  struct Constrain
4440: 74 20 7b 0a 20 20 20 20 69 6e 74 20 6f 70 3b 20  t {.    int op; 
4450: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4460: 20 20 20 20 20 20 2f 2a 20 4d 61 73 6b 20 61 67        /* Mask ag
4470: 61 69 6e 73 74 20 73 71 6c 69 74 65 33 5f 69 6e  ainst sqlite3_in
4480: 64 65 78 5f 63 6f 6e 73 74 72 61 69 6e 74 2e 6f  dex_constraint.o
4490: 70 20 2a 2f 0a 20 20 20 20 69 6e 74 20 66 74 73  p */.    int fts
44a0: 35 6f 70 3b 20 20 20 20 20 20 20 20 20 20 20 20  5op;            
44b0: 20 20 20 20 20 20 20 2f 2a 20 46 54 53 35 20 6d         /* FTS5 m
44c0: 61 73 6b 20 66 6f 72 20 69 64 78 46 6c 61 67 73  ask for idxFlags
44d0: 20 2a 2f 0a 20 20 20 20 69 6e 74 20 69 43 6f 6c   */.    int iCol
44e0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
44f0: 20 20 20 20 20 20 2f 2a 20 30 3d 3d 72 6f 77 69        /* 0==rowi
4500: 64 2c 20 31 3d 3d 74 62 6c 2c 20 32 3d 3d 72 61  d, 1==tbl, 2==ra
4510: 6e 6b 20 2a 2f 0a 20 20 20 20 69 6e 74 20 6f 6d  nk */.    int om
4520: 69 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  it;             
4530: 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20          /* True 
4540: 74 6f 20 6f 6d 69 74 20 74 68 69 73 20 69 66 20  to omit this if 
4550: 66 6f 75 6e 64 20 2a 2f 0a 20 20 20 20 69 6e 74  found */.    int
4560: 20 69 43 6f 6e 73 49 6e 64 65 78 3b 20 20 20 20   iConsIndex;    
4570: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 6e             /* In
4580: 64 65 78 20 69 6e 20 70 49 6e 66 6f 2d 3e 61 43  dex in pInfo->aC
4590: 6f 6e 73 74 72 61 69 6e 74 5b 5d 20 2a 2f 0a 20  onstraint[] */. 
45a0: 20 7d 20 61 43 6f 6e 73 74 72 61 69 6e 74 5b 5d   } aConstraint[]
45b0: 20 3d 20 7b 0a 20 20 20 20 7b 53 51 4c 49 54 45   = {.    {SQLITE
45c0: 5f 49 4e 44 45 58 5f 43 4f 4e 53 54 52 41 49 4e  _INDEX_CONSTRAIN
45d0: 54 5f 4d 41 54 43 48 2c 20 46 54 53 35 5f 42 49  T_MATCH, FTS5_BI
45e0: 5f 4d 41 54 43 48 2c 20 20 20 20 31 2c 20 31 2c  _MATCH,    1, 1,
45f0: 20 2d 31 7d 2c 0a 20 20 20 20 7b 53 51 4c 49 54   -1},.    {SQLIT
4600: 45 5f 49 4e 44 45 58 5f 43 4f 4e 53 54 52 41 49  E_INDEX_CONSTRAI
4610: 4e 54 5f 4d 41 54 43 48 2c 20 46 54 53 35 5f 42  NT_MATCH, FTS5_B
4620: 49 5f 52 41 4e 4b 2c 20 20 20 20 20 32 2c 20 31  I_RANK,     2, 1
4630: 2c 20 2d 31 7d 2c 0a 20 20 20 20 7b 53 51 4c 49  , -1},.    {SQLI
4640: 54 45 5f 49 4e 44 45 58 5f 43 4f 4e 53 54 52 41  TE_INDEX_CONSTRA
4650: 49 4e 54 5f 45 51 2c 20 20 20 20 46 54 53 35 5f  INT_EQ,    FTS5_
4660: 42 49 5f 52 4f 57 49 44 5f 45 51 2c 20 30 2c 20  BI_ROWID_EQ, 0, 
4670: 30 2c 20 2d 31 7d 2c 0a 20 20 20 20 7b 53 51 4c  0, -1},.    {SQL
4680: 49 54 45 5f 49 4e 44 45 58 5f 43 4f 4e 53 54 52  ITE_INDEX_CONSTR
4690: 41 49 4e 54 5f 4c 54 7c 53 51 4c 49 54 45 5f 49  AINT_LT|SQLITE_I
46a0: 4e 44 45 58 5f 43 4f 4e 53 54 52 41 49 4e 54 5f  NDEX_CONSTRAINT_
46b0: 4c 45 2c 20 0a 20 20 20 20 20 20 20 20 20 20 20  LE, .           
46c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
46d0: 20 20 20 20 20 20 20 20 20 46 54 53 35 5f 42 49           FTS5_BI
46e0: 5f 52 4f 57 49 44 5f 4c 45 2c 20 30 2c 20 30 2c  _ROWID_LE, 0, 0,
46f0: 20 2d 31 7d 2c 0a 20 20 20 20 7b 53 51 4c 49 54   -1},.    {SQLIT
4700: 45 5f 49 4e 44 45 58 5f 43 4f 4e 53 54 52 41 49  E_INDEX_CONSTRAI
4710: 4e 54 5f 47 54 7c 53 51 4c 49 54 45 5f 49 4e 44  NT_GT|SQLITE_IND
4720: 45 58 5f 43 4f 4e 53 54 52 41 49 4e 54 5f 47 45  EX_CONSTRAINT_GE
4730: 2c 20 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  , .             
4740: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4750: 20 20 20 20 20 20 20 46 54 53 35 5f 42 49 5f 52         FTS5_BI_R
4760: 4f 57 49 44 5f 47 45 2c 20 30 2c 20 30 2c 20 2d  OWID_GE, 0, 0, -
4770: 31 7d 2c 0a 20 20 7d 3b 0a 0a 20 20 69 6e 74 20  1},.  };..  int 
4780: 61 43 6f 6c 4d 61 70 5b 33 5d 3b 0a 20 20 61 43  aColMap[3];.  aC
4790: 6f 6c 4d 61 70 5b 30 5d 20 3d 20 2d 31 3b 0a 20  olMap[0] = -1;. 
47a0: 20 61 43 6f 6c 4d 61 70 5b 31 5d 20 3d 20 70 43   aColMap[1] = pC
47b0: 6f 6e 66 69 67 2d 3e 6e 43 6f 6c 3b 0a 20 20 61  onfig->nCol;.  a
47c0: 43 6f 6c 4d 61 70 5b 32 5d 20 3d 20 70 43 6f 6e  ColMap[2] = pCon
47d0: 66 69 67 2d 3e 6e 43 6f 6c 2b 31 3b 0a 0a 20 20  fig->nCol+1;..  
47e0: 2f 2a 20 53 65 74 20 69 64 78 46 6c 61 67 73 20  /* Set idxFlags 
47f0: 66 6c 61 67 73 20 66 6f 72 20 61 6c 6c 20 57 48  flags for all WH
4800: 45 52 45 20 63 6c 61 75 73 65 20 74 65 72 6d 73  ERE clause terms
4810: 20 74 68 61 74 20 77 69 6c 6c 20 62 65 20 75 73   that will be us
4820: 65 64 2e 20 2a 2f 0a 20 20 66 6f 72 28 69 3d 30  ed. */.  for(i=0
4830: 3b 20 69 3c 70 49 6e 66 6f 2d 3e 6e 43 6f 6e 73  ; i<pInfo->nCons
4840: 74 72 61 69 6e 74 3b 20 69 2b 2b 29 7b 0a 20 20  traint; i++){.  
4850: 20 20 73 74 72 75 63 74 20 73 71 6c 69 74 65 33    struct sqlite3
4860: 5f 69 6e 64 65 78 5f 63 6f 6e 73 74 72 61 69 6e  _index_constrain
4870: 74 20 2a 70 20 3d 20 26 70 49 6e 66 6f 2d 3e 61  t *p = &pInfo->a
4880: 43 6f 6e 73 74 72 61 69 6e 74 5b 69 5d 3b 0a 20  Constraint[i];. 
4890: 20 20 20 69 6e 74 20 6a 3b 0a 20 20 20 20 66 6f     int j;.    fo
48a0: 72 28 6a 3d 30 3b 20 6a 3c 73 69 7a 65 6f 66 28  r(j=0; j<sizeof(
48b0: 61 43 6f 6e 73 74 72 61 69 6e 74 29 2f 73 69 7a  aConstraint)/siz
48c0: 65 6f 66 28 61 43 6f 6e 73 74 72 61 69 6e 74 5b  eof(aConstraint[
48d0: 30 5d 29 3b 20 6a 2b 2b 29 7b 0a 20 20 20 20 20  0]); j++){.     
48e0: 20 73 74 72 75 63 74 20 43 6f 6e 73 74 72 61 69   struct Constrai
48f0: 6e 74 20 2a 70 43 20 3d 20 26 61 43 6f 6e 73 74  nt *pC = &aConst
4900: 72 61 69 6e 74 5b 6a 5d 3b 0a 20 20 20 20 20 20  raint[j];.      
4910: 69 66 28 20 70 2d 3e 69 43 6f 6c 75 6d 6e 3d 3d  if( p->iColumn==
4920: 61 43 6f 6c 4d 61 70 5b 70 43 2d 3e 69 43 6f 6c  aColMap[pC->iCol
4930: 5d 20 26 26 20 70 2d 3e 6f 70 20 26 20 70 43 2d  ] && p->op & pC-
4940: 3e 6f 70 20 29 7b 0a 20 20 20 20 20 20 20 20 69  >op ){.        i
4950: 66 28 20 70 2d 3e 75 73 61 62 6c 65 20 29 7b 0a  f( p->usable ){.
4960: 20 20 20 20 20 20 20 20 20 20 70 43 2d 3e 69 43            pC->iC
4970: 6f 6e 73 49 6e 64 65 78 20 3d 20 69 3b 0a 20 20  onsIndex = i;.  
4980: 20 20 20 20 20 20 20 20 69 64 78 46 6c 61 67 73          idxFlags
4990: 20 7c 3d 20 70 43 2d 3e 66 74 73 35 6f 70 3b 0a   |= pC->fts5op;.
49a0: 20 20 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66          }else if
49b0: 28 20 6a 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  ( j==0 ){.      
49c0: 20 20 20 20 2f 2a 20 41 73 20 74 68 65 72 65 20      /* As there 
49d0: 65 78 69 73 74 73 20 61 6e 20 75 6e 75 73 61 62  exists an unusab
49e0: 6c 65 20 4d 41 54 43 48 20 63 6f 6e 73 74 72 61  le MATCH constra
49f0: 69 6e 74 20 74 68 69 73 20 69 73 20 61 6e 20 0a  int this is an .
4a00: 20 20 20 20 20 20 20 20 20 20 2a 2a 20 75 6e 75            ** unu
4a10: 73 61 62 6c 65 20 70 6c 61 6e 2e 20 53 65 74 20  sable plan. Set 
4a20: 61 20 70 72 6f 68 69 62 69 74 69 76 65 6c 79 20  a prohibitively 
4a30: 68 69 67 68 20 63 6f 73 74 2e 20 2a 2f 0a 20 20  high cost. */.  
4a40: 20 20 20 20 20 20 20 20 70 49 6e 66 6f 2d 3e 65          pInfo->e
4a50: 73 74 69 6d 61 74 65 64 43 6f 73 74 20 3d 20 31  stimatedCost = 1
4a60: 65 35 30 3b 0a 20 20 20 20 20 20 20 20 20 20 72  e50;.          r
4a70: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
4a80: 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
4a90: 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20   }.    }.  }..  
4aa0: 2f 2a 20 53 65 74 20 69 64 78 46 6c 61 67 73 20  /* Set idxFlags 
4ab0: 66 6c 61 67 73 20 66 6f 72 20 74 68 65 20 4f 52  flags for the OR
4ac0: 44 45 52 20 42 59 20 63 6c 61 75 73 65 20 2a 2f  DER BY clause */
4ad0: 0a 20 20 69 66 28 20 70 49 6e 66 6f 2d 3e 6e 4f  .  if( pInfo->nO
4ae0: 72 64 65 72 42 79 3d 3d 31 20 29 7b 0a 20 20 20  rderBy==1 ){.   
4af0: 20 69 6e 74 20 69 53 6f 72 74 20 3d 20 70 49 6e   int iSort = pIn
4b00: 66 6f 2d 3e 61 4f 72 64 65 72 42 79 5b 30 5d 2e  fo->aOrderBy[0].
4b10: 69 43 6f 6c 75 6d 6e 3b 0a 20 20 20 20 69 66 28  iColumn;.    if(
4b20: 20 69 53 6f 72 74 3d 3d 28 70 43 6f 6e 66 69 67   iSort==(pConfig
4b30: 2d 3e 6e 43 6f 6c 2b 31 29 20 26 26 20 42 69 74  ->nCol+1) && Bit
4b40: 46 6c 61 67 54 65 73 74 28 69 64 78 46 6c 61 67  FlagTest(idxFlag
4b50: 73 2c 20 46 54 53 35 5f 42 49 5f 4d 41 54 43 48  s, FTS5_BI_MATCH
4b60: 29 20 29 7b 0a 20 20 20 20 20 20 69 64 78 46 6c  ) ){.      idxFl
4b70: 61 67 73 20 7c 3d 20 46 54 53 35 5f 42 49 5f 4f  ags |= FTS5_BI_O
4b80: 52 44 45 52 5f 52 41 4e 4b 3b 0a 20 20 20 20 7d  RDER_RANK;.    }
4b90: 65 6c 73 65 20 69 66 28 20 69 53 6f 72 74 3d 3d  else if( iSort==
4ba0: 2d 31 20 29 7b 0a 20 20 20 20 20 20 69 64 78 46  -1 ){.      idxF
4bb0: 6c 61 67 73 20 7c 3d 20 46 54 53 35 5f 42 49 5f  lags |= FTS5_BI_
4bc0: 4f 52 44 45 52 5f 52 4f 57 49 44 3b 0a 20 20 20  ORDER_ROWID;.   
4bd0: 20 7d 0a 20 20 20 20 69 66 28 20 42 69 74 46 6c   }.    if( BitFl
4be0: 61 67 54 65 73 74 28 69 64 78 46 6c 61 67 73 2c  agTest(idxFlags,
4bf0: 20 46 54 53 35 5f 42 49 5f 4f 52 44 45 52 5f 52   FTS5_BI_ORDER_R
4c00: 41 4e 4b 7c 46 54 53 35 5f 42 49 5f 4f 52 44 45  ANK|FTS5_BI_ORDE
4c10: 52 5f 52 4f 57 49 44 29 20 29 7b 0a 20 20 20 20  R_ROWID) ){.    
4c20: 20 20 70 49 6e 66 6f 2d 3e 6f 72 64 65 72 42 79    pInfo->orderBy
4c30: 43 6f 6e 73 75 6d 65 64 20 3d 20 31 3b 0a 20 20  Consumed = 1;.  
4c40: 20 20 20 20 69 66 28 20 70 49 6e 66 6f 2d 3e 61      if( pInfo->a
4c50: 4f 72 64 65 72 42 79 5b 30 5d 2e 64 65 73 63 20  OrderBy[0].desc 
4c60: 29 7b 0a 20 20 20 20 20 20 20 20 69 64 78 46 6c  ){.        idxFl
4c70: 61 67 73 20 7c 3d 20 46 54 53 35 5f 42 49 5f 4f  ags |= FTS5_BI_O
4c80: 52 44 45 52 5f 44 45 53 43 3b 0a 20 20 20 20 20  RDER_DESC;.     
4c90: 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20   }.    }.  }..  
4ca0: 2f 2a 20 43 61 6c 63 75 6c 61 74 65 20 74 68 65  /* Calculate the
4cb0: 20 65 73 74 69 6d 61 74 65 64 20 63 6f 73 74 20   estimated cost 
4cc0: 62 61 73 65 64 20 6f 6e 20 74 68 65 20 66 6c 61  based on the fla
4cd0: 67 73 20 73 65 74 20 69 6e 20 69 64 78 46 6c 61  gs set in idxFla
4ce0: 67 73 2e 20 2a 2f 0a 20 20 62 48 61 73 4d 61 74  gs. */.  bHasMat
4cf0: 63 68 20 3d 20 42 69 74 46 6c 61 67 54 65 73 74  ch = BitFlagTest
4d00: 28 69 64 78 46 6c 61 67 73 2c 20 46 54 53 35 5f  (idxFlags, FTS5_
4d10: 42 49 5f 4d 41 54 43 48 29 3b 0a 20 20 69 66 28  BI_MATCH);.  if(
4d20: 20 42 69 74 46 6c 61 67 54 65 73 74 28 69 64 78   BitFlagTest(idx
4d30: 46 6c 61 67 73 2c 20 46 54 53 35 5f 42 49 5f 52  Flags, FTS5_BI_R
4d40: 4f 57 49 44 5f 45 51 29 20 29 7b 0a 20 20 20 20  OWID_EQ) ){.    
4d50: 70 49 6e 66 6f 2d 3e 65 73 74 69 6d 61 74 65 64  pInfo->estimated
4d60: 43 6f 73 74 20 3d 20 62 48 61 73 4d 61 74 63 68  Cost = bHasMatch
4d70: 20 3f 20 31 30 30 2e 30 20 3a 20 31 30 2e 30 3b   ? 100.0 : 10.0;
4d80: 0a 20 20 7d 65 6c 73 65 20 69 66 28 20 42 69 74  .  }else if( Bit
4d90: 46 6c 61 67 41 6c 6c 54 65 73 74 28 69 64 78 46  FlagAllTest(idxF
4da0: 6c 61 67 73 2c 20 46 54 53 35 5f 42 49 5f 52 4f  lags, FTS5_BI_RO
4db0: 57 49 44 5f 4c 45 7c 46 54 53 35 5f 42 49 5f 52  WID_LE|FTS5_BI_R
4dc0: 4f 57 49 44 5f 47 45 29 20 29 7b 0a 20 20 20 20  OWID_GE) ){.    
4dd0: 70 49 6e 66 6f 2d 3e 65 73 74 69 6d 61 74 65 64  pInfo->estimated
4de0: 43 6f 73 74 20 3d 20 62 48 61 73 4d 61 74 63 68  Cost = bHasMatch
4df0: 20 3f 20 35 30 30 2e 30 20 3a 20 32 35 30 30 30   ? 500.0 : 25000
4e00: 30 2e 30 3b 0a 20 20 7d 65 6c 73 65 20 69 66 28  0.0;.  }else if(
4e10: 20 42 69 74 46 6c 61 67 54 65 73 74 28 69 64 78   BitFlagTest(idx
4e20: 46 6c 61 67 73 2c 20 46 54 53 35 5f 42 49 5f 52  Flags, FTS5_BI_R
4e30: 4f 57 49 44 5f 4c 45 7c 46 54 53 35 5f 42 49 5f  OWID_LE|FTS5_BI_
4e40: 52 4f 57 49 44 5f 47 45 29 20 29 7b 0a 20 20 20  ROWID_GE) ){.   
4e50: 20 70 49 6e 66 6f 2d 3e 65 73 74 69 6d 61 74 65   pInfo->estimate
4e60: 64 43 6f 73 74 20 3d 20 62 48 61 73 4d 61 74 63  dCost = bHasMatc
4e70: 68 20 3f 20 37 35 30 2e 30 20 3a 20 37 35 30 30  h ? 750.0 : 7500
4e80: 30 30 2e 30 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  00.0;.  }else{. 
4e90: 20 20 20 70 49 6e 66 6f 2d 3e 65 73 74 69 6d 61     pInfo->estima
4ea0: 74 65 64 43 6f 73 74 20 3d 20 62 48 61 73 4d 61  tedCost = bHasMa
4eb0: 74 63 68 20 3f 20 31 30 30 30 2e 30 20 3a 20 31  tch ? 1000.0 : 1
4ec0: 30 30 30 30 30 30 2e 30 3b 0a 20 20 7d 0a 0a 20  000000.0;.  }.. 
4ed0: 20 2f 2a 20 41 73 73 69 67 6e 20 61 72 67 76 49   /* Assign argvI
4ee0: 6e 64 65 78 20 76 61 6c 75 65 73 20 74 6f 20 65  ndex values to e
4ef0: 61 63 68 20 63 6f 6e 73 74 72 61 69 6e 74 20 69  ach constraint i
4f00: 6e 20 75 73 65 2e 20 2a 2f 0a 20 20 69 4e 65 78  n use. */.  iNex
4f10: 74 20 3d 20 31 3b 0a 20 20 66 6f 72 28 69 3d 30  t = 1;.  for(i=0
4f20: 3b 20 69 3c 73 69 7a 65 6f 66 28 61 43 6f 6e 73  ; i<sizeof(aCons
4f30: 74 72 61 69 6e 74 29 2f 73 69 7a 65 6f 66 28 61  traint)/sizeof(a
4f40: 43 6f 6e 73 74 72 61 69 6e 74 5b 30 5d 29 3b 20  Constraint[0]); 
4f50: 69 2b 2b 29 7b 0a 20 20 20 20 73 74 72 75 63 74  i++){.    struct
4f60: 20 43 6f 6e 73 74 72 61 69 6e 74 20 2a 70 43 20   Constraint *pC 
4f70: 3d 20 26 61 43 6f 6e 73 74 72 61 69 6e 74 5b 69  = &aConstraint[i
4f80: 5d 3b 0a 20 20 20 20 69 66 28 20 70 43 2d 3e 69  ];.    if( pC->i
4f90: 43 6f 6e 73 49 6e 64 65 78 3e 3d 30 20 29 7b 0a  ConsIndex>=0 ){.
4fa0: 20 20 20 20 20 20 70 49 6e 66 6f 2d 3e 61 43 6f        pInfo->aCo
4fb0: 6e 73 74 72 61 69 6e 74 55 73 61 67 65 5b 70 43  nstraintUsage[pC
4fc0: 2d 3e 69 43 6f 6e 73 49 6e 64 65 78 5d 2e 61 72  ->iConsIndex].ar
4fd0: 67 76 49 6e 64 65 78 20 3d 20 69 4e 65 78 74 2b  gvIndex = iNext+
4fe0: 2b 3b 0a 20 20 20 20 20 20 70 49 6e 66 6f 2d 3e  +;.      pInfo->
4ff0: 61 43 6f 6e 73 74 72 61 69 6e 74 55 73 61 67 65  aConstraintUsage
5000: 5b 70 43 2d 3e 69 43 6f 6e 73 49 6e 64 65 78 5d  [pC->iConsIndex]
5010: 2e 6f 6d 69 74 20 3d 20 70 43 2d 3e 6f 6d 69 74  .omit = pC->omit
5020: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 70  ;.    }.  }..  p
5030: 49 6e 66 6f 2d 3e 69 64 78 4e 75 6d 20 3d 20 69  Info->idxNum = i
5040: 64 78 46 6c 61 67 73 3b 0a 20 20 72 65 74 75 72  dxFlags;.  retur
5050: 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a  n SQLITE_OK;.}..
5060: 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61  /*.** Implementa
5070: 74 69 6f 6e 20 6f 66 20 78 4f 70 65 6e 20 6d 65  tion of xOpen me
5080: 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  thod..*/.static 
5090: 69 6e 74 20 66 74 73 35 4f 70 65 6e 4d 65 74 68  int fts5OpenMeth
50a0: 6f 64 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20  od(sqlite3_vtab 
50b0: 2a 70 56 54 61 62 2c 20 73 71 6c 69 74 65 33 5f  *pVTab, sqlite3_
50c0: 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 2a 70 70  vtab_cursor **pp
50d0: 43 73 72 29 7b 0a 20 20 46 74 73 35 54 61 62 6c  Csr){.  Fts5Tabl
50e0: 65 20 2a 70 54 61 62 20 3d 20 28 46 74 73 35 54  e *pTab = (Fts5T
50f0: 61 62 6c 65 2a 29 70 56 54 61 62 3b 0a 20 20 46  able*)pVTab;.  F
5100: 74 73 35 43 6f 6e 66 69 67 20 2a 70 43 6f 6e 66  ts5Config *pConf
5110: 69 67 20 3d 20 70 54 61 62 2d 3e 70 43 6f 6e 66  ig = pTab->pConf
5120: 69 67 3b 0a 20 20 46 74 73 35 43 75 72 73 6f 72  ig;.  Fts5Cursor
5130: 20 2a 70 43 73 72 3b 20 20 20 20 20 20 20 20 20   *pCsr;         
5140: 20 20 20 20 20 20 2f 2a 20 4e 65 77 20 63 75 72        /* New cur
5150: 73 6f 72 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20  sor object */.  
5160: 69 6e 74 20 6e 42 79 74 65 3b 20 20 20 20 20 20  int nByte;      
5170: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5180: 2f 2a 20 42 79 74 65 73 20 6f 66 20 73 70 61 63  /* Bytes of spac
5190: 65 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20 2a 2f  e to allocate */
51a0: 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49  .  int rc = SQLI
51b0: 54 45 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20 20  TE_OK;          
51c0: 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64     /* Return cod
51d0: 65 20 2a 2f 0a 0a 20 20 6e 42 79 74 65 20 3d 20  e */..  nByte = 
51e0: 73 69 7a 65 6f 66 28 46 74 73 35 43 75 72 73 6f  sizeof(Fts5Curso
51f0: 72 29 20 2b 20 70 43 6f 6e 66 69 67 2d 3e 6e 43  r) + pConfig->nC
5200: 6f 6c 20 2a 20 73 69 7a 65 6f 66 28 69 6e 74 29  ol * sizeof(int)
5210: 3b 0a 20 20 70 43 73 72 20 3d 20 28 46 74 73 35  ;.  pCsr = (Fts5
5220: 43 75 72 73 6f 72 2a 29 73 71 6c 69 74 65 33 5f  Cursor*)sqlite3_
5230: 6d 61 6c 6c 6f 63 28 6e 42 79 74 65 29 3b 0a 20  malloc(nByte);. 
5240: 20 69 66 28 20 70 43 73 72 20 29 7b 0a 20 20 20   if( pCsr ){.   
5250: 20 46 74 73 35 47 6c 6f 62 61 6c 20 2a 70 47 6c   Fts5Global *pGl
5260: 6f 62 61 6c 20 3d 20 70 54 61 62 2d 3e 70 47 6c  obal = pTab->pGl
5270: 6f 62 61 6c 3b 0a 20 20 20 20 6d 65 6d 73 65 74  obal;.    memset
5280: 28 70 43 73 72 2c 20 30 2c 20 6e 42 79 74 65 29  (pCsr, 0, nByte)
5290: 3b 0a 20 20 20 20 70 43 73 72 2d 3e 61 43 6f 6c  ;.    pCsr->aCol
52a0: 75 6d 6e 53 69 7a 65 20 3d 20 28 69 6e 74 2a 29  umnSize = (int*)
52b0: 26 70 43 73 72 5b 31 5d 3b 0a 20 20 20 20 70 43  &pCsr[1];.    pC
52c0: 73 72 2d 3e 70 4e 65 78 74 20 3d 20 70 47 6c 6f  sr->pNext = pGlo
52d0: 62 61 6c 2d 3e 70 43 73 72 3b 0a 20 20 20 20 70  bal->pCsr;.    p
52e0: 47 6c 6f 62 61 6c 2d 3e 70 43 73 72 20 3d 20 70  Global->pCsr = p
52f0: 43 73 72 3b 0a 20 20 20 20 70 43 73 72 2d 3e 69  Csr;.    pCsr->i
5300: 43 73 72 49 64 20 3d 20 2b 2b 70 47 6c 6f 62 61  CsrId = ++pGloba
5310: 6c 2d 3e 69 4e 65 78 74 49 64 3b 0a 20 20 7d 65  l->iNextId;.  }e
5320: 6c 73 65 7b 0a 20 20 20 20 72 63 20 3d 20 53 51  lse{.    rc = SQ
5330: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a  LITE_NOMEM;.  }.
5340: 20 20 2a 70 70 43 73 72 20 3d 20 28 73 71 6c 69    *ppCsr = (sqli
5350: 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 2a  te3_vtab_cursor*
5360: 29 70 43 73 72 3b 0a 20 20 72 65 74 75 72 6e 20  )pCsr;.  return 
5370: 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  rc;.}..static in
5380: 74 20 66 74 73 35 53 74 6d 74 54 79 70 65 28 46  t fts5StmtType(F
5390: 74 73 35 43 75 72 73 6f 72 20 2a 70 43 73 72 29  ts5Cursor *pCsr)
53a0: 7b 0a 20 20 69 66 28 20 70 43 73 72 2d 3e 65 50  {.  if( pCsr->eP
53b0: 6c 61 6e 3d 3d 46 54 53 35 5f 50 4c 41 4e 5f 53  lan==FTS5_PLAN_S
53c0: 43 41 4e 20 29 7b 0a 20 20 20 20 72 65 74 75 72  CAN ){.    retur
53d0: 6e 20 28 70 43 73 72 2d 3e 62 44 65 73 63 29 20  n (pCsr->bDesc) 
53e0: 3f 20 46 54 53 35 5f 53 54 4d 54 5f 53 43 41 4e  ? FTS5_STMT_SCAN
53f0: 5f 44 45 53 43 20 3a 20 46 54 53 35 5f 53 54 4d  _DESC : FTS5_STM
5400: 54 5f 53 43 41 4e 5f 41 53 43 3b 0a 20 20 7d 0a  T_SCAN_ASC;.  }.
5410: 20 20 72 65 74 75 72 6e 20 46 54 53 35 5f 53 54    return FTS5_ST
5420: 4d 54 5f 4c 4f 4f 4b 55 50 3b 0a 7d 0a 0a 2f 2a  MT_LOOKUP;.}../*
5430: 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f  .** This functio
5440: 6e 20 69 73 20 63 61 6c 6c 65 64 20 61 66 74 65  n is called afte
5450: 72 20 74 68 65 20 63 75 72 73 6f 72 20 70 61 73  r the cursor pas
5460: 73 65 64 20 61 73 20 74 68 65 20 6f 6e 6c 79 20  sed as the only 
5470: 61 72 67 75 6d 65 6e 74 0a 2a 2a 20 69 73 20 6d  argument.** is m
5480: 6f 76 65 64 20 74 6f 20 70 6f 69 6e 74 20 61 74  oved to point at
5490: 20 61 20 64 69 66 66 65 72 65 6e 74 20 72 6f 77   a different row
54a0: 2e 20 49 74 20 63 6c 65 61 72 73 20 61 6c 6c 20  . It clears all 
54b0: 63 61 63 68 65 64 20 64 61 74 61 20 0a 2a 2a 20  cached data .** 
54c0: 73 70 65 63 69 66 69 63 20 74 6f 20 74 68 65 20  specific to the 
54d0: 70 72 65 76 69 6f 75 73 20 72 6f 77 20 73 74 6f  previous row sto
54e0: 72 65 64 20 62 79 20 74 68 65 20 63 75 72 73 6f  red by the curso
54f0: 72 20 6f 62 6a 65 63 74 2e 0a 2a 2f 0a 73 74 61  r object..*/.sta
5500: 74 69 63 20 76 6f 69 64 20 66 74 73 35 43 73 72  tic void fts5Csr
5510: 4e 65 77 72 6f 77 28 46 74 73 35 43 75 72 73 6f  Newrow(Fts5Curso
5520: 72 20 2a 70 43 73 72 29 7b 0a 20 20 43 73 72 46  r *pCsr){.  CsrF
5530: 6c 61 67 53 65 74 28 70 43 73 72 2c 20 46 54 53  lagSet(pCsr, FTS
5540: 35 43 53 52 5f 52 45 51 55 49 52 45 5f 43 4f 4e  5CSR_REQUIRE_CON
5550: 54 45 4e 54 20 7c 20 46 54 53 35 43 53 52 5f 52  TENT | FTS5CSR_R
5560: 45 51 55 49 52 45 5f 44 4f 43 53 49 5a 45 20 29  EQUIRE_DOCSIZE )
5570: 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65  ;.  sqlite3_free
5580: 28 70 43 73 72 2d 3e 61 49 6e 73 74 29 3b 0a 20  (pCsr->aInst);. 
5590: 20 70 43 73 72 2d 3e 61 49 6e 73 74 20 3d 20 30   pCsr->aInst = 0
55a0: 3b 0a 20 20 70 43 73 72 2d 3e 6e 49 6e 73 74 43  ;.  pCsr->nInstC
55b0: 6f 75 6e 74 20 3d 20 30 3b 0a 7d 0a 0a 2f 2a 0a  ount = 0;.}../*.
55c0: 2a 2a 20 43 6c 6f 73 65 20 74 68 65 20 63 75 72  ** Close the cur
55d0: 73 6f 72 2e 20 20 46 6f 72 20 61 64 64 69 74 69  sor.  For additi
55e0: 6f 6e 61 6c 20 69 6e 66 6f 72 6d 61 74 69 6f 6e  onal information
55f0: 20 73 65 65 20 74 68 65 20 64 6f 63 75 6d 65 6e   see the documen
5600: 74 61 74 69 6f 6e 0a 2a 2a 20 6f 6e 20 74 68 65  tation.** on the
5610: 20 78 43 6c 6f 73 65 20 6d 65 74 68 6f 64 20 6f   xClose method o
5620: 66 20 74 68 65 20 76 69 72 74 75 61 6c 20 74 61  f the virtual ta
5630: 62 6c 65 20 69 6e 74 65 72 66 61 63 65 2e 0a 2a  ble interface..*
5640: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73  /.static int fts
5650: 35 43 6c 6f 73 65 4d 65 74 68 6f 64 28 73 71 6c  5CloseMethod(sql
5660: 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72  ite3_vtab_cursor
5670: 20 2a 70 43 75 72 73 6f 72 29 7b 0a 20 20 69 66   *pCursor){.  if
5680: 28 20 70 43 75 72 73 6f 72 20 29 7b 0a 20 20 20  ( pCursor ){.   
5690: 20 46 74 73 35 54 61 62 6c 65 20 2a 70 54 61 62   Fts5Table *pTab
56a0: 20 3d 20 28 46 74 73 35 54 61 62 6c 65 2a 29 28   = (Fts5Table*)(
56b0: 70 43 75 72 73 6f 72 2d 3e 70 56 74 61 62 29 3b  pCursor->pVtab);
56c0: 0a 20 20 20 20 46 74 73 35 43 75 72 73 6f 72 20  .    Fts5Cursor 
56d0: 2a 70 43 73 72 20 3d 20 28 46 74 73 35 43 75 72  *pCsr = (Fts5Cur
56e0: 73 6f 72 2a 29 70 43 75 72 73 6f 72 3b 0a 20 20  sor*)pCursor;.  
56f0: 20 20 46 74 73 35 43 75 72 73 6f 72 20 2a 2a 70    Fts5Cursor **p
5700: 70 3b 0a 20 20 20 20 46 74 73 35 41 75 78 64 61  p;.    Fts5Auxda
5710: 74 61 20 2a 70 44 61 74 61 3b 0a 20 20 20 20 46  ta *pData;.    F
5720: 74 73 35 41 75 78 64 61 74 61 20 2a 70 4e 65 78  ts5Auxdata *pNex
5730: 74 3b 0a 0a 20 20 20 20 66 74 73 35 43 73 72 4e  t;..    fts5CsrN
5740: 65 77 72 6f 77 28 70 43 73 72 29 3b 0a 20 20 20  ewrow(pCsr);.   
5750: 20 69 66 28 20 70 43 73 72 2d 3e 70 53 74 6d 74   if( pCsr->pStmt
5760: 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 65 53   ){.      int eS
5770: 74 6d 74 20 3d 20 66 74 73 35 53 74 6d 74 54 79  tmt = fts5StmtTy
5780: 70 65 28 70 43 73 72 29 3b 0a 20 20 20 20 20 20  pe(pCsr);.      
5790: 73 71 6c 69 74 65 33 46 74 73 35 53 74 6f 72 61  sqlite3Fts5Stora
57a0: 67 65 53 74 6d 74 52 65 6c 65 61 73 65 28 70 54  geStmtRelease(pT
57b0: 61 62 2d 3e 70 53 74 6f 72 61 67 65 2c 20 65 53  ab->pStorage, eS
57c0: 74 6d 74 2c 20 70 43 73 72 2d 3e 70 53 74 6d 74  tmt, pCsr->pStmt
57d0: 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28  );.    }.    if(
57e0: 20 70 43 73 72 2d 3e 70 53 6f 72 74 65 72 20 29   pCsr->pSorter )
57f0: 7b 0a 20 20 20 20 20 20 46 74 73 35 53 6f 72 74  {.      Fts5Sort
5800: 65 72 20 2a 70 53 6f 72 74 65 72 20 3d 20 70 43  er *pSorter = pC
5810: 73 72 2d 3e 70 53 6f 72 74 65 72 3b 0a 20 20 20  sr->pSorter;.   
5820: 20 20 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c     sqlite3_final
5830: 69 7a 65 28 70 53 6f 72 74 65 72 2d 3e 70 53 74  ize(pSorter->pSt
5840: 6d 74 29 3b 0a 20 20 20 20 20 20 73 71 6c 69 74  mt);.      sqlit
5850: 65 33 5f 66 72 65 65 28 70 53 6f 72 74 65 72 29  e3_free(pSorter)
5860: 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 28  ;.    }..    if(
5870: 20 70 43 73 72 2d 3e 65 50 6c 61 6e 21 3d 46 54   pCsr->ePlan!=FT
5880: 53 35 5f 50 4c 41 4e 5f 53 4f 55 52 43 45 20 29  S5_PLAN_SOURCE )
5890: 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 46  {.      sqlite3F
58a0: 74 73 35 45 78 70 72 46 72 65 65 28 70 43 73 72  ts5ExprFree(pCsr
58b0: 2d 3e 70 45 78 70 72 29 3b 0a 20 20 20 20 7d 0a  ->pExpr);.    }.
58c0: 0a 20 20 20 20 66 6f 72 28 70 44 61 74 61 3d 70  .    for(pData=p
58d0: 43 73 72 2d 3e 70 41 75 78 64 61 74 61 3b 20 70  Csr->pAuxdata; p
58e0: 44 61 74 61 3b 20 70 44 61 74 61 3d 70 4e 65 78  Data; pData=pNex
58f0: 74 29 7b 0a 20 20 20 20 20 20 70 4e 65 78 74 20  t){.      pNext 
5900: 3d 20 70 44 61 74 61 2d 3e 70 4e 65 78 74 3b 0a  = pData->pNext;.
5910: 20 20 20 20 20 20 69 66 28 20 70 44 61 74 61 2d        if( pData-
5920: 3e 78 44 65 6c 65 74 65 20 29 20 70 44 61 74 61  >xDelete ) pData
5930: 2d 3e 78 44 65 6c 65 74 65 28 70 44 61 74 61 2d  ->xDelete(pData-
5940: 3e 70 50 74 72 29 3b 0a 20 20 20 20 20 20 73 71  >pPtr);.      sq
5950: 6c 69 74 65 33 5f 66 72 65 65 28 70 44 61 74 61  lite3_free(pData
5960: 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a  );.    }..    /*
5970: 20 52 65 6d 6f 76 65 20 74 68 65 20 63 75 72 73   Remove the curs
5980: 6f 72 20 66 72 6f 6d 20 74 68 65 20 46 74 73 35  or from the Fts5
5990: 47 6c 6f 62 61 6c 2e 70 43 73 72 20 6c 69 73 74  Global.pCsr list
59a0: 20 2a 2f 0a 20 20 20 20 66 6f 72 28 70 70 3d 26   */.    for(pp=&
59b0: 70 54 61 62 2d 3e 70 47 6c 6f 62 61 6c 2d 3e 70  pTab->pGlobal->p
59c0: 43 73 72 3b 20 28 2a 70 70 29 21 3d 70 43 73 72  Csr; (*pp)!=pCsr
59d0: 3b 20 70 70 3d 26 28 2a 70 70 29 2d 3e 70 4e 65  ; pp=&(*pp)->pNe
59e0: 78 74 29 3b 0a 20 20 20 20 2a 70 70 20 3d 20 70  xt);.    *pp = p
59f0: 43 73 72 2d 3e 70 4e 65 78 74 3b 0a 0a 20 20 20  Csr->pNext;..   
5a00: 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a   sqlite3_finaliz
5a10: 65 28 70 43 73 72 2d 3e 70 52 61 6e 6b 41 72 67  e(pCsr->pRankArg
5a20: 53 74 6d 74 29 3b 0a 20 20 20 20 73 71 6c 69 74  Stmt);.    sqlit
5a30: 65 33 5f 66 72 65 65 28 70 43 73 72 2d 3e 61 70  e3_free(pCsr->ap
5a40: 52 61 6e 6b 41 72 67 29 3b 0a 0a 20 20 20 20 69  RankArg);..    i
5a50: 66 28 20 43 73 72 46 6c 61 67 54 65 73 74 28 70  f( CsrFlagTest(p
5a60: 43 73 72 2c 20 46 54 53 35 43 53 52 5f 46 52 45  Csr, FTS5CSR_FRE
5a70: 45 5f 5a 52 41 4e 4b 29 20 29 7b 0a 20 20 20 20  E_ZRANK) ){.    
5a80: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70    sqlite3_free(p
5a90: 43 73 72 2d 3e 7a 52 61 6e 6b 29 3b 0a 20 20 20  Csr->zRank);.   
5aa0: 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28     sqlite3_free(
5ab0: 70 43 73 72 2d 3e 7a 52 61 6e 6b 41 72 67 73 29  pCsr->zRankArgs)
5ac0: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 73 71 6c 69  ;.    }.    sqli
5ad0: 74 65 33 5f 66 72 65 65 28 70 43 73 72 29 3b 0a  te3_free(pCsr);.
5ae0: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 53 51 4c    }.  return SQL
5af0: 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 73 74 61 74 69  ITE_OK;.}..stati
5b00: 63 20 69 6e 74 20 66 74 73 35 53 6f 72 74 65 72  c int fts5Sorter
5b10: 4e 65 78 74 28 46 74 73 35 43 75 72 73 6f 72 20  Next(Fts5Cursor 
5b20: 2a 70 43 73 72 29 7b 0a 20 20 46 74 73 35 53 6f  *pCsr){.  Fts5So
5b30: 72 74 65 72 20 2a 70 53 6f 72 74 65 72 20 3d 20  rter *pSorter = 
5b40: 70 43 73 72 2d 3e 70 53 6f 72 74 65 72 3b 0a 20  pCsr->pSorter;. 
5b50: 20 69 6e 74 20 72 63 3b 0a 0a 20 20 72 63 20 3d   int rc;..  rc =
5b60: 20 73 71 6c 69 74 65 33 5f 73 74 65 70 28 70 53   sqlite3_step(pS
5b70: 6f 72 74 65 72 2d 3e 70 53 74 6d 74 29 3b 0a 20  orter->pStmt);. 
5b80: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
5b90: 44 4f 4e 45 20 29 7b 0a 20 20 20 20 72 63 20 3d  DONE ){.    rc =
5ba0: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 20 20   SQLITE_OK;.    
5bb0: 43 73 72 46 6c 61 67 53 65 74 28 70 43 73 72 2c  CsrFlagSet(pCsr,
5bc0: 20 46 54 53 35 43 53 52 5f 45 4f 46 29 3b 0a 20   FTS5CSR_EOF);. 
5bd0: 20 7d 65 6c 73 65 20 69 66 28 20 72 63 3d 3d 53   }else if( rc==S
5be0: 51 4c 49 54 45 5f 52 4f 57 20 29 7b 0a 20 20 20  QLITE_ROW ){.   
5bf0: 20 63 6f 6e 73 74 20 75 38 20 2a 61 3b 0a 20 20   const u8 *a;.  
5c00: 20 20 63 6f 6e 73 74 20 75 38 20 2a 61 42 6c 6f    const u8 *aBlo
5c10: 62 3b 0a 20 20 20 20 69 6e 74 20 6e 42 6c 6f 62  b;.    int nBlob
5c20: 3b 0a 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20  ;.    int i;.   
5c30: 20 69 6e 74 20 69 4f 66 66 20 3d 20 30 3b 0a 20   int iOff = 0;. 
5c40: 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f     rc = SQLITE_O
5c50: 4b 3b 0a 0a 20 20 20 20 70 53 6f 72 74 65 72 2d  K;..    pSorter-
5c60: 3e 69 52 6f 77 69 64 20 3d 20 73 71 6c 69 74 65  >iRowid = sqlite
5c70: 33 5f 63 6f 6c 75 6d 6e 5f 69 6e 74 36 34 28 70  3_column_int64(p
5c80: 53 6f 72 74 65 72 2d 3e 70 53 74 6d 74 2c 20 30  Sorter->pStmt, 0
5c90: 29 3b 0a 20 20 20 20 6e 42 6c 6f 62 20 3d 20 73  );.    nBlob = s
5ca0: 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 62 79  qlite3_column_by
5cb0: 74 65 73 28 70 53 6f 72 74 65 72 2d 3e 70 53 74  tes(pSorter->pSt
5cc0: 6d 74 2c 20 31 29 3b 0a 20 20 20 20 61 42 6c 6f  mt, 1);.    aBlo
5cd0: 62 20 3d 20 61 20 3d 20 73 71 6c 69 74 65 33 5f  b = a = sqlite3_
5ce0: 63 6f 6c 75 6d 6e 5f 62 6c 6f 62 28 70 53 6f 72  column_blob(pSor
5cf0: 74 65 72 2d 3e 70 53 74 6d 74 2c 20 31 29 3b 0a  ter->pStmt, 1);.
5d00: 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c  .    for(i=0; i<
5d10: 28 70 53 6f 72 74 65 72 2d 3e 6e 49 64 78 2d 31  (pSorter->nIdx-1
5d20: 29 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 69  ); i++){.      i
5d30: 6e 74 20 69 56 61 6c 3b 0a 20 20 20 20 20 20 61  nt iVal;.      a
5d40: 20 2b 3d 20 66 74 73 35 47 65 74 56 61 72 69 6e   += fts5GetVarin
5d50: 74 33 32 28 61 2c 20 69 56 61 6c 29 3b 0a 20 20  t32(a, iVal);.  
5d60: 20 20 20 20 69 4f 66 66 20 2b 3d 20 69 56 61 6c      iOff += iVal
5d70: 3b 0a 20 20 20 20 20 20 70 53 6f 72 74 65 72 2d  ;.      pSorter-
5d80: 3e 61 49 64 78 5b 69 5d 20 3d 20 69 4f 66 66 3b  >aIdx[i] = iOff;
5d90: 0a 20 20 20 20 7d 0a 20 20 20 20 70 53 6f 72 74  .    }.    pSort
5da0: 65 72 2d 3e 61 49 64 78 5b 69 5d 20 3d 20 26 61  er->aIdx[i] = &a
5db0: 42 6c 6f 62 5b 6e 42 6c 6f 62 5d 20 2d 20 61 3b  Blob[nBlob] - a;
5dc0: 0a 0a 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 61  ..    pSorter->a
5dd0: 50 6f 73 6c 69 73 74 20 3d 20 61 3b 0a 20 20 20  Poslist = a;.   
5de0: 20 66 74 73 35 43 73 72 4e 65 77 72 6f 77 28 70   fts5CsrNewrow(p
5df0: 43 73 72 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74  Csr);.  }..  ret
5e00: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a  urn rc;.}.../*.*
5e10: 2a 20 53 65 74 20 74 68 65 20 46 54 53 35 43 53  * Set the FTS5CS
5e20: 52 5f 52 45 51 55 49 52 45 5f 52 45 53 45 45 4b  R_REQUIRE_RESEEK
5e30: 20 66 6c 61 67 20 6f 6e 20 61 6c 6c 20 46 54 53   flag on all FTS
5e40: 35 5f 50 4c 41 4e 5f 4d 41 54 43 48 20 63 75 72  5_PLAN_MATCH cur
5e50: 73 6f 72 73 20 0a 2a 2a 20 6f 70 65 6e 20 6f 6e  sors .** open on
5e60: 20 74 61 62 6c 65 20 70 54 61 62 2e 0a 2a 2f 0a   table pTab..*/.
5e70: 73 74 61 74 69 63 20 76 6f 69 64 20 66 74 73 35  static void fts5
5e80: 54 72 69 70 43 75 72 73 6f 72 73 28 46 74 73 35  TripCursors(Fts5
5e90: 54 61 62 6c 65 20 2a 70 54 61 62 29 7b 0a 20 20  Table *pTab){.  
5ea0: 46 74 73 35 43 75 72 73 6f 72 20 2a 70 43 73 72  Fts5Cursor *pCsr
5eb0: 3b 0a 20 20 66 6f 72 28 70 43 73 72 3d 70 54 61  ;.  for(pCsr=pTa
5ec0: 62 2d 3e 70 47 6c 6f 62 61 6c 2d 3e 70 43 73 72  b->pGlobal->pCsr
5ed0: 3b 20 70 43 73 72 3b 20 70 43 73 72 3d 70 43 73  ; pCsr; pCsr=pCs
5ee0: 72 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20 69  r->pNext){.    i
5ef0: 66 28 20 70 43 73 72 2d 3e 65 50 6c 61 6e 3d 3d  f( pCsr->ePlan==
5f00: 46 54 53 35 5f 50 4c 41 4e 5f 4d 41 54 43 48 0a  FTS5_PLAN_MATCH.
5f10: 20 20 20 20 20 26 26 20 70 43 73 72 2d 3e 62 61       && pCsr->ba
5f20: 73 65 2e 70 56 74 61 62 3d 3d 28 73 71 6c 69 74  se.pVtab==(sqlit
5f30: 65 33 5f 76 74 61 62 2a 29 70 54 61 62 20 0a 20  e3_vtab*)pTab . 
5f40: 20 20 20 29 7b 0a 20 20 20 20 20 20 43 73 72 46     ){.      CsrF
5f50: 6c 61 67 53 65 74 28 70 43 73 72 2c 20 46 54 53  lagSet(pCsr, FTS
5f60: 35 43 53 52 5f 52 45 51 55 49 52 45 5f 52 45 53  5CSR_REQUIRE_RES
5f70: 45 45 4b 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  EEK);.    }.  }.
5f80: 7d 0a 0a 2f 2a 0a 2a 2a 20 49 66 20 74 68 65 20  }../*.** If the 
5f90: 52 45 51 55 49 52 45 5f 52 45 53 45 45 4b 20 66  REQUIRE_RESEEK f
5fa0: 6c 61 67 20 69 73 20 73 65 74 20 6f 6e 20 74 68  lag is set on th
5fb0: 65 20 63 75 72 73 6f 72 20 70 61 73 73 65 64 20  e cursor passed 
5fc0: 61 73 20 74 68 65 20 66 69 72 73 74 0a 2a 2a 20  as the first.** 
5fd0: 61 72 67 75 6d 65 6e 74 2c 20 63 6c 6f 73 65 20  argument, close 
5fe0: 61 6e 64 20 72 65 6f 70 65 6e 20 61 6c 6c 20 46  and reopen all F
5ff0: 74 73 35 49 6e 64 65 78 49 74 65 72 20 69 74 65  ts5IndexIter ite
6000: 72 61 74 6f 72 73 20 74 68 61 74 20 74 68 65 20  rators that the 
6010: 63 75 72 73 6f 72 20 0a 2a 2a 20 69 73 20 75 73  cursor .** is us
6020: 69 6e 67 2e 20 54 68 65 6e 20 61 74 74 65 6d 70  ing. Then attemp
6030: 74 20 74 6f 20 6d 6f 76 65 20 74 68 65 20 63 75  t to move the cu
6040: 72 73 6f 72 20 74 6f 20 61 20 72 6f 77 69 64 20  rsor to a rowid 
6050: 65 71 75 61 6c 20 74 6f 20 6f 72 20 6c 61 73 74  equal to or last
6060: 65 72 0a 2a 2a 20 28 69 6e 20 74 68 65 20 63 75  er.** (in the cu
6070: 72 73 6f 72 73 20 73 6f 72 74 20 6f 72 64 65 72  rsors sort order
6080: 20 2d 20 41 53 43 20 6f 72 20 44 45 53 43 29 20   - ASC or DESC) 
6090: 74 68 61 6e 20 74 68 65 20 63 75 72 72 65 6e 74  than the current
60a0: 20 72 6f 77 69 64 2e 20 0a 2a 2a 0a 2a 2a 20 49   rowid. .**.** I
60b0: 66 20 74 68 65 20 6e 65 77 20 72 6f 77 69 64 20  f the new rowid 
60c0: 69 73 20 6e 6f 74 20 65 71 75 61 6c 20 74 6f 20  is not equal to 
60d0: 74 68 65 20 6f 6c 64 2c 20 73 65 74 20 6f 75 74  the old, set out
60e0: 70 75 74 20 70 61 72 61 6d 65 74 65 72 20 2a 70  put parameter *p
60f0: 62 53 6b 69 70 0a 2a 2a 20 74 6f 20 31 20 62 65  bSkip.** to 1 be
6100: 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 2e 20  fore returning. 
6110: 4f 74 68 65 72 77 69 73 65 2c 20 6c 65 61 76 65  Otherwise, leave
6120: 20 69 74 20 75 6e 63 68 61 6e 67 65 64 2e 0a 2a   it unchanged..*
6130: 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 53 51 4c 49  *.** Return SQLI
6140: 54 45 5f 4f 4b 20 69 66 20 73 75 63 63 65 73 73  TE_OK if success
6150: 66 75 6c 20 6f 72 20 69 66 20 6e 6f 20 72 65 73  ful or if no res
6160: 65 65 6b 20 77 61 73 20 72 65 71 75 69 72 65 64  eek was required
6170: 2c 20 6f 72 20 61 6e 20 0a 2a 2a 20 65 72 72 6f  , or an .** erro
6180: 72 20 63 6f 64 65 20 69 66 20 61 6e 20 65 72 72  r code if an err
6190: 6f 72 20 6f 63 63 75 72 72 65 64 2e 0a 2a 2f 0a  or occurred..*/.
61a0: 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 43  static int fts5C
61b0: 75 72 73 6f 72 52 65 73 65 65 6b 28 46 74 73 35  ursorReseek(Fts5
61c0: 43 75 72 73 6f 72 20 2a 70 43 73 72 2c 20 69 6e  Cursor *pCsr, in
61d0: 74 20 2a 70 62 53 6b 69 70 29 7b 0a 20 20 69 6e  t *pbSkip){.  in
61e0: 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b  t rc = SQLITE_OK
61f0: 3b 0a 20 20 61 73 73 65 72 74 28 20 2a 70 62 53  ;.  assert( *pbS
6200: 6b 69 70 3d 3d 30 20 29 3b 0a 20 20 69 66 28 20  kip==0 );.  if( 
6210: 43 73 72 46 6c 61 67 54 65 73 74 28 70 43 73 72  CsrFlagTest(pCsr
6220: 2c 20 46 54 53 35 43 53 52 5f 52 45 51 55 49 52  , FTS5CSR_REQUIR
6230: 45 5f 52 45 53 45 45 4b 29 20 29 7b 0a 20 20 20  E_RESEEK) ){.   
6240: 20 46 74 73 35 54 61 62 6c 65 20 2a 70 54 61 62   Fts5Table *pTab
6250: 20 3d 20 28 46 74 73 35 54 61 62 6c 65 2a 29 28   = (Fts5Table*)(
6260: 70 43 73 72 2d 3e 62 61 73 65 2e 70 56 74 61 62  pCsr->base.pVtab
6270: 29 3b 0a 20 20 20 20 69 6e 74 20 62 44 65 73 63  );.    int bDesc
6280: 20 3d 20 70 43 73 72 2d 3e 62 44 65 73 63 3b 0a   = pCsr->bDesc;.
6290: 20 20 20 20 69 36 34 20 69 52 6f 77 69 64 20 3d      i64 iRowid =
62a0: 20 73 71 6c 69 74 65 33 46 74 73 35 45 78 70 72   sqlite3Fts5Expr
62b0: 52 6f 77 69 64 28 70 43 73 72 2d 3e 70 45 78 70  Rowid(pCsr->pExp
62c0: 72 29 3b 0a 0a 20 20 20 20 72 63 20 3d 20 73 71  r);..    rc = sq
62d0: 6c 69 74 65 33 46 74 73 35 45 78 70 72 46 69 72  lite3Fts5ExprFir
62e0: 73 74 28 70 43 73 72 2d 3e 70 45 78 70 72 2c 20  st(pCsr->pExpr, 
62f0: 70 54 61 62 2d 3e 70 49 6e 64 65 78 2c 20 69 52  pTab->pIndex, iR
6300: 6f 77 69 64 2c 20 62 44 65 73 63 29 3b 0a 20 20  owid, bDesc);.  
6310: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
6320: 5f 4f 4b 20 26 26 20 69 52 6f 77 69 64 21 3d 73  _OK && iRowid!=s
6330: 71 6c 69 74 65 33 46 74 73 35 45 78 70 72 52 6f  qlite3Fts5ExprRo
6340: 77 69 64 28 70 43 73 72 2d 3e 70 45 78 70 72 29  wid(pCsr->pExpr)
6350: 20 29 7b 0a 20 20 20 20 20 20 2a 70 62 53 6b 69   ){.      *pbSki
6360: 70 20 3d 20 31 3b 0a 20 20 20 20 7d 0a 0a 20 20  p = 1;.    }..  
6370: 20 20 43 73 72 46 6c 61 67 43 6c 65 61 72 28 70    CsrFlagClear(p
6380: 43 73 72 2c 20 46 54 53 35 43 53 52 5f 52 45 51  Csr, FTS5CSR_REQ
6390: 55 49 52 45 5f 52 45 53 45 45 4b 29 3b 0a 20 20  UIRE_RESEEK);.  
63a0: 20 20 66 74 73 35 43 73 72 4e 65 77 72 6f 77 28    fts5CsrNewrow(
63b0: 70 43 73 72 29 3b 0a 20 20 20 20 69 66 28 20 73  pCsr);.    if( s
63c0: 71 6c 69 74 65 33 46 74 73 35 45 78 70 72 45 6f  qlite3Fts5ExprEo
63d0: 66 28 70 43 73 72 2d 3e 70 45 78 70 72 29 20 29  f(pCsr->pExpr) )
63e0: 7b 0a 20 20 20 20 20 20 43 73 72 46 6c 61 67 53  {.      CsrFlagS
63f0: 65 74 28 70 43 73 72 2c 20 46 54 53 35 43 53 52  et(pCsr, FTS5CSR
6400: 5f 45 4f 46 29 3b 0a 20 20 20 20 7d 0a 20 20 7d  _EOF);.    }.  }
6410: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
6420: 0a 0a 2f 2a 0a 2a 2a 20 41 64 76 61 6e 63 65 20  ../*.** Advance 
6430: 74 68 65 20 63 75 72 73 6f 72 20 74 6f 20 74 68  the cursor to th
6440: 65 20 6e 65 78 74 20 72 6f 77 20 69 6e 20 74 68  e next row in th
6450: 65 20 74 61 62 6c 65 20 74 68 61 74 20 6d 61 74  e table that mat
6460: 63 68 65 73 20 74 68 65 20 0a 2a 2a 20 73 65 61  ches the .** sea
6470: 72 63 68 20 63 72 69 74 65 72 69 61 2e 0a 2a 2a  rch criteria..**
6480: 0a 2a 2a 20 52 65 74 75 72 6e 20 53 51 4c 49 54  .** Return SQLIT
6490: 45 5f 4f 4b 20 69 66 20 6e 6f 74 68 69 6e 67 20  E_OK if nothing 
64a0: 67 6f 65 73 20 77 72 6f 6e 67 2e 20 20 53 51 4c  goes wrong.  SQL
64b0: 49 54 45 5f 4f 4b 20 69 73 20 72 65 74 75 72 6e  ITE_OK is return
64c0: 65 64 0a 2a 2a 20 65 76 65 6e 20 69 66 20 77 65  ed.** even if we
64d0: 20 72 65 61 63 68 20 65 6e 64 2d 6f 66 2d 66 69   reach end-of-fi
64e0: 6c 65 2e 20 20 54 68 65 20 66 74 73 35 45 6f 66  le.  The fts5Eof
64f0: 4d 65 74 68 6f 64 28 29 20 77 69 6c 6c 20 62 65  Method() will be
6500: 20 63 61 6c 6c 65 64 0a 2a 2a 20 73 75 62 73 65   called.** subse
6510: 71 75 65 6e 74 6c 79 20 74 6f 20 64 65 74 65 72  quently to deter
6520: 6d 69 6e 65 20 77 68 65 74 68 65 72 20 6f 72 20  mine whether or 
6530: 6e 6f 74 20 61 6e 20 45 4f 46 20 77 61 73 20 68  not an EOF was h
6540: 69 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  it..*/.static in
6550: 74 20 66 74 73 35 4e 65 78 74 4d 65 74 68 6f 64  t fts5NextMethod
6560: 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75  (sqlite3_vtab_cu
6570: 72 73 6f 72 20 2a 70 43 75 72 73 6f 72 29 7b 0a  rsor *pCursor){.
6580: 20 20 46 74 73 35 43 75 72 73 6f 72 20 2a 70 43    Fts5Cursor *pC
6590: 73 72 20 3d 20 28 46 74 73 35 43 75 72 73 6f 72  sr = (Fts5Cursor
65a0: 2a 29 70 43 75 72 73 6f 72 3b 0a 20 20 69 6e 74  *)pCursor;.  int
65b0: 20 65 50 6c 61 6e 20 3d 20 70 43 73 72 2d 3e 65   ePlan = pCsr->e
65c0: 50 6c 61 6e 3b 0a 20 20 69 6e 74 20 62 53 6b 69  Plan;.  int bSki
65d0: 70 20 3d 20 30 3b 0a 20 20 69 6e 74 20 72 63 3b  p = 0;.  int rc;
65e0: 0a 0a 20 20 69 66 28 20 28 72 63 20 3d 20 66 74  ..  if( (rc = ft
65f0: 73 35 43 75 72 73 6f 72 52 65 73 65 65 6b 28 70  s5CursorReseek(p
6600: 43 73 72 2c 20 26 62 53 6b 69 70 29 29 20 7c 7c  Csr, &bSkip)) ||
6610: 20 62 53 6b 69 70 20 29 20 72 65 74 75 72 6e 20   bSkip ) return 
6620: 72 63 3b 0a 0a 20 20 73 77 69 74 63 68 28 20 65  rc;..  switch( e
6630: 50 6c 61 6e 20 29 7b 0a 20 20 20 20 63 61 73 65  Plan ){.    case
6640: 20 46 54 53 35 5f 50 4c 41 4e 5f 4d 41 54 43 48   FTS5_PLAN_MATCH
6650: 3a 0a 20 20 20 20 63 61 73 65 20 46 54 53 35 5f  :.    case FTS5_
6660: 50 4c 41 4e 5f 53 4f 55 52 43 45 3a 0a 20 20 20  PLAN_SOURCE:.   
6670: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 46     rc = sqlite3F
6680: 74 73 35 45 78 70 72 4e 65 78 74 28 70 43 73 72  ts5ExprNext(pCsr
6690: 2d 3e 70 45 78 70 72 2c 20 70 43 73 72 2d 3e 69  ->pExpr, pCsr->i
66a0: 4c 61 73 74 52 6f 77 69 64 29 3b 0a 20 20 20 20  LastRowid);.    
66b0: 20 20 69 66 28 20 73 71 6c 69 74 65 33 46 74 73    if( sqlite3Fts
66c0: 35 45 78 70 72 45 6f 66 28 70 43 73 72 2d 3e 70  5ExprEof(pCsr->p
66d0: 45 78 70 72 29 20 29 7b 0a 20 20 20 20 20 20 20  Expr) ){.       
66e0: 20 43 73 72 46 6c 61 67 53 65 74 28 70 43 73 72   CsrFlagSet(pCsr
66f0: 2c 20 46 54 53 35 43 53 52 5f 45 4f 46 29 3b 0a  , FTS5CSR_EOF);.
6700: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 66 74        }.      ft
6710: 73 35 43 73 72 4e 65 77 72 6f 77 28 70 43 73 72  s5CsrNewrow(pCsr
6720: 29 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a  );.      break;.
6730: 0a 20 20 20 20 63 61 73 65 20 46 54 53 35 5f 50  .    case FTS5_P
6740: 4c 41 4e 5f 53 50 45 43 49 41 4c 3a 20 7b 0a 20  LAN_SPECIAL: {. 
6750: 20 20 20 20 20 43 73 72 46 6c 61 67 53 65 74 28       CsrFlagSet(
6760: 70 43 73 72 2c 20 46 54 53 35 43 53 52 5f 45 4f  pCsr, FTS5CSR_EO
6770: 46 29 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b  F);.      break;
6780: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 63 61 73 65  .    }..    case
6790: 20 46 54 53 35 5f 50 4c 41 4e 5f 53 4f 52 54 45   FTS5_PLAN_SORTE
67a0: 44 5f 4d 41 54 43 48 3a 20 7b 0a 20 20 20 20 20  D_MATCH: {.     
67b0: 20 72 63 20 3d 20 66 74 73 35 53 6f 72 74 65 72   rc = fts5Sorter
67c0: 4e 65 78 74 28 70 43 73 72 29 3b 0a 20 20 20 20  Next(pCsr);.    
67d0: 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 0a    break;.    }..
67e0: 20 20 20 20 64 65 66 61 75 6c 74 3a 0a 20 20 20      default:.   
67f0: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f     rc = sqlite3_
6800: 73 74 65 70 28 70 43 73 72 2d 3e 70 53 74 6d 74  step(pCsr->pStmt
6810: 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 21  );.      if( rc!
6820: 3d 53 51 4c 49 54 45 5f 52 4f 57 20 29 7b 0a 20  =SQLITE_ROW ){. 
6830: 20 20 20 20 20 20 20 43 73 72 46 6c 61 67 53 65         CsrFlagSe
6840: 74 28 70 43 73 72 2c 20 46 54 53 35 43 53 52 5f  t(pCsr, FTS5CSR_
6850: 45 4f 46 29 3b 0a 20 20 20 20 20 20 20 20 72 63  EOF);.        rc
6860: 20 3d 20 73 71 6c 69 74 65 33 5f 72 65 73 65 74   = sqlite3_reset
6870: 28 70 43 73 72 2d 3e 70 53 74 6d 74 29 3b 0a 20  (pCsr->pStmt);. 
6880: 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20       }else{.    
6890: 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
68a0: 4f 4b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  OK;.      }.    
68b0: 20 20 62 72 65 61 6b 3b 0a 20 20 7d 0a 20 20 0a    break;.  }.  .
68c0: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
68d0: 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 43  static int fts5C
68e0: 75 72 73 6f 72 46 69 72 73 74 53 6f 72 74 65 64  ursorFirstSorted
68f0: 28 46 74 73 35 54 61 62 6c 65 20 2a 70 54 61 62  (Fts5Table *pTab
6900: 2c 20 46 74 73 35 43 75 72 73 6f 72 20 2a 70 43  , Fts5Cursor *pC
6910: 73 72 2c 20 69 6e 74 20 62 44 65 73 63 29 7b 0a  sr, int bDesc){.
6920: 20 20 46 74 73 35 43 6f 6e 66 69 67 20 2a 70 43    Fts5Config *pC
6930: 6f 6e 66 69 67 20 3d 20 70 54 61 62 2d 3e 70 43  onfig = pTab->pC
6940: 6f 6e 66 69 67 3b 0a 20 20 46 74 73 35 53 6f 72  onfig;.  Fts5Sor
6950: 74 65 72 20 2a 70 53 6f 72 74 65 72 3b 0a 20 20  ter *pSorter;.  
6960: 69 6e 74 20 6e 50 68 72 61 73 65 3b 0a 20 20 69  int nPhrase;.  i
6970: 6e 74 20 6e 42 79 74 65 3b 0a 20 20 69 6e 74 20  nt nByte;.  int 
6980: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  rc = SQLITE_OK;.
6990: 20 20 63 68 61 72 20 2a 7a 53 71 6c 3b 0a 20 20    char *zSql;.  
69a0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 52 61 6e  const char *zRan
69b0: 6b 20 3d 20 70 43 73 72 2d 3e 7a 52 61 6e 6b 3b  k = pCsr->zRank;
69c0: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
69d0: 52 61 6e 6b 41 72 67 73 20 3d 20 70 43 73 72 2d  RankArgs = pCsr-
69e0: 3e 7a 52 61 6e 6b 41 72 67 73 3b 0a 20 20 0a 20  >zRankArgs;.  . 
69f0: 20 6e 50 68 72 61 73 65 20 3d 20 73 71 6c 69 74   nPhrase = sqlit
6a00: 65 33 46 74 73 35 45 78 70 72 50 68 72 61 73 65  e3Fts5ExprPhrase
6a10: 43 6f 75 6e 74 28 70 43 73 72 2d 3e 70 45 78 70  Count(pCsr->pExp
6a20: 72 29 3b 0a 20 20 6e 42 79 74 65 20 3d 20 73 69  r);.  nByte = si
6a30: 7a 65 6f 66 28 46 74 73 35 53 6f 72 74 65 72 29  zeof(Fts5Sorter)
6a40: 20 2b 20 73 69 7a 65 6f 66 28 69 6e 74 29 20 2a   + sizeof(int) *
6a50: 20 6e 50 68 72 61 73 65 3b 0a 20 20 70 53 6f 72   nPhrase;.  pSor
6a60: 74 65 72 20 3d 20 28 46 74 73 35 53 6f 72 74 65  ter = (Fts5Sorte
6a70: 72 2a 29 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f  r*)sqlite3_mallo
6a80: 63 28 6e 42 79 74 65 29 3b 0a 20 20 69 66 28 20  c(nByte);.  if( 
6a90: 70 53 6f 72 74 65 72 3d 3d 30 20 29 20 72 65 74  pSorter==0 ) ret
6aa0: 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  urn SQLITE_NOMEM
6ab0: 3b 0a 20 20 6d 65 6d 73 65 74 28 70 53 6f 72 74  ;.  memset(pSort
6ac0: 65 72 2c 20 30 2c 20 6e 42 79 74 65 29 3b 0a 20  er, 0, nByte);. 
6ad0: 20 70 53 6f 72 74 65 72 2d 3e 6e 49 64 78 20 3d   pSorter->nIdx =
6ae0: 20 6e 50 68 72 61 73 65 3b 0a 0a 20 20 2f 2a 20   nPhrase;..  /* 
6af0: 54 4f 44 4f 3a 20 49 74 20 77 6f 75 6c 64 20 62  TODO: It would b
6b00: 65 20 62 65 74 74 65 72 20 74 6f 20 68 61 76 65  e better to have
6b10: 20 73 6f 6d 65 20 73 79 73 74 65 6d 20 66 6f 72   some system for
6b20: 20 72 65 75 73 69 6e 67 20 73 74 61 74 65 6d 65   reusing stateme
6b30: 6e 74 0a 20 20 2a 2a 20 68 61 6e 64 6c 65 73 20  nt.  ** handles 
6b40: 68 65 72 65 2c 20 72 61 74 68 65 72 20 74 68 61  here, rather tha
6b50: 6e 20 70 72 65 70 61 72 69 6e 67 20 61 20 6e 65  n preparing a ne
6b60: 77 20 6f 6e 65 20 66 6f 72 20 65 61 63 68 20 71  w one for each q
6b70: 75 65 72 79 2e 20 42 75 74 20 74 68 61 74 0a 20  uery. But that. 
6b80: 20 2a 2a 20 69 73 20 6e 6f 74 20 70 6f 73 73 69   ** is not possi
6b90: 62 6c 65 20 61 73 20 53 51 4c 69 74 65 20 72 65  ble as SQLite re
6ba0: 66 65 72 65 6e 63 65 20 63 6f 75 6e 74 73 20 74  ference counts t
6bb0: 68 65 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65  he virtual table
6bc0: 20 6f 62 6a 65 63 74 73 2e 0a 20 20 2a 2a 20 41   objects..  ** A
6bd0: 6e 64 20 73 69 6e 63 65 20 74 68 65 20 73 74 61  nd since the sta
6be0: 74 65 6d 65 6e 74 20 72 65 71 75 69 72 65 64 20  tement required 
6bf0: 68 65 72 65 20 72 65 61 64 73 20 66 72 6f 6d 20  here reads from 
6c00: 74 68 69 73 20 76 65 72 79 20 76 69 72 74 75 61  this very virtua
6c10: 6c 20 0a 20 20 2a 2a 20 74 61 62 6c 65 2c 20 73  l .  ** table, s
6c20: 61 76 69 6e 67 20 69 74 20 63 72 65 61 74 65 73  aving it creates
6c30: 20 61 20 63 69 72 63 75 6c 61 72 20 72 65 66 65   a circular refe
6c40: 72 65 6e 63 65 2e 0a 20 20 2a 2a 0a 20 20 2a 2a  rence..  **.  **
6c50: 20 49 66 20 53 51 4c 69 74 65 20 61 20 62 75 69   If SQLite a bui
6c60: 6c 74 2d 69 6e 20 73 74 61 74 65 6d 65 6e 74 20  lt-in statement 
6c70: 63 61 63 68 65 2c 20 74 68 69 73 20 77 6f 75 6c  cache, this woul
6c80: 64 6e 27 74 20 62 65 20 61 20 70 72 6f 62 6c 65  dn't be a proble
6c90: 6d 2e 20 2a 2f 0a 20 20 7a 53 71 6c 20 3d 20 73  m. */.  zSql = s
6ca0: 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22  qlite3_mprintf("
6cb0: 53 45 4c 45 43 54 20 72 6f 77 69 64 2c 20 72 61  SELECT rowid, ra
6cc0: 6e 6b 20 46 52 4f 4d 20 25 51 2e 25 51 20 4f 52  nk FROM %Q.%Q OR
6cd0: 44 45 52 20 42 59 20 25 73 28 25 73 25 73 25 73  DER BY %s(%s%s%s
6ce0: 29 20 25 73 22 2c 0a 20 20 20 20 20 20 70 43 6f  ) %s",.      pCo
6cf0: 6e 66 69 67 2d 3e 7a 44 62 2c 20 70 43 6f 6e 66  nfig->zDb, pConf
6d00: 69 67 2d 3e 7a 4e 61 6d 65 2c 20 7a 52 61 6e 6b  ig->zName, zRank
6d10: 2c 20 70 43 6f 6e 66 69 67 2d 3e 7a 4e 61 6d 65  , pConfig->zName
6d20: 2c 0a 20 20 20 20 20 20 28 7a 52 61 6e 6b 41 72  ,.      (zRankAr
6d30: 67 73 20 3f 20 22 2c 20 22 20 3a 20 22 22 29 2c  gs ? ", " : ""),
6d40: 0a 20 20 20 20 20 20 28 7a 52 61 6e 6b 41 72 67  .      (zRankArg
6d50: 73 20 3f 20 7a 52 61 6e 6b 41 72 67 73 20 3a 20  s ? zRankArgs : 
6d60: 22 22 29 2c 0a 20 20 20 20 20 20 62 44 65 73 63  ""),.      bDesc
6d70: 20 3f 20 22 44 45 53 43 22 20 3a 20 22 41 53 43   ? "DESC" : "ASC
6d80: 22 0a 20 20 29 3b 0a 20 20 69 66 28 20 7a 53 71  ".  );.  if( zSq
6d90: 6c 3d 3d 30 20 29 7b 0a 20 20 20 20 72 63 20 3d  l==0 ){.    rc =
6da0: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
6db0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 72 63 20 3d   }else{.    rc =
6dc0: 20 73 71 6c 69 74 65 33 5f 70 72 65 70 61 72 65   sqlite3_prepare
6dd0: 5f 76 32 28 70 43 6f 6e 66 69 67 2d 3e 64 62 2c  _v2(pConfig->db,
6de0: 20 7a 53 71 6c 2c 20 2d 31 2c 20 26 70 53 6f 72   zSql, -1, &pSor
6df0: 74 65 72 2d 3e 70 53 74 6d 74 2c 20 30 29 3b 0a  ter->pStmt, 0);.
6e00: 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65      sqlite3_free
6e10: 28 7a 53 71 6c 29 3b 0a 20 20 7d 0a 0a 20 20 70  (zSql);.  }..  p
6e20: 43 73 72 2d 3e 70 53 6f 72 74 65 72 20 3d 20 70  Csr->pSorter = p
6e30: 53 6f 72 74 65 72 3b 0a 20 20 69 66 28 20 72 63  Sorter;.  if( rc
6e40: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
6e50: 20 20 20 61 73 73 65 72 74 28 20 70 54 61 62 2d     assert( pTab-
6e60: 3e 70 53 6f 72 74 43 73 72 3d 3d 30 20 29 3b 0a  >pSortCsr==0 );.
6e70: 20 20 20 20 70 54 61 62 2d 3e 70 53 6f 72 74 43      pTab->pSortC
6e80: 73 72 20 3d 20 70 43 73 72 3b 0a 20 20 20 20 72  sr = pCsr;.    r
6e90: 63 20 3d 20 66 74 73 35 53 6f 72 74 65 72 4e 65  c = fts5SorterNe
6ea0: 78 74 28 70 43 73 72 29 3b 0a 20 20 20 20 70 54  xt(pCsr);.    pT
6eb0: 61 62 2d 3e 70 53 6f 72 74 43 73 72 20 3d 20 30  ab->pSortCsr = 0
6ec0: 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 21  ;.  }..  if( rc!
6ed0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
6ee0: 20 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69    sqlite3_finali
6ef0: 7a 65 28 70 53 6f 72 74 65 72 2d 3e 70 53 74 6d  ze(pSorter->pStm
6f00: 74 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f  t);.    sqlite3_
6f10: 66 72 65 65 28 70 53 6f 72 74 65 72 29 3b 0a 20  free(pSorter);. 
6f20: 20 20 20 70 43 73 72 2d 3e 70 53 6f 72 74 65 72     pCsr->pSorter
6f30: 20 3d 20 30 3b 0a 20 20 7d 0a 0a 20 20 72 65 74   = 0;.  }..  ret
6f40: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69  urn rc;.}..stati
6f50: 63 20 69 6e 74 20 66 74 73 35 43 75 72 73 6f 72  c int fts5Cursor
6f60: 46 69 72 73 74 28 46 74 73 35 54 61 62 6c 65 20  First(Fts5Table 
6f70: 2a 70 54 61 62 2c 20 46 74 73 35 43 75 72 73 6f  *pTab, Fts5Curso
6f80: 72 20 2a 70 43 73 72 2c 20 69 6e 74 20 62 44 65  r *pCsr, int bDe
6f90: 73 63 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20  sc){.  int rc;. 
6fa0: 20 46 74 73 35 45 78 70 72 20 2a 70 45 78 70 72   Fts5Expr *pExpr
6fb0: 20 3d 20 70 43 73 72 2d 3e 70 45 78 70 72 3b 0a   = pCsr->pExpr;.
6fc0: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 46 74    rc = sqlite3Ft
6fd0: 73 35 45 78 70 72 46 69 72 73 74 28 70 45 78 70  s5ExprFirst(pExp
6fe0: 72 2c 20 70 54 61 62 2d 3e 70 49 6e 64 65 78 2c  r, pTab->pIndex,
6ff0: 20 70 43 73 72 2d 3e 69 46 69 72 73 74 52 6f 77   pCsr->iFirstRow
7000: 69 64 2c 20 62 44 65 73 63 29 3b 0a 20 20 69 66  id, bDesc);.  if
7010: 28 20 73 71 6c 69 74 65 33 46 74 73 35 45 78 70  ( sqlite3Fts5Exp
7020: 72 45 6f 66 28 70 45 78 70 72 29 20 29 7b 0a 20  rEof(pExpr) ){. 
7030: 20 20 20 43 73 72 46 6c 61 67 53 65 74 28 70 43     CsrFlagSet(pC
7040: 73 72 2c 20 46 54 53 35 43 53 52 5f 45 4f 46 29  sr, FTS5CSR_EOF)
7050: 3b 0a 20 20 7d 0a 20 20 66 74 73 35 43 73 72 4e  ;.  }.  fts5CsrN
7060: 65 77 72 6f 77 28 70 43 73 72 29 3b 0a 20 20 72  ewrow(pCsr);.  r
7070: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
7080: 2a 2a 20 50 72 6f 63 65 73 73 20 61 20 22 73 70  ** Process a "sp
7090: 65 63 69 61 6c 22 20 71 75 65 72 79 2e 20 41 20  ecial" query. A 
70a0: 73 70 65 63 69 61 6c 20 71 75 65 72 79 20 69 73  special query is
70b0: 20 69 64 65 6e 74 69 66 69 65 64 20 61 73 20 6f   identified as o
70c0: 6e 65 20 77 69 74 68 20 61 0a 2a 2a 20 4d 41 54  ne with a.** MAT
70d0: 43 48 20 65 78 70 72 65 73 73 69 6f 6e 20 74 68  CH expression th
70e0: 61 74 20 62 65 67 69 6e 73 20 77 69 74 68 20 61  at begins with a
70f0: 20 27 2a 27 20 63 68 61 72 61 63 74 65 72 2e 20   '*' character. 
7100: 54 68 65 20 72 65 6d 61 69 6e 64 65 72 20 6f 66  The remainder of
7110: 0a 2a 2a 20 74 68 65 20 74 65 78 74 20 70 61 73  .** the text pas
7120: 73 65 64 20 74 6f 20 74 68 65 20 4d 41 54 43 48  sed to the MATCH
7130: 20 6f 70 65 72 61 74 6f 72 20 61 72 65 20 75 73   operator are us
7140: 65 64 20 61 73 20 20 74 68 65 20 73 70 65 63 69  ed as  the speci
7150: 61 6c 20 71 75 65 72 79 0a 2a 2a 20 70 61 72 61  al query.** para
7160: 6d 65 74 65 72 73 2e 0a 2a 2f 0a 73 74 61 74 69  meters..*/.stati
7170: 63 20 69 6e 74 20 66 74 73 35 53 70 65 63 69 61  c int fts5Specia
7180: 6c 4d 61 74 63 68 28 0a 20 20 46 74 73 35 54 61  lMatch(.  Fts5Ta
7190: 62 6c 65 20 2a 70 54 61 62 2c 20 0a 20 20 46 74  ble *pTab, .  Ft
71a0: 73 35 43 75 72 73 6f 72 20 2a 70 43 73 72 2c 20  s5Cursor *pCsr, 
71b0: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
71c0: 51 75 65 72 79 0a 29 7b 0a 20 20 69 6e 74 20 72  Query.){.  int r
71d0: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 20 20  c = SQLITE_OK;  
71e0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65             /* Re
71f0: 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 63  turn code */.  c
7200: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 20 3d 20 7a  onst char *z = z
7210: 51 75 65 72 79 3b 20 20 20 20 20 20 20 20 20 2f  Query;         /
7220: 2a 20 53 70 65 63 69 61 6c 20 71 75 65 72 79 20  * Special query 
7230: 74 65 78 74 20 2a 2f 0a 20 20 69 6e 74 20 6e 3b  text */.  int n;
7240: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7250: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d            /* Num
7260: 62 65 72 20 6f 66 20 62 79 74 65 73 20 69 6e 20  ber of bytes in 
7270: 74 65 78 74 20 61 74 20 7a 20 2a 2f 0a 0a 20 20  text at z */..  
7280: 77 68 69 6c 65 28 20 7a 5b 30 5d 3d 3d 27 20 27  while( z[0]==' '
7290: 20 29 20 7a 2b 2b 3b 0a 20 20 66 6f 72 28 6e 3d   ) z++;.  for(n=
72a0: 30 3b 20 7a 5b 6e 5d 20 26 26 20 7a 5b 6e 5d 21  0; z[n] && z[n]!
72b0: 3d 27 20 27 3b 20 6e 2b 2b 29 3b 0a 0a 20 20 61  =' '; n++);..  a
72c0: 73 73 65 72 74 28 20 70 54 61 62 2d 3e 62 61 73  ssert( pTab->bas
72d0: 65 2e 7a 45 72 72 4d 73 67 3d 3d 30 20 29 3b 0a  e.zErrMsg==0 );.
72e0: 20 20 70 43 73 72 2d 3e 65 50 6c 61 6e 20 3d 20    pCsr->ePlan = 
72f0: 46 54 53 35 5f 50 4c 41 4e 5f 53 50 45 43 49 41  FTS5_PLAN_SPECIA
7300: 4c 3b 0a 0a 20 20 69 66 28 20 30 3d 3d 73 71 6c  L;..  if( 0==sql
7310: 69 74 65 33 5f 73 74 72 6e 69 63 6d 70 28 22 72  ite3_strnicmp("r
7320: 65 61 64 73 22 2c 20 7a 2c 20 6e 29 20 29 7b 0a  eads", z, n) ){.
7330: 20 20 20 20 70 43 73 72 2d 3e 69 53 70 65 63 69      pCsr->iSpeci
7340: 61 6c 20 3d 20 73 71 6c 69 74 65 33 46 74 73 35  al = sqlite3Fts5
7350: 49 6e 64 65 78 52 65 61 64 73 28 70 54 61 62 2d  IndexReads(pTab-
7360: 3e 70 49 6e 64 65 78 29 3b 0a 20 20 7d 0a 20 20  >pIndex);.  }.  
7370: 65 6c 73 65 20 69 66 28 20 30 3d 3d 73 71 6c 69  else if( 0==sqli
7380: 74 65 33 5f 73 74 72 6e 69 63 6d 70 28 22 69 64  te3_strnicmp("id
7390: 22 2c 20 7a 2c 20 6e 29 20 29 7b 0a 20 20 20 20  ", z, n) ){.    
73a0: 70 43 73 72 2d 3e 69 53 70 65 63 69 61 6c 20 3d  pCsr->iSpecial =
73b0: 20 70 43 73 72 2d 3e 69 43 73 72 49 64 3b 0a 20   pCsr->iCsrId;. 
73c0: 20 7d 0a 20 20 65 6c 73 65 7b 0a 20 20 20 20 2f   }.  else{.    /
73d0: 2a 20 41 6e 20 75 6e 72 65 63 6f 67 6e 69 7a 65  * An unrecognize
73e0: 64 20 64 69 72 65 63 74 69 76 65 2e 20 52 65 74  d directive. Ret
73f0: 75 72 6e 20 61 6e 20 65 72 72 6f 72 20 6d 65 73  urn an error mes
7400: 73 61 67 65 2e 20 2a 2f 0a 20 20 20 20 70 54 61  sage. */.    pTa
7410: 62 2d 3e 62 61 73 65 2e 7a 45 72 72 4d 73 67 20  b->base.zErrMsg 
7420: 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74  = sqlite3_mprint
7430: 66 28 22 75 6e 6b 6e 6f 77 6e 20 73 70 65 63 69  f("unknown speci
7440: 61 6c 20 71 75 65 72 79 3a 20 25 2e 2a 73 22 2c  al query: %.*s",
7450: 20 6e 2c 20 7a 29 3b 0a 20 20 20 20 72 63 20 3d   n, z);.    rc =
7460: 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20   SQLITE_ERROR;. 
7470: 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b   }..  return rc;
7480: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 65 61 72 63 68  .}../*.** Search
7490: 20 66 6f 72 20 61 6e 20 61 75 78 69 6c 69 61 72   for an auxiliar
74a0: 79 20 66 75 6e 63 74 69 6f 6e 20 6e 61 6d 65 64  y function named
74b0: 20 7a 4e 61 6d 65 20 74 68 61 74 20 63 61 6e 20   zName that can 
74c0: 62 65 20 75 73 65 64 20 77 69 74 68 20 74 61 62  be used with tab
74d0: 6c 65 0a 2a 2a 20 70 54 61 62 2e 20 49 66 20 6f  le.** pTab. If o
74e0: 6e 65 20 69 73 20 66 6f 75 6e 64 2c 20 72 65 74  ne is found, ret
74f0: 75 72 6e 20 61 20 70 6f 69 6e 74 65 72 20 74 6f  urn a pointer to
7500: 20 74 68 65 20 63 6f 72 72 65 73 70 6f 6e 64 69   the correspondi
7510: 6e 67 20 46 74 73 35 41 75 78 69 6c 69 61 72 79  ng Fts5Auxiliary
7520: 0a 2a 2a 20 73 74 72 75 63 74 75 72 65 2e 20 4f  .** structure. O
7530: 74 68 65 72 77 69 73 65 2c 20 69 66 20 6e 6f 20  therwise, if no 
7540: 73 75 63 68 20 66 75 6e 63 74 69 6f 6e 20 65 78  such function ex
7550: 69 73 74 73 2c 20 72 65 74 75 72 6e 20 4e 55 4c  ists, return NUL
7560: 4c 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 46 74 73  L..*/.static Fts
7570: 35 41 75 78 69 6c 69 61 72 79 20 2a 66 74 73 35  5Auxiliary *fts5
7580: 46 69 6e 64 41 75 78 69 6c 69 61 72 79 28 46 74  FindAuxiliary(Ft
7590: 73 35 54 61 62 6c 65 20 2a 70 54 61 62 2c 20 63  s5Table *pTab, c
75a0: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65  onst char *zName
75b0: 29 7b 0a 20 20 46 74 73 35 41 75 78 69 6c 69 61  ){.  Fts5Auxilia
75c0: 72 79 20 2a 70 41 75 78 3b 0a 0a 20 20 66 6f 72  ry *pAux;..  for
75d0: 28 70 41 75 78 3d 70 54 61 62 2d 3e 70 47 6c 6f  (pAux=pTab->pGlo
75e0: 62 61 6c 2d 3e 70 41 75 78 3b 20 70 41 75 78 3b  bal->pAux; pAux;
75f0: 20 70 41 75 78 3d 70 41 75 78 2d 3e 70 4e 65 78   pAux=pAux->pNex
7600: 74 29 7b 0a 20 20 20 20 69 66 28 20 73 71 6c 69  t){.    if( sqli
7610: 74 65 33 5f 73 74 72 69 63 6d 70 28 7a 4e 61 6d  te3_stricmp(zNam
7620: 65 2c 20 70 41 75 78 2d 3e 7a 46 75 6e 63 29 3d  e, pAux->zFunc)=
7630: 3d 30 20 29 20 72 65 74 75 72 6e 20 70 41 75 78  =0 ) return pAux
7640: 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 4e 6f 20 66  ;.  }..  /* No f
7650: 75 6e 63 74 69 6f 6e 20 6f 66 20 74 68 65 20 73  unction of the s
7660: 70 65 63 69 66 69 65 64 20 6e 61 6d 65 20 77 61  pecified name wa
7670: 73 20 66 6f 75 6e 64 2e 20 52 65 74 75 72 6e 20  s found. Return 
7680: 30 2e 20 2a 2f 0a 20 20 72 65 74 75 72 6e 20 30  0. */.  return 0
7690: 3b 0a 7d 0a 0a 0a 73 74 61 74 69 63 20 69 6e 74  ;.}...static int
76a0: 20 66 74 73 35 46 69 6e 64 52 61 6e 6b 46 75 6e   fts5FindRankFun
76b0: 63 74 69 6f 6e 28 46 74 73 35 43 75 72 73 6f 72  ction(Fts5Cursor
76c0: 20 2a 70 43 73 72 29 7b 0a 20 20 46 74 73 35 54   *pCsr){.  Fts5T
76d0: 61 62 6c 65 20 2a 70 54 61 62 20 3d 20 28 46 74  able *pTab = (Ft
76e0: 73 35 54 61 62 6c 65 2a 29 28 70 43 73 72 2d 3e  s5Table*)(pCsr->
76f0: 62 61 73 65 2e 70 56 74 61 62 29 3b 0a 20 20 46  base.pVtab);.  F
7700: 74 73 35 43 6f 6e 66 69 67 20 2a 70 43 6f 6e 66  ts5Config *pConf
7710: 69 67 20 3d 20 70 54 61 62 2d 3e 70 43 6f 6e 66  ig = pTab->pConf
7720: 69 67 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53  ig;.  int rc = S
7730: 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 46 74 73 35  QLITE_OK;.  Fts5
7740: 41 75 78 69 6c 69 61 72 79 20 2a 70 41 75 78 20  Auxiliary *pAux 
7750: 3d 20 30 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61  = 0;.  const cha
7760: 72 20 2a 7a 52 61 6e 6b 20 3d 20 70 43 73 72 2d  r *zRank = pCsr-
7770: 3e 7a 52 61 6e 6b 3b 0a 20 20 63 6f 6e 73 74 20  >zRank;.  const 
7780: 63 68 61 72 20 2a 7a 52 61 6e 6b 41 72 67 73 20  char *zRankArgs 
7790: 3d 20 70 43 73 72 2d 3e 7a 52 61 6e 6b 41 72 67  = pCsr->zRankArg
77a0: 73 3b 0a 0a 20 20 69 66 28 20 7a 52 61 6e 6b 41  s;..  if( zRankA
77b0: 72 67 73 20 29 7b 0a 20 20 20 20 63 68 61 72 20  rgs ){.    char 
77c0: 2a 7a 53 71 6c 20 3d 20 73 71 6c 69 74 65 33 5f  *zSql = sqlite3_
77d0: 6d 70 72 69 6e 74 66 28 22 53 45 4c 45 43 54 20  mprintf("SELECT 
77e0: 25 73 22 2c 20 7a 52 61 6e 6b 41 72 67 73 29 3b  %s", zRankArgs);
77f0: 0a 20 20 20 20 69 66 28 20 7a 53 71 6c 3d 3d 30  .    if( zSql==0
7800: 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 53   ){.      rc = S
7810: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20  QLITE_NOMEM;.   
7820: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 73 71   }else{.      sq
7830: 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 74 6d  lite3_stmt *pStm
7840: 74 20 3d 20 30 3b 0a 20 20 20 20 20 20 72 63 20  t = 0;.      rc 
7850: 3d 20 73 71 6c 69 74 65 33 5f 70 72 65 70 61 72  = sqlite3_prepar
7860: 65 5f 76 32 28 70 43 6f 6e 66 69 67 2d 3e 64 62  e_v2(pConfig->db
7870: 2c 20 7a 53 71 6c 2c 20 2d 31 2c 20 26 70 53 74  , zSql, -1, &pSt
7880: 6d 74 2c 20 30 29 3b 0a 20 20 20 20 20 20 73 71  mt, 0);.      sq
7890: 6c 69 74 65 33 5f 66 72 65 65 28 7a 53 71 6c 29  lite3_free(zSql)
78a0: 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20  ;.      assert( 
78b0: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 7c 7c  rc==SQLITE_OK ||
78c0: 20 70 43 73 72 2d 3e 70 52 61 6e 6b 41 72 67 53   pCsr->pRankArgS
78d0: 74 6d 74 3d 3d 30 20 29 3b 0a 20 20 20 20 20 20  tmt==0 );.      
78e0: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
78f0: 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 69 66 28  K ){.        if(
7900: 20 53 51 4c 49 54 45 5f 52 4f 57 3d 3d 73 71 6c   SQLITE_ROW==sql
7910: 69 74 65 33 5f 73 74 65 70 28 70 53 74 6d 74 29  ite3_step(pStmt)
7920: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 69 6e   ){.          in
7930: 74 20 6e 42 79 74 65 3b 0a 20 20 20 20 20 20 20  t nByte;.       
7940: 20 20 20 70 43 73 72 2d 3e 6e 52 61 6e 6b 41 72     pCsr->nRankAr
7950: 67 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75  g = sqlite3_colu
7960: 6d 6e 5f 63 6f 75 6e 74 28 70 53 74 6d 74 29 3b  mn_count(pStmt);
7970: 0a 20 20 20 20 20 20 20 20 20 20 6e 42 79 74 65  .          nByte
7980: 20 3d 20 73 69 7a 65 6f 66 28 73 71 6c 69 74 65   = sizeof(sqlite
7990: 33 5f 76 61 6c 75 65 2a 29 2a 70 43 73 72 2d 3e  3_value*)*pCsr->
79a0: 6e 52 61 6e 6b 41 72 67 3b 0a 20 20 20 20 20 20  nRankArg;.      
79b0: 20 20 20 20 70 43 73 72 2d 3e 61 70 52 61 6e 6b      pCsr->apRank
79c0: 41 72 67 20 3d 20 28 73 71 6c 69 74 65 33 5f 76  Arg = (sqlite3_v
79d0: 61 6c 75 65 2a 2a 29 73 71 6c 69 74 65 33 46 74  alue**)sqlite3Ft
79e0: 73 35 4d 61 6c 6c 6f 63 5a 65 72 6f 28 26 72 63  s5MallocZero(&rc
79f0: 2c 20 6e 42 79 74 65 29 3b 0a 20 20 20 20 20 20  , nByte);.      
7a00: 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49      if( rc==SQLI
7a10: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20  TE_OK ){.       
7a20: 20 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20       int i;.    
7a30: 20 20 20 20 20 20 20 20 66 6f 72 28 69 3d 30 3b          for(i=0;
7a40: 20 69 3c 70 43 73 72 2d 3e 6e 52 61 6e 6b 41 72   i<pCsr->nRankAr
7a50: 67 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20  g; i++){.       
7a60: 20 20 20 20 20 20 20 70 43 73 72 2d 3e 61 70 52         pCsr->apR
7a70: 61 6e 6b 41 72 67 5b 69 5d 20 3d 20 73 71 6c 69  ankArg[i] = sqli
7a80: 74 65 33 5f 63 6f 6c 75 6d 6e 5f 76 61 6c 75 65  te3_column_value
7a90: 28 70 53 74 6d 74 2c 20 69 29 3b 0a 20 20 20 20  (pStmt, i);.    
7aa0: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
7ab0: 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 20 20      }.          
7ac0: 70 43 73 72 2d 3e 70 52 61 6e 6b 41 72 67 53 74  pCsr->pRankArgSt
7ad0: 6d 74 20 3d 20 70 53 74 6d 74 3b 0a 20 20 20 20  mt = pStmt;.    
7ae0: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
7af0: 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65       rc = sqlite
7b00: 33 5f 66 69 6e 61 6c 69 7a 65 28 70 53 74 6d 74  3_finalize(pStmt
7b10: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 61 73 73  );.          ass
7b20: 65 72 74 28 20 72 63 21 3d 53 51 4c 49 54 45 5f  ert( rc!=SQLITE_
7b30: 4f 4b 20 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a  OK );.        }.
7b40: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20        }.    }.  
7b50: 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  }..  if( rc==SQL
7b60: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 70 41  ITE_OK ){.    pA
7b70: 75 78 20 3d 20 66 74 73 35 46 69 6e 64 41 75 78  ux = fts5FindAux
7b80: 69 6c 69 61 72 79 28 70 54 61 62 2c 20 7a 52 61  iliary(pTab, zRa
7b90: 6e 6b 29 3b 0a 20 20 20 20 69 66 28 20 70 41 75  nk);.    if( pAu
7ba0: 78 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 61 73  x==0 ){.      as
7bb0: 73 65 72 74 28 20 70 54 61 62 2d 3e 62 61 73 65  sert( pTab->base
7bc0: 2e 7a 45 72 72 4d 73 67 3d 3d 30 20 29 3b 0a 20  .zErrMsg==0 );. 
7bd0: 20 20 20 20 20 70 54 61 62 2d 3e 62 61 73 65 2e       pTab->base.
7be0: 7a 45 72 72 4d 73 67 20 3d 20 73 71 6c 69 74 65  zErrMsg = sqlite
7bf0: 33 5f 6d 70 72 69 6e 74 66 28 22 6e 6f 20 73 75  3_mprintf("no su
7c00: 63 68 20 66 75 6e 63 74 69 6f 6e 3a 20 25 73 22  ch function: %s"
7c10: 2c 20 7a 52 61 6e 6b 29 3b 0a 20 20 20 20 20 20  , zRank);.      
7c20: 72 63 20 3d 20 53 51 4c 49 54 45 5f 45 52 52 4f  rc = SQLITE_ERRO
7c30: 52 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20  R;.    }.  }..  
7c40: 70 43 73 72 2d 3e 70 52 61 6e 6b 20 3d 20 70 41  pCsr->pRank = pA
7c50: 75 78 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b  ux;.  return rc;
7c60: 0a 7d 0a 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  .}...static int 
7c70: 66 74 73 35 43 75 72 73 6f 72 50 61 72 73 65 52  fts5CursorParseR
7c80: 61 6e 6b 28 0a 20 20 46 74 73 35 43 6f 6e 66 69  ank(.  Fts5Confi
7c90: 67 20 2a 70 43 6f 6e 66 69 67 2c 0a 20 20 46 74  g *pConfig,.  Ft
7ca0: 73 35 43 75 72 73 6f 72 20 2a 70 43 73 72 2c 20  s5Cursor *pCsr, 
7cb0: 0a 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65  .  sqlite3_value
7cc0: 20 2a 70 52 61 6e 6b 0a 29 7b 0a 20 20 69 6e 74   *pRank.){.  int
7cd0: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
7ce0: 0a 20 20 69 66 28 20 70 52 61 6e 6b 20 29 7b 0a  .  if( pRank ){.
7cf0: 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a      const char *
7d00: 7a 20 3d 20 28 63 6f 6e 73 74 20 63 68 61 72 2a  z = (const char*
7d10: 29 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74  )sqlite3_value_t
7d20: 65 78 74 28 70 52 61 6e 6b 29 3b 0a 20 20 20 20  ext(pRank);.    
7d30: 63 68 61 72 20 2a 7a 52 61 6e 6b 20 3d 20 30 3b  char *zRank = 0;
7d40: 0a 20 20 20 20 63 68 61 72 20 2a 7a 52 61 6e 6b  .    char *zRank
7d50: 41 72 67 73 20 3d 20 30 3b 0a 0a 20 20 20 20 69  Args = 0;..    i
7d60: 66 28 20 7a 3d 3d 30 20 29 7b 0a 20 20 20 20 20  f( z==0 ){.     
7d70: 20 69 66 28 20 73 71 6c 69 74 65 33 5f 76 61 6c   if( sqlite3_val
7d80: 75 65 5f 74 79 70 65 28 70 52 61 6e 6b 29 3d 3d  ue_type(pRank)==
7d90: 53 51 4c 49 54 45 5f 4e 55 4c 4c 20 29 20 72 63  SQLITE_NULL ) rc
7da0: 20 3d 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b   = SQLITE_ERROR;
7db0: 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
7dc0: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 46 74    rc = sqlite3Ft
7dd0: 73 35 43 6f 6e 66 69 67 50 61 72 73 65 52 61 6e  s5ConfigParseRan
7de0: 6b 28 7a 2c 20 26 7a 52 61 6e 6b 2c 20 26 7a 52  k(z, &zRank, &zR
7df0: 61 6e 6b 41 72 67 73 29 3b 0a 20 20 20 20 7d 0a  ankArgs);.    }.
7e00: 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49      if( rc==SQLI
7e10: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 70  TE_OK ){.      p
7e20: 43 73 72 2d 3e 7a 52 61 6e 6b 20 3d 20 7a 52 61  Csr->zRank = zRa
7e30: 6e 6b 3b 0a 20 20 20 20 20 20 70 43 73 72 2d 3e  nk;.      pCsr->
7e40: 7a 52 61 6e 6b 41 72 67 73 20 3d 20 7a 52 61 6e  zRankArgs = zRan
7e50: 6b 41 72 67 73 3b 0a 20 20 20 20 20 20 43 73 72  kArgs;.      Csr
7e60: 46 6c 61 67 53 65 74 28 70 43 73 72 2c 20 46 54  FlagSet(pCsr, FT
7e70: 53 35 43 53 52 5f 46 52 45 45 5f 5a 52 41 4e 4b  S5CSR_FREE_ZRANK
7e80: 29 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28  );.    }else if(
7e90: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 45 52 52 4f   rc==SQLITE_ERRO
7ea0: 52 20 29 7b 0a 20 20 20 20 20 20 70 43 73 72 2d  R ){.      pCsr-
7eb0: 3e 62 61 73 65 2e 70 56 74 61 62 2d 3e 7a 45 72  >base.pVtab->zEr
7ec0: 72 4d 73 67 20 3d 20 73 71 6c 69 74 65 33 5f 6d  rMsg = sqlite3_m
7ed0: 70 72 69 6e 74 66 28 0a 20 20 20 20 20 20 20 20  printf(.        
7ee0: 20 20 22 70 61 72 73 65 20 65 72 72 6f 72 20 69    "parse error i
7ef0: 6e 20 72 61 6e 6b 20 66 75 6e 63 74 69 6f 6e 3a  n rank function:
7f00: 20 25 73 22 2c 20 7a 0a 20 20 20 20 20 20 29 3b   %s", z.      );
7f10: 0a 20 20 20 20 7d 0a 20 20 7d 65 6c 73 65 7b 0a  .    }.  }else{.
7f20: 20 20 20 20 69 66 28 20 70 43 6f 6e 66 69 67 2d      if( pConfig-
7f30: 3e 7a 52 61 6e 6b 20 29 7b 0a 20 20 20 20 20 20  >zRank ){.      
7f40: 70 43 73 72 2d 3e 7a 52 61 6e 6b 20 3d 20 28 63  pCsr->zRank = (c
7f50: 68 61 72 2a 29 70 43 6f 6e 66 69 67 2d 3e 7a 52  har*)pConfig->zR
7f60: 61 6e 6b 3b 0a 20 20 20 20 20 20 70 43 73 72 2d  ank;.      pCsr-
7f70: 3e 7a 52 61 6e 6b 41 72 67 73 20 3d 20 28 63 68  >zRankArgs = (ch
7f80: 61 72 2a 29 70 43 6f 6e 66 69 67 2d 3e 7a 52 61  ar*)pConfig->zRa
7f90: 6e 6b 41 72 67 73 3b 0a 20 20 20 20 7d 65 6c 73  nkArgs;.    }els
7fa0: 65 7b 0a 20 20 20 20 20 20 70 43 73 72 2d 3e 7a  e{.      pCsr->z
7fb0: 52 61 6e 6b 20 3d 20 28 63 68 61 72 2a 29 46 54  Rank = (char*)FT
7fc0: 53 35 5f 44 45 46 41 55 4c 54 5f 52 41 4e 4b 3b  S5_DEFAULT_RANK;
7fd0: 0a 20 20 20 20 20 20 70 43 73 72 2d 3e 7a 52 61  .      pCsr->zRa
7fe0: 6e 6b 41 72 67 73 20 3d 20 30 3b 0a 20 20 20 20  nkArgs = 0;.    
7ff0: 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72  }.  }.  return r
8000: 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 36 34  c;.}..static i64
8010: 20 66 74 73 35 47 65 74 52 6f 77 69 64 4c 69 6d   fts5GetRowidLim
8020: 69 74 28 73 71 6c 69 74 65 33 5f 76 61 6c 75 65  it(sqlite3_value
8030: 20 2a 70 56 61 6c 2c 20 69 36 34 20 69 44 65 66   *pVal, i64 iDef
8040: 61 75 6c 74 29 7b 0a 20 20 69 66 28 20 70 56 61  ault){.  if( pVa
8050: 6c 20 29 7b 0a 20 20 20 20 69 6e 74 20 65 54 79  l ){.    int eTy
8060: 70 65 20 3d 20 73 71 6c 69 74 65 33 5f 76 61 6c  pe = sqlite3_val
8070: 75 65 5f 6e 75 6d 65 72 69 63 5f 74 79 70 65 28  ue_numeric_type(
8080: 70 56 61 6c 29 3b 0a 20 20 20 20 69 66 28 20 65  pVal);.    if( e
8090: 54 79 70 65 3d 3d 53 51 4c 49 54 45 5f 49 4e 54  Type==SQLITE_INT
80a0: 45 47 45 52 20 29 7b 0a 20 20 20 20 20 20 72 65  EGER ){.      re
80b0: 74 75 72 6e 20 73 71 6c 69 74 65 33 5f 76 61 6c  turn sqlite3_val
80c0: 75 65 5f 69 6e 74 36 34 28 70 56 61 6c 29 3b 0a  ue_int64(pVal);.
80d0: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75      }.  }.  retu
80e0: 72 6e 20 69 44 65 66 61 75 6c 74 3b 0a 7d 0a 0a  rn iDefault;.}..
80f0: 2f 2a 0a 2a 2a 20 54 68 69 73 20 69 73 20 74 68  /*.** This is th
8100: 65 20 78 46 69 6c 74 65 72 20 69 6e 74 65 72 66  e xFilter interf
8110: 61 63 65 20 66 6f 72 20 74 68 65 20 76 69 72 74  ace for the virt
8120: 75 61 6c 20 74 61 62 6c 65 2e 20 20 53 65 65 0a  ual table.  See.
8130: 2a 2a 20 74 68 65 20 76 69 72 74 75 61 6c 20 74  ** the virtual t
8140: 61 62 6c 65 20 78 46 69 6c 74 65 72 20 6d 65 74  able xFilter met
8150: 68 6f 64 20 64 6f 63 75 6d 65 6e 74 61 74 69 6f  hod documentatio
8160: 6e 20 66 6f 72 20 61 64 64 69 74 69 6f 6e 61 6c  n for additional
8170: 0a 2a 2a 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 2e  .** information.
8180: 0a 2a 2a 20 0a 2a 2a 20 54 68 65 72 65 20 61 72  .** .** There ar
8190: 65 20 74 68 72 65 65 20 70 6f 73 73 69 62 6c 65  e three possible
81a0: 20 71 75 65 72 79 20 73 74 72 61 74 65 67 69 65   query strategie
81b0: 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 31 2e 20 46 75  s:.**.**   1. Fu
81c0: 6c 6c 2d 74 65 78 74 20 73 65 61 72 63 68 20 75  ll-text search u
81d0: 73 69 6e 67 20 61 20 4d 41 54 43 48 20 6f 70 65  sing a MATCH ope
81e0: 72 61 74 6f 72 2e 0a 2a 2a 20 20 20 32 2e 20 41  rator..**   2. A
81f0: 20 62 79 2d 72 6f 77 69 64 20 6c 6f 6f 6b 75 70   by-rowid lookup
8200: 2e 0a 2a 2a 20 20 20 33 2e 20 41 20 66 75 6c 6c  ..**   3. A full
8210: 2d 74 61 62 6c 65 20 73 63 61 6e 2e 0a 2a 2f 0a  -table scan..*/.
8220: 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 46  static int fts5F
8230: 69 6c 74 65 72 4d 65 74 68 6f 64 28 0a 20 20 73  ilterMethod(.  s
8240: 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73  qlite3_vtab_curs
8250: 6f 72 20 2a 70 43 75 72 73 6f 72 2c 20 20 20 2f  or *pCursor,   /
8260: 2a 20 54 68 65 20 63 75 72 73 6f 72 20 75 73 65  * The cursor use
8270: 64 20 66 6f 72 20 74 68 69 73 20 71 75 65 72 79  d for this query
8280: 20 2a 2f 0a 20 20 69 6e 74 20 69 64 78 4e 75 6d   */.  int idxNum
8290: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
82a0: 20 20 20 20 20 20 2f 2a 20 53 74 72 61 74 65 67        /* Strateg
82b0: 79 20 69 6e 64 65 78 20 2a 2f 0a 20 20 63 6f 6e  y index */.  con
82c0: 73 74 20 63 68 61 72 20 2a 69 64 78 53 74 72 2c  st char *idxStr,
82d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
82e0: 55 6e 75 73 65 64 20 2a 2f 0a 20 20 69 6e 74 20  Unused */.  int 
82f0: 6e 56 61 6c 2c 20 20 20 20 20 20 20 20 20 20 20  nVal,           
8300: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
8310: 75 6d 62 65 72 20 6f 66 20 65 6c 65 6d 65 6e 74  umber of element
8320: 73 20 69 6e 20 61 70 56 61 6c 20 2a 2f 0a 20 20  s in apVal */.  
8330: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a  sqlite3_value **
8340: 61 70 56 61 6c 20 20 20 20 20 20 20 20 20 20 20  apVal           
8350: 2f 2a 20 41 72 67 75 6d 65 6e 74 73 20 66 6f 72  /* Arguments for
8360: 20 74 68 65 20 69 6e 64 65 78 69 6e 67 20 73 63   the indexing sc
8370: 68 65 6d 65 20 2a 2f 0a 29 7b 0a 20 20 46 74 73  heme */.){.  Fts
8380: 35 54 61 62 6c 65 20 2a 70 54 61 62 20 3d 20 28  5Table *pTab = (
8390: 46 74 73 35 54 61 62 6c 65 2a 29 28 70 43 75 72  Fts5Table*)(pCur
83a0: 73 6f 72 2d 3e 70 56 74 61 62 29 3b 0a 20 20 46  sor->pVtab);.  F
83b0: 74 73 35 43 75 72 73 6f 72 20 2a 70 43 73 72 20  ts5Cursor *pCsr 
83c0: 3d 20 28 46 74 73 35 43 75 72 73 6f 72 2a 29 70  = (Fts5Cursor*)p
83d0: 43 75 72 73 6f 72 3b 0a 20 20 69 6e 74 20 72 63  Cursor;.  int rc
83e0: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 20 20 20   = SQLITE_OK;   
83f0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 45 72 72            /* Err
8400: 6f 72 20 63 6f 64 65 20 2a 2f 0a 20 20 69 6e 74  or code */.  int
8410: 20 69 56 61 6c 20 3d 20 30 3b 20 20 20 20 20 20   iVal = 0;      
8420: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
8430: 43 6f 75 6e 74 65 72 20 66 6f 72 20 61 70 56 61  Counter for apVa
8440: 6c 5b 5d 20 2a 2f 0a 20 20 69 6e 74 20 62 44 65  l[] */.  int bDe
8450: 73 63 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  sc;             
8460: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65           /* True
8470: 20 69 66 20 4f 52 44 45 52 20 42 59 20 5b 72 61   if ORDER BY [ra
8480: 6e 6b 7c 72 6f 77 69 64 5d 20 44 45 53 43 20 2a  nk|rowid] DESC *
8490: 2f 0a 20 20 69 6e 74 20 62 4f 72 64 65 72 42 79  /.  int bOrderBy
84a0: 52 61 6e 6b 3b 20 20 20 20 20 20 20 20 20 20 20  Rank;           
84b0: 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20 4f      /* True if O
84c0: 52 44 45 52 20 42 59 20 72 61 6e 6b 20 2a 2f 0a  RDER BY rank */.
84d0: 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20    sqlite3_value 
84e0: 2a 70 4d 61 74 63 68 20 3d 20 30 3b 20 20 20 20  *pMatch = 0;    
84f0: 20 20 2f 2a 20 3c 74 62 6c 3e 20 4d 41 54 43 48    /* <tbl> MATCH
8500: 20 3f 20 65 78 70 72 65 73 73 69 6f 6e 20 28 6f   ? expression (o
8510: 72 20 4e 55 4c 4c 29 20 2a 2f 0a 20 20 73 71 6c  r NULL) */.  sql
8520: 69 74 65 33 5f 76 61 6c 75 65 20 2a 70 52 61 6e  ite3_value *pRan
8530: 6b 20 3d 20 30 3b 20 20 20 20 20 20 20 2f 2a 20  k = 0;       /* 
8540: 72 61 6e 6b 20 4d 41 54 43 48 20 3f 20 65 78 70  rank MATCH ? exp
8550: 72 65 73 73 69 6f 6e 20 28 6f 72 20 4e 55 4c 4c  ression (or NULL
8560: 29 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 76  ) */.  sqlite3_v
8570: 61 6c 75 65 20 2a 70 52 6f 77 69 64 45 71 20 3d  alue *pRowidEq =
8580: 20 30 3b 20 20 20 20 2f 2a 20 72 6f 77 69 64 20   0;    /* rowid 
8590: 3d 20 3f 20 65 78 70 72 65 73 73 69 6f 6e 20 28  = ? expression (
85a0: 6f 72 20 4e 55 4c 4c 29 20 2a 2f 0a 20 20 73 71  or NULL) */.  sq
85b0: 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 70 52 6f  lite3_value *pRo
85c0: 77 69 64 4c 65 20 3d 20 30 3b 20 20 20 20 2f 2a  widLe = 0;    /*
85d0: 20 72 6f 77 69 64 20 3c 3d 20 3f 20 65 78 70 72   rowid <= ? expr
85e0: 65 73 73 69 6f 6e 20 28 6f 72 20 4e 55 4c 4c 29  ession (or NULL)
85f0: 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 76 61   */.  sqlite3_va
8600: 6c 75 65 20 2a 70 52 6f 77 69 64 47 65 20 3d 20  lue *pRowidGe = 
8610: 30 3b 20 20 20 20 2f 2a 20 72 6f 77 69 64 20 3e  0;    /* rowid >
8620: 3d 20 3f 20 65 78 70 72 65 73 73 69 6f 6e 20 28  = ? expression (
8630: 6f 72 20 4e 55 4c 4c 29 20 2a 2f 0a 20 20 63 68  or NULL) */.  ch
8640: 61 72 20 2a 2a 70 7a 45 72 72 6d 73 67 20 3d 20  ar **pzErrmsg = 
8650: 70 54 61 62 2d 3e 70 43 6f 6e 66 69 67 2d 3e 70  pTab->pConfig->p
8660: 7a 45 72 72 6d 73 67 3b 0a 0a 20 20 61 73 73 65  zErrmsg;..  asse
8670: 72 74 28 20 70 43 73 72 2d 3e 70 53 74 6d 74 3d  rt( pCsr->pStmt=
8680: 3d 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  =0 );.  assert( 
8690: 70 43 73 72 2d 3e 70 45 78 70 72 3d 3d 30 20 29  pCsr->pExpr==0 )
86a0: 3b 0a 20 20 61 73 73 65 72 74 28 20 70 43 73 72  ;.  assert( pCsr
86b0: 2d 3e 63 73 72 66 6c 61 67 73 3d 3d 30 20 29 3b  ->csrflags==0 );
86c0: 0a 20 20 61 73 73 65 72 74 28 20 70 43 73 72 2d  .  assert( pCsr-
86d0: 3e 70 52 61 6e 6b 3d 3d 30 20 29 3b 0a 20 20 61  >pRank==0 );.  a
86e0: 73 73 65 72 74 28 20 70 43 73 72 2d 3e 7a 52 61  ssert( pCsr->zRa
86f0: 6e 6b 3d 3d 30 20 29 3b 0a 20 20 61 73 73 65 72  nk==0 );.  asser
8700: 74 28 20 70 43 73 72 2d 3e 7a 52 61 6e 6b 41 72  t( pCsr->zRankAr
8710: 67 73 3d 3d 30 20 29 3b 0a 0a 20 20 61 73 73 65  gs==0 );..  asse
8720: 72 74 28 20 70 7a 45 72 72 6d 73 67 3d 3d 30 20  rt( pzErrmsg==0 
8730: 7c 7c 20 70 7a 45 72 72 6d 73 67 3d 3d 26 70 54  || pzErrmsg==&pT
8740: 61 62 2d 3e 62 61 73 65 2e 7a 45 72 72 4d 73 67  ab->base.zErrMsg
8750: 20 29 3b 0a 20 20 70 54 61 62 2d 3e 70 43 6f 6e   );.  pTab->pCon
8760: 66 69 67 2d 3e 70 7a 45 72 72 6d 73 67 20 3d 20  fig->pzErrmsg = 
8770: 26 70 54 61 62 2d 3e 62 61 73 65 2e 7a 45 72 72  &pTab->base.zErr
8780: 4d 73 67 3b 0a 0a 20 20 2f 2a 20 44 65 63 6f 64  Msg;..  /* Decod
8790: 65 20 74 68 65 20 61 72 67 75 6d 65 6e 74 73 20  e the arguments 
87a0: 70 61 73 73 65 64 20 74 68 72 6f 75 67 68 20 74  passed through t
87b0: 6f 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 2e  o this function.
87c0: 0a 20 20 2a 2a 0a 20 20 2a 2a 20 4e 6f 74 65 3a  .  **.  ** Note:
87d0: 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 73   The following s
87e0: 65 74 20 6f 66 20 69 66 28 2e 2e 2e 29 20 73 74  et of if(...) st
87f0: 61 74 65 6d 65 6e 74 73 20 6d 75 73 74 20 62 65  atements must be
8800: 20 69 6e 20 74 68 65 20 73 61 6d 65 0a 20 20 2a   in the same.  *
8810: 2a 20 6f 72 64 65 72 20 61 73 20 74 68 65 20 63  * order as the c
8820: 6f 72 72 65 73 70 6f 6e 64 69 6e 67 20 65 6e 74  orresponding ent
8830: 72 69 65 73 20 69 6e 20 74 68 65 20 73 74 72 75  ries in the stru
8840: 63 74 20 61 74 20 74 68 65 20 74 6f 70 20 6f 66  ct at the top of
8850: 0a 20 20 2a 2a 20 66 74 73 35 42 65 73 74 49 6e  .  ** fts5BestIn
8860: 64 65 78 4d 65 74 68 6f 64 28 29 2e 20 20 2a 2f  dexMethod().  */
8870: 0a 20 20 69 66 28 20 42 69 74 46 6c 61 67 54 65  .  if( BitFlagTe
8880: 73 74 28 69 64 78 4e 75 6d 2c 20 46 54 53 35 5f  st(idxNum, FTS5_
8890: 42 49 5f 4d 41 54 43 48 29 20 29 20 70 4d 61 74  BI_MATCH) ) pMat
88a0: 63 68 20 3d 20 61 70 56 61 6c 5b 69 56 61 6c 2b  ch = apVal[iVal+
88b0: 2b 5d 3b 0a 20 20 69 66 28 20 42 69 74 46 6c 61  +];.  if( BitFla
88c0: 67 54 65 73 74 28 69 64 78 4e 75 6d 2c 20 46 54  gTest(idxNum, FT
88d0: 53 35 5f 42 49 5f 52 41 4e 4b 29 20 29 20 70 52  S5_BI_RANK) ) pR
88e0: 61 6e 6b 20 3d 20 61 70 56 61 6c 5b 69 56 61 6c  ank = apVal[iVal
88f0: 2b 2b 5d 3b 0a 20 20 69 66 28 20 42 69 74 46 6c  ++];.  if( BitFl
8900: 61 67 54 65 73 74 28 69 64 78 4e 75 6d 2c 20 46  agTest(idxNum, F
8910: 54 53 35 5f 42 49 5f 52 4f 57 49 44 5f 45 51 29  TS5_BI_ROWID_EQ)
8920: 20 29 20 70 52 6f 77 69 64 45 71 20 3d 20 61 70   ) pRowidEq = ap
8930: 56 61 6c 5b 69 56 61 6c 2b 2b 5d 3b 0a 20 20 69  Val[iVal++];.  i
8940: 66 28 20 42 69 74 46 6c 61 67 54 65 73 74 28 69  f( BitFlagTest(i
8950: 64 78 4e 75 6d 2c 20 46 54 53 35 5f 42 49 5f 52  dxNum, FTS5_BI_R
8960: 4f 57 49 44 5f 4c 45 29 20 29 20 70 52 6f 77 69  OWID_LE) ) pRowi
8970: 64 4c 65 20 3d 20 61 70 56 61 6c 5b 69 56 61 6c  dLe = apVal[iVal
8980: 2b 2b 5d 3b 0a 20 20 69 66 28 20 42 69 74 46 6c  ++];.  if( BitFl
8990: 61 67 54 65 73 74 28 69 64 78 4e 75 6d 2c 20 46  agTest(idxNum, F
89a0: 54 53 35 5f 42 49 5f 52 4f 57 49 44 5f 47 45 29  TS5_BI_ROWID_GE)
89b0: 20 29 20 70 52 6f 77 69 64 47 65 20 3d 20 61 70   ) pRowidGe = ap
89c0: 56 61 6c 5b 69 56 61 6c 2b 2b 5d 3b 0a 20 20 61  Val[iVal++];.  a
89d0: 73 73 65 72 74 28 20 69 56 61 6c 3d 3d 6e 56 61  ssert( iVal==nVa
89e0: 6c 20 29 3b 0a 20 20 62 4f 72 64 65 72 42 79 52  l );.  bOrderByR
89f0: 61 6e 6b 20 3d 20 28 28 69 64 78 4e 75 6d 20 26  ank = ((idxNum &
8a00: 20 46 54 53 35 5f 42 49 5f 4f 52 44 45 52 5f 52   FTS5_BI_ORDER_R
8a10: 41 4e 4b 29 20 3f 20 31 20 3a 20 30 29 3b 0a 20  ANK) ? 1 : 0);. 
8a20: 20 70 43 73 72 2d 3e 62 44 65 73 63 20 3d 20 62   pCsr->bDesc = b
8a30: 44 65 73 63 20 3d 20 28 28 69 64 78 4e 75 6d 20  Desc = ((idxNum 
8a40: 26 20 46 54 53 35 5f 42 49 5f 4f 52 44 45 52 5f  & FTS5_BI_ORDER_
8a50: 44 45 53 43 29 20 3f 20 31 20 3a 20 30 29 3b 0a  DESC) ? 1 : 0);.
8a60: 0a 20 20 2f 2a 20 53 65 74 20 74 68 65 20 63 75  .  /* Set the cu
8a70: 72 73 6f 72 20 75 70 70 65 72 20 61 6e 64 20 6c  rsor upper and l
8a80: 6f 77 65 72 20 72 6f 77 69 64 20 6c 69 6d 69 74  ower rowid limit
8a90: 73 2e 20 4f 6e 6c 79 20 73 6f 6d 65 20 73 74 72  s. Only some str
8aa0: 61 74 65 67 69 65 73 20 0a 20 20 2a 2a 20 61 63  ategies .  ** ac
8ab0: 74 75 61 6c 6c 79 20 75 73 65 20 74 68 65 6d 2e  tually use them.
8ac0: 20 54 68 69 73 20 69 73 20 6f 6b 2c 20 61 73 20   This is ok, as 
8ad0: 74 68 65 20 78 42 65 73 74 49 6e 64 65 78 28 29  the xBestIndex()
8ae0: 20 6d 65 74 68 6f 64 20 6c 65 61 76 65 73 20 74   method leaves t
8af0: 68 65 0a 20 20 2a 2a 20 73 71 6c 69 74 65 33 5f  he.  ** sqlite3_
8b00: 69 6e 64 65 78 5f 63 6f 6e 73 74 72 61 69 6e 74  index_constraint
8b10: 2e 6f 6d 69 74 20 66 6c 61 67 20 63 6c 65 61 72  .omit flag clear
8b20: 20 66 6f 72 20 72 61 6e 67 65 20 63 6f 6e 73 74   for range const
8b30: 72 61 69 6e 74 73 0a 20 20 2a 2a 20 6f 6e 20 74  raints.  ** on t
8b40: 68 65 20 72 6f 77 69 64 20 66 69 65 6c 64 2e 20  he rowid field. 
8b50: 20 2a 2f 0a 20 20 69 66 28 20 70 52 6f 77 69 64   */.  if( pRowid
8b60: 45 71 20 29 7b 0a 20 20 20 20 70 52 6f 77 69 64  Eq ){.    pRowid
8b70: 4c 65 20 3d 20 70 52 6f 77 69 64 47 65 20 3d 20  Le = pRowidGe = 
8b80: 70 52 6f 77 69 64 45 71 3b 0a 20 20 7d 0a 20 20  pRowidEq;.  }.  
8b90: 69 66 28 20 62 44 65 73 63 20 29 7b 0a 20 20 20  if( bDesc ){.   
8ba0: 20 70 43 73 72 2d 3e 69 46 69 72 73 74 52 6f 77   pCsr->iFirstRow
8bb0: 69 64 20 3d 20 66 74 73 35 47 65 74 52 6f 77 69  id = fts5GetRowi
8bc0: 64 4c 69 6d 69 74 28 70 52 6f 77 69 64 4c 65 2c  dLimit(pRowidLe,
8bd0: 20 4c 41 52 47 45 53 54 5f 49 4e 54 36 34 29 3b   LARGEST_INT64);
8be0: 0a 20 20 20 20 70 43 73 72 2d 3e 69 4c 61 73 74  .    pCsr->iLast
8bf0: 52 6f 77 69 64 20 3d 20 66 74 73 35 47 65 74 52  Rowid = fts5GetR
8c00: 6f 77 69 64 4c 69 6d 69 74 28 70 52 6f 77 69 64  owidLimit(pRowid
8c10: 47 65 2c 20 53 4d 41 4c 4c 45 53 54 5f 49 4e 54  Ge, SMALLEST_INT
8c20: 36 34 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  64);.  }else{.  
8c30: 20 20 70 43 73 72 2d 3e 69 4c 61 73 74 52 6f 77    pCsr->iLastRow
8c40: 69 64 20 3d 20 66 74 73 35 47 65 74 52 6f 77 69  id = fts5GetRowi
8c50: 64 4c 69 6d 69 74 28 70 52 6f 77 69 64 4c 65 2c  dLimit(pRowidLe,
8c60: 20 4c 41 52 47 45 53 54 5f 49 4e 54 36 34 29 3b   LARGEST_INT64);
8c70: 0a 20 20 20 20 70 43 73 72 2d 3e 69 46 69 72 73  .    pCsr->iFirs
8c80: 74 52 6f 77 69 64 20 3d 20 66 74 73 35 47 65 74  tRowid = fts5Get
8c90: 52 6f 77 69 64 4c 69 6d 69 74 28 70 52 6f 77 69  RowidLimit(pRowi
8ca0: 64 47 65 2c 20 53 4d 41 4c 4c 45 53 54 5f 49 4e  dGe, SMALLEST_IN
8cb0: 54 36 34 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28  T64);.  }..  if(
8cc0: 20 70 54 61 62 2d 3e 70 53 6f 72 74 43 73 72 20   pTab->pSortCsr 
8cd0: 29 7b 0a 20 20 20 20 2f 2a 20 49 66 20 70 53 6f  ){.    /* If pSo
8ce0: 72 74 43 73 72 20 69 73 20 6e 6f 6e 2d 4e 55 4c  rtCsr is non-NUL
8cf0: 4c 2c 20 74 68 65 6e 20 74 68 69 73 20 63 61 6c  L, then this cal
8d00: 6c 20 69 73 20 62 65 69 6e 67 20 6d 61 64 65 20  l is being made 
8d10: 61 73 20 70 61 72 74 20 6f 66 20 0a 20 20 20 20  as part of .    
8d20: 2a 2a 20 70 72 6f 63 65 73 73 69 6e 67 20 66 6f  ** processing fo
8d30: 72 20 61 20 22 2e 2e 2e 20 4d 41 54 43 48 20 3c  r a "... MATCH <
8d40: 65 78 70 72 3e 20 4f 52 44 45 52 20 42 59 20 72  expr> ORDER BY r
8d50: 61 6e 6b 22 20 71 75 65 72 79 20 28 65 50 6c 61  ank" query (ePla
8d60: 6e 20 69 73 0a 20 20 20 20 2a 2a 20 73 65 74 20  n is.    ** set 
8d70: 74 6f 20 46 54 53 35 5f 50 4c 41 4e 5f 53 4f 52  to FTS5_PLAN_SOR
8d80: 54 45 44 5f 4d 41 54 43 48 29 2e 20 70 53 6f 72  TED_MATCH). pSor
8d90: 74 43 73 72 20 69 73 20 74 68 65 20 63 75 72 73  tCsr is the curs
8da0: 6f 72 20 74 68 61 74 20 77 69 6c 6c 0a 20 20 20  or that will.   
8db0: 20 2a 2a 20 72 65 74 75 72 6e 20 72 65 73 75 6c   ** return resul
8dc0: 74 73 20 74 6f 20 74 68 65 20 75 73 65 72 20 66  ts to the user f
8dd0: 6f 72 20 74 68 69 73 20 71 75 65 72 79 2e 20 54  or this query. T
8de0: 68 65 20 63 75 72 72 65 6e 74 20 63 75 72 73 6f  he current curso
8df0: 72 20 0a 20 20 20 20 2a 2a 20 28 70 43 75 72 73  r .    ** (pCurs
8e00: 6f 72 29 20 69 73 20 75 73 65 64 20 74 6f 20 65  or) is used to e
8e10: 78 65 63 75 74 65 20 74 68 65 20 71 75 65 72 79  xecute the query
8e20: 20 69 73 73 75 65 64 20 62 79 20 66 75 6e 63 74   issued by funct
8e30: 69 6f 6e 20 0a 20 20 20 20 2a 2a 20 66 74 73 35  ion .    ** fts5
8e40: 43 75 72 73 6f 72 46 69 72 73 74 53 6f 72 74 65  CursorFirstSorte
8e50: 64 28 29 20 61 62 6f 76 65 2e 20 20 2a 2f 0a 20  d() above.  */. 
8e60: 20 20 20 61 73 73 65 72 74 28 20 70 52 6f 77 69     assert( pRowi
8e70: 64 45 71 3d 3d 30 20 26 26 20 70 52 6f 77 69 64  dEq==0 && pRowid
8e80: 4c 65 3d 3d 30 20 26 26 20 70 52 6f 77 69 64 47  Le==0 && pRowidG
8e90: 65 3d 3d 30 20 26 26 20 70 52 61 6e 6b 3d 3d 30  e==0 && pRank==0
8ea0: 20 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20   );.    assert( 
8eb0: 6e 56 61 6c 3d 3d 30 20 26 26 20 70 4d 61 74 63  nVal==0 && pMatc
8ec0: 68 3d 3d 30 20 26 26 20 62 4f 72 64 65 72 42 79  h==0 && bOrderBy
8ed0: 52 61 6e 6b 3d 3d 30 20 26 26 20 62 44 65 73 63  Rank==0 && bDesc
8ee0: 3d 3d 30 20 29 3b 0a 20 20 20 20 61 73 73 65 72  ==0 );.    asser
8ef0: 74 28 20 70 43 73 72 2d 3e 69 4c 61 73 74 52 6f  t( pCsr->iLastRo
8f00: 77 69 64 3d 3d 4c 41 52 47 45 53 54 5f 49 4e 54  wid==LARGEST_INT
8f10: 36 34 20 29 3b 0a 20 20 20 20 61 73 73 65 72 74  64 );.    assert
8f20: 28 20 70 43 73 72 2d 3e 69 46 69 72 73 74 52 6f  ( pCsr->iFirstRo
8f30: 77 69 64 3d 3d 53 4d 41 4c 4c 45 53 54 5f 49 4e  wid==SMALLEST_IN
8f40: 54 36 34 20 29 3b 0a 20 20 20 20 70 43 73 72 2d  T64 );.    pCsr-
8f50: 3e 65 50 6c 61 6e 20 3d 20 46 54 53 35 5f 50 4c  >ePlan = FTS5_PL
8f60: 41 4e 5f 53 4f 55 52 43 45 3b 0a 20 20 20 20 70  AN_SOURCE;.    p
8f70: 43 73 72 2d 3e 70 45 78 70 72 20 3d 20 70 54 61  Csr->pExpr = pTa
8f80: 62 2d 3e 70 53 6f 72 74 43 73 72 2d 3e 70 45 78  b->pSortCsr->pEx
8f90: 70 72 3b 0a 20 20 20 20 72 63 20 3d 20 66 74 73  pr;.    rc = fts
8fa0: 35 43 75 72 73 6f 72 46 69 72 73 74 28 70 54 61  5CursorFirst(pTa
8fb0: 62 2c 20 70 43 73 72 2c 20 62 44 65 73 63 29 3b  b, pCsr, bDesc);
8fc0: 0a 20 20 7d 65 6c 73 65 20 69 66 28 20 70 4d 61  .  }else if( pMa
8fd0: 74 63 68 20 29 7b 0a 20 20 20 20 63 6f 6e 73 74  tch ){.    const
8fe0: 20 63 68 61 72 20 2a 7a 45 78 70 72 20 3d 20 28   char *zExpr = (
8ff0: 63 6f 6e 73 74 20 63 68 61 72 2a 29 73 71 6c 69  const char*)sqli
9000: 74 65 33 5f 76 61 6c 75 65 5f 74 65 78 74 28 61  te3_value_text(a
9010: 70 56 61 6c 5b 30 5d 29 3b 0a 0a 20 20 20 20 72  pVal[0]);..    r
9020: 63 20 3d 20 66 74 73 35 43 75 72 73 6f 72 50 61  c = fts5CursorPa
9030: 72 73 65 52 61 6e 6b 28 70 54 61 62 2d 3e 70 43  rseRank(pTab->pC
9040: 6f 6e 66 69 67 2c 20 70 43 73 72 2c 20 70 52 61  onfig, pCsr, pRa
9050: 6e 6b 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d  nk);.    if( rc=
9060: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
9070: 20 20 20 20 69 66 28 20 7a 45 78 70 72 5b 30 5d      if( zExpr[0]
9080: 3d 3d 27 2a 27 20 29 7b 0a 20 20 20 20 20 20 20  =='*' ){.       
9090: 20 2f 2a 20 54 68 65 20 75 73 65 72 20 68 61 73   /* The user has
90a0: 20 69 73 73 75 65 64 20 61 20 71 75 65 72 79 20   issued a query 
90b0: 6f 66 20 74 68 65 20 66 6f 72 6d 20 22 4d 41 54  of the form "MAT
90c0: 43 48 20 27 2a 2e 2e 2e 27 22 2e 20 54 68 69 73  CH '*...'". This
90d0: 0a 20 20 20 20 20 20 20 20 2a 2a 20 69 6e 64 69  .        ** indi
90e0: 63 61 74 65 73 20 74 68 61 74 20 74 68 65 20 4d  cates that the M
90f0: 41 54 43 48 20 65 78 70 72 65 73 73 69 6f 6e 20  ATCH expression 
9100: 69 73 20 6e 6f 74 20 61 20 66 75 6c 6c 20 74 65  is not a full te
9110: 78 74 20 71 75 65 72 79 2c 0a 20 20 20 20 20 20  xt query,.      
9120: 20 20 2a 2a 20 62 75 74 20 61 20 72 65 71 75 65    ** but a reque
9130: 73 74 20 66 6f 72 20 61 6e 20 69 6e 74 65 72 6e  st for an intern
9140: 61 6c 20 70 61 72 61 6d 65 74 65 72 2e 20 20 2a  al parameter.  *
9150: 2f 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 66  /.        rc = f
9160: 74 73 35 53 70 65 63 69 61 6c 4d 61 74 63 68 28  ts5SpecialMatch(
9170: 70 54 61 62 2c 20 70 43 73 72 2c 20 26 7a 45 78  pTab, pCsr, &zEx
9180: 70 72 5b 31 5d 29 3b 0a 20 20 20 20 20 20 7d 65  pr[1]);.      }e
9190: 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 63 68 61  lse{.        cha
91a0: 72 20 2a 2a 70 7a 45 72 72 20 3d 20 26 70 54 61  r **pzErr = &pTa
91b0: 62 2d 3e 62 61 73 65 2e 7a 45 72 72 4d 73 67 3b  b->base.zErrMsg;
91c0: 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 73 71  .        rc = sq
91d0: 6c 69 74 65 33 46 74 73 35 45 78 70 72 4e 65 77  lite3Fts5ExprNew
91e0: 28 70 54 61 62 2d 3e 70 43 6f 6e 66 69 67 2c 20  (pTab->pConfig, 
91f0: 7a 45 78 70 72 2c 20 26 70 43 73 72 2d 3e 70 45  zExpr, &pCsr->pE
9200: 78 70 72 2c 20 70 7a 45 72 72 29 3b 0a 20 20 20  xpr, pzErr);.   
9210: 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c       if( rc==SQL
9220: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20  ITE_OK ){.      
9230: 20 20 20 20 69 66 28 20 62 4f 72 64 65 72 42 79      if( bOrderBy
9240: 52 61 6e 6b 20 29 7b 0a 20 20 20 20 20 20 20 20  Rank ){.        
9250: 20 20 20 20 70 43 73 72 2d 3e 65 50 6c 61 6e 20      pCsr->ePlan 
9260: 3d 20 46 54 53 35 5f 50 4c 41 4e 5f 53 4f 52 54  = FTS5_PLAN_SORT
9270: 45 44 5f 4d 41 54 43 48 3b 0a 20 20 20 20 20 20  ED_MATCH;.      
9280: 20 20 20 20 20 20 72 63 20 3d 20 66 74 73 35 43        rc = fts5C
9290: 75 72 73 6f 72 46 69 72 73 74 53 6f 72 74 65 64  ursorFirstSorted
92a0: 28 70 54 61 62 2c 20 70 43 73 72 2c 20 62 44 65  (pTab, pCsr, bDe
92b0: 73 63 29 3b 0a 20 20 20 20 20 20 20 20 20 20 7d  sc);.          }
92c0: 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 20 20  else{.          
92d0: 20 20 70 43 73 72 2d 3e 65 50 6c 61 6e 20 3d 20    pCsr->ePlan = 
92e0: 46 54 53 35 5f 50 4c 41 4e 5f 4d 41 54 43 48 3b  FTS5_PLAN_MATCH;
92f0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 72 63 20  .            rc 
9300: 3d 20 66 74 73 35 43 75 72 73 6f 72 46 69 72 73  = fts5CursorFirs
9310: 74 28 70 54 61 62 2c 20 70 43 73 72 2c 20 62 44  t(pTab, pCsr, bD
9320: 65 73 63 29 3b 0a 20 20 20 20 20 20 20 20 20 20  esc);.          
9330: 7d 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  }.        }.    
9340: 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 65 6c 73    }.    }.  }els
9350: 65 7b 0a 20 20 20 20 2f 2a 20 54 68 69 73 20 69  e{.    /* This i
9360: 73 20 65 69 74 68 65 72 20 61 20 66 75 6c 6c 2d  s either a full-
9370: 74 61 62 6c 65 20 73 63 61 6e 20 28 65 50 6c 61  table scan (ePla
9380: 6e 3d 3d 46 54 53 35 5f 50 4c 41 4e 5f 53 43 41  n==FTS5_PLAN_SCA
9390: 4e 29 20 6f 72 20 61 20 6c 6f 6f 6b 75 70 0a 20  N) or a lookup. 
93a0: 20 20 20 2a 2a 20 62 79 20 72 6f 77 69 64 20 28     ** by rowid (
93b0: 65 50 6c 61 6e 3d 3d 46 54 53 35 5f 50 4c 41 4e  ePlan==FTS5_PLAN
93c0: 5f 52 4f 57 49 44 29 2e 20 20 2a 2f 0a 20 20 20  _ROWID).  */.   
93d0: 20 70 43 73 72 2d 3e 65 50 6c 61 6e 20 3d 20 28   pCsr->ePlan = (
93e0: 70 52 6f 77 69 64 45 71 20 3f 20 46 54 53 35 5f  pRowidEq ? FTS5_
93f0: 50 4c 41 4e 5f 52 4f 57 49 44 20 3a 20 46 54 53  PLAN_ROWID : FTS
9400: 35 5f 50 4c 41 4e 5f 53 43 41 4e 29 3b 0a 20 20  5_PLAN_SCAN);.  
9410: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 46 74    rc = sqlite3Ft
9420: 73 35 53 74 6f 72 61 67 65 53 74 6d 74 28 0a 20  s5StorageStmt(. 
9430: 20 20 20 20 20 20 20 70 54 61 62 2d 3e 70 53 74         pTab->pSt
9440: 6f 72 61 67 65 2c 20 66 74 73 35 53 74 6d 74 54  orage, fts5StmtT
9450: 79 70 65 28 70 43 73 72 29 2c 20 26 70 43 73 72  ype(pCsr), &pCsr
9460: 2d 3e 70 53 74 6d 74 2c 20 26 70 54 61 62 2d 3e  ->pStmt, &pTab->
9470: 62 61 73 65 2e 7a 45 72 72 4d 73 67 0a 20 20 20  base.zErrMsg.   
9480: 20 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d   );.    if( rc==
9490: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
94a0: 20 20 20 69 66 28 20 70 43 73 72 2d 3e 65 50 6c     if( pCsr->ePl
94b0: 61 6e 3d 3d 46 54 53 35 5f 50 4c 41 4e 5f 52 4f  an==FTS5_PLAN_RO
94c0: 57 49 44 20 29 7b 0a 20 20 20 20 20 20 20 20 73  WID ){.        s
94d0: 71 6c 69 74 65 33 5f 62 69 6e 64 5f 76 61 6c 75  qlite3_bind_valu
94e0: 65 28 70 43 73 72 2d 3e 70 53 74 6d 74 2c 20 31  e(pCsr->pStmt, 1
94f0: 2c 20 61 70 56 61 6c 5b 30 5d 29 3b 0a 20 20 20  , apVal[0]);.   
9500: 20 20 20 7d 0a 20 20 20 20 20 20 72 63 20 3d 20     }.      rc = 
9510: 66 74 73 35 4e 65 78 74 4d 65 74 68 6f 64 28 70  fts5NextMethod(p
9520: 43 75 72 73 6f 72 29 3b 0a 20 20 20 20 7d 0a 20  Cursor);.    }. 
9530: 20 7d 0a 0a 20 20 70 54 61 62 2d 3e 70 43 6f 6e   }..  pTab->pCon
9540: 66 69 67 2d 3e 70 7a 45 72 72 6d 73 67 20 3d 20  fig->pzErrmsg = 
9550: 70 7a 45 72 72 6d 73 67 3b 0a 20 20 72 65 74 75  pzErrmsg;.  retu
9560: 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a  rn rc;.}../* .**
9570: 20 54 68 69 73 20 69 73 20 74 68 65 20 78 45 6f   This is the xEo
9580: 66 20 6d 65 74 68 6f 64 20 6f 66 20 74 68 65 20  f method of the 
9590: 76 69 72 74 75 61 6c 20 74 61 62 6c 65 2e 20 53  virtual table. S
95a0: 51 4c 69 74 65 20 63 61 6c 6c 73 20 74 68 69 73  QLite calls this
95b0: 20 0a 2a 2a 20 72 6f 75 74 69 6e 65 20 74 6f 20   .** routine to 
95c0: 66 69 6e 64 20 6f 75 74 20 69 66 20 69 74 20 68  find out if it h
95d0: 61 73 20 72 65 61 63 68 65 64 20 74 68 65 20 65  as reached the e
95e0: 6e 64 20 6f 66 20 61 20 72 65 73 75 6c 74 20 73  nd of a result s
95f0: 65 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  et..*/.static in
9600: 74 20 66 74 73 35 45 6f 66 4d 65 74 68 6f 64 28  t fts5EofMethod(
9610: 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72  sqlite3_vtab_cur
9620: 73 6f 72 20 2a 70 43 75 72 73 6f 72 29 7b 0a 20  sor *pCursor){. 
9630: 20 46 74 73 35 43 75 72 73 6f 72 20 2a 70 43 73   Fts5Cursor *pCs
9640: 72 20 3d 20 28 46 74 73 35 43 75 72 73 6f 72 2a  r = (Fts5Cursor*
9650: 29 70 43 75 72 73 6f 72 3b 0a 20 20 72 65 74 75  )pCursor;.  retu
9660: 72 6e 20 28 43 73 72 46 6c 61 67 54 65 73 74 28  rn (CsrFlagTest(
9670: 70 43 73 72 2c 20 46 54 53 35 43 53 52 5f 45 4f  pCsr, FTS5CSR_EO
9680: 46 29 20 3f 20 31 20 3a 20 30 29 3b 0a 7d 0a 0a  F) ? 1 : 0);.}..
9690: 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65  /*.** Return the
96a0: 20 72 6f 77 69 64 20 74 68 61 74 20 74 68 65 20   rowid that the 
96b0: 63 75 72 73 6f 72 20 63 75 72 72 65 6e 74 6c 79  cursor currently
96c0: 20 70 6f 69 6e 74 73 20 74 6f 2e 0a 2a 2f 0a 73   points to..*/.s
96d0: 74 61 74 69 63 20 69 36 34 20 66 74 73 35 43 75  tatic i64 fts5Cu
96e0: 72 73 6f 72 52 6f 77 69 64 28 46 74 73 35 43 75  rsorRowid(Fts5Cu
96f0: 72 73 6f 72 20 2a 70 43 73 72 29 7b 0a 20 20 61  rsor *pCsr){.  a
9700: 73 73 65 72 74 28 20 70 43 73 72 2d 3e 65 50 6c  ssert( pCsr->ePl
9710: 61 6e 3d 3d 46 54 53 35 5f 50 4c 41 4e 5f 4d 41  an==FTS5_PLAN_MA
9720: 54 43 48 20 0a 20 20 20 20 20 20 20 7c 7c 20 70  TCH .       || p
9730: 43 73 72 2d 3e 65 50 6c 61 6e 3d 3d 46 54 53 35  Csr->ePlan==FTS5
9740: 5f 50 4c 41 4e 5f 53 4f 52 54 45 44 5f 4d 41 54  _PLAN_SORTED_MAT
9750: 43 48 20 0a 20 20 20 20 20 20 20 7c 7c 20 70 43  CH .       || pC
9760: 73 72 2d 3e 65 50 6c 61 6e 3d 3d 46 54 53 35 5f  sr->ePlan==FTS5_
9770: 50 4c 41 4e 5f 53 4f 55 52 43 45 20 0a 20 20 29  PLAN_SOURCE .  )
9780: 3b 0a 20 20 69 66 28 20 70 43 73 72 2d 3e 70 53  ;.  if( pCsr->pS
9790: 6f 72 74 65 72 20 29 7b 0a 20 20 20 20 72 65 74  orter ){.    ret
97a0: 75 72 6e 20 70 43 73 72 2d 3e 70 53 6f 72 74 65  urn pCsr->pSorte
97b0: 72 2d 3e 69 52 6f 77 69 64 3b 0a 20 20 7d 65 6c  r->iRowid;.  }el
97c0: 73 65 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 73  se{.    return s
97d0: 71 6c 69 74 65 33 46 74 73 35 45 78 70 72 52 6f  qlite3Fts5ExprRo
97e0: 77 69 64 28 70 43 73 72 2d 3e 70 45 78 70 72 29  wid(pCsr->pExpr)
97f0: 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20  ;.  }.}../* .** 
9800: 54 68 69 73 20 69 73 20 74 68 65 20 78 52 6f 77  This is the xRow
9810: 69 64 20 6d 65 74 68 6f 64 2e 20 54 68 65 20 53  id method. The S
9820: 51 4c 69 74 65 20 63 6f 72 65 20 63 61 6c 6c 73  QLite core calls
9830: 20 74 68 69 73 20 72 6f 75 74 69 6e 65 20 74 6f   this routine to
9840: 0a 2a 2a 20 72 65 74 72 69 65 76 65 20 74 68 65  .** retrieve the
9850: 20 72 6f 77 69 64 20 66 6f 72 20 74 68 65 20 63   rowid for the c
9860: 75 72 72 65 6e 74 20 72 6f 77 20 6f 66 20 74 68  urrent row of th
9870: 65 20 72 65 73 75 6c 74 20 73 65 74 2e 20 66 74  e result set. ft
9880: 73 35 0a 2a 2a 20 65 78 70 6f 73 65 73 20 25 5f  s5.** exposes %_
9890: 63 6f 6e 74 65 6e 74 2e 64 6f 63 69 64 20 61 73  content.docid as
98a0: 20 74 68 65 20 72 6f 77 69 64 20 66 6f 72 20 74   the rowid for t
98b0: 68 65 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65  he virtual table
98c0: 2e 20 54 68 65 0a 2a 2a 20 72 6f 77 69 64 20 73  . The.** rowid s
98d0: 68 6f 75 6c 64 20 62 65 20 77 72 69 74 74 65 6e  hould be written
98e0: 20 74 6f 20 2a 70 52 6f 77 69 64 2e 0a 2a 2f 0a   to *pRowid..*/.
98f0: 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 52  static int fts5R
9900: 6f 77 69 64 4d 65 74 68 6f 64 28 73 71 6c 69 74  owidMethod(sqlit
9910: 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a  e3_vtab_cursor *
9920: 70 43 75 72 73 6f 72 2c 20 73 71 6c 69 74 65 5f  pCursor, sqlite_
9930: 69 6e 74 36 34 20 2a 70 52 6f 77 69 64 29 7b 0a  int64 *pRowid){.
9940: 20 20 46 74 73 35 43 75 72 73 6f 72 20 2a 70 43    Fts5Cursor *pC
9950: 73 72 20 3d 20 28 46 74 73 35 43 75 72 73 6f 72  sr = (Fts5Cursor
9960: 2a 29 70 43 75 72 73 6f 72 3b 0a 20 20 69 6e 74  *)pCursor;.  int
9970: 20 65 50 6c 61 6e 20 3d 20 70 43 73 72 2d 3e 65   ePlan = pCsr->e
9980: 50 6c 61 6e 3b 0a 20 20 0a 20 20 61 73 73 65 72  Plan;.  .  asser
9990: 74 28 20 43 73 72 46 6c 61 67 54 65 73 74 28 70  t( CsrFlagTest(p
99a0: 43 73 72 2c 20 46 54 53 35 43 53 52 5f 45 4f 46  Csr, FTS5CSR_EOF
99b0: 29 3d 3d 30 20 29 3b 0a 20 20 73 77 69 74 63 68  )==0 );.  switch
99c0: 28 20 65 50 6c 61 6e 20 29 7b 0a 20 20 20 20 63  ( ePlan ){.    c
99d0: 61 73 65 20 46 54 53 35 5f 50 4c 41 4e 5f 53 50  ase FTS5_PLAN_SP
99e0: 45 43 49 41 4c 3a 0a 20 20 20 20 20 20 2a 70 52  ECIAL:.      *pR
99f0: 6f 77 69 64 20 3d 20 30 3b 0a 20 20 20 20 20 20  owid = 0;.      
9a00: 62 72 65 61 6b 3b 0a 0a 20 20 20 20 63 61 73 65  break;..    case
9a10: 20 46 54 53 35 5f 50 4c 41 4e 5f 53 4f 55 52 43   FTS5_PLAN_SOURC
9a20: 45 3a 0a 20 20 20 20 63 61 73 65 20 46 54 53 35  E:.    case FTS5
9a30: 5f 50 4c 41 4e 5f 4d 41 54 43 48 3a 0a 20 20 20  _PLAN_MATCH:.   
9a40: 20 63 61 73 65 20 46 54 53 35 5f 50 4c 41 4e 5f   case FTS5_PLAN_
9a50: 53 4f 52 54 45 44 5f 4d 41 54 43 48 3a 0a 20 20  SORTED_MATCH:.  
9a60: 20 20 20 20 2a 70 52 6f 77 69 64 20 3d 20 66 74      *pRowid = ft
9a70: 73 35 43 75 72 73 6f 72 52 6f 77 69 64 28 70 43  s5CursorRowid(pC
9a80: 73 72 29 3b 0a 20 20 20 20 20 20 62 72 65 61 6b  sr);.      break
9a90: 3b 0a 0a 20 20 20 20 64 65 66 61 75 6c 74 3a 0a  ;..    default:.
9aa0: 20 20 20 20 20 20 2a 70 52 6f 77 69 64 20 3d 20        *pRowid = 
9ab0: 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 69  sqlite3_column_i
9ac0: 6e 74 36 34 28 70 43 73 72 2d 3e 70 53 74 6d 74  nt64(pCsr->pStmt
9ad0: 2c 20 30 29 3b 0a 20 20 20 20 20 20 62 72 65 61  , 0);.      brea
9ae0: 6b 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e  k;.  }..  return
9af0: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f   SQLITE_OK;.}../
9b00: 2a 0a 2a 2a 20 49 66 20 74 68 65 20 63 75 72 73  *.** If the curs
9b10: 6f 72 20 72 65 71 75 69 72 65 73 20 73 65 65 6b  or requires seek
9b20: 69 6e 67 20 28 62 53 65 65 6b 52 65 71 75 69 72  ing (bSeekRequir
9b30: 65 64 20 66 6c 61 67 20 69 73 20 73 65 74 29 2c  ed flag is set),
9b40: 20 73 65 65 6b 20 69 74 2e 0a 2a 2a 20 52 65 74   seek it..** Ret
9b50: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 20 69 66  urn SQLITE_OK if
9b60: 20 6e 6f 20 65 72 72 6f 72 20 6f 63 63 75 72 73   no error occurs
9b70: 2c 20 6f 72 20 61 6e 20 53 51 4c 69 74 65 20 65  , or an SQLite e
9b80: 72 72 6f 72 20 63 6f 64 65 20 6f 74 68 65 72 77  rror code otherw
9b90: 69 73 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ise..*/.static i
9ba0: 6e 74 20 66 74 73 35 53 65 65 6b 43 75 72 73 6f  nt fts5SeekCurso
9bb0: 72 28 46 74 73 35 43 75 72 73 6f 72 20 2a 70 43  r(Fts5Cursor *pC
9bc0: 73 72 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20  sr){.  int rc = 
9bd0: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20 2f 2a  SQLITE_OK;..  /*
9be0: 20 49 66 20 74 68 65 20 63 75 72 73 6f 72 20 64   If the cursor d
9bf0: 6f 65 73 20 6e 6f 74 20 79 65 74 20 68 61 76 65  oes not yet have
9c00: 20 61 20 73 74 61 74 65 6d 65 6e 74 20 68 61 6e   a statement han
9c10: 64 6c 65 2c 20 6f 62 74 61 69 6e 20 6f 6e 65 20  dle, obtain one 
9c20: 6e 6f 77 2e 20 2a 2f 20 0a 20 20 69 66 28 20 70  now. */ .  if( p
9c30: 43 73 72 2d 3e 70 53 74 6d 74 3d 3d 30 20 29 7b  Csr->pStmt==0 ){
9c40: 0a 20 20 20 20 46 74 73 35 54 61 62 6c 65 20 2a  .    Fts5Table *
9c50: 70 54 61 62 20 3d 20 28 46 74 73 35 54 61 62 6c  pTab = (Fts5Tabl
9c60: 65 2a 29 28 70 43 73 72 2d 3e 62 61 73 65 2e 70  e*)(pCsr->base.p
9c70: 56 74 61 62 29 3b 0a 20 20 20 20 69 6e 74 20 65  Vtab);.    int e
9c80: 53 74 6d 74 20 3d 20 66 74 73 35 53 74 6d 74 54  Stmt = fts5StmtT
9c90: 79 70 65 28 70 43 73 72 29 3b 0a 20 20 20 20 72  ype(pCsr);.    r
9ca0: 63 20 3d 20 73 71 6c 69 74 65 33 46 74 73 35 53  c = sqlite3Fts5S
9cb0: 74 6f 72 61 67 65 53 74 6d 74 28 0a 20 20 20 20  torageStmt(.    
9cc0: 20 20 20 20 70 54 61 62 2d 3e 70 53 74 6f 72 61      pTab->pStora
9cd0: 67 65 2c 20 65 53 74 6d 74 2c 20 26 70 43 73 72  ge, eStmt, &pCsr
9ce0: 2d 3e 70 53 74 6d 74 2c 20 26 70 54 61 62 2d 3e  ->pStmt, &pTab->
9cf0: 62 61 73 65 2e 7a 45 72 72 4d 73 67 0a 20 20 20  base.zErrMsg.   
9d00: 20 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20   );.    assert( 
9d10: 43 73 72 46 6c 61 67 54 65 73 74 28 70 43 73 72  CsrFlagTest(pCsr
9d20: 2c 20 46 54 53 35 43 53 52 5f 52 45 51 55 49 52  , FTS5CSR_REQUIR
9d30: 45 5f 43 4f 4e 54 45 4e 54 29 20 29 3b 0a 20 20  E_CONTENT) );.  
9d40: 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  }..  if( rc==SQL
9d50: 49 54 45 5f 4f 4b 20 26 26 20 43 73 72 46 6c 61  ITE_OK && CsrFla
9d60: 67 54 65 73 74 28 70 43 73 72 2c 20 46 54 53 35  gTest(pCsr, FTS5
9d70: 43 53 52 5f 52 45 51 55 49 52 45 5f 43 4f 4e 54  CSR_REQUIRE_CONT
9d80: 45 4e 54 29 20 29 7b 0a 20 20 20 20 61 73 73 65  ENT) ){.    asse
9d90: 72 74 28 20 70 43 73 72 2d 3e 70 45 78 70 72 20  rt( pCsr->pExpr 
9da0: 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 72  );.    sqlite3_r
9db0: 65 73 65 74 28 70 43 73 72 2d 3e 70 53 74 6d 74  eset(pCsr->pStmt
9dc0: 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 62  );.    sqlite3_b
9dd0: 69 6e 64 5f 69 6e 74 36 34 28 70 43 73 72 2d 3e  ind_int64(pCsr->
9de0: 70 53 74 6d 74 2c 20 31 2c 20 66 74 73 35 43 75  pStmt, 1, fts5Cu
9df0: 72 73 6f 72 52 6f 77 69 64 28 70 43 73 72 29 29  rsorRowid(pCsr))
9e00: 3b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74  ;.    rc = sqlit
9e10: 65 33 5f 73 74 65 70 28 70 43 73 72 2d 3e 70 53  e3_step(pCsr->pS
9e20: 74 6d 74 29 3b 0a 20 20 20 20 69 66 28 20 72 63  tmt);.    if( rc
9e30: 3d 3d 53 51 4c 49 54 45 5f 52 4f 57 20 29 7b 0a  ==SQLITE_ROW ){.
9e40: 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54        rc = SQLIT
9e50: 45 5f 4f 4b 3b 0a 20 20 20 20 20 20 43 73 72 46  E_OK;.      CsrF
9e60: 6c 61 67 43 6c 65 61 72 28 70 43 73 72 2c 20 46  lagClear(pCsr, F
9e70: 54 53 35 43 53 52 5f 52 45 51 55 49 52 45 5f 43  TS5CSR_REQUIRE_C
9e80: 4f 4e 54 45 4e 54 29 3b 0a 20 20 20 20 7d 65 6c  ONTENT);.    }el
9e90: 73 65 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 73  se{.      rc = s
9ea0: 71 6c 69 74 65 33 5f 72 65 73 65 74 28 70 43 73  qlite3_reset(pCs
9eb0: 72 2d 3e 70 53 74 6d 74 29 3b 0a 20 20 20 20 20  r->pStmt);.     
9ec0: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
9ed0: 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 72 63  OK ){.        rc
9ee0: 20 3d 20 46 54 53 35 5f 43 4f 52 52 55 50 54 3b   = FTS5_CORRUPT;
9ef0: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
9f00: 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a   }.  return rc;.
9f10: 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 66  }..static void f
9f20: 74 73 35 53 65 74 56 74 61 62 45 72 72 6f 72 28  ts5SetVtabError(
9f30: 46 74 73 35 54 61 62 6c 65 20 2a 70 2c 20 63 6f  Fts5Table *p, co
9f40: 6e 73 74 20 63 68 61 72 20 2a 7a 46 6f 72 6d 61  nst char *zForma
9f50: 74 2c 20 2e 2e 2e 29 7b 0a 20 20 76 61 5f 6c 69  t, ...){.  va_li
9f60: 73 74 20 61 70 3b 20 20 20 20 20 20 20 20 20 20  st ap;          
9f70: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 2e 2e             /* ..
9f80: 2e 20 70 72 69 6e 74 66 20 61 72 67 75 6d 65 6e  . printf argumen
9f90: 74 73 20 2a 2f 0a 20 20 76 61 5f 73 74 61 72 74  ts */.  va_start
9fa0: 28 61 70 2c 20 7a 46 6f 72 6d 61 74 29 3b 0a 20  (ap, zFormat);. 
9fb0: 20 61 73 73 65 72 74 28 20 70 2d 3e 62 61 73 65   assert( p->base
9fc0: 2e 7a 45 72 72 4d 73 67 3d 3d 30 20 29 3b 0a 20  .zErrMsg==0 );. 
9fd0: 20 70 2d 3e 62 61 73 65 2e 7a 45 72 72 4d 73 67   p->base.zErrMsg
9fe0: 20 3d 20 73 71 6c 69 74 65 33 5f 76 6d 70 72 69   = sqlite3_vmpri
9ff0: 6e 74 66 28 7a 46 6f 72 6d 61 74 2c 20 61 70 29  ntf(zFormat, ap)
a000: 3b 0a 20 20 76 61 5f 65 6e 64 28 61 70 29 3b 0a  ;.  va_end(ap);.
a010: 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75  }../*.** This fu
a020: 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64  nction is called
a030: 20 74 6f 20 68 61 6e 64 6c 65 20 61 6e 20 46 54   to handle an FT
a040: 53 20 49 4e 53 45 52 54 20 63 6f 6d 6d 61 6e 64  S INSERT command
a050: 2e 20 49 6e 20 6f 74 68 65 72 20 77 6f 72 64 73  . In other words
a060: 2c 0a 2a 2a 20 61 6e 20 49 4e 53 45 52 54 20 73  ,.** an INSERT s
a070: 74 61 74 65 6d 65 6e 74 20 6f 66 20 74 68 65 20  tatement of the 
a080: 66 6f 72 6d 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20  form:.**.**     
a090: 49 4e 53 45 52 54 20 49 4e 54 4f 20 66 74 73 28  INSERT INTO fts(
a0a0: 66 74 73 29 20 56 41 4c 55 45 53 28 24 70 43 6d  fts) VALUES($pCm
a0b0: 64 29 0a 2a 2a 20 20 20 20 20 49 4e 53 45 52 54  d).**     INSERT
a0c0: 20 49 4e 54 4f 20 66 74 73 28 66 74 73 2c 20 72   INTO fts(fts, r
a0d0: 61 6e 6b 29 20 56 41 4c 55 45 53 28 24 70 43 6d  ank) VALUES($pCm
a0e0: 64 2c 20 24 70 56 61 6c 29 0a 2a 2a 0a 2a 2a 20  d, $pVal).**.** 
a0f0: 41 72 67 75 6d 65 6e 74 20 70 56 61 6c 20 69 73  Argument pVal is
a100: 20 74 68 65 20 76 61 6c 75 65 20 61 73 73 69 67   the value assig
a110: 6e 65 64 20 74 6f 20 63 6f 6c 75 6d 6e 20 22 66  ned to column "f
a120: 74 73 22 20 62 79 20 74 68 65 20 49 4e 53 45 52  ts" by the INSER
a130: 54 20 0a 2a 2a 20 73 74 61 74 65 6d 65 6e 74 2e  T .** statement.
a140: 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 72   This function r
a150: 65 74 75 72 6e 73 20 53 51 4c 49 54 45 5f 4f 4b  eturns SQLITE_OK
a160: 20 69 66 20 73 75 63 63 65 73 73 66 75 6c 2c 20   if successful, 
a170: 6f 72 20 61 6e 20 53 51 4c 69 74 65 0a 2a 2a 20  or an SQLite.** 
a180: 65 72 72 6f 72 20 63 6f 64 65 20 69 66 20 61 6e  error code if an
a190: 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2e 0a 2a   error occurs..*
a1a0: 2a 0a 2a 2a 20 54 68 65 20 63 6f 6d 6d 61 6e 64  *.** The command
a1b0: 73 20 69 6d 70 6c 65 6d 65 6e 74 65 64 20 62 79  s implemented by
a1c0: 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 61   this function a
a1d0: 72 65 20 64 6f 63 75 6d 65 6e 74 65 64 20 69 6e  re documented in
a1e0: 20 74 68 65 20 22 53 70 65 63 69 61 6c 0a 2a 2a   the "Special.**
a1f0: 20 49 4e 53 45 52 54 20 44 69 72 65 63 74 69 76   INSERT Directiv
a200: 65 73 22 20 73 65 63 74 69 6f 6e 20 6f 66 20 74  es" section of t
a210: 68 65 20 64 6f 63 75 6d 65 6e 74 61 74 69 6f 6e  he documentation
a220: 2e 20 49 74 20 73 68 6f 75 6c 64 20 62 65 20 75  . It should be u
a230: 70 64 61 74 65 64 20 69 66 0a 2a 2a 20 6d 6f 72  pdated if.** mor
a240: 65 20 63 6f 6d 6d 61 6e 64 73 20 61 72 65 20 61  e commands are a
a250: 64 64 65 64 20 74 6f 20 74 68 69 73 20 66 75 6e  dded to this fun
a260: 63 74 69 6f 6e 2e 0a 2a 2f 0a 73 74 61 74 69 63  ction..*/.static
a270: 20 69 6e 74 20 66 74 73 35 53 70 65 63 69 61 6c   int fts5Special
a280: 49 6e 73 65 72 74 28 0a 20 20 46 74 73 35 54 61  Insert(.  Fts5Ta
a290: 62 6c 65 20 2a 70 54 61 62 2c 20 20 20 20 20 20  ble *pTab,      
a2a0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 74 73            /* Fts
a2b0: 35 20 74 61 62 6c 65 20 6f 62 6a 65 63 74 20 2a  5 table object *
a2c0: 2f 0a 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75  /.  sqlite3_valu
a2d0: 65 20 2a 70 43 6d 64 2c 20 20 20 20 20 20 20 20  e *pCmd,        
a2e0: 20 20 20 20 2f 2a 20 56 61 6c 75 65 20 69 6e 73      /* Value ins
a2f0: 65 72 74 65 64 20 69 6e 74 6f 20 73 70 65 63 69  erted into speci
a300: 61 6c 20 63 6f 6c 75 6d 6e 20 2a 2f 0a 20 20 73  al column */.  s
a310: 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 70 56  qlite3_value *pV
a320: 61 6c 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  al             /
a330: 2a 20 56 61 6c 75 65 20 69 6e 73 65 72 74 65 64  * Value inserted
a340: 20 69 6e 74 6f 20 72 61 6e 6b 20 63 6f 6c 75 6d   into rank colum
a350: 6e 20 2a 2f 0a 29 7b 0a 20 20 46 74 73 35 43 6f  n */.){.  Fts5Co
a360: 6e 66 69 67 20 2a 70 43 6f 6e 66 69 67 20 3d 20  nfig *pConfig = 
a370: 70 54 61 62 2d 3e 70 43 6f 6e 66 69 67 3b 0a 20  pTab->pConfig;. 
a380: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 20 3d   const char *z =
a390: 20 28 63 6f 6e 73 74 20 63 68 61 72 2a 29 73 71   (const char*)sq
a3a0: 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 65 78 74  lite3_value_text
a3b0: 28 70 43 6d 64 29 3b 0a 20 20 69 6e 74 20 72 63  (pCmd);.  int rc
a3c0: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20   = SQLITE_OK;.  
a3d0: 69 6e 74 20 62 45 72 72 6f 72 20 3d 20 30 3b 0a  int bError = 0;.
a3e0: 0a 20 20 69 66 28 20 30 3d 3d 73 71 6c 69 74 65  .  if( 0==sqlite
a3f0: 33 5f 73 74 72 69 63 6d 70 28 22 64 65 6c 65 74  3_stricmp("delet
a400: 65 2d 61 6c 6c 22 2c 20 7a 29 20 29 7b 0a 20 20  e-all", z) ){.  
a410: 20 20 69 66 28 20 70 43 6f 6e 66 69 67 2d 3e 65    if( pConfig->e
a420: 43 6f 6e 74 65 6e 74 3d 3d 46 54 53 35 5f 43 4f  Content==FTS5_CO
a430: 4e 54 45 4e 54 5f 4e 4f 52 4d 41 4c 20 29 7b 0a  NTENT_NORMAL ){.
a440: 20 20 20 20 20 20 66 74 73 35 53 65 74 56 74 61        fts5SetVta
a450: 62 45 72 72 6f 72 28 70 54 61 62 2c 20 0a 20 20  bError(pTab, .  
a460: 20 20 20 20 20 20 20 20 22 27 64 65 6c 65 74 65          "'delete
a470: 2d 61 6c 6c 27 20 6d 61 79 20 6f 6e 6c 79 20 62  -all' may only b
a480: 65 20 75 73 65 64 20 77 69 74 68 20 61 20 22 0a  e used with a ".
a490: 20 20 20 20 20 20 20 20 20 20 22 63 6f 6e 74 65            "conte
a4a0: 6e 74 6c 65 73 73 20 6f 72 20 65 78 74 65 72 6e  ntless or extern
a4b0: 61 6c 20 63 6f 6e 74 65 6e 74 20 66 74 73 35 20  al content fts5 
a4c0: 74 61 62 6c 65 22 0a 20 20 20 20 20 20 29 3b 0a  table".      );.
a4d0: 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54        rc = SQLIT
a4e0: 45 5f 45 52 52 4f 52 3b 0a 20 20 20 20 7d 65 6c  E_ERROR;.    }el
a4f0: 73 65 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 73  se{.      rc = s
a500: 71 6c 69 74 65 33 46 74 73 35 53 74 6f 72 61 67  qlite3Fts5Storag
a510: 65 44 65 6c 65 74 65 41 6c 6c 28 70 54 61 62 2d  eDeleteAll(pTab-
a520: 3e 70 53 74 6f 72 61 67 65 29 3b 0a 20 20 20 20  >pStorage);.    
a530: 7d 0a 20 20 7d 65 6c 73 65 20 69 66 28 20 30 3d  }.  }else if( 0=
a540: 3d 73 71 6c 69 74 65 33 5f 73 74 72 69 63 6d 70  =sqlite3_stricmp
a550: 28 22 72 65 62 75 69 6c 64 22 2c 20 7a 29 20 29  ("rebuild", z) )
a560: 7b 0a 20 20 20 20 69 66 28 20 70 43 6f 6e 66 69  {.    if( pConfi
a570: 67 2d 3e 65 43 6f 6e 74 65 6e 74 3d 3d 46 54 53  g->eContent==FTS
a580: 35 5f 43 4f 4e 54 45 4e 54 5f 4e 4f 4e 45 20 29  5_CONTENT_NONE )
a590: 7b 0a 20 20 20 20 20 20 66 74 73 35 53 65 74 56  {.      fts5SetV
a5a0: 74 61 62 45 72 72 6f 72 28 70 54 61 62 2c 20 0a  tabError(pTab, .
a5b0: 20 20 20 20 20 20 20 20 20 20 22 27 72 65 62 75            "'rebu
a5c0: 69 6c 64 27 20 6d 61 79 20 6e 6f 74 20 62 65 20  ild' may not be 
a5d0: 75 73 65 64 20 77 69 74 68 20 61 20 63 6f 6e 74  used with a cont
a5e0: 65 6e 74 6c 65 73 73 20 66 74 73 35 20 74 61 62  entless fts5 tab
a5f0: 6c 65 22 0a 20 20 20 20 20 20 29 3b 0a 20 20 20  le".      );.   
a600: 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 45     rc = SQLITE_E
a610: 52 52 4f 52 3b 0a 20 20 20 20 7d 65 6c 73 65 7b  RROR;.    }else{
a620: 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69  .      rc = sqli
a630: 74 65 33 46 74 73 35 53 74 6f 72 61 67 65 52 65  te3Fts5StorageRe
a640: 62 75 69 6c 64 28 70 54 61 62 2d 3e 70 53 74 6f  build(pTab->pSto
a650: 72 61 67 65 29 3b 0a 20 20 20 20 7d 0a 20 20 7d  rage);.    }.  }
a660: 65 6c 73 65 20 69 66 28 20 30 3d 3d 73 71 6c 69  else if( 0==sqli
a670: 74 65 33 5f 73 74 72 69 63 6d 70 28 22 6f 70 74  te3_stricmp("opt
a680: 69 6d 69 7a 65 22 2c 20 7a 29 20 29 7b 0a 20 20  imize", z) ){.  
a690: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 46 74    rc = sqlite3Ft
a6a0: 73 35 53 74 6f 72 61 67 65 4f 70 74 69 6d 69 7a  s5StorageOptimiz
a6b0: 65 28 70 54 61 62 2d 3e 70 53 74 6f 72 61 67 65  e(pTab->pStorage
a6c0: 29 3b 0a 20 20 7d 65 6c 73 65 20 69 66 28 20 30  );.  }else if( 0
a6d0: 3d 3d 73 71 6c 69 74 65 33 5f 73 74 72 69 63 6d  ==sqlite3_stricm
a6e0: 70 28 22 6d 65 72 67 65 22 2c 20 7a 29 20 29 7b  p("merge", z) ){
a6f0: 0a 20 20 20 20 69 6e 74 20 6e 4d 65 72 67 65 20  .    int nMerge 
a700: 3d 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f  = sqlite3_value_
a710: 69 6e 74 28 70 56 61 6c 29 3b 0a 20 20 20 20 72  int(pVal);.    r
a720: 63 20 3d 20 73 71 6c 69 74 65 33 46 74 73 35 53  c = sqlite3Fts5S
a730: 74 6f 72 61 67 65 4d 65 72 67 65 28 70 54 61 62  torageMerge(pTab
a740: 2d 3e 70 53 74 6f 72 61 67 65 2c 20 6e 4d 65 72  ->pStorage, nMer
a750: 67 65 29 3b 0a 20 20 7d 65 6c 73 65 20 69 66 28  ge);.  }else if(
a760: 20 30 3d 3d 73 71 6c 69 74 65 33 5f 73 74 72 69   0==sqlite3_stri
a770: 63 6d 70 28 22 69 6e 74 65 67 72 69 74 79 2d 63  cmp("integrity-c
a780: 68 65 63 6b 22 2c 20 7a 29 20 29 7b 0a 20 20 20  heck", z) ){.   
a790: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 46 74 73   rc = sqlite3Fts
a7a0: 35 53 74 6f 72 61 67 65 49 6e 74 65 67 72 69 74  5StorageIntegrit
a7b0: 79 28 70 54 61 62 2d 3e 70 53 74 6f 72 61 67 65  y(pTab->pStorage
a7c0: 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  );.  }else{.    
a7d0: 72 63 20 3d 20 73 71 6c 69 74 65 33 46 74 73 35  rc = sqlite3Fts5
a7e0: 49 6e 64 65 78 4c 6f 61 64 43 6f 6e 66 69 67 28  IndexLoadConfig(
a7f0: 70 54 61 62 2d 3e 70 49 6e 64 65 78 29 3b 0a 20  pTab->pIndex);. 
a800: 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
a810: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72 63  E_OK ){.      rc
a820: 20 3d 20 73 71 6c 69 74 65 33 46 74 73 35 43 6f   = sqlite3Fts5Co
a830: 6e 66 69 67 53 65 74 56 61 6c 75 65 28 70 54 61  nfigSetValue(pTa
a840: 62 2d 3e 70 43 6f 6e 66 69 67 2c 20 7a 2c 20 70  b->pConfig, z, p
a850: 56 61 6c 2c 20 26 62 45 72 72 6f 72 29 3b 0a 20  Val, &bError);. 
a860: 20 20 20 7d 0a 20 20 20 20 69 66 28 20 72 63 3d     }.    if( rc=
a870: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
a880: 20 20 20 20 69 66 28 20 62 45 72 72 6f 72 20 29      if( bError )
a890: 7b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 53  {.        rc = S
a8a0: 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 20  QLITE_ERROR;.   
a8b0: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
a8c0: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 46 74    rc = sqlite3Ft
a8d0: 73 35 53 74 6f 72 61 67 65 43 6f 6e 66 69 67 56  s5StorageConfigV
a8e0: 61 6c 75 65 28 70 54 61 62 2d 3e 70 53 74 6f 72  alue(pTab->pStor
a8f0: 61 67 65 2c 20 7a 2c 20 70 56 61 6c 2c 20 30 29  age, z, pVal, 0)
a900: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  ;.      }.    }.
a910: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b    }.  return rc;
a920: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 66  .}..static int f
a930: 74 73 35 53 70 65 63 69 61 6c 44 65 6c 65 74 65  ts5SpecialDelete
a940: 28 0a 20 20 46 74 73 35 54 61 62 6c 65 20 2a 70  (.  Fts5Table *p
a950: 54 61 62 2c 20 0a 20 20 73 71 6c 69 74 65 33 5f  Tab, .  sqlite3_
a960: 76 61 6c 75 65 20 2a 2a 61 70 56 61 6c 2c 20 0a  value **apVal, .
a970: 20 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20    sqlite3_int64 
a980: 2a 70 69 52 6f 77 69 64 0a 29 7b 0a 20 20 69 6e  *piRowid.){.  in
a990: 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b  t rc = SQLITE_OK
a9a0: 3b 0a 20 20 69 6e 74 20 65 54 79 70 65 31 20 3d  ;.  int eType1 =
a9b0: 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74   sqlite3_value_t
a9c0: 79 70 65 28 61 70 56 61 6c 5b 31 5d 29 3b 0a 20  ype(apVal[1]);. 
a9d0: 20 69 66 28 20 65 54 79 70 65 31 3d 3d 53 51 4c   if( eType1==SQL
a9e0: 49 54 45 5f 49 4e 54 45 47 45 52 20 29 7b 0a 20  ITE_INTEGER ){. 
a9f0: 20 20 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34     sqlite3_int64
aa00: 20 69 44 65 6c 20 3d 20 73 71 6c 69 74 65 33 5f   iDel = sqlite3_
aa10: 76 61 6c 75 65 5f 69 6e 74 36 34 28 61 70 56 61  value_int64(apVa
aa20: 6c 5b 31 5d 29 3b 0a 20 20 20 20 72 63 20 3d 20  l[1]);.    rc = 
aa30: 73 71 6c 69 74 65 33 46 74 73 35 53 74 6f 72 61  sqlite3Fts5Stora
aa40: 67 65 53 70 65 63 69 61 6c 44 65 6c 65 74 65 28  geSpecialDelete(
aa50: 70 54 61 62 2d 3e 70 53 74 6f 72 61 67 65 2c 20  pTab->pStorage, 
aa60: 69 44 65 6c 2c 20 26 61 70 56 61 6c 5b 32 5d 29  iDel, &apVal[2])
aa70: 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72  ;.  }.  return r
aa80: 63 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 54 68 69  c;.}../* .** Thi
aa90: 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 74 68  s function is th
aaa0: 65 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e  e implementation
aab0: 20 6f 66 20 74 68 65 20 78 55 70 64 61 74 65 20   of the xUpdate 
aac0: 63 61 6c 6c 62 61 63 6b 20 75 73 65 64 20 62 79  callback used by
aad0: 20 0a 2a 2a 20 46 54 53 33 20 76 69 72 74 75 61   .** FTS3 virtua
aae0: 6c 20 74 61 62 6c 65 73 2e 20 49 74 20 69 73 20  l tables. It is 
aaf0: 69 6e 76 6f 6b 65 64 20 62 79 20 53 51 4c 69 74  invoked by SQLit
ab00: 65 20 65 61 63 68 20 74 69 6d 65 20 61 20 72 6f  e each time a ro
ab10: 77 20 69 73 20 74 6f 20 62 65 0a 2a 2a 20 69 6e  w is to be.** in
ab20: 73 65 72 74 65 64 2c 20 75 70 64 61 74 65 64 20  serted, updated 
ab30: 6f 72 20 64 65 6c 65 74 65 64 2e 0a 2a 2f 0a 73  or deleted..*/.s
ab40: 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 55 70  tatic int fts5Up
ab50: 64 61 74 65 4d 65 74 68 6f 64 28 0a 20 20 73 71  dateMethod(.  sq
ab60: 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56 74 61  lite3_vtab *pVta
ab70: 62 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  b,            /*
ab80: 20 56 69 72 74 75 61 6c 20 74 61 62 6c 65 20 68   Virtual table h
ab90: 61 6e 64 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 6e  andle */.  int n
aba0: 41 72 67 2c 20 20 20 20 20 20 20 20 20 20 20 20  Arg,            
abb0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69             /* Si
abc0: 7a 65 20 6f 66 20 61 72 67 75 6d 65 6e 74 20 61  ze of argument a
abd0: 72 72 61 79 20 2a 2f 0a 20 20 73 71 6c 69 74 65  rray */.  sqlite
abe0: 33 5f 76 61 6c 75 65 20 2a 2a 61 70 56 61 6c 2c  3_value **apVal,
abf0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 41 72 72            /* Arr
ac00: 61 79 20 6f 66 20 61 72 67 75 6d 65 6e 74 73 20  ay of arguments 
ac10: 2a 2f 0a 20 20 73 71 6c 69 74 65 5f 69 6e 74 36  */.  sqlite_int6
ac20: 34 20 2a 70 52 6f 77 69 64 20 20 20 20 20 20 20  4 *pRowid       
ac30: 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 54 68 65       /* OUT: The
ac40: 20 61 66 66 65 63 74 65 64 20 28 6f 72 20 65 66   affected (or ef
ac50: 66 65 63 74 65 64 29 20 72 6f 77 69 64 20 2a 2f  fected) rowid */
ac60: 0a 29 7b 0a 20 20 46 74 73 35 54 61 62 6c 65 20  .){.  Fts5Table 
ac70: 2a 70 54 61 62 20 3d 20 28 46 74 73 35 54 61 62  *pTab = (Fts5Tab
ac80: 6c 65 2a 29 70 56 74 61 62 3b 0a 20 20 46 74 73  le*)pVtab;.  Fts
ac90: 35 43 6f 6e 66 69 67 20 2a 70 43 6f 6e 66 69 67  5Config *pConfig
aca0: 20 3d 20 70 54 61 62 2d 3e 70 43 6f 6e 66 69 67   = pTab->pConfig
acb0: 3b 0a 20 20 69 6e 74 20 65 54 79 70 65 30 3b 20  ;.  int eType0; 
acc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
acd0: 20 20 20 20 2f 2a 20 76 61 6c 75 65 5f 74 79 70      /* value_typ
ace0: 65 28 29 20 6f 66 20 61 70 56 61 6c 5b 30 5d 20  e() of apVal[0] 
acf0: 2a 2f 0a 20 20 69 6e 74 20 65 43 6f 6e 66 6c 69  */.  int eConfli
ad00: 63 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ct;             
ad10: 20 20 20 20 20 2f 2a 20 4f 4e 20 43 4f 4e 46 4c       /* ON CONFL
ad20: 49 43 54 20 66 6f 72 20 74 68 69 73 20 44 4d 4c  ICT for this DML
ad30: 20 2a 2f 0a 20 20 69 6e 74 20 72 63 20 3d 20 53   */.  int rc = S
ad40: 51 4c 49 54 45 5f 4f 4b 3b 20 20 20 20 20 20 20  QLITE_OK;       
ad50: 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20        /* Return 
ad60: 63 6f 64 65 20 2a 2f 0a 0a 20 20 2f 2a 20 41 20  code */..  /* A 
ad70: 74 72 61 6e 73 61 63 74 69 6f 6e 20 6d 75 73 74  transaction must
ad80: 20 62 65 20 6f 70 65 6e 20 77 68 65 6e 20 74 68   be open when th
ad90: 69 73 20 69 73 20 63 61 6c 6c 65 64 2e 20 2a 2f  is is called. */
ada0: 0a 20 20 61 73 73 65 72 74 28 20 70 54 61 62 2d  .  assert( pTab-
adb0: 3e 74 73 2e 65 53 74 61 74 65 3d 3d 31 20 29 3b  >ts.eState==1 );
adc0: 0a 0a 20 20 61 73 73 65 72 74 28 20 70 54 61 62  ..  assert( pTab
add0: 2d 3e 70 43 6f 6e 66 69 67 2d 3e 70 7a 45 72 72  ->pConfig->pzErr
ade0: 6d 73 67 3d 3d 30 20 29 3b 0a 20 20 70 54 61 62  msg==0 );.  pTab
adf0: 2d 3e 70 43 6f 6e 66 69 67 2d 3e 70 7a 45 72 72  ->pConfig->pzErr
ae00: 6d 73 67 20 3d 20 26 70 54 61 62 2d 3e 62 61 73  msg = &pTab->bas
ae10: 65 2e 7a 45 72 72 4d 73 67 3b 0a 0a 20 20 2f 2a  e.zErrMsg;..  /*
ae20: 20 41 20 64 65 6c 65 74 65 20 73 70 65 63 69 66   A delete specif
ae30: 69 65 73 20 61 20 73 69 6e 67 6c 65 20 61 72 67  ies a single arg
ae40: 75 6d 65 6e 74 20 2d 20 74 68 65 20 72 6f 77 69  ument - the rowi
ae50: 64 20 6f 66 20 74 68 65 20 72 6f 77 20 74 6f 20  d of the row to 
ae60: 72 65 6d 6f 76 65 2e 0a 20 20 2a 2a 20 55 70 64  remove..  ** Upd
ae70: 61 74 65 20 61 6e 64 20 69 6e 73 65 72 74 20 6f  ate and insert o
ae80: 70 65 72 61 74 69 6f 6e 73 20 70 61 73 73 3a 0a  perations pass:.
ae90: 20 20 2a 2a 0a 20 20 2a 2a 20 20 20 31 2e 20 54    **.  **   1. T
aea0: 68 65 20 22 6f 6c 64 22 20 72 6f 77 69 64 2c 20  he "old" rowid, 
aeb0: 6f 72 20 4e 55 4c 4c 2e 0a 20 20 2a 2a 20 20 20  or NULL..  **   
aec0: 32 2e 20 54 68 65 20 22 6e 65 77 22 20 72 6f 77  2. The "new" row
aed0: 69 64 2e 0a 20 20 2a 2a 20 20 20 33 2e 20 56 61  id..  **   3. Va
aee0: 6c 75 65 73 20 66 6f 72 20 65 61 63 68 20 6f 66  lues for each of
aef0: 20 74 68 65 20 6e 43 6f 6c 20 6d 61 74 63 68 61   the nCol matcha
af00: 62 6c 65 20 63 6f 6c 75 6d 6e 73 2e 0a 20 20 2a  ble columns..  *
af10: 2a 20 20 20 34 2e 20 56 61 6c 75 65 73 20 66 6f  *   4. Values fo
af20: 72 20 74 68 65 20 74 77 6f 20 68 69 64 64 65 6e  r the two hidden
af30: 20 63 6f 6c 75 6d 6e 73 20 28 3c 74 61 62 6c 65   columns (<table
af40: 6e 61 6d 65 3e 20 61 6e 64 20 22 72 61 6e 6b 22  name> and "rank"
af50: 29 2e 0a 20 20 2a 2f 0a 0a 20 20 65 54 79 70 65  )..  */..  eType
af60: 30 20 3d 20 73 71 6c 69 74 65 33 5f 76 61 6c 75  0 = sqlite3_valu
af70: 65 5f 74 79 70 65 28 61 70 56 61 6c 5b 30 5d 29  e_type(apVal[0])
af80: 3b 0a 20 20 65 43 6f 6e 66 6c 69 63 74 20 3d 20  ;.  eConflict = 
af90: 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 6f 6e 5f  sqlite3_vtab_on_
afa0: 63 6f 6e 66 6c 69 63 74 28 70 43 6f 6e 66 69 67  conflict(pConfig
afb0: 2d 3e 64 62 29 3b 0a 0a 20 20 61 73 73 65 72 74  ->db);..  assert
afc0: 28 20 65 54 79 70 65 30 3d 3d 53 51 4c 49 54 45  ( eType0==SQLITE
afd0: 5f 49 4e 54 45 47 45 52 20 7c 7c 20 65 54 79 70  _INTEGER || eTyp
afe0: 65 30 3d 3d 53 51 4c 49 54 45 5f 4e 55 4c 4c 20  e0==SQLITE_NULL 
aff0: 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 56 74  );.  assert( pVt
b000: 61 62 2d 3e 7a 45 72 72 4d 73 67 3d 3d 30 20 29  ab->zErrMsg==0 )
b010: 3b 0a 20 20 61 73 73 65 72 74 28 20 28 6e 41 72  ;.  assert( (nAr
b020: 67 3d 3d 31 20 26 26 20 65 54 79 70 65 30 3d 3d  g==1 && eType0==
b030: 53 51 4c 49 54 45 5f 49 4e 54 45 47 45 52 29 20  SQLITE_INTEGER) 
b040: 7c 7c 20 6e 41 72 67 3d 3d 28 32 2b 70 43 6f 6e  || nArg==(2+pCon
b050: 66 69 67 2d 3e 6e 43 6f 6c 2b 32 29 20 29 3b 0a  fig->nCol+2) );.
b060: 0a 20 20 66 74 73 35 54 72 69 70 43 75 72 73 6f  .  fts5TripCurso
b070: 72 73 28 70 54 61 62 29 3b 0a 20 20 69 66 28 20  rs(pTab);.  if( 
b080: 65 54 79 70 65 30 3d 3d 53 51 4c 49 54 45 5f 49  eType0==SQLITE_I
b090: 4e 54 45 47 45 52 20 29 7b 0a 20 20 20 20 69 66  NTEGER ){.    if
b0a0: 28 20 66 74 73 35 49 73 43 6f 6e 74 65 6e 74 6c  ( fts5IsContentl
b0b0: 65 73 73 28 70 54 61 62 29 20 29 7b 0a 20 20 20  ess(pTab) ){.   
b0c0: 20 20 20 70 54 61 62 2d 3e 62 61 73 65 2e 7a 45     pTab->base.zE
b0d0: 72 72 4d 73 67 20 3d 20 73 71 6c 69 74 65 33 5f  rrMsg = sqlite3_
b0e0: 6d 70 72 69 6e 74 66 28 0a 20 20 20 20 20 20 20  mprintf(.       
b0f0: 20 20 20 22 63 61 6e 6e 6f 74 20 25 73 20 63 6f     "cannot %s co
b100: 6e 74 65 6e 74 6c 65 73 73 20 66 74 73 35 20 74  ntentless fts5 t
b110: 61 62 6c 65 3a 20 25 73 22 2c 20 0a 20 20 20 20  able: %s", .    
b120: 20 20 20 20 20 20 28 6e 41 72 67 3e 31 20 3f 20        (nArg>1 ? 
b130: 22 55 50 44 41 54 45 22 20 3a 20 22 44 45 4c 45  "UPDATE" : "DELE
b140: 54 45 20 66 72 6f 6d 22 29 2c 20 70 43 6f 6e 66  TE from"), pConf
b150: 69 67 2d 3e 7a 4e 61 6d 65 0a 20 20 20 20 20 20  ig->zName.      
b160: 29 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51  );.      rc = SQ
b170: 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 20 20  LITE_ERROR;.    
b180: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 69 36 34  }else{.      i64
b190: 20 69 44 65 6c 20 3d 20 73 71 6c 69 74 65 33 5f   iDel = sqlite3_
b1a0: 76 61 6c 75 65 5f 69 6e 74 36 34 28 61 70 56 61  value_int64(apVa
b1b0: 6c 5b 30 5d 29 3b 20 20 2f 2a 20 52 6f 77 69 64  l[0]);  /* Rowid
b1c0: 20 74 6f 20 64 65 6c 65 74 65 20 2a 2f 0a 20 20   to delete */.  
b1d0: 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
b1e0: 46 74 73 35 53 74 6f 72 61 67 65 44 65 6c 65 74  Fts5StorageDelet
b1f0: 65 28 70 54 61 62 2d 3e 70 53 74 6f 72 61 67 65  e(pTab->pStorage
b200: 2c 20 69 44 65 6c 29 3b 0a 20 20 20 20 7d 0a 20  , iDel);.    }. 
b210: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 61 73 73 65   }else{.    asse
b220: 72 74 28 20 6e 41 72 67 3e 31 20 29 3b 0a 20 20  rt( nArg>1 );.  
b230: 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20    sqlite3_value 
b240: 2a 70 43 6d 64 20 3d 20 61 70 56 61 6c 5b 32 20  *pCmd = apVal[2 
b250: 2b 20 70 43 6f 6e 66 69 67 2d 3e 6e 43 6f 6c 5d  + pConfig->nCol]
b260: 3b 0a 20 20 20 20 69 66 28 20 53 51 4c 49 54 45  ;.    if( SQLITE
b270: 5f 4e 55 4c 4c 21 3d 73 71 6c 69 74 65 33 5f 76  _NULL!=sqlite3_v
b280: 61 6c 75 65 5f 74 79 70 65 28 70 43 6d 64 29 20  alue_type(pCmd) 
b290: 29 7b 0a 20 20 20 20 20 20 63 6f 6e 73 74 20 63  ){.      const c
b2a0: 68 61 72 20 2a 7a 20 3d 20 28 63 6f 6e 73 74 20  har *z = (const 
b2b0: 63 68 61 72 2a 29 73 71 6c 69 74 65 33 5f 76 61  char*)sqlite3_va
b2c0: 6c 75 65 5f 74 65 78 74 28 70 43 6d 64 29 3b 0a  lue_text(pCmd);.
b2d0: 20 20 20 20 20 20 69 66 28 20 70 43 6f 6e 66 69        if( pConfi
b2e0: 67 2d 3e 65 43 6f 6e 74 65 6e 74 21 3d 46 54 53  g->eContent!=FTS
b2f0: 35 5f 43 4f 4e 54 45 4e 54 5f 4e 4f 52 4d 41 4c  5_CONTENT_NORMAL
b300: 20 0a 20 20 20 20 20 20 20 26 26 20 30 3d 3d 73   .       && 0==s
b310: 71 6c 69 74 65 33 5f 73 74 72 69 63 6d 70 28 22  qlite3_stricmp("
b320: 64 65 6c 65 74 65 22 2c 20 7a 29 20 0a 20 20 20  delete", z) .   
b330: 20 20 20 29 7b 0a 20 20 20 20 20 20 20 20 72 63     ){.        rc
b340: 20 3d 20 66 74 73 35 53 70 65 63 69 61 6c 44 65   = fts5SpecialDe
b350: 6c 65 74 65 28 70 54 61 62 2c 20 61 70 56 61 6c  lete(pTab, apVal
b360: 2c 20 70 52 6f 77 69 64 29 3b 0a 20 20 20 20 20  , pRowid);.     
b370: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20   }else{.        
b380: 72 63 20 3d 20 66 74 73 35 53 70 65 63 69 61 6c  rc = fts5Special
b390: 49 6e 73 65 72 74 28 70 54 61 62 2c 20 70 43 6d  Insert(pTab, pCm
b3a0: 64 2c 20 61 70 56 61 6c 5b 32 20 2b 20 70 43 6f  d, apVal[2 + pCo
b3b0: 6e 66 69 67 2d 3e 6e 43 6f 6c 20 2b 20 31 5d 29  nfig->nCol + 1])
b3c0: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
b3d0: 67 6f 74 6f 20 75 70 64 61 74 65 5f 6d 65 74 68  goto update_meth
b3e0: 6f 64 5f 6f 75 74 3b 0a 20 20 20 20 7d 0a 20 20  od_out;.    }.  
b3f0: 7d 0a 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51  }...  if( rc==SQ
b400: 4c 49 54 45 5f 4f 4b 20 26 26 20 6e 41 72 67 3e  LITE_OK && nArg>
b410: 31 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 73 71  1 ){.    rc = sq
b420: 6c 69 74 65 33 46 74 73 35 53 74 6f 72 61 67 65  lite3Fts5Storage
b430: 49 6e 73 65 72 74 28 70 54 61 62 2d 3e 70 53 74  Insert(pTab->pSt
b440: 6f 72 61 67 65 2c 20 61 70 56 61 6c 2c 20 65 43  orage, apVal, eC
b450: 6f 6e 66 6c 69 63 74 2c 20 70 52 6f 77 69 64 29  onflict, pRowid)
b460: 3b 0a 20 20 7d 0a 0a 20 75 70 64 61 74 65 5f 6d  ;.  }.. update_m
b470: 65 74 68 6f 64 5f 6f 75 74 3a 0a 20 20 70 54 61  ethod_out:.  pTa
b480: 62 2d 3e 70 43 6f 6e 66 69 67 2d 3e 70 7a 45 72  b->pConfig->pzEr
b490: 72 6d 73 67 20 3d 20 30 3b 0a 20 20 72 65 74 75  rmsg = 0;.  retu
b4a0: 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  rn rc;.}../*.** 
b4b0: 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f  Implementation o
b4c0: 66 20 78 53 79 6e 63 28 29 20 6d 65 74 68 6f 64  f xSync() method
b4d0: 2e 20 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  . .*/.static int
b4e0: 20 66 74 73 35 53 79 6e 63 4d 65 74 68 6f 64 28   fts5SyncMethod(
b4f0: 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56  sqlite3_vtab *pV
b500: 74 61 62 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a  tab){.  int rc;.
b510: 20 20 46 74 73 35 54 61 62 6c 65 20 2a 70 54 61    Fts5Table *pTa
b520: 62 20 3d 20 28 46 74 73 35 54 61 62 6c 65 2a 29  b = (Fts5Table*)
b530: 70 56 74 61 62 3b 0a 20 20 66 74 73 35 43 68 65  pVtab;.  fts5Che
b540: 63 6b 54 72 61 6e 73 61 63 74 69 6f 6e 53 74 61  ckTransactionSta
b550: 74 65 28 70 54 61 62 2c 20 46 54 53 35 5f 53 59  te(pTab, FTS5_SY
b560: 4e 43 2c 20 30 29 3b 0a 20 20 70 54 61 62 2d 3e  NC, 0);.  pTab->
b570: 70 43 6f 6e 66 69 67 2d 3e 70 7a 45 72 72 6d 73  pConfig->pzErrms
b580: 67 20 3d 20 26 70 54 61 62 2d 3e 62 61 73 65 2e  g = &pTab->base.
b590: 7a 45 72 72 4d 73 67 3b 0a 20 20 66 74 73 35 54  zErrMsg;.  fts5T
b5a0: 72 69 70 43 75 72 73 6f 72 73 28 70 54 61 62 29  ripCursors(pTab)
b5b0: 3b 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33  ;.  rc = sqlite3
b5c0: 46 74 73 35 53 74 6f 72 61 67 65 53 79 6e 63 28  Fts5StorageSync(
b5d0: 70 54 61 62 2d 3e 70 53 74 6f 72 61 67 65 2c 20  pTab->pStorage, 
b5e0: 31 29 3b 0a 20 20 70 54 61 62 2d 3e 70 43 6f 6e  1);.  pTab->pCon
b5f0: 66 69 67 2d 3e 70 7a 45 72 72 6d 73 67 20 3d 20  fig->pzErrmsg = 
b600: 30 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  0;.  return rc;.
b610: 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65  }../*.** Impleme
b620: 6e 74 61 74 69 6f 6e 20 6f 66 20 78 42 65 67 69  ntation of xBegi
b630: 6e 28 29 20 6d 65 74 68 6f 64 2e 20 0a 2a 2f 0a  n() method. .*/.
b640: 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 42  static int fts5B
b650: 65 67 69 6e 4d 65 74 68 6f 64 28 73 71 6c 69 74  eginMethod(sqlit
b660: 65 33 5f 76 74 61 62 20 2a 70 56 74 61 62 29 7b  e3_vtab *pVtab){
b670: 0a 20 20 66 74 73 35 43 68 65 63 6b 54 72 61 6e  .  fts5CheckTran
b680: 73 61 63 74 69 6f 6e 53 74 61 74 65 28 28 46 74  sactionState((Ft
b690: 73 35 54 61 62 6c 65 2a 29 70 56 74 61 62 2c 20  s5Table*)pVtab, 
b6a0: 46 54 53 35 5f 42 45 47 49 4e 2c 20 30 29 3b 0a  FTS5_BEGIN, 0);.
b6b0: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
b6c0: 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70  OK;.}../*.** Imp
b6d0: 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 78  lementation of x
b6e0: 43 6f 6d 6d 69 74 28 29 20 6d 65 74 68 6f 64 2e  Commit() method.
b6f0: 20 54 68 69 73 20 69 73 20 61 20 6e 6f 2d 6f 70   This is a no-op
b700: 2e 20 54 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f  . The contents o
b710: 66 0a 2a 2a 20 74 68 65 20 70 65 6e 64 69 6e 67  f.** the pending
b720: 2d 74 65 72 6d 73 20 68 61 73 68 2d 74 61 62 6c  -terms hash-tabl
b730: 65 20 68 61 76 65 20 61 6c 72 65 61 64 79 20 62  e have already b
b740: 65 65 6e 20 66 6c 75 73 68 65 64 20 69 6e 74 6f  een flushed into
b750: 20 74 68 65 20 64 61 74 61 62 61 73 65 0a 2a 2a   the database.**
b760: 20 62 79 20 66 74 73 35 53 79 6e 63 4d 65 74 68   by fts5SyncMeth
b770: 6f 64 28 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  od()..*/.static 
b780: 69 6e 74 20 66 74 73 35 43 6f 6d 6d 69 74 4d 65  int fts5CommitMe
b790: 74 68 6f 64 28 73 71 6c 69 74 65 33 5f 76 74 61  thod(sqlite3_vta
b7a0: 62 20 2a 70 56 74 61 62 29 7b 0a 20 20 66 74 73  b *pVtab){.  fts
b7b0: 35 43 68 65 63 6b 54 72 61 6e 73 61 63 74 69 6f  5CheckTransactio
b7c0: 6e 53 74 61 74 65 28 28 46 74 73 35 54 61 62 6c  nState((Fts5Tabl
b7d0: 65 2a 29 70 56 74 61 62 2c 20 46 54 53 35 5f 43  e*)pVtab, FTS5_C
b7e0: 4f 4d 4d 49 54 2c 20 30 29 3b 0a 20 20 72 65 74  OMMIT, 0);.  ret
b7f0: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
b800: 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e  ../*.** Implemen
b810: 74 61 74 69 6f 6e 20 6f 66 20 78 52 6f 6c 6c 62  tation of xRollb
b820: 61 63 6b 28 29 2e 20 44 69 73 63 61 72 64 20 74  ack(). Discard t
b830: 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 74  he contents of t
b840: 68 65 20 70 65 6e 64 69 6e 67 2d 74 65 72 6d 73  he pending-terms
b850: 0a 2a 2a 20 68 61 73 68 2d 74 61 62 6c 65 2e 20  .** hash-table. 
b860: 41 6e 79 20 63 68 61 6e 67 65 73 20 6d 61 64 65  Any changes made
b870: 20 74 6f 20 74 68 65 20 64 61 74 61 62 61 73 65   to the database
b880: 20 61 72 65 20 72 65 76 65 72 74 65 64 20 62 79   are reverted by
b890: 20 53 51 4c 69 74 65 2e 0a 2a 2f 0a 73 74 61 74   SQLite..*/.stat
b8a0: 69 63 20 69 6e 74 20 66 74 73 35 52 6f 6c 6c 62  ic int fts5Rollb
b8b0: 61 63 6b 4d 65 74 68 6f 64 28 73 71 6c 69 74 65  ackMethod(sqlite
b8c0: 33 5f 76 74 61 62 20 2a 70 56 74 61 62 29 7b 0a  3_vtab *pVtab){.
b8d0: 20 20 69 6e 74 20 72 63 3b 0a 20 20 46 74 73 35    int rc;.  Fts5
b8e0: 54 61 62 6c 65 20 2a 70 54 61 62 20 3d 20 28 46  Table *pTab = (F
b8f0: 74 73 35 54 61 62 6c 65 2a 29 70 56 74 61 62 3b  ts5Table*)pVtab;
b900: 0a 20 20 66 74 73 35 43 68 65 63 6b 54 72 61 6e  .  fts5CheckTran
b910: 73 61 63 74 69 6f 6e 53 74 61 74 65 28 70 54 61  sactionState(pTa
b920: 62 2c 20 46 54 53 35 5f 52 4f 4c 4c 42 41 43 4b  b, FTS5_ROLLBACK
b930: 2c 20 30 29 3b 0a 20 20 72 63 20 3d 20 73 71 6c  , 0);.  rc = sql
b940: 69 74 65 33 46 74 73 35 53 74 6f 72 61 67 65 52  ite3Fts5StorageR
b950: 6f 6c 6c 62 61 63 6b 28 70 54 61 62 2d 3e 70 53  ollback(pTab->pS
b960: 74 6f 72 61 67 65 29 3b 0a 20 20 72 65 74 75 72  torage);.  retur
b970: 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  n rc;.}..static 
b980: 76 6f 69 64 20 2a 66 74 73 35 41 70 69 55 73 65  void *fts5ApiUse
b990: 72 44 61 74 61 28 46 74 73 35 43 6f 6e 74 65 78  rData(Fts5Contex
b9a0: 74 20 2a 70 43 74 78 29 7b 0a 20 20 46 74 73 35  t *pCtx){.  Fts5
b9b0: 43 75 72 73 6f 72 20 2a 70 43 73 72 20 3d 20 28  Cursor *pCsr = (
b9c0: 46 74 73 35 43 75 72 73 6f 72 2a 29 70 43 74 78  Fts5Cursor*)pCtx
b9d0: 3b 0a 20 20 72 65 74 75 72 6e 20 70 43 73 72 2d  ;.  return pCsr-
b9e0: 3e 70 41 75 78 2d 3e 70 55 73 65 72 44 61 74 61  >pAux->pUserData
b9f0: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  ;.}..static int 
ba00: 66 74 73 35 41 70 69 43 6f 6c 75 6d 6e 43 6f 75  fts5ApiColumnCou
ba10: 6e 74 28 46 74 73 35 43 6f 6e 74 65 78 74 20 2a  nt(Fts5Context *
ba20: 70 43 74 78 29 7b 0a 20 20 46 74 73 35 43 75 72  pCtx){.  Fts5Cur
ba30: 73 6f 72 20 2a 70 43 73 72 20 3d 20 28 46 74 73  sor *pCsr = (Fts
ba40: 35 43 75 72 73 6f 72 2a 29 70 43 74 78 3b 0a 20  5Cursor*)pCtx;. 
ba50: 20 72 65 74 75 72 6e 20 28 28 46 74 73 35 54 61   return ((Fts5Ta
ba60: 62 6c 65 2a 29 28 70 43 73 72 2d 3e 62 61 73 65  ble*)(pCsr->base
ba70: 2e 70 56 74 61 62 29 29 2d 3e 70 43 6f 6e 66 69  .pVtab))->pConfi
ba80: 67 2d 3e 6e 43 6f 6c 3b 0a 7d 0a 0a 73 74 61 74  g->nCol;.}..stat
ba90: 69 63 20 69 6e 74 20 66 74 73 35 41 70 69 43 6f  ic int fts5ApiCo
baa0: 6c 75 6d 6e 54 6f 74 61 6c 53 69 7a 65 28 0a 20  lumnTotalSize(. 
bab0: 20 46 74 73 35 43 6f 6e 74 65 78 74 20 2a 70 43   Fts5Context *pC
bac0: 74 78 2c 20 0a 20 20 69 6e 74 20 69 43 6f 6c 2c  tx, .  int iCol,
bad0: 20 0a 20 20 73 71 6c 69 74 65 33 5f 69 6e 74 36   .  sqlite3_int6
bae0: 34 20 2a 70 6e 54 6f 6b 65 6e 0a 29 7b 0a 20 20  4 *pnToken.){.  
baf0: 46 74 73 35 43 75 72 73 6f 72 20 2a 70 43 73 72  Fts5Cursor *pCsr
bb00: 20 3d 20 28 46 74 73 35 43 75 72 73 6f 72 2a 29   = (Fts5Cursor*)
bb10: 70 43 74 78 3b 0a 20 20 46 74 73 35 54 61 62 6c  pCtx;.  Fts5Tabl
bb20: 65 20 2a 70 54 61 62 20 3d 20 28 46 74 73 35 54  e *pTab = (Fts5T
bb30: 61 62 6c 65 2a 29 28 70 43 73 72 2d 3e 62 61 73  able*)(pCsr->bas
bb40: 65 2e 70 56 74 61 62 29 3b 0a 20 20 72 65 74 75  e.pVtab);.  retu
bb50: 72 6e 20 73 71 6c 69 74 65 33 46 74 73 35 53 74  rn sqlite3Fts5St
bb60: 6f 72 61 67 65 53 69 7a 65 28 70 54 61 62 2d 3e  orageSize(pTab->
bb70: 70 53 74 6f 72 61 67 65 2c 20 69 43 6f 6c 2c 20  pStorage, iCol, 
bb80: 70 6e 54 6f 6b 65 6e 29 3b 0a 7d 0a 0a 73 74 61  pnToken);.}..sta
bb90: 74 69 63 20 69 6e 74 20 66 74 73 35 41 70 69 52  tic int fts5ApiR
bba0: 6f 77 43 6f 75 6e 74 28 46 74 73 35 43 6f 6e 74  owCount(Fts5Cont
bbb0: 65 78 74 20 2a 70 43 74 78 2c 20 69 36 34 20 2a  ext *pCtx, i64 *
bbc0: 70 6e 52 6f 77 29 7b 0a 20 20 46 74 73 35 43 75  pnRow){.  Fts5Cu
bbd0: 72 73 6f 72 20 2a 70 43 73 72 20 3d 20 28 46 74  rsor *pCsr = (Ft
bbe0: 73 35 43 75 72 73 6f 72 2a 29 70 43 74 78 3b 0a  s5Cursor*)pCtx;.
bbf0: 20 20 46 74 73 35 54 61 62 6c 65 20 2a 70 54 61    Fts5Table *pTa
bc00: 62 20 3d 20 28 46 74 73 35 54 61 62 6c 65 2a 29  b = (Fts5Table*)
bc10: 28 70 43 73 72 2d 3e 62 61 73 65 2e 70 56 74 61  (pCsr->base.pVta
bc20: 62 29 3b 0a 20 20 72 65 74 75 72 6e 20 73 71 6c  b);.  return sql
bc30: 69 74 65 33 46 74 73 35 53 74 6f 72 61 67 65 52  ite3Fts5StorageR
bc40: 6f 77 43 6f 75 6e 74 28 70 54 61 62 2d 3e 70 53  owCount(pTab->pS
bc50: 74 6f 72 61 67 65 2c 20 70 6e 52 6f 77 29 3b 0a  torage, pnRow);.
bc60: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74  }..static int ft
bc70: 73 35 41 70 69 54 6f 6b 65 6e 69 7a 65 28 0a 20  s5ApiTokenize(. 
bc80: 20 46 74 73 35 43 6f 6e 74 65 78 74 20 2a 70 43   Fts5Context *pC
bc90: 74 78 2c 20 0a 20 20 63 6f 6e 73 74 20 63 68 61  tx, .  const cha
bca0: 72 20 2a 70 54 65 78 74 2c 20 69 6e 74 20 6e 54  r *pText, int nT
bcb0: 65 78 74 2c 20 0a 20 20 76 6f 69 64 20 2a 70 55  ext, .  void *pU
bcc0: 73 65 72 44 61 74 61 2c 0a 20 20 69 6e 74 20 28  serData,.  int (
bcd0: 2a 78 54 6f 6b 65 6e 29 28 76 6f 69 64 2a 2c 20  *xToken)(void*, 
bce0: 63 6f 6e 73 74 20 63 68 61 72 2a 2c 20 69 6e 74  const char*, int
bcf0: 2c 20 69 6e 74 2c 20 69 6e 74 29 0a 29 7b 0a 20  , int, int).){. 
bd00: 20 46 74 73 35 43 75 72 73 6f 72 20 2a 70 43 73   Fts5Cursor *pCs
bd10: 72 20 3d 20 28 46 74 73 35 43 75 72 73 6f 72 2a  r = (Fts5Cursor*
bd20: 29 70 43 74 78 3b 0a 20 20 46 74 73 35 54 61 62  )pCtx;.  Fts5Tab
bd30: 6c 65 20 2a 70 54 61 62 20 3d 20 28 46 74 73 35  le *pTab = (Fts5
bd40: 54 61 62 6c 65 2a 29 28 70 43 73 72 2d 3e 62 61  Table*)(pCsr->ba
bd50: 73 65 2e 70 56 74 61 62 29 3b 0a 20 20 72 65 74  se.pVtab);.  ret
bd60: 75 72 6e 20 73 71 6c 69 74 65 33 46 74 73 35 54  urn sqlite3Fts5T
bd70: 6f 6b 65 6e 69 7a 65 28 70 54 61 62 2d 3e 70 43  okenize(pTab->pC
bd80: 6f 6e 66 69 67 2c 20 70 54 65 78 74 2c 20 6e 54  onfig, pText, nT
bd90: 65 78 74 2c 20 70 55 73 65 72 44 61 74 61 2c 20  ext, pUserData, 
bda0: 78 54 6f 6b 65 6e 29 3b 0a 7d 0a 0a 73 74 61 74  xToken);.}..stat
bdb0: 69 63 20 69 6e 74 20 66 74 73 35 41 70 69 50 68  ic int fts5ApiPh
bdc0: 72 61 73 65 43 6f 75 6e 74 28 46 74 73 35 43 6f  raseCount(Fts5Co
bdd0: 6e 74 65 78 74 20 2a 70 43 74 78 29 7b 0a 20 20  ntext *pCtx){.  
bde0: 46 74 73 35 43 75 72 73 6f 72 20 2a 70 43 73 72  Fts5Cursor *pCsr
bdf0: 20 3d 20 28 46 74 73 35 43 75 72 73 6f 72 2a 29   = (Fts5Cursor*)
be00: 70 43 74 78 3b 0a 20 20 72 65 74 75 72 6e 20 73  pCtx;.  return s
be10: 71 6c 69 74 65 33 46 74 73 35 45 78 70 72 50 68  qlite3Fts5ExprPh
be20: 72 61 73 65 43 6f 75 6e 74 28 70 43 73 72 2d 3e  raseCount(pCsr->
be30: 70 45 78 70 72 29 3b 0a 7d 0a 0a 73 74 61 74 69  pExpr);.}..stati
be40: 63 20 69 6e 74 20 66 74 73 35 41 70 69 50 68 72  c int fts5ApiPhr
be50: 61 73 65 53 69 7a 65 28 46 74 73 35 43 6f 6e 74  aseSize(Fts5Cont
be60: 65 78 74 20 2a 70 43 74 78 2c 20 69 6e 74 20 69  ext *pCtx, int i
be70: 50 68 72 61 73 65 29 7b 0a 20 20 46 74 73 35 43  Phrase){.  Fts5C
be80: 75 72 73 6f 72 20 2a 70 43 73 72 20 3d 20 28 46  ursor *pCsr = (F
be90: 74 73 35 43 75 72 73 6f 72 2a 29 70 43 74 78 3b  ts5Cursor*)pCtx;
bea0: 0a 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74 65  .  return sqlite
beb0: 33 46 74 73 35 45 78 70 72 50 68 72 61 73 65 53  3Fts5ExprPhraseS
bec0: 69 7a 65 28 70 43 73 72 2d 3e 70 45 78 70 72 2c  ize(pCsr->pExpr,
bed0: 20 69 50 68 72 61 73 65 29 3b 0a 7d 0a 0a 73 74   iPhrase);.}..st
bee0: 61 74 69 63 20 69 6e 74 20 66 74 73 35 43 73 72  atic int fts5Csr
bef0: 50 6f 73 6c 69 73 74 28 46 74 73 35 43 75 72 73  Poslist(Fts5Curs
bf00: 6f 72 20 2a 70 43 73 72 2c 20 69 6e 74 20 69 50  or *pCsr, int iP
bf10: 68 72 61 73 65 2c 20 63 6f 6e 73 74 20 75 38 20  hrase, const u8 
bf20: 2a 2a 70 61 29 7b 0a 20 20 69 6e 74 20 6e 3b 0a  **pa){.  int n;.
bf30: 20 20 69 66 28 20 70 43 73 72 2d 3e 70 53 6f 72    if( pCsr->pSor
bf40: 74 65 72 20 29 7b 0a 20 20 20 20 46 74 73 35 53  ter ){.    Fts5S
bf50: 6f 72 74 65 72 20 2a 70 53 6f 72 74 65 72 20 3d  orter *pSorter =
bf60: 20 70 43 73 72 2d 3e 70 53 6f 72 74 65 72 3b 0a   pCsr->pSorter;.
bf70: 20 20 20 20 69 6e 74 20 69 31 20 3d 20 28 69 50      int i1 = (iP
bf80: 68 72 61 73 65 3d 3d 30 20 3f 20 30 20 3a 20 70  hrase==0 ? 0 : p
bf90: 53 6f 72 74 65 72 2d 3e 61 49 64 78 5b 69 50 68  Sorter->aIdx[iPh
bfa0: 72 61 73 65 2d 31 5d 29 3b 0a 20 20 20 20 6e 20  rase-1]);.    n 
bfb0: 3d 20 70 53 6f 72 74 65 72 2d 3e 61 49 64 78 5b  = pSorter->aIdx[
bfc0: 69 50 68 72 61 73 65 5d 20 2d 20 69 31 3b 0a 20  iPhrase] - i1;. 
bfd0: 20 20 20 2a 70 61 20 3d 20 26 70 53 6f 72 74 65     *pa = &pSorte
bfe0: 72 2d 3e 61 50 6f 73 6c 69 73 74 5b 69 31 5d 3b  r->aPoslist[i1];
bff0: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 6e 20  .  }else{.    n 
c000: 3d 20 73 71 6c 69 74 65 33 46 74 73 35 45 78 70  = sqlite3Fts5Exp
c010: 72 50 6f 73 6c 69 73 74 28 70 43 73 72 2d 3e 70  rPoslist(pCsr->p
c020: 45 78 70 72 2c 20 69 50 68 72 61 73 65 2c 20 70  Expr, iPhrase, p
c030: 61 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  a);.  }.  return
c040: 20 6e 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 45 6e 73   n;.}../*.** Ens
c050: 75 72 65 20 74 68 61 74 20 74 68 65 20 46 74 73  ure that the Fts
c060: 35 43 75 72 73 6f 72 2e 6e 49 6e 73 74 43 6f 75  5Cursor.nInstCou
c070: 6e 74 20 61 6e 64 20 61 49 6e 73 74 5b 5d 20 76  nt and aInst[] v
c080: 61 72 69 61 62 6c 65 73 20 61 72 65 20 70 6f 70  ariables are pop
c090: 75 6c 61 74 65 64 0a 2a 2a 20 63 6f 72 72 65 63  ulated.** correc
c0a0: 74 6c 79 20 66 6f 72 20 74 68 65 20 63 75 72 72  tly for the curr
c0b0: 65 6e 74 20 76 69 65 77 2e 20 52 65 74 75 72 6e  ent view. Return
c0c0: 20 53 51 4c 49 54 45 5f 4f 4b 20 69 66 20 73 75   SQLITE_OK if su
c0d0: 63 63 65 73 73 66 75 6c 2c 20 6f 72 20 61 6e 0a  ccessful, or an.
c0e0: 2a 2a 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20  ** SQLite error 
c0f0: 63 6f 64 65 20 6f 74 68 65 72 77 69 73 65 2e 0a  code otherwise..
c100: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74  */.static int ft
c110: 73 35 43 61 63 68 65 49 6e 73 74 41 72 72 61 79  s5CacheInstArray
c120: 28 46 74 73 35 43 75 72 73 6f 72 20 2a 70 43 73  (Fts5Cursor *pCs
c130: 72 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53  r){.  int rc = S
c140: 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 66 28 20  QLITE_OK;.  if( 
c150: 70 43 73 72 2d 3e 61 49 6e 73 74 3d 3d 30 20 29  pCsr->aInst==0 )
c160: 7b 0a 20 20 20 20 46 74 73 35 50 6f 73 6c 69 73  {.    Fts5Poslis
c170: 74 52 65 61 64 65 72 20 2a 61 49 74 65 72 3b 20  tReader *aIter; 
c180: 20 20 20 20 2f 2a 20 4f 6e 65 20 69 74 65 72 61      /* One itera
c190: 74 6f 72 20 66 6f 72 20 65 61 63 68 20 70 68 72  tor for each phr
c1a0: 61 73 65 20 2a 2f 0a 20 20 20 20 69 6e 74 20 6e  ase */.    int n
c1b0: 49 74 65 72 3b 20 20 20 20 20 20 20 20 20 20 20  Iter;           
c1c0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
c1d0: 65 72 20 6f 66 20 69 74 65 72 61 74 6f 72 73 2f  er of iterators/
c1e0: 70 68 72 61 73 65 73 20 2a 2f 0a 20 20 20 20 69  phrases */.    i
c1f0: 6e 74 20 6e 42 79 74 65 3b 0a 20 20 20 20 0a 20  nt nByte;.    . 
c200: 20 20 20 6e 49 74 65 72 20 3d 20 73 71 6c 69 74     nIter = sqlit
c210: 65 33 46 74 73 35 45 78 70 72 50 68 72 61 73 65  e3Fts5ExprPhrase
c220: 43 6f 75 6e 74 28 70 43 73 72 2d 3e 70 45 78 70  Count(pCsr->pExp
c230: 72 29 3b 0a 20 20 20 20 6e 42 79 74 65 20 3d 20  r);.    nByte = 
c240: 73 69 7a 65 6f 66 28 46 74 73 35 50 6f 73 6c 69  sizeof(Fts5Posli
c250: 73 74 52 65 61 64 65 72 29 20 2a 20 6e 49 74 65  stReader) * nIte
c260: 72 3b 0a 20 20 20 20 61 49 74 65 72 20 3d 20 28  r;.    aIter = (
c270: 46 74 73 35 50 6f 73 6c 69 73 74 52 65 61 64 65  Fts5PoslistReade
c280: 72 2a 29 73 71 6c 69 74 65 33 46 74 73 35 4d 61  r*)sqlite3Fts5Ma
c290: 6c 6c 6f 63 5a 65 72 6f 28 26 72 63 2c 20 6e 42  llocZero(&rc, nB
c2a0: 79 74 65 29 3b 0a 20 20 20 20 69 66 28 20 61 49  yte);.    if( aI
c2b0: 74 65 72 20 29 7b 0a 20 20 20 20 20 20 46 74 73  ter ){.      Fts
c2c0: 35 42 75 66 66 65 72 20 62 75 66 20 3d 20 7b 30  5Buffer buf = {0
c2d0: 2c 20 30 2c 20 30 7d 3b 20 2f 2a 20 42 75 69 6c  , 0, 0}; /* Buil
c2e0: 64 20 75 70 20 61 49 6e 73 74 5b 5d 20 68 65 72  d up aInst[] her
c2f0: 65 20 2a 2f 0a 20 20 20 20 20 20 69 6e 74 20 6e  e */.      int n
c300: 49 6e 73 74 20 3d 20 30 3b 20 20 20 20 20 20 20  Inst = 0;       
c310: 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
c320: 20 69 6e 73 74 61 6e 63 65 73 20 73 65 65 6e 20   instances seen 
c330: 73 6f 20 66 61 72 20 2a 2f 0a 20 20 20 20 20 20  so far */.      
c340: 69 6e 74 20 69 3b 0a 0a 20 20 20 20 20 20 2f 2a  int i;..      /*
c350: 20 49 6e 69 74 69 61 6c 69 7a 65 20 61 6c 6c 20   Initialize all 
c360: 69 74 65 72 61 74 6f 72 73 20 2a 2f 0a 20 20 20  iterators */.   
c370: 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 49     for(i=0; i<nI
c380: 74 65 72 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20  ter; i++){.     
c390: 20 20 20 63 6f 6e 73 74 20 75 38 20 2a 61 3b 0a     const u8 *a;.
c3a0: 20 20 20 20 20 20 20 20 69 6e 74 20 6e 20 3d 20          int n = 
c3b0: 66 74 73 35 43 73 72 50 6f 73 6c 69 73 74 28 70  fts5CsrPoslist(p
c3c0: 43 73 72 2c 20 69 2c 20 26 61 29 3b 0a 20 20 20  Csr, i, &a);.   
c3d0: 20 20 20 20 20 73 71 6c 69 74 65 33 46 74 73 35       sqlite3Fts5
c3e0: 50 6f 73 6c 69 73 74 52 65 61 64 65 72 49 6e 69  PoslistReaderIni
c3f0: 74 28 2d 31 2c 20 61 2c 20 6e 2c 20 26 61 49 74  t(-1, a, n, &aIt
c400: 65 72 5b 69 5d 29 3b 0a 20 20 20 20 20 20 7d 0a  er[i]);.      }.
c410: 0a 20 20 20 20 20 20 77 68 69 6c 65 28 20 31 20  .      while( 1 
c420: 29 7b 0a 20 20 20 20 20 20 20 20 69 6e 74 20 2a  ){.        int *
c430: 61 49 6e 73 74 3b 0a 20 20 20 20 20 20 20 20 69  aInst;.        i
c440: 6e 74 20 69 42 65 73 74 20 3d 20 2d 31 3b 0a 20  nt iBest = -1;. 
c450: 20 20 20 20 20 20 20 66 6f 72 28 69 3d 30 3b 20         for(i=0; 
c460: 69 3c 6e 49 74 65 72 3b 20 69 2b 2b 29 7b 0a 20  i<nIter; i++){. 
c470: 20 20 20 20 20 20 20 20 20 69 66 28 20 28 61 49           if( (aI
c480: 74 65 72 5b 69 5d 2e 62 45 6f 66 3d 3d 30 29 20  ter[i].bEof==0) 
c490: 0a 20 20 20 20 20 20 20 20 20 20 20 26 26 20 28  .           && (
c4a0: 69 42 65 73 74 3c 30 20 7c 7c 20 61 49 74 65 72  iBest<0 || aIter
c4b0: 5b 69 5d 2e 69 50 6f 73 3c 61 49 74 65 72 5b 69  [i].iPos<aIter[i
c4c0: 42 65 73 74 5d 2e 69 50 6f 73 29 20 0a 20 20 20  Best].iPos) .   
c4d0: 20 20 20 20 20 20 20 29 7b 0a 20 20 20 20 20 20         ){.      
c4e0: 20 20 20 20 20 20 69 42 65 73 74 20 3d 20 69 3b        iBest = i;
c4f0: 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20  .          }.   
c500: 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 20 20       }..        
c510: 69 66 28 20 69 42 65 73 74 3c 30 20 29 20 62 72  if( iBest<0 ) br
c520: 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 6e 49 6e  eak;.        nIn
c530: 73 74 2b 2b 3b 0a 20 20 20 20 20 20 20 20 69 66  st++;.        if
c540: 28 20 73 71 6c 69 74 65 33 46 74 73 35 42 75 66  ( sqlite3Fts5Buf
c550: 66 65 72 47 72 6f 77 28 26 72 63 2c 20 26 62 75  ferGrow(&rc, &bu
c560: 66 2c 20 6e 49 6e 73 74 20 2a 20 73 69 7a 65 6f  f, nInst * sizeo
c570: 66 28 69 6e 74 29 20 2a 20 33 29 20 29 20 62 72  f(int) * 3) ) br
c580: 65 61 6b 3b 0a 0a 20 20 20 20 20 20 20 20 61 49  eak;..        aI
c590: 6e 73 74 20 3d 20 26 28 28 69 6e 74 2a 29 62 75  nst = &((int*)bu
c5a0: 66 2e 70 29 5b 33 20 2a 20 28 6e 49 6e 73 74 2d  f.p)[3 * (nInst-
c5b0: 31 29 5d 3b 0a 20 20 20 20 20 20 20 20 61 49 6e  1)];.        aIn
c5c0: 73 74 5b 30 5d 20 3d 20 69 42 65 73 74 3b 0a 20  st[0] = iBest;. 
c5d0: 20 20 20 20 20 20 20 61 49 6e 73 74 5b 31 5d 20         aInst[1] 
c5e0: 3d 20 46 54 53 35 5f 50 4f 53 32 43 4f 4c 55 4d  = FTS5_POS2COLUM
c5f0: 4e 28 61 49 74 65 72 5b 69 42 65 73 74 5d 2e 69  N(aIter[iBest].i
c600: 50 6f 73 29 3b 0a 20 20 20 20 20 20 20 20 61 49  Pos);.        aI
c610: 6e 73 74 5b 32 5d 20 3d 20 46 54 53 35 5f 50 4f  nst[2] = FTS5_PO
c620: 53 32 4f 46 46 53 45 54 28 61 49 74 65 72 5b 69  S2OFFSET(aIter[i
c630: 42 65 73 74 5d 2e 69 50 6f 73 29 3b 0a 20 20 20  Best].iPos);.   
c640: 20 20 20 20 20 73 71 6c 69 74 65 33 46 74 73 35       sqlite3Fts5
c650: 50 6f 73 6c 69 73 74 52 65 61 64 65 72 4e 65 78  PoslistReaderNex
c660: 74 28 26 61 49 74 65 72 5b 69 42 65 73 74 5d 29  t(&aIter[iBest])
c670: 3b 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20  ;.      }..     
c680: 20 70 43 73 72 2d 3e 61 49 6e 73 74 20 3d 20 28   pCsr->aInst = (
c690: 69 6e 74 2a 29 62 75 66 2e 70 3b 0a 20 20 20 20  int*)buf.p;.    
c6a0: 20 20 70 43 73 72 2d 3e 6e 49 6e 73 74 43 6f 75    pCsr->nInstCou
c6b0: 6e 74 20 3d 20 6e 49 6e 73 74 3b 0a 20 20 20 20  nt = nInst;.    
c6c0: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 61    sqlite3_free(a
c6d0: 49 74 65 72 29 3b 0a 20 20 20 20 7d 0a 20 20 7d  Iter);.    }.  }
c6e0: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
c6f0: 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35  .static int fts5
c700: 41 70 69 49 6e 73 74 43 6f 75 6e 74 28 46 74 73  ApiInstCount(Fts
c710: 35 43 6f 6e 74 65 78 74 20 2a 70 43 74 78 2c 20  5Context *pCtx, 
c720: 69 6e 74 20 2a 70 6e 49 6e 73 74 29 7b 0a 20 20  int *pnInst){.  
c730: 46 74 73 35 43 75 72 73 6f 72 20 2a 70 43 73 72  Fts5Cursor *pCsr
c740: 20 3d 20 28 46 74 73 35 43 75 72 73 6f 72 2a 29   = (Fts5Cursor*)
c750: 70 43 74 78 3b 0a 20 20 69 6e 74 20 72 63 3b 0a  pCtx;.  int rc;.
c760: 20 20 69 66 28 20 53 51 4c 49 54 45 5f 4f 4b 3d    if( SQLITE_OK=
c770: 3d 28 72 63 20 3d 20 66 74 73 35 43 61 63 68 65  =(rc = fts5Cache
c780: 49 6e 73 74 41 72 72 61 79 28 70 43 73 72 29 29  InstArray(pCsr))
c790: 20 29 7b 0a 20 20 20 20 2a 70 6e 49 6e 73 74 20   ){.    *pnInst 
c7a0: 3d 20 70 43 73 72 2d 3e 6e 49 6e 73 74 43 6f 75  = pCsr->nInstCou
c7b0: 6e 74 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  nt;.  }.  return
c7c0: 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69   rc;.}..static i
c7d0: 6e 74 20 66 74 73 35 41 70 69 49 6e 73 74 28 0a  nt fts5ApiInst(.
c7e0: 20 20 46 74 73 35 43 6f 6e 74 65 78 74 20 2a 70    Fts5Context *p
c7f0: 43 74 78 2c 20 0a 20 20 69 6e 74 20 69 49 64 78  Ctx, .  int iIdx
c800: 2c 20 0a 20 20 69 6e 74 20 2a 70 69 50 68 72 61  , .  int *piPhra
c810: 73 65 2c 20 0a 20 20 69 6e 74 20 2a 70 69 43 6f  se, .  int *piCo
c820: 6c 2c 20 0a 20 20 69 6e 74 20 2a 70 69 4f 66 66  l, .  int *piOff
c830: 0a 29 7b 0a 20 20 46 74 73 35 43 75 72 73 6f 72  .){.  Fts5Cursor
c840: 20 2a 70 43 73 72 20 3d 20 28 46 74 73 35 43 75   *pCsr = (Fts5Cu
c850: 72 73 6f 72 2a 29 70 43 74 78 3b 0a 20 20 69 6e  rsor*)pCtx;.  in
c860: 74 20 72 63 3b 0a 20 20 69 66 28 20 53 51 4c 49  t rc;.  if( SQLI
c870: 54 45 5f 4f 4b 3d 3d 28 72 63 20 3d 20 66 74 73  TE_OK==(rc = fts
c880: 35 43 61 63 68 65 49 6e 73 74 41 72 72 61 79 28  5CacheInstArray(
c890: 70 43 73 72 29 29 20 29 7b 0a 20 20 20 20 69 66  pCsr)) ){.    if
c8a0: 28 20 69 49 64 78 3c 30 20 7c 7c 20 69 49 64 78  ( iIdx<0 || iIdx
c8b0: 3e 3d 70 43 73 72 2d 3e 6e 49 6e 73 74 43 6f 75  >=pCsr->nInstCou
c8c0: 6e 74 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d  nt ){.      rc =
c8d0: 20 53 51 4c 49 54 45 5f 52 41 4e 47 45 3b 0a 20   SQLITE_RANGE;. 
c8e0: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
c8f0: 2a 70 69 50 68 72 61 73 65 20 3d 20 70 43 73 72  *piPhrase = pCsr
c900: 2d 3e 61 49 6e 73 74 5b 69 49 64 78 2a 33 5d 3b  ->aInst[iIdx*3];
c910: 0a 20 20 20 20 20 20 2a 70 69 43 6f 6c 20 3d 20  .      *piCol = 
c920: 70 43 73 72 2d 3e 61 49 6e 73 74 5b 69 49 64 78  pCsr->aInst[iIdx
c930: 2a 33 20 2b 20 31 5d 3b 0a 20 20 20 20 20 20 2a  *3 + 1];.      *
c940: 70 69 4f 66 66 20 3d 20 70 43 73 72 2d 3e 61 49  piOff = pCsr->aI
c950: 6e 73 74 5b 69 49 64 78 2a 33 20 2b 20 32 5d 3b  nst[iIdx*3 + 2];
c960: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74  .    }.  }.  ret
c970: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69  urn rc;.}..stati
c980: 63 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20  c sqlite3_int64 
c990: 66 74 73 35 41 70 69 52 6f 77 69 64 28 46 74 73  fts5ApiRowid(Fts
c9a0: 35 43 6f 6e 74 65 78 74 20 2a 70 43 74 78 29 7b  5Context *pCtx){
c9b0: 0a 20 20 72 65 74 75 72 6e 20 66 74 73 35 43 75  .  return fts5Cu
c9c0: 72 73 6f 72 52 6f 77 69 64 28 28 46 74 73 35 43  rsorRowid((Fts5C
c9d0: 75 72 73 6f 72 2a 29 70 43 74 78 29 3b 0a 7d 0a  ursor*)pCtx);.}.
c9e0: 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35  .static int fts5
c9f0: 41 70 69 43 6f 6c 75 6d 6e 54 65 78 74 28 0a 20  ApiColumnText(. 
ca00: 20 46 74 73 35 43 6f 6e 74 65 78 74 20 2a 70 43   Fts5Context *pC
ca10: 74 78 2c 20 0a 20 20 69 6e 74 20 69 43 6f 6c 2c  tx, .  int iCol,
ca20: 20 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a   .  const char *
ca30: 2a 70 7a 2c 20 0a 20 20 69 6e 74 20 2a 70 6e 0a  *pz, .  int *pn.
ca40: 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51  ){.  int rc = SQ
ca50: 4c 49 54 45 5f 4f 4b 3b 0a 20 20 46 74 73 35 43  LITE_OK;.  Fts5C
ca60: 75 72 73 6f 72 20 2a 70 43 73 72 20 3d 20 28 46  ursor *pCsr = (F
ca70: 74 73 35 43 75 72 73 6f 72 2a 29 70 43 74 78 3b  ts5Cursor*)pCtx;
ca80: 0a 20 20 69 66 28 20 66 74 73 35 49 73 43 6f 6e  .  if( fts5IsCon
ca90: 74 65 6e 74 6c 65 73 73 28 28 46 74 73 35 54 61  tentless((Fts5Ta
caa0: 62 6c 65 2a 29 28 70 43 73 72 2d 3e 62 61 73 65  ble*)(pCsr->base
cab0: 2e 70 56 74 61 62 29 29 20 29 7b 0a 20 20 20 20  .pVtab)) ){.    
cac0: 2a 70 7a 20 3d 20 30 3b 0a 20 20 20 20 2a 70 6e  *pz = 0;.    *pn
cad0: 20 3d 20 30 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20   = 0;.  }else{. 
cae0: 20 20 20 72 63 20 3d 20 66 74 73 35 53 65 65 6b     rc = fts5Seek
caf0: 43 75 72 73 6f 72 28 70 43 73 72 29 3b 0a 20 20  Cursor(pCsr);.  
cb00: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
cb10: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 2a 70 7a  _OK ){.      *pz
cb20: 20 3d 20 28 63 6f 6e 73 74 20 63 68 61 72 2a 29   = (const char*)
cb30: 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 74  sqlite3_column_t
cb40: 65 78 74 28 70 43 73 72 2d 3e 70 53 74 6d 74 2c  ext(pCsr->pStmt,
cb50: 20 69 43 6f 6c 2b 31 29 3b 0a 20 20 20 20 20 20   iCol+1);.      
cb60: 2a 70 6e 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f  *pn = sqlite3_co
cb70: 6c 75 6d 6e 5f 62 79 74 65 73 28 70 43 73 72 2d  lumn_bytes(pCsr-
cb80: 3e 70 53 74 6d 74 2c 20 69 43 6f 6c 2b 31 29 3b  >pStmt, iCol+1);
cb90: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74  .    }.  }.  ret
cba0: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69  urn rc;.}..stati
cbb0: 63 20 69 6e 74 20 66 74 73 35 41 70 69 43 6f 6c  c int fts5ApiCol
cbc0: 75 6d 6e 53 69 7a 65 28 46 74 73 35 43 6f 6e 74  umnSize(Fts5Cont
cbd0: 65 78 74 20 2a 70 43 74 78 2c 20 69 6e 74 20 69  ext *pCtx, int i
cbe0: 43 6f 6c 2c 20 69 6e 74 20 2a 70 6e 54 6f 6b 65  Col, int *pnToke
cbf0: 6e 29 7b 0a 20 20 46 74 73 35 43 75 72 73 6f 72  n){.  Fts5Cursor
cc00: 20 2a 70 43 73 72 20 3d 20 28 46 74 73 35 43 75   *pCsr = (Fts5Cu
cc10: 72 73 6f 72 2a 29 70 43 74 78 3b 0a 20 20 46 74  rsor*)pCtx;.  Ft
cc20: 73 35 54 61 62 6c 65 20 2a 70 54 61 62 20 3d 20  s5Table *pTab = 
cc30: 28 46 74 73 35 54 61 62 6c 65 2a 29 28 70 43 73  (Fts5Table*)(pCs
cc40: 72 2d 3e 62 61 73 65 2e 70 56 74 61 62 29 3b 0a  r->base.pVtab);.
cc50: 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
cc60: 45 5f 4f 4b 3b 0a 0a 20 20 69 66 28 20 43 73 72  E_OK;..  if( Csr
cc70: 46 6c 61 67 54 65 73 74 28 70 43 73 72 2c 20 46  FlagTest(pCsr, F
cc80: 54 53 35 43 53 52 5f 52 45 51 55 49 52 45 5f 44  TS5CSR_REQUIRE_D
cc90: 4f 43 53 49 5a 45 29 20 29 7b 0a 20 20 20 20 69  OCSIZE) ){.    i
cca0: 36 34 20 69 52 6f 77 69 64 20 3d 20 66 74 73 35  64 iRowid = fts5
ccb0: 43 75 72 73 6f 72 52 6f 77 69 64 28 70 43 73 72  CursorRowid(pCsr
ccc0: 29 3b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69  );.    rc = sqli
ccd0: 74 65 33 46 74 73 35 53 74 6f 72 61 67 65 44 6f  te3Fts5StorageDo
cce0: 63 73 69 7a 65 28 70 54 61 62 2d 3e 70 53 74 6f  csize(pTab->pSto
ccf0: 72 61 67 65 2c 20 69 52 6f 77 69 64 2c 20 70 43  rage, iRowid, pC
cd00: 73 72 2d 3e 61 43 6f 6c 75 6d 6e 53 69 7a 65 29  sr->aColumnSize)
cd10: 3b 0a 20 20 20 20 43 73 72 46 6c 61 67 43 6c 65  ;.    CsrFlagCle
cd20: 61 72 28 70 43 73 72 2c 20 46 54 53 35 43 53 52  ar(pCsr, FTS5CSR
cd30: 5f 52 45 51 55 49 52 45 5f 44 4f 43 53 49 5a 45  _REQUIRE_DOCSIZE
cd40: 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20 69 43 6f  );.  }.  if( iCo
cd50: 6c 3c 30 20 29 7b 0a 20 20 20 20 69 6e 74 20 69  l<0 ){.    int i
cd60: 3b 0a 20 20 20 20 2a 70 6e 54 6f 6b 65 6e 20 3d  ;.    *pnToken =
cd70: 20 30 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b   0;.    for(i=0;
cd80: 20 69 3c 70 54 61 62 2d 3e 70 43 6f 6e 66 69 67   i<pTab->pConfig
cd90: 2d 3e 6e 43 6f 6c 3b 20 69 2b 2b 29 7b 0a 20 20  ->nCol; i++){.  
cda0: 20 20 20 20 2a 70 6e 54 6f 6b 65 6e 20 2b 3d 20      *pnToken += 
cdb0: 70 43 73 72 2d 3e 61 43 6f 6c 75 6d 6e 53 69 7a  pCsr->aColumnSiz
cdc0: 65 5b 69 5d 3b 0a 20 20 20 20 7d 0a 20 20 7d 65  e[i];.    }.  }e
cdd0: 6c 73 65 20 69 66 28 20 69 43 6f 6c 3c 70 54 61  lse if( iCol<pTa
cde0: 62 2d 3e 70 43 6f 6e 66 69 67 2d 3e 6e 43 6f 6c  b->pConfig->nCol
cdf0: 20 29 7b 0a 20 20 20 20 2a 70 6e 54 6f 6b 65 6e   ){.    *pnToken
ce00: 20 3d 20 70 43 73 72 2d 3e 61 43 6f 6c 75 6d 6e   = pCsr->aColumn
ce10: 53 69 7a 65 5b 69 43 6f 6c 5d 3b 0a 20 20 7d 65  Size[iCol];.  }e
ce20: 6c 73 65 7b 0a 20 20 20 20 2a 70 6e 54 6f 6b 65  lse{.    *pnToke
ce30: 6e 20 3d 20 30 3b 0a 20 20 20 20 72 63 20 3d 20  n = 0;.    rc = 
ce40: 53 51 4c 49 54 45 5f 52 41 4e 47 45 3b 0a 20 20  SQLITE_RANGE;.  
ce50: 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  }.  return rc;.}
ce60: 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e  ../*.** Implemen
ce70: 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 78 53  tation of the xS
ce80: 65 74 41 75 78 64 61 74 61 28 29 20 6d 65 74 68  etAuxdata() meth
ce90: 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  od..*/.static in
cea0: 74 20 66 74 73 35 41 70 69 53 65 74 41 75 78 64  t fts5ApiSetAuxd
ceb0: 61 74 61 28 0a 20 20 46 74 73 35 43 6f 6e 74 65  ata(.  Fts5Conte
cec0: 78 74 20 2a 70 43 74 78 2c 20 20 20 20 20 20 20  xt *pCtx,       
ced0: 20 20 20 20 20 20 20 2f 2a 20 46 74 73 35 20 63         /* Fts5 c
cee0: 6f 6e 74 65 78 74 20 2a 2f 0a 20 20 76 6f 69 64  ontext */.  void
cef0: 20 2a 70 50 74 72 2c 20 20 20 20 20 20 20 20 20   *pPtr,         
cf00: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50              /* P
cf10: 6f 69 6e 74 65 72 20 74 6f 20 73 61 76 65 20 61  ointer to save a
cf20: 73 20 61 75 78 64 61 74 61 20 2a 2f 0a 20 20 76  s auxdata */.  v
cf30: 6f 69 64 28 2a 78 44 65 6c 65 74 65 29 28 76 6f  oid(*xDelete)(vo
cf40: 69 64 2a 29 20 20 20 20 20 20 20 20 20 20 20 2f  id*)           /
cf50: 2a 20 44 65 73 74 72 75 63 74 6f 72 20 66 6f 72  * Destructor for
cf60: 20 70 50 74 72 20 28 6f 72 20 4e 55 4c 4c 29 20   pPtr (or NULL) 
cf70: 2a 2f 0a 29 7b 0a 20 20 46 74 73 35 43 75 72 73  */.){.  Fts5Curs
cf80: 6f 72 20 2a 70 43 73 72 20 3d 20 28 46 74 73 35  or *pCsr = (Fts5
cf90: 43 75 72 73 6f 72 2a 29 70 43 74 78 3b 0a 20 20  Cursor*)pCtx;.  
cfa0: 46 74 73 35 41 75 78 64 61 74 61 20 2a 70 44 61  Fts5Auxdata *pDa
cfb0: 74 61 3b 0a 0a 20 20 2f 2a 20 53 65 61 72 63 68  ta;..  /* Search
cfc0: 20 74 68 72 6f 75 67 68 20 74 68 65 20 63 75 72   through the cur
cfd0: 73 6f 72 73 20 6c 69 73 74 20 6f 66 20 46 74 73  sors list of Fts
cfe0: 35 41 75 78 64 61 74 61 20 6f 62 6a 65 63 74 73  5Auxdata objects
cff0: 20 66 6f 72 20 6f 6e 65 20 74 68 61 74 0a 20 20   for one that.  
d000: 2a 2a 20 63 6f 72 72 65 73 70 6f 6e 64 73 20 74  ** corresponds t
d010: 6f 20 74 68 65 20 63 75 72 72 65 6e 74 6c 79 20  o the currently 
d020: 65 78 65 63 75 74 69 6e 67 20 61 75 78 69 6c 69  executing auxili
d030: 61 72 79 20 66 75 6e 63 74 69 6f 6e 2e 20 20 2a  ary function.  *
d040: 2f 0a 20 20 66 6f 72 28 70 44 61 74 61 3d 70 43  /.  for(pData=pC
d050: 73 72 2d 3e 70 41 75 78 64 61 74 61 3b 20 70 44  sr->pAuxdata; pD
d060: 61 74 61 3b 20 70 44 61 74 61 3d 70 44 61 74 61  ata; pData=pData
d070: 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20 69 66  ->pNext){.    if
d080: 28 20 70 44 61 74 61 2d 3e 70 41 75 78 3d 3d 70  ( pData->pAux==p
d090: 43 73 72 2d 3e 70 41 75 78 20 29 20 62 72 65 61  Csr->pAux ) brea
d0a0: 6b 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 70 44  k;.  }..  if( pD
d0b0: 61 74 61 20 29 7b 0a 20 20 20 20 69 66 28 20 70  ata ){.    if( p
d0c0: 44 61 74 61 2d 3e 78 44 65 6c 65 74 65 20 29 7b  Data->xDelete ){
d0d0: 0a 20 20 20 20 20 20 70 44 61 74 61 2d 3e 78 44  .      pData->xD
d0e0: 65 6c 65 74 65 28 70 44 61 74 61 2d 3e 70 50 74  elete(pData->pPt
d0f0: 72 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 65 6c 73  r);.    }.  }els
d100: 65 7b 0a 20 20 20 20 69 6e 74 20 72 63 20 3d 20  e{.    int rc = 
d110: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 20 20 70  SQLITE_OK;.    p
d120: 44 61 74 61 20 3d 20 28 46 74 73 35 41 75 78 64  Data = (Fts5Auxd
d130: 61 74 61 2a 29 73 71 6c 69 74 65 33 46 74 73 35  ata*)sqlite3Fts5
d140: 4d 61 6c 6c 6f 63 5a 65 72 6f 28 26 72 63 2c 20  MallocZero(&rc, 
d150: 73 69 7a 65 6f 66 28 46 74 73 35 41 75 78 64 61  sizeof(Fts5Auxda
d160: 74 61 29 29 3b 0a 20 20 20 20 69 66 28 20 70 44  ta));.    if( pD
d170: 61 74 61 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  ata==0 ){.      
d180: 69 66 28 20 78 44 65 6c 65 74 65 20 29 20 78 44  if( xDelete ) xD
d190: 65 6c 65 74 65 28 70 50 74 72 29 3b 0a 20 20 20  elete(pPtr);.   
d1a0: 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20     return rc;.  
d1b0: 20 20 7d 0a 20 20 20 20 70 44 61 74 61 2d 3e 70    }.    pData->p
d1c0: 41 75 78 20 3d 20 70 43 73 72 2d 3e 70 41 75 78  Aux = pCsr->pAux
d1d0: 3b 0a 20 20 20 20 70 44 61 74 61 2d 3e 70 4e 65  ;.    pData->pNe
d1e0: 78 74 20 3d 20 70 43 73 72 2d 3e 70 41 75 78 64  xt = pCsr->pAuxd
d1f0: 61 74 61 3b 0a 20 20 20 20 70 43 73 72 2d 3e 70  ata;.    pCsr->p
d200: 41 75 78 64 61 74 61 20 3d 20 70 44 61 74 61 3b  Auxdata = pData;
d210: 0a 20 20 7d 0a 0a 20 20 70 44 61 74 61 2d 3e 78  .  }..  pData->x
d220: 44 65 6c 65 74 65 20 3d 20 78 44 65 6c 65 74 65  Delete = xDelete
d230: 3b 0a 20 20 70 44 61 74 61 2d 3e 70 50 74 72 20  ;.  pData->pPtr 
d240: 3d 20 70 50 74 72 3b 0a 20 20 72 65 74 75 72 6e  = pPtr;.  return
d250: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 73   SQLITE_OK;.}..s
d260: 74 61 74 69 63 20 76 6f 69 64 20 2a 66 74 73 35  tatic void *fts5
d270: 41 70 69 47 65 74 41 75 78 64 61 74 61 28 46 74  ApiGetAuxdata(Ft
d280: 73 35 43 6f 6e 74 65 78 74 20 2a 70 43 74 78 2c  s5Context *pCtx,
d290: 20 69 6e 74 20 62 43 6c 65 61 72 29 7b 0a 20 20   int bClear){.  
d2a0: 46 74 73 35 43 75 72 73 6f 72 20 2a 70 43 73 72  Fts5Cursor *pCsr
d2b0: 20 3d 20 28 46 74 73 35 43 75 72 73 6f 72 2a 29   = (Fts5Cursor*)
d2c0: 70 43 74 78 3b 0a 20 20 46 74 73 35 41 75 78 64  pCtx;.  Fts5Auxd
d2d0: 61 74 61 20 2a 70 44 61 74 61 3b 0a 20 20 76 6f  ata *pData;.  vo
d2e0: 69 64 20 2a 70 52 65 74 20 3d 20 30 3b 0a 0a 20  id *pRet = 0;.. 
d2f0: 20 66 6f 72 28 70 44 61 74 61 3d 70 43 73 72 2d   for(pData=pCsr-
d300: 3e 70 41 75 78 64 61 74 61 3b 20 70 44 61 74 61  >pAuxdata; pData
d310: 3b 20 70 44 61 74 61 3d 70 44 61 74 61 2d 3e 70  ; pData=pData->p
d320: 4e 65 78 74 29 7b 0a 20 20 20 20 69 66 28 20 70  Next){.    if( p
d330: 44 61 74 61 2d 3e 70 41 75 78 3d 3d 70 43 73 72  Data->pAux==pCsr
d340: 2d 3e 70 41 75 78 20 29 20 62 72 65 61 6b 3b 0a  ->pAux ) break;.
d350: 20 20 7d 0a 0a 20 20 69 66 28 20 70 44 61 74 61    }..  if( pData
d360: 20 29 7b 0a 20 20 20 20 70 52 65 74 20 3d 20 70   ){.    pRet = p
d370: 44 61 74 61 2d 3e 70 50 74 72 3b 0a 20 20 20 20  Data->pPtr;.    
d380: 69 66 28 20 62 43 6c 65 61 72 20 29 7b 0a 20 20  if( bClear ){.  
d390: 20 20 20 20 70 44 61 74 61 2d 3e 70 50 74 72 20      pData->pPtr 
d3a0: 3d 20 30 3b 0a 20 20 20 20 20 20 70 44 61 74 61  = 0;.      pData
d3b0: 2d 3e 78 44 65 6c 65 74 65 20 3d 20 30 3b 0a 20  ->xDelete = 0;. 
d3c0: 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75     }.  }..  retu
d3d0: 72 6e 20 70 52 65 74 3b 0a 7d 0a 0a 73 74 61 74  rn pRet;.}..stat
d3e0: 69 63 20 69 6e 74 20 66 74 73 35 41 70 69 51 75  ic int fts5ApiQu
d3f0: 65 72 79 50 68 72 61 73 65 28 46 74 73 35 43 6f  eryPhrase(Fts5Co
d400: 6e 74 65 78 74 2a 2c 20 69 6e 74 2c 20 76 6f 69  ntext*, int, voi
d410: 64 2a 2c 20 0a 20 20 20 20 69 6e 74 28 2a 29 28  d*, .    int(*)(
d420: 63 6f 6e 73 74 20 46 74 73 35 45 78 74 65 6e 73  const Fts5Extens
d430: 69 6f 6e 41 70 69 2a 2c 20 46 74 73 35 43 6f 6e  ionApi*, Fts5Con
d440: 74 65 78 74 2a 2c 20 76 6f 69 64 2a 29 0a 29 3b  text*, void*).);
d450: 0a 0a 73 74 61 74 69 63 20 63 6f 6e 73 74 20 46  ..static const F
d460: 74 73 35 45 78 74 65 6e 73 69 6f 6e 41 70 69 20  ts5ExtensionApi 
d470: 73 46 74 73 35 41 70 69 20 3d 20 7b 0a 20 20 31  sFts5Api = {.  1
d480: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
d490: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
d4a0: 69 56 65 72 73 69 6f 6e 20 2a 2f 0a 20 20 66 74  iVersion */.  ft
d4b0: 73 35 41 70 69 55 73 65 72 44 61 74 61 2c 0a 20  s5ApiUserData,. 
d4c0: 20 66 74 73 35 41 70 69 43 6f 6c 75 6d 6e 43 6f   fts5ApiColumnCo
d4d0: 75 6e 74 2c 0a 20 20 66 74 73 35 41 70 69 52 6f  unt,.  fts5ApiRo
d4e0: 77 43 6f 75 6e 74 2c 0a 20 20 66 74 73 35 41 70  wCount,.  fts5Ap
d4f0: 69 43 6f 6c 75 6d 6e 54 6f 74 61 6c 53 69 7a 65  iColumnTotalSize
d500: 2c 0a 20 20 66 74 73 35 41 70 69 54 6f 6b 65 6e  ,.  fts5ApiToken
d510: 69 7a 65 2c 0a 20 20 66 74 73 35 41 70 69 50 68  ize,.  fts5ApiPh
d520: 72 61 73 65 43 6f 75 6e 74 2c 0a 20 20 66 74 73  raseCount,.  fts
d530: 35 41 70 69 50 68 72 61 73 65 53 69 7a 65 2c 0a  5ApiPhraseSize,.
d540: 20 20 66 74 73 35 41 70 69 49 6e 73 74 43 6f 75    fts5ApiInstCou
d550: 6e 74 2c 0a 20 20 66 74 73 35 41 70 69 49 6e 73  nt,.  fts5ApiIns
d560: 74 2c 0a 20 20 66 74 73 35 41 70 69 52 6f 77 69  t,.  fts5ApiRowi
d570: 64 2c 0a 20 20 66 74 73 35 41 70 69 43 6f 6c 75  d,.  fts5ApiColu
d580: 6d 6e 54 65 78 74 2c 0a 20 20 66 74 73 35 41 70  mnText,.  fts5Ap
d590: 69 43 6f 6c 75 6d 6e 53 69 7a 65 2c 0a 20 20 66  iColumnSize,.  f
d5a0: 74 73 35 41 70 69 51 75 65 72 79 50 68 72 61 73  ts5ApiQueryPhras
d5b0: 65 2c 0a 20 20 66 74 73 35 41 70 69 53 65 74 41  e,.  fts5ApiSetA
d5c0: 75 78 64 61 74 61 2c 0a 20 20 66 74 73 35 41 70  uxdata,.  fts5Ap
d5d0: 69 47 65 74 41 75 78 64 61 74 61 2c 0a 7d 3b 0a  iGetAuxdata,.};.
d5e0: 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e  ../*.** Implemen
d5f0: 74 61 74 69 6f 6e 20 6f 66 20 41 50 49 20 66 75  tation of API fu
d600: 6e 63 74 69 6f 6e 20 78 51 75 65 72 79 50 68 72  nction xQueryPhr
d610: 61 73 65 28 29 2e 0a 2a 2f 0a 73 74 61 74 69 63  ase()..*/.static
d620: 20 69 6e 74 20 66 74 73 35 41 70 69 51 75 65 72   int fts5ApiQuer
d630: 79 50 68 72 61 73 65 28 0a 20 20 46 74 73 35 43  yPhrase(.  Fts5C
d640: 6f 6e 74 65 78 74 20 2a 70 43 74 78 2c 20 0a 20  ontext *pCtx, . 
d650: 20 69 6e 74 20 69 50 68 72 61 73 65 2c 20 0a 20   int iPhrase, . 
d660: 20 76 6f 69 64 20 2a 70 55 73 65 72 44 61 74 61   void *pUserData
d670: 2c 0a 20 20 69 6e 74 28 2a 78 43 61 6c 6c 62 61  ,.  int(*xCallba
d680: 63 6b 29 28 63 6f 6e 73 74 20 46 74 73 35 45 78  ck)(const Fts5Ex
d690: 74 65 6e 73 69 6f 6e 41 70 69 2a 2c 20 46 74 73  tensionApi*, Fts
d6a0: 35 43 6f 6e 74 65 78 74 2a 2c 20 76 6f 69 64 2a  5Context*, void*
d6b0: 29 0a 29 7b 0a 20 20 46 74 73 35 43 75 72 73 6f  ).){.  Fts5Curso
d6c0: 72 20 2a 70 43 73 72 20 3d 20 28 46 74 73 35 43  r *pCsr = (Fts5C
d6d0: 75 72 73 6f 72 2a 29 70 43 74 78 3b 0a 20 20 46  ursor*)pCtx;.  F
d6e0: 74 73 35 54 61 62 6c 65 20 2a 70 54 61 62 20 3d  ts5Table *pTab =
d6f0: 20 28 46 74 73 35 54 61 62 6c 65 2a 29 28 70 43   (Fts5Table*)(pC
d700: 73 72 2d 3e 62 61 73 65 2e 70 56 74 61 62 29 3b  sr->base.pVtab);
d710: 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 46 74 73  .  int rc;.  Fts
d720: 35 43 75 72 73 6f 72 20 2a 70 4e 65 77 20 3d 20  5Cursor *pNew = 
d730: 30 3b 0a 0a 20 20 72 63 20 3d 20 66 74 73 35 4f  0;..  rc = fts5O
d740: 70 65 6e 4d 65 74 68 6f 64 28 70 43 73 72 2d 3e  penMethod(pCsr->
d750: 62 61 73 65 2e 70 56 74 61 62 2c 20 28 73 71 6c  base.pVtab, (sql
d760: 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72  ite3_vtab_cursor
d770: 2a 2a 29 26 70 4e 65 77 29 3b 0a 20 20 69 66 28  **)&pNew);.  if(
d780: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
d790: 7b 0a 20 20 20 20 46 74 73 35 43 6f 6e 66 69 67  {.    Fts5Config
d7a0: 20 2a 70 43 6f 6e 66 20 3d 20 70 54 61 62 2d 3e   *pConf = pTab->
d7b0: 70 43 6f 6e 66 69 67 3b 0a 20 20 20 20 70 4e 65  pConfig;.    pNe
d7c0: 77 2d 3e 65 50 6c 61 6e 20 3d 20 46 54 53 35 5f  w->ePlan = FTS5_
d7d0: 50 4c 41 4e 5f 4d 41 54 43 48 3b 0a 20 20 20 20  PLAN_MATCH;.    
d7e0: 70 4e 65 77 2d 3e 69 46 69 72 73 74 52 6f 77 69  pNew->iFirstRowi
d7f0: 64 20 3d 20 53 4d 41 4c 4c 45 53 54 5f 49 4e 54  d = SMALLEST_INT
d800: 36 34 3b 0a 20 20 20 20 70 4e 65 77 2d 3e 69 4c  64;.    pNew->iL
d810: 61 73 74 52 6f 77 69 64 20 3d 20 4c 41 52 47 45  astRowid = LARGE
d820: 53 54 5f 49 4e 54 36 34 3b 0a 20 20 20 20 70 4e  ST_INT64;.    pN
d830: 65 77 2d 3e 62 61 73 65 2e 70 56 74 61 62 20 3d  ew->base.pVtab =
d840: 20 28 73 71 6c 69 74 65 33 5f 76 74 61 62 2a 29   (sqlite3_vtab*)
d850: 70 54 61 62 3b 0a 20 20 20 20 72 63 20 3d 20 73  pTab;.    rc = s
d860: 71 6c 69 74 65 33 46 74 73 35 45 78 70 72 50 68  qlite3Fts5ExprPh
d870: 72 61 73 65 45 78 70 72 28 70 43 6f 6e 66 2c 20  raseExpr(pConf, 
d880: 70 43 73 72 2d 3e 70 45 78 70 72 2c 20 69 50 68  pCsr->pExpr, iPh
d890: 72 61 73 65 2c 20 26 70 4e 65 77 2d 3e 70 45 78  rase, &pNew->pEx
d8a0: 70 72 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20  pr);.  }..  if( 
d8b0: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
d8c0: 0a 20 20 20 20 66 6f 72 28 72 63 20 3d 20 66 74  .    for(rc = ft
d8d0: 73 35 43 75 72 73 6f 72 46 69 72 73 74 28 70 54  s5CursorFirst(pT
d8e0: 61 62 2c 20 70 4e 65 77 2c 20 30 29 3b 0a 20 20  ab, pNew, 0);.  
d8f0: 20 20 20 20 20 20 72 63 3d 3d 53 51 4c 49 54 45        rc==SQLITE
d900: 5f 4f 4b 20 26 26 20 43 73 72 46 6c 61 67 54 65  _OK && CsrFlagTe
d910: 73 74 28 70 4e 65 77 2c 20 46 54 53 35 43 53 52  st(pNew, FTS5CSR
d920: 5f 45 4f 46 29 3d 3d 30 3b 0a 20 20 20 20 20 20  _EOF)==0;.      
d930: 20 20 72 63 20 3d 20 66 74 73 35 4e 65 78 74 4d    rc = fts5NextM
d940: 65 74 68 6f 64 28 28 73 71 6c 69 74 65 33 5f 76  ethod((sqlite3_v
d950: 74 61 62 5f 63 75 72 73 6f 72 2a 29 70 4e 65 77  tab_cursor*)pNew
d960: 29 0a 20 20 20 20 29 7b 0a 20 20 20 20 20 20 72  ).    ){.      r
d970: 63 20 3d 20 78 43 61 6c 6c 62 61 63 6b 28 26 73  c = xCallback(&s
d980: 46 74 73 35 41 70 69 2c 20 28 46 74 73 35 43 6f  Fts5Api, (Fts5Co
d990: 6e 74 65 78 74 2a 29 70 4e 65 77 2c 20 70 55 73  ntext*)pNew, pUs
d9a0: 65 72 44 61 74 61 29 3b 0a 20 20 20 20 20 20 69  erData);.      i
d9b0: 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
d9c0: 20 29 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20   ){.        if( 
d9d0: 72 63 3d 3d 53 51 4c 49 54 45 5f 44 4f 4e 45 20  rc==SQLITE_DONE 
d9e0: 29 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b  ) rc = SQLITE_OK
d9f0: 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b  ;.        break;
da00: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
da10: 20 7d 0a 0a 20 20 66 74 73 35 43 6c 6f 73 65 4d   }..  fts5CloseM
da20: 65 74 68 6f 64 28 28 73 71 6c 69 74 65 33 5f 76  ethod((sqlite3_v
da30: 74 61 62 5f 63 75 72 73 6f 72 2a 29 70 4e 65 77  tab_cursor*)pNew
da40: 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  );.  return rc;.
da50: 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 66  }..static void f
da60: 74 73 35 41 70 69 49 6e 76 6f 6b 65 28 0a 20 20  ts5ApiInvoke(.  
da70: 46 74 73 35 41 75 78 69 6c 69 61 72 79 20 2a 70  Fts5Auxiliary *p
da80: 41 75 78 2c 0a 20 20 46 74 73 35 43 75 72 73 6f  Aux,.  Fts5Curso
da90: 72 20 2a 70 43 73 72 2c 0a 20 20 73 71 6c 69 74  r *pCsr,.  sqlit
daa0: 65 33 5f 63 6f 6e 74 65 78 74 20 2a 63 6f 6e 74  e3_context *cont
dab0: 65 78 74 2c 0a 20 20 69 6e 74 20 61 72 67 63 2c  ext,.  int argc,
dac0: 0a 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65  .  sqlite3_value
dad0: 20 2a 2a 61 72 67 76 0a 29 7b 0a 20 20 61 73 73   **argv.){.  ass
dae0: 65 72 74 28 20 70 43 73 72 2d 3e 70 41 75 78 3d  ert( pCsr->pAux=
daf0: 3d 30 20 29 3b 0a 20 20 70 43 73 72 2d 3e 70 41  =0 );.  pCsr->pA
db00: 75 78 20 3d 20 70 41 75 78 3b 0a 20 20 70 41 75  ux = pAux;.  pAu
db10: 78 2d 3e 78 46 75 6e 63 28 26 73 46 74 73 35 41  x->xFunc(&sFts5A
db20: 70 69 2c 20 28 46 74 73 35 43 6f 6e 74 65 78 74  pi, (Fts5Context
db30: 2a 29 70 43 73 72 2c 20 63 6f 6e 74 65 78 74 2c  *)pCsr, context,
db40: 20 61 72 67 63 2c 20 61 72 67 76 29 3b 0a 20 20   argc, argv);.  
db50: 70 43 73 72 2d 3e 70 41 75 78 20 3d 20 30 3b 0a  pCsr->pAux = 0;.
db60: 7d 0a 0a 73 74 61 74 69 63 20 46 74 73 35 43 75  }..static Fts5Cu
db70: 72 73 6f 72 20 2a 66 74 73 35 43 75 72 73 6f 72  rsor *fts5Cursor
db80: 46 72 6f 6d 43 73 72 69 64 28 46 74 73 35 47 6c  FromCsrid(Fts5Gl
db90: 6f 62 61 6c 20 2a 70 47 6c 6f 62 61 6c 2c 20 69  obal *pGlobal, i
dba0: 36 34 20 69 43 73 72 49 64 29 7b 0a 20 20 46 74  64 iCsrId){.  Ft
dbb0: 73 35 43 75 72 73 6f 72 20 2a 70 43 73 72 3b 0a  s5Cursor *pCsr;.
dbc0: 20 20 66 6f 72 28 70 43 73 72 3d 70 47 6c 6f 62    for(pCsr=pGlob
dbd0: 61 6c 2d 3e 70 43 73 72 3b 20 70 43 73 72 3b 20  al->pCsr; pCsr; 
dbe0: 70 43 73 72 3d 70 43 73 72 2d 3e 70 4e 65 78 74  pCsr=pCsr->pNext
dbf0: 29 7b 0a 20 20 20 20 69 66 28 20 70 43 73 72 2d  ){.    if( pCsr-
dc00: 3e 69 43 73 72 49 64 3d 3d 69 43 73 72 49 64 20  >iCsrId==iCsrId 
dc10: 29 20 62 72 65 61 6b 3b 0a 20 20 7d 0a 20 20 72  ) break;.  }.  r
dc20: 65 74 75 72 6e 20 70 43 73 72 3b 0a 7d 0a 0a 73  eturn pCsr;.}..s
dc30: 74 61 74 69 63 20 76 6f 69 64 20 66 74 73 35 41  tatic void fts5A
dc40: 70 69 43 61 6c 6c 62 61 63 6b 28 0a 20 20 73 71  piCallback(.  sq
dc50: 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74 20 2a 63  lite3_context *c
dc60: 6f 6e 74 65 78 74 2c 0a 20 20 69 6e 74 20 61 72  ontext,.  int ar
dc70: 67 63 2c 0a 20 20 73 71 6c 69 74 65 33 5f 76 61  gc,.  sqlite3_va
dc80: 6c 75 65 20 2a 2a 61 72 67 76 0a 29 7b 0a 0a 20  lue **argv.){.. 
dc90: 20 46 74 73 35 41 75 78 69 6c 69 61 72 79 20 2a   Fts5Auxiliary *
dca0: 70 41 75 78 3b 0a 20 20 46 74 73 35 43 75 72 73  pAux;.  Fts5Curs
dcb0: 6f 72 20 2a 70 43 73 72 3b 0a 20 20 69 36 34 20  or *pCsr;.  i64 
dcc0: 69 43 73 72 49 64 3b 0a 0a 20 20 61 73 73 65 72  iCsrId;..  asser
dcd0: 74 28 20 61 72 67 63 3e 3d 31 20 29 3b 0a 20 20  t( argc>=1 );.  
dce0: 70 41 75 78 20 3d 20 28 46 74 73 35 41 75 78 69  pAux = (Fts5Auxi
dcf0: 6c 69 61 72 79 2a 29 73 71 6c 69 74 65 33 5f 75  liary*)sqlite3_u
dd00: 73 65 72 5f 64 61 74 61 28 63 6f 6e 74 65 78 74  ser_data(context
dd10: 29 3b 0a 20 20 69 43 73 72 49 64 20 3d 20 73 71  );.  iCsrId = sq
dd20: 6c 69 74 65 33 5f 76 61 6c 75 65 5f 69 6e 74 36  lite3_value_int6
dd30: 34 28 61 72 67 76 5b 30 5d 29 3b 0a 0a 20 20 70  4(argv[0]);..  p
dd40: 43 73 72 20 3d 20 66 74 73 35 43 75 72 73 6f 72  Csr = fts5Cursor
dd50: 46 72 6f 6d 43 73 72 69 64 28 70 41 75 78 2d 3e  FromCsrid(pAux->
dd60: 70 47 6c 6f 62 61 6c 2c 20 69 43 73 72 49 64 29  pGlobal, iCsrId)
dd70: 3b 0a 20 20 69 66 28 20 70 43 73 72 3d 3d 30 20  ;.  if( pCsr==0 
dd80: 29 7b 0a 20 20 20 20 63 68 61 72 20 2a 7a 45 72  ){.    char *zEr
dd90: 72 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69  r = sqlite3_mpri
dda0: 6e 74 66 28 22 6e 6f 20 73 75 63 68 20 63 75 72  ntf("no such cur
ddb0: 73 6f 72 3a 20 25 6c 6c 64 22 2c 20 69 43 73 72  sor: %lld", iCsr
ddc0: 49 64 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33  Id);.    sqlite3
ddd0: 5f 72 65 73 75 6c 74 5f 65 72 72 6f 72 28 63 6f  _result_error(co
dde0: 6e 74 65 78 74 2c 20 7a 45 72 72 2c 20 2d 31 29  ntext, zErr, -1)
ddf0: 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72  ;.    sqlite3_fr
de00: 65 65 28 7a 45 72 72 29 3b 0a 20 20 7d 65 6c 73  ee(zErr);.  }els
de10: 65 7b 0a 20 20 20 20 66 74 73 35 41 70 69 49 6e  e{.    fts5ApiIn
de20: 76 6f 6b 65 28 70 41 75 78 2c 20 70 43 73 72 2c  voke(pAux, pCsr,
de30: 20 63 6f 6e 74 65 78 74 2c 20 61 72 67 63 2d 31   context, argc-1
de40: 2c 20 26 61 72 67 76 5b 31 5d 29 3b 0a 20 20 7d  , &argv[1]);.  }
de50: 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 47 69 76 65 6e  .}.../*.** Given
de60: 20 63 75 72 73 6f 72 20 69 64 20 69 49 64 2c 20   cursor id iId, 
de70: 72 65 74 75 72 6e 20 61 20 70 6f 69 6e 74 65 72  return a pointer
de80: 20 74 6f 20 74 68 65 20 63 6f 72 72 65 73 70 6f   to the correspo
de90: 6e 64 69 6e 67 20 46 74 73 35 49 6e 64 65 78 20  nding Fts5Index 
dea0: 0a 2a 2a 20 6f 62 6a 65 63 74 2e 20 4f 72 20 4e  .** object. Or N
deb0: 55 4c 4c 20 49 66 20 74 68 65 20 63 75 72 73 6f  ULL If the curso
dec0: 72 20 69 64 20 64 6f 65 73 20 6e 6f 74 20 65 78  r id does not ex
ded0: 69 73 74 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 73 75  ist..**.** If su
dee0: 63 63 65 73 73 66 75 6c 2c 20 73 65 74 20 2a 70  ccessful, set *p
def0: 6e 43 6f 6c 20 74 6f 20 74 68 65 20 6e 75 6d 62  nCol to the numb
df00: 65 72 20 6f 66 20 69 6e 64 65 78 65 64 20 63 6f  er of indexed co
df10: 6c 75 6d 6e 73 20 69 6e 20 74 68 65 0a 2a 2a 20  lumns in the.** 
df20: 74 61 62 6c 65 20 62 65 66 6f 72 65 20 72 65 74  table before ret
df30: 75 72 6e 69 6e 67 2e 0a 2a 2f 0a 46 74 73 35 49  urning..*/.Fts5I
df40: 6e 64 65 78 20 2a 73 71 6c 69 74 65 33 46 74 73  ndex *sqlite3Fts
df50: 35 49 6e 64 65 78 46 72 6f 6d 43 73 72 69 64 28  5IndexFromCsrid(
df60: 0a 20 20 46 74 73 35 47 6c 6f 62 61 6c 20 2a 70  .  Fts5Global *p
df70: 47 6c 6f 62 61 6c 2c 20 0a 20 20 69 36 34 20 69  Global, .  i64 i
df80: 43 73 72 49 64 2c 20 0a 20 20 69 6e 74 20 2a 70  CsrId, .  int *p
df90: 6e 43 6f 6c 0a 29 7b 0a 20 20 46 74 73 35 43 75  nCol.){.  Fts5Cu
dfa0: 72 73 6f 72 20 2a 70 43 73 72 3b 0a 20 20 46 74  rsor *pCsr;.  Ft
dfb0: 73 35 54 61 62 6c 65 20 2a 70 54 61 62 3b 0a 0a  s5Table *pTab;..
dfc0: 20 20 70 43 73 72 20 3d 20 66 74 73 35 43 75 72    pCsr = fts5Cur
dfd0: 73 6f 72 46 72 6f 6d 43 73 72 69 64 28 70 47 6c  sorFromCsrid(pGl
dfe0: 6f 62 61 6c 2c 20 69 43 73 72 49 64 29 3b 0a 20  obal, iCsrId);. 
dff0: 20 70 54 61 62 20 3d 20 28 46 74 73 35 54 61 62   pTab = (Fts5Tab
e000: 6c 65 2a 29 70 43 73 72 2d 3e 62 61 73 65 2e 70  le*)pCsr->base.p
e010: 56 74 61 62 3b 0a 20 20 2a 70 6e 43 6f 6c 20 3d  Vtab;.  *pnCol =
e020: 20 70 54 61 62 2d 3e 70 43 6f 6e 66 69 67 2d 3e   pTab->pConfig->
e030: 6e 43 6f 6c 3b 0a 0a 20 20 72 65 74 75 72 6e 20  nCol;..  return 
e040: 70 54 61 62 2d 3e 70 49 6e 64 65 78 3b 0a 7d 0a  pTab->pIndex;.}.
e050: 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 61 20  ./*.** Return a 
e060: 22 70 6f 73 69 74 69 6f 6e 2d 6c 69 73 74 20 62  "position-list b
e070: 6c 6f 62 22 20 63 6f 72 72 65 73 70 6f 6e 64 69  lob" correspondi
e080: 6e 67 20 74 6f 20 74 68 65 20 63 75 72 72 65 6e  ng to the curren
e090: 74 20 70 6f 73 69 74 69 6f 6e 20 6f 66 0a 2a 2a  t position of.**
e0a0: 20 63 75 72 73 6f 72 20 70 43 73 72 20 76 69 61   cursor pCsr via
e0b0: 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f   sqlite3_result_
e0c0: 62 6c 6f 62 28 29 2e 20 41 20 70 6f 73 69 74 69  blob(). A positi
e0d0: 6f 6e 2d 6c 69 73 74 20 62 6c 6f 62 20 63 6f 6e  on-list blob con
e0e0: 74 61 69 6e 73 0a 2a 2a 20 74 68 65 20 63 75 72  tains.** the cur
e0f0: 72 65 6e 74 20 70 6f 73 69 74 69 6f 6e 2d 6c 69  rent position-li
e100: 73 74 20 66 6f 72 20 65 61 63 68 20 70 68 72 61  st for each phra
e110: 73 65 20 69 6e 20 74 68 65 20 71 75 65 72 79 20  se in the query 
e120: 61 73 73 6f 63 69 61 74 65 64 20 77 69 74 68 0a  associated with.
e130: 2a 2a 20 63 75 72 73 6f 72 20 70 43 73 72 2e 0a  ** cursor pCsr..
e140: 2a 2a 0a 2a 2a 20 41 20 70 6f 73 69 74 69 6f 6e  **.** A position
e150: 2d 6c 69 73 74 20 62 6c 6f 62 20 62 65 67 69 6e  -list blob begin
e160: 73 20 77 69 74 68 20 28 6e 50 68 72 61 73 65 2d  s with (nPhrase-
e170: 31 29 20 76 61 72 69 6e 74 73 2c 20 77 68 65 72  1) varints, wher
e180: 65 20 6e 50 68 72 61 73 65 20 69 73 0a 2a 2a 20  e nPhrase is.** 
e190: 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 70 68  the number of ph
e1a0: 72 61 73 65 73 20 69 6e 20 74 68 65 20 71 75 65  rases in the que
e1b0: 72 79 2e 20 46 6f 6c 6c 6f 77 69 6e 67 20 74 68  ry. Following th
e1c0: 65 20 76 61 72 69 6e 74 73 20 61 72 65 20 74 68  e varints are th
e1d0: 65 0a 2a 2a 20 63 6f 6e 63 61 74 65 6e 61 74 65  e.** concatenate
e1e0: 64 20 70 6f 73 69 74 69 6f 6e 20 6c 69 73 74 73  d position lists
e1f0: 20 66 6f 72 20 65 61 63 68 20 70 68 72 61 73 65   for each phrase
e200: 2c 20 69 6e 20 6f 72 64 65 72 2e 0a 2a 2a 0a 2a  , in order..**.*
e210: 2a 20 54 68 65 20 66 69 72 73 74 20 76 61 72 69  * The first vari
e220: 6e 74 20 28 69 66 20 69 74 20 65 78 69 73 74 73  nt (if it exists
e230: 29 20 63 6f 6e 74 61 69 6e 73 20 74 68 65 20 73  ) contains the s
e240: 69 7a 65 20 6f 66 20 74 68 65 20 70 6f 73 69 74  ize of the posit
e250: 69 6f 6e 20 6c 69 73 74 0a 2a 2a 20 66 6f 72 20  ion list.** for 
e260: 70 68 72 61 73 65 20 30 2e 20 54 68 65 20 73 65  phrase 0. The se
e270: 63 6f 6e 64 20 28 73 61 6d 65 20 64 69 73 63 6c  cond (same discl
e280: 61 69 6d 65 72 29 20 63 6f 6e 74 61 69 6e 73 20  aimer) contains 
e290: 74 68 65 20 73 69 7a 65 20 6f 66 20 70 6f 73 69  the size of posi
e2a0: 74 69 6f 6e 0a 2a 2a 20 6c 69 73 74 20 31 2e 20  tion.** list 1. 
e2b0: 41 6e 64 20 73 6f 20 6f 6e 2e 20 54 68 65 72 65  And so on. There
e2c0: 20 69 73 20 6e 6f 20 73 69 7a 65 20 66 69 65 6c   is no size fiel
e2d0: 64 20 66 6f 72 20 74 68 65 20 66 69 6e 61 6c 20  d for the final 
e2e0: 70 6f 73 69 74 69 6f 6e 20 6c 69 73 74 2c 0a 2a  position list,.*
e2f0: 2a 20 61 73 20 69 74 20 63 61 6e 20 62 65 20 64  * as it can be d
e300: 65 72 69 76 65 64 20 66 72 6f 6d 20 74 68 65 20  erived from the 
e310: 74 6f 74 61 6c 20 73 69 7a 65 20 6f 66 20 74 68  total size of th
e320: 65 20 62 6c 6f 62 2e 0a 2a 2f 0a 73 74 61 74 69  e blob..*/.stati
e330: 63 20 69 6e 74 20 66 74 73 35 50 6f 73 6c 69 73  c int fts5Poslis
e340: 74 42 6c 6f 62 28 73 71 6c 69 74 65 33 5f 63 6f  tBlob(sqlite3_co
e350: 6e 74 65 78 74 20 2a 70 43 74 78 2c 20 46 74 73  ntext *pCtx, Fts
e360: 35 43 75 72 73 6f 72 20 2a 70 43 73 72 29 7b 0a  5Cursor *pCsr){.
e370: 20 20 69 6e 74 20 69 3b 0a 20 20 69 6e 74 20 72    int i;.  int r
e380: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  c = SQLITE_OK;. 
e390: 20 69 6e 74 20 6e 50 68 72 61 73 65 20 3d 20 73   int nPhrase = s
e3a0: 71 6c 69 74 65 33 46 74 73 35 45 78 70 72 50 68  qlite3Fts5ExprPh
e3b0: 72 61 73 65 43 6f 75 6e 74 28 70 43 73 72 2d 3e  raseCount(pCsr->
e3c0: 70 45 78 70 72 29 3b 0a 20 20 46 74 73 35 42 75  pExpr);.  Fts5Bu
e3d0: 66 66 65 72 20 76 61 6c 3b 0a 0a 20 20 6d 65 6d  ffer val;..  mem
e3e0: 73 65 74 28 26 76 61 6c 2c 20 30 2c 20 73 69 7a  set(&val, 0, siz
e3f0: 65 6f 66 28 46 74 73 35 42 75 66 66 65 72 29 29  eof(Fts5Buffer))
e400: 3b 0a 0a 20 20 2f 2a 20 41 70 70 65 6e 64 20 74  ;..  /* Append t
e410: 68 65 20 76 61 72 69 6e 74 73 20 2a 2f 0a 20 20  he varints */.  
e420: 66 6f 72 28 69 3d 30 3b 20 69 3c 28 6e 50 68 72  for(i=0; i<(nPhr
e430: 61 73 65 2d 31 29 3b 20 69 2b 2b 29 7b 0a 20 20  ase-1); i++){.  
e440: 20 20 63 6f 6e 73 74 20 75 38 20 2a 64 75 6d 6d    const u8 *dumm
e450: 79 3b 0a 20 20 20 20 69 6e 74 20 6e 42 79 74 65  y;.    int nByte
e460: 20 3d 20 73 71 6c 69 74 65 33 46 74 73 35 45 78   = sqlite3Fts5Ex
e470: 70 72 50 6f 73 6c 69 73 74 28 70 43 73 72 2d 3e  prPoslist(pCsr->
e480: 70 45 78 70 72 2c 20 69 2c 20 26 64 75 6d 6d 79  pExpr, i, &dummy
e490: 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 46 74  );.    sqlite3Ft
e4a0: 73 35 42 75 66 66 65 72 41 70 70 65 6e 64 56 61  s5BufferAppendVa
e4b0: 72 69 6e 74 28 26 72 63 2c 20 26 76 61 6c 2c 20  rint(&rc, &val, 
e4c0: 6e 42 79 74 65 29 3b 0a 20 20 7d 0a 0a 20 20 2f  nByte);.  }..  /
e4d0: 2a 20 41 70 70 65 6e 64 20 74 68 65 20 70 6f 73  * Append the pos
e4e0: 69 74 69 6f 6e 20 6c 69 73 74 73 20 2a 2f 0a 20  ition lists */. 
e4f0: 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 50 68 72   for(i=0; i<nPhr
e500: 61 73 65 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 63  ase; i++){.    c
e510: 6f 6e 73 74 20 75 38 20 2a 70 50 6f 73 6c 69 73  onst u8 *pPoslis
e520: 74 3b 0a 20 20 20 20 69 6e 74 20 6e 50 6f 73 6c  t;.    int nPosl
e530: 69 73 74 3b 0a 20 20 20 20 6e 50 6f 73 6c 69 73  ist;.    nPoslis
e540: 74 20 3d 20 73 71 6c 69 74 65 33 46 74 73 35 45  t = sqlite3Fts5E
e550: 78 70 72 50 6f 73 6c 69 73 74 28 70 43 73 72 2d  xprPoslist(pCsr-
e560: 3e 70 45 78 70 72 2c 20 69 2c 20 26 70 50 6f 73  >pExpr, i, &pPos
e570: 6c 69 73 74 29 3b 0a 20 20 20 20 73 71 6c 69 74  list);.    sqlit
e580: 65 33 46 74 73 35 42 75 66 66 65 72 41 70 70 65  e3Fts5BufferAppe
e590: 6e 64 42 6c 6f 62 28 26 72 63 2c 20 26 76 61 6c  ndBlob(&rc, &val
e5a0: 2c 20 6e 50 6f 73 6c 69 73 74 2c 20 70 50 6f 73  , nPoslist, pPos
e5b0: 6c 69 73 74 29 3b 0a 20 20 7d 0a 0a 20 20 73 71  list);.  }..  sq
e5c0: 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 62 6c 6f  lite3_result_blo
e5d0: 62 28 70 43 74 78 2c 20 76 61 6c 2e 70 2c 20 76  b(pCtx, val.p, v
e5e0: 61 6c 2e 6e 2c 20 73 71 6c 69 74 65 33 5f 66 72  al.n, sqlite3_fr
e5f0: 65 65 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63  ee);.  return rc
e600: 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 54 68 69 73  ;.}../* .** This
e610: 20 69 73 20 74 68 65 20 78 43 6f 6c 75 6d 6e 20   is the xColumn 
e620: 6d 65 74 68 6f 64 2c 20 63 61 6c 6c 65 64 20 62  method, called b
e630: 79 20 53 51 4c 69 74 65 20 74 6f 20 72 65 71 75  y SQLite to requ
e640: 65 73 74 20 61 20 76 61 6c 75 65 20 66 72 6f 6d  est a value from
e650: 0a 2a 2a 20 74 68 65 20 72 6f 77 20 74 68 61 74  .** the row that
e660: 20 74 68 65 20 73 75 70 70 6c 69 65 64 20 63 75   the supplied cu
e670: 72 73 6f 72 20 63 75 72 72 65 6e 74 6c 79 20 70  rsor currently p
e680: 6f 69 6e 74 73 20 74 6f 2e 0a 2a 2f 0a 73 74 61  oints to..*/.sta
e690: 74 69 63 20 69 6e 74 20 66 74 73 35 43 6f 6c 75  tic int fts5Colu
e6a0: 6d 6e 4d 65 74 68 6f 64 28 0a 20 20 73 71 6c 69  mnMethod(.  sqli
e6b0: 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20  te3_vtab_cursor 
e6c0: 2a 70 43 75 72 73 6f 72 2c 20 20 20 2f 2a 20 43  *pCursor,   /* C
e6d0: 75 72 73 6f 72 20 74 6f 20 72 65 74 72 69 65 76  ursor to retriev
e6e0: 65 20 76 61 6c 75 65 20 66 72 6f 6d 20 2a 2f 0a  e value from */.
e6f0: 20 20 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78    sqlite3_contex
e700: 74 20 2a 70 43 74 78 2c 20 20 20 20 20 20 20 20  t *pCtx,        
e710: 20 20 2f 2a 20 43 6f 6e 74 65 78 74 20 66 6f 72    /* Context for
e720: 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f   sqlite3_result_
e730: 78 78 78 28 29 20 63 61 6c 6c 73 20 2a 2f 0a 20  xxx() calls */. 
e740: 20 69 6e 74 20 69 43 6f 6c 20 20 20 20 20 20 20   int iCol       
e750: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
e760: 20 2f 2a 20 49 6e 64 65 78 20 6f 66 20 63 6f 6c   /* Index of col
e770: 75 6d 6e 20 74 6f 20 72 65 61 64 20 76 61 6c 75  umn to read valu
e780: 65 20 66 72 6f 6d 20 2a 2f 0a 29 7b 0a 20 20 46  e from */.){.  F
e790: 74 73 35 54 61 62 6c 65 20 2a 70 54 61 62 20 3d  ts5Table *pTab =
e7a0: 20 28 46 74 73 35 54 61 62 6c 65 2a 29 28 70 43   (Fts5Table*)(pC
e7b0: 75 72 73 6f 72 2d 3e 70 56 74 61 62 29 3b 0a 20  ursor->pVtab);. 
e7c0: 20 46 74 73 35 43 6f 6e 66 69 67 20 2a 70 43 6f   Fts5Config *pCo
e7d0: 6e 66 69 67 20 3d 20 70 54 61 62 2d 3e 70 43 6f  nfig = pTab->pCo
e7e0: 6e 66 69 67 3b 0a 20 20 46 74 73 35 43 75 72 73  nfig;.  Fts5Curs
e7f0: 6f 72 20 2a 70 43 73 72 20 3d 20 28 46 74 73 35  or *pCsr = (Fts5
e800: 43 75 72 73 6f 72 2a 29 70 43 75 72 73 6f 72 3b  Cursor*)pCursor;
e810: 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49  .  int rc = SQLI
e820: 54 45 5f 4f 4b 3b 0a 20 20 0a 20 20 61 73 73 65  TE_OK;.  .  asse
e830: 72 74 28 20 43 73 72 46 6c 61 67 54 65 73 74 28  rt( CsrFlagTest(
e840: 70 43 73 72 2c 20 46 54 53 35 43 53 52 5f 45 4f  pCsr, FTS5CSR_EO
e850: 46 29 3d 3d 30 20 29 3b 0a 0a 20 20 69 66 28 20  F)==0 );..  if( 
e860: 70 43 73 72 2d 3e 65 50 6c 61 6e 3d 3d 46 54 53  pCsr->ePlan==FTS
e870: 35 5f 50 4c 41 4e 5f 53 50 45 43 49 41 4c 20 29  5_PLAN_SPECIAL )
e880: 7b 0a 20 20 20 20 69 66 28 20 69 43 6f 6c 3d 3d  {.    if( iCol==
e890: 70 43 6f 6e 66 69 67 2d 3e 6e 43 6f 6c 20 29 7b  pConfig->nCol ){
e8a0: 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 72  .      sqlite3_r
e8b0: 65 73 75 6c 74 5f 69 6e 74 36 34 28 70 43 74 78  esult_int64(pCtx
e8c0: 2c 20 70 43 73 72 2d 3e 69 53 70 65 63 69 61 6c  , pCsr->iSpecial
e8d0: 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 65 6c 73 65  );.    }.  }else
e8e0: 0a 0a 20 20 69 66 28 20 69 43 6f 6c 3d 3d 70 43  ..  if( iCol==pC
e8f0: 6f 6e 66 69 67 2d 3e 6e 43 6f 6c 20 29 7b 0a 20  onfig->nCol ){. 
e900: 20 20 20 2f 2a 20 55 73 65 72 20 69 73 20 72 65     /* User is re
e910: 71 75 65 73 74 69 6e 67 20 74 68 65 20 76 61 6c  questing the val
e920: 75 65 20 6f 66 20 74 68 65 20 73 70 65 63 69 61  ue of the specia
e930: 6c 20 63 6f 6c 75 6d 6e 20 77 69 74 68 20 74 68  l column with th
e940: 65 20 73 61 6d 65 20 6e 61 6d 65 0a 20 20 20 20  e same name.    
e950: 2a 2a 20 61 73 20 74 68 65 20 74 61 62 6c 65 2e  ** as the table.
e960: 20 52 65 74 75 72 6e 20 74 68 65 20 63 75 72 73   Return the curs
e970: 6f 72 20 69 6e 74 65 67 65 72 20 69 64 20 6e 75  or integer id nu
e980: 6d 62 65 72 2e 20 54 68 69 73 20 76 61 6c 75 65  mber. This value
e990: 20 69 73 20 6f 6e 6c 79 0a 20 20 20 20 2a 2a 20   is only.    ** 
e9a0: 75 73 65 66 75 6c 20 69 6e 20 74 68 61 74 20 69  useful in that i
e9b0: 74 20 6d 61 79 20 62 65 20 70 61 73 73 65 64 20  t may be passed 
e9c0: 61 73 20 74 68 65 20 66 69 72 73 74 20 61 72 67  as the first arg
e9d0: 75 6d 65 6e 74 20 74 6f 20 61 6e 20 46 54 53 35  ument to an FTS5
e9e0: 0a 20 20 20 20 2a 2a 20 61 75 78 69 6c 69 61 72  .    ** auxiliar
e9f0: 79 20 66 75 6e 63 74 69 6f 6e 2e 20 20 2a 2f 0a  y function.  */.
ea00: 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75      sqlite3_resu
ea10: 6c 74 5f 69 6e 74 36 34 28 70 43 74 78 2c 20 70  lt_int64(pCtx, p
ea20: 43 73 72 2d 3e 69 43 73 72 49 64 29 3b 0a 20 20  Csr->iCsrId);.  
ea30: 7d 65 6c 73 65 20 69 66 28 20 69 43 6f 6c 3d 3d  }else if( iCol==
ea40: 70 43 6f 6e 66 69 67 2d 3e 6e 43 6f 6c 2b 31 20  pConfig->nCol+1 
ea50: 29 7b 0a 0a 20 20 20 20 2f 2a 20 54 68 65 20 76  ){..    /* The v
ea60: 61 6c 75 65 20 6f 66 20 74 68 65 20 22 72 61 6e  alue of the "ran
ea70: 6b 22 20 63 6f 6c 75 6d 6e 2e 20 2a 2f 0a 20 20  k" column. */.  
ea80: 20 20 69 66 28 20 70 43 73 72 2d 3e 65 50 6c 61    if( pCsr->ePla
ea90: 6e 3d 3d 46 54 53 35 5f 50 4c 41 4e 5f 53 4f 55  n==FTS5_PLAN_SOU
eaa0: 52 43 45 20 29 7b 0a 20 20 20 20 20 20 66 74 73  RCE ){.      fts
eab0: 35 50 6f 73 6c 69 73 74 42 6c 6f 62 28 70 43 74  5PoslistBlob(pCt
eac0: 78 2c 20 70 43 73 72 29 3b 0a 20 20 20 20 7d 65  x, pCsr);.    }e
ead0: 6c 73 65 20 69 66 28 20 0a 20 20 20 20 20 20 20  lse if( .       
eae0: 20 70 43 73 72 2d 3e 65 50 6c 61 6e 3d 3d 46 54   pCsr->ePlan==FT
eaf0: 53 35 5f 50 4c 41 4e 5f 4d 41 54 43 48 0a 20 20  S5_PLAN_MATCH.  
eb00: 20 20 20 7c 7c 20 70 43 73 72 2d 3e 65 50 6c 61     || pCsr->ePla
eb10: 6e 3d 3d 46 54 53 35 5f 50 4c 41 4e 5f 53 4f 52  n==FTS5_PLAN_SOR
eb20: 54 45 44 5f 4d 41 54 43 48 0a 20 20 20 20 29 7b  TED_MATCH.    ){
eb30: 0a 20 20 20 20 20 20 69 66 28 20 70 43 73 72 2d  .      if( pCsr-
eb40: 3e 70 52 61 6e 6b 20 7c 7c 20 53 51 4c 49 54 45  >pRank || SQLITE
eb50: 5f 4f 4b 3d 3d 28 72 63 20 3d 20 66 74 73 35 46  _OK==(rc = fts5F
eb60: 69 6e 64 52 61 6e 6b 46 75 6e 63 74 69 6f 6e 28  indRankFunction(
eb70: 70 43 73 72 29 29 20 29 7b 0a 20 20 20 20 20 20  pCsr)) ){.      
eb80: 20 20 66 74 73 35 41 70 69 49 6e 76 6f 6b 65 28    fts5ApiInvoke(
eb90: 70 43 73 72 2d 3e 70 52 61 6e 6b 2c 20 70 43 73  pCsr->pRank, pCs
eba0: 72 2c 20 70 43 74 78 2c 20 70 43 73 72 2d 3e 6e  r, pCtx, pCsr->n
ebb0: 52 61 6e 6b 41 72 67 2c 20 70 43 73 72 2d 3e 61  RankArg, pCsr->a
ebc0: 70 52 61 6e 6b 41 72 67 29 3b 0a 20 20 20 20 20  pRankArg);.     
ebd0: 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 65 6c 73 65   }.    }.  }else
ebe0: 20 69 66 28 20 21 66 74 73 35 49 73 43 6f 6e 74   if( !fts5IsCont
ebf0: 65 6e 74 6c 65 73 73 28 70 54 61 62 29 20 29 7b  entless(pTab) ){
ec00: 0a 20 20 20 20 72 63 20 3d 20 66 74 73 35 53 65  .    rc = fts5Se
ec10: 65 6b 43 75 72 73 6f 72 28 70 43 73 72 29 3b 0a  ekCursor(pCsr);.
ec20: 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49      if( rc==SQLI
ec30: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 73  TE_OK ){.      s
ec40: 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 76 61  qlite3_result_va
ec50: 6c 75 65 28 70 43 74 78 2c 20 73 71 6c 69 74 65  lue(pCtx, sqlite
ec60: 33 5f 63 6f 6c 75 6d 6e 5f 76 61 6c 75 65 28 70  3_column_value(p
ec70: 43 73 72 2d 3e 70 53 74 6d 74 2c 20 69 43 6f 6c  Csr->pStmt, iCol
ec80: 2b 31 29 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  +1));.    }.  }.
ec90: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
eca0: 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74  ./*.** This rout
ecb0: 69 6e 65 20 69 6d 70 6c 65 6d 65 6e 74 73 20 74  ine implements t
ecc0: 68 65 20 78 46 69 6e 64 46 75 6e 63 74 69 6f 6e  he xFindFunction
ecd0: 20 6d 65 74 68 6f 64 20 66 6f 72 20 74 68 65 20   method for the 
ece0: 46 54 53 33 0a 2a 2a 20 76 69 72 74 75 61 6c 20  FTS3.** virtual 
ecf0: 74 61 62 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63  table..*/.static
ed00: 20 69 6e 74 20 66 74 73 35 46 69 6e 64 46 75 6e   int fts5FindFun
ed10: 63 74 69 6f 6e 4d 65 74 68 6f 64 28 0a 20 20 73  ctionMethod(.  s
ed20: 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56 74  qlite3_vtab *pVt
ed30: 61 62 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f  ab,            /
ed40: 2a 20 56 69 72 74 75 61 6c 20 74 61 62 6c 65 20  * Virtual table 
ed50: 68 61 6e 64 6c 65 20 2a 2f 0a 20 20 69 6e 74 20  handle */.  int 
ed60: 6e 41 72 67 2c 20 20 20 20 20 20 20 20 20 20 20  nArg,           
ed70: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
ed80: 75 6d 62 65 72 20 6f 66 20 53 51 4c 20 66 75 6e  umber of SQL fun
ed90: 63 74 69 6f 6e 20 61 72 67 75 6d 65 6e 74 73 20  ction arguments 
eda0: 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  */.  const char 
edb0: 2a 7a 4e 61 6d 65 2c 20 20 20 20 20 20 20 20 20  *zName,         
edc0: 20 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20       /* Name of 
edd0: 53 51 4c 20 66 75 6e 63 74 69 6f 6e 20 2a 2f 0a  SQL function */.
ede0: 20 20 76 6f 69 64 20 28 2a 2a 70 78 46 75 6e 63    void (**pxFunc
edf0: 29 28 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78  )(sqlite3_contex
ee00: 74 2a 2c 69 6e 74 2c 73 71 6c 69 74 65 33 5f 76  t*,int,sqlite3_v
ee10: 61 6c 75 65 2a 2a 29 2c 20 2f 2a 20 4f 55 54 3a  alue**), /* OUT:
ee20: 20 52 65 73 75 6c 74 20 2a 2f 0a 20 20 76 6f 69   Result */.  voi
ee30: 64 20 2a 2a 70 70 41 72 67 20 20 20 20 20 20 20  d **ppArg       
ee40: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
ee50: 4f 55 54 3a 20 55 73 65 72 20 64 61 74 61 20 66  OUT: User data f
ee60: 6f 72 20 2a 70 78 46 75 6e 63 20 2a 2f 0a 29 7b  or *pxFunc */.){
ee70: 0a 20 20 46 74 73 35 54 61 62 6c 65 20 2a 70 54  .  Fts5Table *pT
ee80: 61 62 20 3d 20 28 46 74 73 35 54 61 62 6c 65 2a  ab = (Fts5Table*
ee90: 29 70 56 74 61 62 3b 0a 20 20 46 74 73 35 41 75  )pVtab;.  Fts5Au
eea0: 78 69 6c 69 61 72 79 20 2a 70 41 75 78 3b 0a 0a  xiliary *pAux;..
eeb0: 20 20 70 41 75 78 20 3d 20 66 74 73 35 46 69 6e    pAux = fts5Fin
eec0: 64 41 75 78 69 6c 69 61 72 79 28 70 54 61 62 2c  dAuxiliary(pTab,
eed0: 20 7a 4e 61 6d 65 29 3b 0a 20 20 69 66 28 20 70   zName);.  if( p
eee0: 41 75 78 20 29 7b 0a 20 20 20 20 2a 70 78 46 75  Aux ){.    *pxFu
eef0: 6e 63 20 3d 20 66 74 73 35 41 70 69 43 61 6c 6c  nc = fts5ApiCall
ef00: 62 61 63 6b 3b 0a 20 20 20 20 2a 70 70 41 72 67  back;.    *ppArg
ef10: 20 3d 20 28 76 6f 69 64 2a 29 70 41 75 78 3b 0a   = (void*)pAux;.
ef20: 20 20 20 20 72 65 74 75 72 6e 20 31 3b 0a 20 20      return 1;.  
ef30: 7d 0a 0a 20 20 2f 2a 20 4e 6f 20 66 75 6e 63 74  }..  /* No funct
ef40: 69 6f 6e 20 6f 66 20 74 68 65 20 73 70 65 63 69  ion of the speci
ef50: 66 69 65 64 20 6e 61 6d 65 20 77 61 73 20 66 6f  fied name was fo
ef60: 75 6e 64 2e 20 52 65 74 75 72 6e 20 30 2e 20 2a  und. Return 0. *
ef70: 2f 0a 20 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a  /.  return 0;.}.
ef80: 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74  ./*.** Implement
ef90: 61 74 69 6f 6e 20 6f 66 20 46 54 53 33 20 78 52  ation of FTS3 xR
efa0: 65 6e 61 6d 65 20 6d 65 74 68 6f 64 2e 20 52 65  ename method. Re
efb0: 6e 61 6d 65 20 61 6e 20 66 74 73 35 20 74 61 62  name an fts5 tab
efc0: 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  le..*/.static in
efd0: 74 20 66 74 73 35 52 65 6e 61 6d 65 4d 65 74 68  t fts5RenameMeth
efe0: 6f 64 28 0a 20 20 73 71 6c 69 74 65 33 5f 76 74  od(.  sqlite3_vt
eff0: 61 62 20 2a 70 56 74 61 62 2c 20 20 20 20 20 20  ab *pVtab,      
f000: 20 20 20 20 20 20 2f 2a 20 56 69 72 74 75 61 6c        /* Virtual
f010: 20 74 61 62 6c 65 20 68 61 6e 64 6c 65 20 2a 2f   table handle */
f020: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
f030: 4e 61 6d 65 20 20 20 20 20 20 20 20 20 20 20 20  Name            
f040: 20 20 20 2f 2a 20 4e 65 77 20 6e 61 6d 65 20 6f     /* New name o
f050: 66 20 74 61 62 6c 65 20 2a 2f 0a 29 7b 0a 20 20  f table */.){.  
f060: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
f070: 4f 4b 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b  OK;.  return rc;
f080: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 78 53  .}../*.** The xS
f090: 61 76 65 70 6f 69 6e 74 28 29 20 6d 65 74 68 6f  avepoint() metho
f0a0: 64 2e 0a 2a 2a 0a 2a 2a 20 46 6c 75 73 68 20 74  d..**.** Flush t
f0b0: 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 74  he contents of t
f0c0: 68 65 20 70 65 6e 64 69 6e 67 2d 74 65 72 6d 73  he pending-terms
f0d0: 20 74 61 62 6c 65 20 74 6f 20 64 69 73 6b 2e 0a   table to disk..
f0e0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74  */.static int ft
f0f0: 73 35 53 61 76 65 70 6f 69 6e 74 4d 65 74 68 6f  s5SavepointMetho
f100: 64 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a  d(sqlite3_vtab *
f110: 70 56 74 61 62 2c 20 69 6e 74 20 69 53 61 76 65  pVtab, int iSave
f120: 70 6f 69 6e 74 29 7b 0a 20 20 46 74 73 35 54 61  point){.  Fts5Ta
f130: 62 6c 65 20 2a 70 54 61 62 20 3d 20 28 46 74 73  ble *pTab = (Fts
f140: 35 54 61 62 6c 65 2a 29 70 56 74 61 62 3b 0a 20  5Table*)pVtab;. 
f150: 20 66 74 73 35 43 68 65 63 6b 54 72 61 6e 73 61   fts5CheckTransa
f160: 63 74 69 6f 6e 53 74 61 74 65 28 70 54 61 62 2c  ctionState(pTab,
f170: 20 46 54 53 35 5f 53 41 56 45 50 4f 49 4e 54 2c   FTS5_SAVEPOINT,
f180: 20 69 53 61 76 65 70 6f 69 6e 74 29 3b 0a 20 20   iSavepoint);.  
f190: 66 74 73 35 54 72 69 70 43 75 72 73 6f 72 73 28  fts5TripCursors(
f1a0: 70 54 61 62 29 3b 0a 20 20 72 65 74 75 72 6e 20  pTab);.  return 
f1b0: 73 71 6c 69 74 65 33 46 74 73 35 53 74 6f 72 61  sqlite3Fts5Stora
f1c0: 67 65 53 79 6e 63 28 70 54 61 62 2d 3e 70 53 74  geSync(pTab->pSt
f1d0: 6f 72 61 67 65 2c 20 30 29 3b 0a 7d 0a 0a 2f 2a  orage, 0);.}../*
f1e0: 0a 2a 2a 20 54 68 65 20 78 52 65 6c 65 61 73 65  .** The xRelease
f1f0: 28 29 20 6d 65 74 68 6f 64 2e 0a 2a 2a 0a 2a 2a  () method..**.**
f200: 20 54 68 69 73 20 69 73 20 61 20 6e 6f 2d 6f 70   This is a no-op
f210: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
f220: 66 74 73 35 52 65 6c 65 61 73 65 4d 65 74 68 6f  fts5ReleaseMetho
f230: 64 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a  d(sqlite3_vtab *
f240: 70 56 74 61 62 2c 20 69 6e 74 20 69 53 61 76 65  pVtab, int iSave
f250: 70 6f 69 6e 74 29 7b 0a 20 20 46 74 73 35 54 61  point){.  Fts5Ta
f260: 62 6c 65 20 2a 70 54 61 62 20 3d 20 28 46 74 73  ble *pTab = (Fts
f270: 35 54 61 62 6c 65 2a 29 70 56 74 61 62 3b 0a 20  5Table*)pVtab;. 
f280: 20 66 74 73 35 43 68 65 63 6b 54 72 61 6e 73 61   fts5CheckTransa
f290: 63 74 69 6f 6e 53 74 61 74 65 28 70 54 61 62 2c  ctionState(pTab,
f2a0: 20 46 54 53 35 5f 52 45 4c 45 41 53 45 2c 20 69   FTS5_RELEASE, i
f2b0: 53 61 76 65 70 6f 69 6e 74 29 3b 0a 20 20 66 74  Savepoint);.  ft
f2c0: 73 35 54 72 69 70 43 75 72 73 6f 72 73 28 70 54  s5TripCursors(pT
f2d0: 61 62 29 3b 0a 20 20 72 65 74 75 72 6e 20 73 71  ab);.  return sq
f2e0: 6c 69 74 65 33 46 74 73 35 53 74 6f 72 61 67 65  lite3Fts5Storage
f2f0: 53 79 6e 63 28 70 54 61 62 2d 3e 70 53 74 6f 72  Sync(pTab->pStor
f300: 61 67 65 2c 20 30 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  age, 0);.}../*.*
f310: 2a 20 54 68 65 20 78 52 6f 6c 6c 62 61 63 6b 54  * The xRollbackT
f320: 6f 28 29 20 6d 65 74 68 6f 64 2e 0a 2a 2a 0a 2a  o() method..**.*
f330: 2a 20 44 69 73 63 61 72 64 20 74 68 65 20 63 6f  * Discard the co
f340: 6e 74 65 6e 74 73 20 6f 66 20 74 68 65 20 70 65  ntents of the pe
f350: 6e 64 69 6e 67 20 74 65 72 6d 73 20 74 61 62 6c  nding terms tabl
f360: 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  e..*/.static int
f370: 20 66 74 73 35 52 6f 6c 6c 62 61 63 6b 54 6f 4d   fts5RollbackToM
f380: 65 74 68 6f 64 28 73 71 6c 69 74 65 33 5f 76 74  ethod(sqlite3_vt
f390: 61 62 20 2a 70 56 74 61 62 2c 20 69 6e 74 20 69  ab *pVtab, int i
f3a0: 53 61 76 65 70 6f 69 6e 74 29 7b 0a 20 20 46 74  Savepoint){.  Ft
f3b0: 73 35 54 61 62 6c 65 20 2a 70 54 61 62 20 3d 20  s5Table *pTab = 
f3c0: 28 46 74 73 35 54 61 62 6c 65 2a 29 70 56 74 61  (Fts5Table*)pVta
f3d0: 62 3b 0a 20 20 66 74 73 35 43 68 65 63 6b 54 72  b;.  fts5CheckTr
f3e0: 61 6e 73 61 63 74 69 6f 6e 53 74 61 74 65 28 70  ansactionState(p
f3f0: 54 61 62 2c 20 46 54 53 35 5f 52 4f 4c 4c 42 41  Tab, FTS5_ROLLBA
f400: 43 4b 54 4f 2c 20 69 53 61 76 65 70 6f 69 6e 74  CKTO, iSavepoint
f410: 29 3b 0a 20 20 66 74 73 35 54 72 69 70 43 75 72  );.  fts5TripCur
f420: 73 6f 72 73 28 70 54 61 62 29 3b 0a 20 20 72 65  sors(pTab);.  re
f430: 74 75 72 6e 20 73 71 6c 69 74 65 33 46 74 73 35  turn sqlite3Fts5
f440: 53 74 6f 72 61 67 65 52 6f 6c 6c 62 61 63 6b 28  StorageRollback(
f450: 70 54 61 62 2d 3e 70 53 74 6f 72 61 67 65 29 3b  pTab->pStorage);
f460: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 67 69 73 74  .}../*.** Regist
f470: 65 72 20 61 20 6e 65 77 20 61 75 78 69 6c 69 61  er a new auxilia
f480: 72 79 20 66 75 6e 63 74 69 6f 6e 20 77 69 74 68  ry function with
f490: 20 67 6c 6f 62 61 6c 20 63 6f 6e 74 65 78 74 20   global context 
f4a0: 70 47 6c 6f 62 61 6c 2e 0a 2a 2f 0a 73 74 61 74  pGlobal..*/.stat
f4b0: 69 63 20 69 6e 74 20 66 74 73 35 43 72 65 61 74  ic int fts5Creat
f4c0: 65 41 75 78 28 0a 20 20 66 74 73 35 5f 61 70 69  eAux(.  fts5_api
f4d0: 20 2a 70 41 70 69 2c 20 20 20 20 20 20 20 20 20   *pApi,         
f4e0: 20 20 20 20 20 20 20 20 2f 2a 20 47 6c 6f 62 61          /* Globa
f4f0: 6c 20 63 6f 6e 74 65 78 74 20 28 6f 6e 65 20 70  l context (one p
f500: 65 72 20 64 62 20 68 61 6e 64 6c 65 29 20 2a 2f  er db handle) */
f510: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
f520: 4e 61 6d 65 2c 20 20 20 20 20 20 20 20 20 20 20  Name,           
f530: 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 6e 65     /* Name of ne
f540: 77 20 66 75 6e 63 74 69 6f 6e 20 2a 2f 0a 20 20  w function */.  
f550: 76 6f 69 64 20 2a 70 55 73 65 72 44 61 74 61 2c  void *pUserData,
f560: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
f570: 2f 2a 20 55 73 65 72 20 64 61 74 61 20 66 6f 72  /* User data for
f580: 20 61 75 78 2e 20 66 75 6e 63 74 69 6f 6e 20 2a   aux. function *
f590: 2f 0a 20 20 66 74 73 35 5f 65 78 74 65 6e 73 69  /.  fts5_extensi
f5a0: 6f 6e 5f 66 75 6e 63 74 69 6f 6e 20 78 46 75 6e  on_function xFun
f5b0: 63 2c 20 20 2f 2a 20 41 75 78 2e 20 66 75 6e 63  c,  /* Aux. func
f5c0: 74 69 6f 6e 20 69 6d 70 6c 65 6d 65 6e 74 61 74  tion implementat
f5d0: 69 6f 6e 20 2a 2f 0a 20 20 76 6f 69 64 28 2a 78  ion */.  void(*x
f5e0: 44 65 73 74 72 6f 79 29 28 76 6f 69 64 2a 29 20  Destroy)(void*) 
f5f0: 20 20 20 20 20 20 20 20 20 2f 2a 20 44 65 73 74           /* Dest
f600: 72 75 63 74 6f 72 20 66 6f 72 20 70 55 73 65 72  ructor for pUser
f610: 44 61 74 61 20 2a 2f 0a 29 7b 0a 20 20 46 74 73  Data */.){.  Fts
f620: 35 47 6c 6f 62 61 6c 20 2a 70 47 6c 6f 62 61 6c  5Global *pGlobal
f630: 20 3d 20 28 46 74 73 35 47 6c 6f 62 61 6c 2a 29   = (Fts5Global*)
f640: 70 41 70 69 3b 0a 20 20 69 6e 74 20 72 63 20 3d  pApi;.  int rc =
f650: 20 73 71 6c 69 74 65 33 5f 6f 76 65 72 6c 6f 61   sqlite3_overloa
f660: 64 5f 66 75 6e 63 74 69 6f 6e 28 70 47 6c 6f 62  d_function(pGlob
f670: 61 6c 2d 3e 64 62 2c 20 7a 4e 61 6d 65 2c 20 2d  al->db, zName, -
f680: 31 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51  1);.  if( rc==SQ
f690: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 46  LITE_OK ){.    F
f6a0: 74 73 35 41 75 78 69 6c 69 61 72 79 20 2a 70 41  ts5Auxiliary *pA
f6b0: 75 78 3b 0a 20 20 20 20 69 6e 74 20 6e 42 79 74  ux;.    int nByt
f6c0: 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e;              
f6d0: 20 20 20 20 20 20 20 20 2f 2a 20 42 79 74 65 73          /* Bytes
f6e0: 20 6f 66 20 73 70 61 63 65 20 74 6f 20 61 6c 6c   of space to all
f6f0: 6f 63 61 74 65 20 2a 2f 0a 0a 20 20 20 20 6e 42  ocate */..    nB
f700: 79 74 65 20 3d 20 73 69 7a 65 6f 66 28 46 74 73  yte = sizeof(Fts
f710: 35 41 75 78 69 6c 69 61 72 79 29 20 2b 20 73 74  5Auxiliary) + st
f720: 72 6c 65 6e 28 7a 4e 61 6d 65 29 20 2b 20 31 3b  rlen(zName) + 1;
f730: 0a 20 20 20 20 70 41 75 78 20 3d 20 28 46 74 73  .    pAux = (Fts
f740: 35 41 75 78 69 6c 69 61 72 79 2a 29 73 71 6c 69  5Auxiliary*)sqli
f750: 74 65 33 5f 6d 61 6c 6c 6f 63 28 6e 42 79 74 65  te3_malloc(nByte
f760: 29 3b 0a 20 20 20 20 69 66 28 20 70 41 75 78 20  );.    if( pAux 
f770: 29 7b 0a 20 20 20 20 20 20 6d 65 6d 73 65 74 28  ){.      memset(
f780: 70 41 75 78 2c 20 30 2c 20 6e 42 79 74 65 29 3b  pAux, 0, nByte);
f790: 0a 20 20 20 20 20 20 70 41 75 78 2d 3e 7a 46 75  .      pAux->zFu
f7a0: 6e 63 20 3d 20 28 63 68 61 72 2a 29 26 70 41 75  nc = (char*)&pAu
f7b0: 78 5b 31 5d 3b 0a 20 20 20 20 20 20 73 74 72 63  x[1];.      strc
f7c0: 70 79 28 70 41 75 78 2d 3e 7a 46 75 6e 63 2c 20  py(pAux->zFunc, 
f7d0: 7a 4e 61 6d 65 29 3b 0a 20 20 20 20 20 20 70 41  zName);.      pA
f7e0: 75 78 2d 3e 70 47 6c 6f 62 61 6c 20 3d 20 70 47  ux->pGlobal = pG
f7f0: 6c 6f 62 61 6c 3b 0a 20 20 20 20 20 20 70 41 75  lobal;.      pAu
f800: 78 2d 3e 70 55 73 65 72 44 61 74 61 20 3d 20 70  x->pUserData = p
f810: 55 73 65 72 44 61 74 61 3b 0a 20 20 20 20 20 20  UserData;.      
f820: 70 41 75 78 2d 3e 78 46 75 6e 63 20 3d 20 78 46  pAux->xFunc = xF
f830: 75 6e 63 3b 0a 20 20 20 20 20 20 70 41 75 78 2d  unc;.      pAux-
f840: 3e 78 44 65 73 74 72 6f 79 20 3d 20 78 44 65 73  >xDestroy = xDes
f850: 74 72 6f 79 3b 0a 20 20 20 20 20 20 70 41 75 78  troy;.      pAux
f860: 2d 3e 70 4e 65 78 74 20 3d 20 70 47 6c 6f 62 61  ->pNext = pGloba
f870: 6c 2d 3e 70 41 75 78 3b 0a 20 20 20 20 20 20 70  l->pAux;.      p
f880: 47 6c 6f 62 61 6c 2d 3e 70 41 75 78 20 3d 20 70  Global->pAux = p
f890: 41 75 78 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a  Aux;.    }else{.
f8a0: 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54        rc = SQLIT
f8b0: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d 0a 20  E_NOMEM;.    }. 
f8c0: 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b   }..  return rc;
f8d0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 67 69 73 74  .}../*.** Regist
f8e0: 65 72 20 61 20 6e 65 77 20 74 6f 6b 65 6e 69 7a  er a new tokeniz
f8f0: 65 72 2e 20 54 68 69 73 20 69 73 20 74 68 65 20  er. This is the 
f900: 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f  implementation o
f910: 66 20 74 68 65 20 0a 2a 2a 20 66 74 73 35 5f 61  f the .** fts5_a
f920: 70 69 2e 78 43 72 65 61 74 65 54 6f 6b 65 6e 69  pi.xCreateTokeni
f930: 7a 65 72 28 29 20 6d 65 74 68 6f 64 2e 0a 2a 2f  zer() method..*/
f940: 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35  .static int fts5
f950: 43 72 65 61 74 65 54 6f 6b 65 6e 69 7a 65 72 28  CreateTokenizer(
f960: 0a 20 20 66 74 73 35 5f 61 70 69 20 2a 70 41 70  .  fts5_api *pAp
f970: 69 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  i,              
f980: 20 20 20 2f 2a 20 47 6c 6f 62 61 6c 20 63 6f 6e     /* Global con
f990: 74 65 78 74 20 28 6f 6e 65 20 70 65 72 20 64 62  text (one per db
f9a0: 20 68 61 6e 64 6c 65 29 20 2a 2f 0a 20 20 63 6f   handle) */.  co
f9b0: 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 2c  nst char *zName,
f9c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
f9d0: 20 4e 61 6d 65 20 6f 66 20 6e 65 77 20 66 75 6e   Name of new fun
f9e0: 63 74 69 6f 6e 20 2a 2f 0a 20 20 76 6f 69 64 20  ction */.  void 
f9f0: 2a 70 55 73 65 72 44 61 74 61 2c 20 20 20 20 20  *pUserData,     
fa00: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 55 73             /* Us
fa10: 65 72 20 64 61 74 61 20 66 6f 72 20 61 75 78 2e  er data for aux.
fa20: 20 66 75 6e 63 74 69 6f 6e 20 2a 2f 0a 20 20 66   function */.  f
fa30: 74 73 35 5f 74 6f 6b 65 6e 69 7a 65 72 20 2a 70  ts5_tokenizer *p
fa40: 54 6f 6b 65 6e 69 7a 65 72 2c 20 20 20 20 20 2f  Tokenizer,     /
fa50: 2a 20 54 6f 6b 65 6e 69 7a 65 72 20 69 6d 70 6c  * Tokenizer impl
fa60: 65 6d 65 6e 74 61 74 69 6f 6e 20 2a 2f 0a 20 20  ementation */.  
fa70: 76 6f 69 64 28 2a 78 44 65 73 74 72 6f 79 29 28  void(*xDestroy)(
fa80: 76 6f 69 64 2a 29 20 20 20 20 20 20 20 20 20 20  void*)          
fa90: 2f 2a 20 44 65 73 74 72 75 63 74 6f 72 20 66 6f  /* Destructor fo
faa0: 72 20 70 55 73 65 72 44 61 74 61 20 2a 2f 0a 29  r pUserData */.)
fab0: 7b 0a 20 20 46 74 73 35 47 6c 6f 62 61 6c 20 2a  {.  Fts5Global *
fac0: 70 47 6c 6f 62 61 6c 20 3d 20 28 46 74 73 35 47  pGlobal = (Fts5G
fad0: 6c 6f 62 61 6c 2a 29 70 41 70 69 3b 0a 20 20 46  lobal*)pApi;.  F
fae0: 74 73 35 54 6f 6b 65 6e 69 7a 65 72 4d 6f 64 75  ts5TokenizerModu
faf0: 6c 65 20 2a 70 4e 65 77 3b 0a 20 20 69 6e 74 20  le *pNew;.  int 
fb00: 6e 42 79 74 65 3b 20 20 20 20 20 20 20 20 20 20  nByte;          
fb10: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42              /* B
fb20: 79 74 65 73 20 6f 66 20 73 70 61 63 65 20 74 6f  ytes of space to
fb30: 20 61 6c 6c 6f 63 61 74 65 20 2a 2f 0a 20 20 69   allocate */.  i
fb40: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
fb50: 4b 3b 0a 0a 20 20 6e 42 79 74 65 20 3d 20 73 69  K;..  nByte = si
fb60: 7a 65 6f 66 28 46 74 73 35 54 6f 6b 65 6e 69 7a  zeof(Fts5Tokeniz
fb70: 65 72 4d 6f 64 75 6c 65 29 20 2b 20 73 74 72 6c  erModule) + strl
fb80: 65 6e 28 7a 4e 61 6d 65 29 20 2b 20 31 3b 0a 20  en(zName) + 1;. 
fb90: 20 70 4e 65 77 20 3d 20 28 46 74 73 35 54 6f 6b   pNew = (Fts5Tok
fba0: 65 6e 69 7a 65 72 4d 6f 64 75 6c 65 2a 29 73 71  enizerModule*)sq
fbb0: 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 6e 42 79  lite3_malloc(nBy
fbc0: 74 65 29 3b 0a 20 20 69 66 28 20 70 4e 65 77 20  te);.  if( pNew 
fbd0: 29 7b 0a 20 20 20 20 6d 65 6d 73 65 74 28 70 4e  ){.    memset(pN
fbe0: 65 77 2c 20 30 2c 20 6e 42 79 74 65 29 3b 0a 20  ew, 0, nByte);. 
fbf0: 20 20 20 70 4e 65 77 2d 3e 7a 4e 61 6d 65 20 3d     pNew->zName =
fc00: 20 28 63 68 61 72 2a 29 26 70 4e 65 77 5b 31 5d   (char*)&pNew[1]
fc10: 3b 0a 20 20 20 20 73 74 72 63 70 79 28 70 4e 65  ;.    strcpy(pNe
fc20: 77 2d 3e 7a 4e 61 6d 65 2c 20 7a 4e 61 6d 65 29  w->zName, zName)
fc30: 3b 0a 20 20 20 20 70 4e 65 77 2d 3e 70 55 73 65  ;.    pNew->pUse
fc40: 72 44 61 74 61 20 3d 20 70 55 73 65 72 44 61 74  rData = pUserDat
fc50: 61 3b 0a 20 20 20 20 70 4e 65 77 2d 3e 78 20 3d  a;.    pNew->x =
fc60: 20 2a 70 54 6f 6b 65 6e 69 7a 65 72 3b 0a 20 20   *pTokenizer;.  
fc70: 20 20 70 4e 65 77 2d 3e 78 44 65 73 74 72 6f 79    pNew->xDestroy
fc80: 20 3d 20 78 44 65 73 74 72 6f 79 3b 0a 20 20 20   = xDestroy;.   
fc90: 20 70 4e 65 77 2d 3e 70 4e 65 78 74 20 3d 20 70   pNew->pNext = p
fca0: 47 6c 6f 62 61 6c 2d 3e 70 54 6f 6b 3b 0a 20 20  Global->pTok;.  
fcb0: 20 20 70 47 6c 6f 62 61 6c 2d 3e 70 54 6f 6b 20    pGlobal->pTok 
fcc0: 3d 20 70 4e 65 77 3b 0a 20 20 20 20 69 66 28 20  = pNew;.    if( 
fcd0: 70 4e 65 77 2d 3e 70 4e 65 78 74 3d 3d 30 20 29  pNew->pNext==0 )
fce0: 7b 0a 20 20 20 20 20 20 70 47 6c 6f 62 61 6c 2d  {.      pGlobal-
fcf0: 3e 70 44 66 6c 74 54 6f 6b 20 3d 20 70 4e 65 77  >pDfltTok = pNew
fd00: 3b 0a 20 20 20 20 7d 0a 20 20 7d 65 6c 73 65 7b  ;.    }.  }else{
fd10: 0a 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45  .    rc = SQLITE
fd20: 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 0a 20 20 72  _NOMEM;.  }..  r
fd30: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61  eturn rc;.}..sta
fd40: 74 69 63 20 46 74 73 35 54 6f 6b 65 6e 69 7a 65  tic Fts5Tokenize
fd50: 72 4d 6f 64 75 6c 65 20 2a 66 74 73 35 4c 6f 63  rModule *fts5Loc
fd60: 61 74 65 54 6f 6b 65 6e 69 7a 65 72 28 0a 20 20  ateTokenizer(.  
fd70: 46 74 73 35 47 6c 6f 62 61 6c 20 2a 70 47 6c 6f  Fts5Global *pGlo
fd80: 62 61 6c 2c 20 0a 20 20 63 6f 6e 73 74 20 63 68  bal, .  const ch
fd90: 61 72 20 2a 7a 4e 61 6d 65 0a 29 7b 0a 20 20 46  ar *zName.){.  F
fda0: 74 73 35 54 6f 6b 65 6e 69 7a 65 72 4d 6f 64 75  ts5TokenizerModu
fdb0: 6c 65 20 2a 70 4d 6f 64 20 3d 20 30 3b 0a 0a 20  le *pMod = 0;.. 
fdc0: 20 69 66 28 20 7a 4e 61 6d 65 3d 3d 30 20 29 7b   if( zName==0 ){
fdd0: 0a 20 20 20 20 70 4d 6f 64 20 3d 20 70 47 6c 6f  .    pMod = pGlo
fde0: 62 61 6c 2d 3e 70 44 66 6c 74 54 6f 6b 3b 0a 20  bal->pDfltTok;. 
fdf0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 66 6f 72 28   }else{.    for(
fe00: 70 4d 6f 64 3d 70 47 6c 6f 62 61 6c 2d 3e 70 54  pMod=pGlobal->pT
fe10: 6f 6b 3b 20 70 4d 6f 64 3b 20 70 4d 6f 64 3d 70  ok; pMod; pMod=p
fe20: 4d 6f 64 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20  Mod->pNext){.   
fe30: 20 20 20 69 66 28 20 73 71 6c 69 74 65 33 5f 73     if( sqlite3_s
fe40: 74 72 69 63 6d 70 28 7a 4e 61 6d 65 2c 20 70 4d  tricmp(zName, pM
fe50: 6f 64 2d 3e 7a 4e 61 6d 65 29 3d 3d 30 20 29 20  od->zName)==0 ) 
fe60: 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 20 20 7d  break;.    }.  }
fe70: 0a 0a 20 20 72 65 74 75 72 6e 20 70 4d 6f 64 3b  ..  return pMod;
fe80: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 69 6e 64 20 61  .}../*.** Find a
fe90: 20 74 6f 6b 65 6e 69 7a 65 72 2e 20 54 68 69 73   tokenizer. This
fea0: 20 69 73 20 74 68 65 20 69 6d 70 6c 65 6d 65 6e   is the implemen
feb0: 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 0a 2a  tation of the .*
fec0: 2a 20 66 74 73 35 5f 61 70 69 2e 78 46 69 6e 64  * fts5_api.xFind
fed0: 54 6f 6b 65 6e 69 7a 65 72 28 29 20 6d 65 74 68  Tokenizer() meth
fee0: 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  od..*/.static in
fef0: 74 20 66 74 73 35 46 69 6e 64 54 6f 6b 65 6e 69  t fts5FindTokeni
ff00: 7a 65 72 28 0a 20 20 66 74 73 35 5f 61 70 69 20  zer(.  fts5_api 
ff10: 2a 70 41 70 69 2c 20 20 20 20 20 20 20 20 20 20  *pApi,          
ff20: 20 20 20 20 20 20 20 2f 2a 20 47 6c 6f 62 61 6c         /* Global
ff30: 20 63 6f 6e 74 65 78 74 20 28 6f 6e 65 20 70 65   context (one pe
ff40: 72 20 64 62 20 68 61 6e 64 6c 65 29 20 2a 2f 0a  r db handle) */.
ff50: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e    const char *zN
ff60: 61 6d 65 2c 20 20 20 20 20 20 20 20 20 20 20 20  ame,            
ff70: 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 6e 65 77    /* Name of new
ff80: 20 66 75 6e 63 74 69 6f 6e 20 2a 2f 0a 20 20 76   function */.  v
ff90: 6f 69 64 20 2a 2a 70 70 55 73 65 72 44 61 74 61  oid **ppUserData
ffa0: 2c 0a 20 20 66 74 73 35 5f 74 6f 6b 65 6e 69 7a  ,.  fts5_tokeniz
ffb0: 65 72 20 2a 70 54 6f 6b 65 6e 69 7a 65 72 20 20  er *pTokenizer  
ffc0: 20 20 20 20 2f 2a 20 50 6f 70 75 6c 61 74 65 20      /* Populate 
ffd0: 74 68 69 73 20 6f 62 6a 65 63 74 20 2a 2f 0a 29  this object */.)
ffe0: 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c  {.  int rc = SQL
fff0: 49 54 45 5f 4f 4b 3b 0a 20 20 46 74 73 35 54 6f  ITE_OK;.  Fts5To
10000 6b 65 6e 69 7a 65 72 4d 6f 64 75 6c 65 20 2a 70  kenizerModule *p
10010 4d 6f 64 3b 0a 0a 20 20 70 4d 6f 64 20 3d 20 66  Mod;..  pMod = f
10020 74 73 35 4c 6f 63 61 74 65 54 6f 6b 65 6e 69 7a  ts5LocateTokeniz
10030 65 72 28 28 46 74 73 35 47 6c 6f 62 61 6c 2a 29  er((Fts5Global*)
10040 70 41 70 69 2c 20 7a 4e 61 6d 65 29 3b 0a 20 20  pApi, zName);.  
10050 69 66 28 20 70 4d 6f 64 20 29 7b 0a 20 20 20 20  if( pMod ){.    
10060 2a 70 54 6f 6b 65 6e 69 7a 65 72 20 3d 20 70 4d  *pTokenizer = pM
10070 6f 64 2d 3e 78 3b 0a 20 20 20 20 2a 70 70 55 73  od->x;.    *ppUs
10080 65 72 44 61 74 61 20 3d 20 70 4d 6f 64 2d 3e 70  erData = pMod->p
10090 55 73 65 72 44 61 74 61 3b 0a 20 20 7d 65 6c 73  UserData;.  }els
100a0 65 7b 0a 20 20 20 20 6d 65 6d 73 65 74 28 70 54  e{.    memset(pT
100b0 6f 6b 65 6e 69 7a 65 72 2c 20 30 2c 20 73 69 7a  okenizer, 0, siz
100c0 65 6f 66 28 66 74 73 35 5f 74 6f 6b 65 6e 69 7a  eof(fts5_tokeniz
100d0 65 72 29 29 3b 0a 20 20 20 20 72 63 20 3d 20 53  er));.    rc = S
100e0 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 7d  QLITE_ERROR;.  }
100f0 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ..  return rc;.}
10100 0a 0a 69 6e 74 20 73 71 6c 69 74 65 33 46 74 73  ..int sqlite3Fts
10110 35 47 65 74 54 6f 6b 65 6e 69 7a 65 72 28 0a 20  5GetTokenizer(. 
10120 20 46 74 73 35 47 6c 6f 62 61 6c 20 2a 70 47 6c   Fts5Global *pGl
10130 6f 62 61 6c 2c 20 0a 20 20 63 6f 6e 73 74 20 63  obal, .  const c
10140 68 61 72 20 2a 2a 61 7a 41 72 67 2c 0a 20 20 69  har **azArg,.  i
10150 6e 74 20 6e 41 72 67 2c 0a 20 20 46 74 73 35 54  nt nArg,.  Fts5T
10160 6f 6b 65 6e 69 7a 65 72 20 2a 2a 70 70 54 6f 6b  okenizer **ppTok
10170 2c 0a 20 20 66 74 73 35 5f 74 6f 6b 65 6e 69 7a  ,.  fts5_tokeniz
10180 65 72 20 2a 2a 70 70 54 6f 6b 41 70 69 2c 0a 20  er **ppTokApi,. 
10190 20 63 68 61 72 20 2a 2a 70 7a 45 72 72 0a 29 7b   char **pzErr.){
101a0 0a 20 20 46 74 73 35 54 6f 6b 65 6e 69 7a 65 72  .  Fts5Tokenizer
101b0 4d 6f 64 75 6c 65 20 2a 70 4d 6f 64 3b 0a 20 20  Module *pMod;.  
101c0 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
101d0 4f 4b 3b 0a 0a 20 20 70 4d 6f 64 20 3d 20 66 74  OK;..  pMod = ft
101e0 73 35 4c 6f 63 61 74 65 54 6f 6b 65 6e 69 7a 65  s5LocateTokenize
101f0 72 28 70 47 6c 6f 62 61 6c 2c 20 6e 41 72 67 3d  r(pGlobal, nArg=
10200 3d 30 20 3f 20 30 20 3a 20 61 7a 41 72 67 5b 30  =0 ? 0 : azArg[0
10210 5d 29 3b 0a 20 20 69 66 28 20 70 4d 6f 64 3d 3d  ]);.  if( pMod==
10220 30 20 29 7b 0a 20 20 20 20 61 73 73 65 72 74 28  0 ){.    assert(
10230 20 6e 41 72 67 3e 30 20 29 3b 0a 20 20 20 20 72   nArg>0 );.    r
10240 63 20 3d 20 53 51 4c 49 54 45 5f 45 52 52 4f 52  c = SQLITE_ERROR
10250 3b 0a 20 20 20 20 2a 70 7a 45 72 72 20 3d 20 73  ;.    *pzErr = s
10260 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22  qlite3_mprintf("
10270 6e 6f 20 73 75 63 68 20 74 6f 6b 65 6e 69 7a 65  no such tokenize
10280 72 3a 20 25 73 22 2c 20 61 7a 41 72 67 5b 30 5d  r: %s", azArg[0]
10290 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  );.  }else{.    
102a0 72 63 20 3d 20 70 4d 6f 64 2d 3e 78 2e 78 43 72  rc = pMod->x.xCr
102b0 65 61 74 65 28 70 4d 6f 64 2d 3e 70 55 73 65 72  eate(pMod->pUser
102c0 44 61 74 61 2c 20 26 61 7a 41 72 67 5b 31 5d 2c  Data, &azArg[1],
102d0 20 28 6e 41 72 67 3f 6e 41 72 67 2d 31 3a 30 29   (nArg?nArg-1:0)
102e0 2c 20 70 70 54 6f 6b 29 3b 0a 20 20 20 20 2a 70  , ppTok);.    *p
102f0 70 54 6f 6b 41 70 69 20 3d 20 26 70 4d 6f 64 2d  pTokApi = &pMod-
10300 3e 78 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d  >x;.    if( rc!=
10310 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 70 7a 45  SQLITE_OK && pzE
10320 72 72 20 29 7b 0a 20 20 20 20 20 20 2a 70 7a 45  rr ){.      *pzE
10330 72 72 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72  rr = sqlite3_mpr
10340 69 6e 74 66 28 22 65 72 72 6f 72 20 69 6e 20 74  intf("error in t
10350 6f 6b 65 6e 69 7a 65 72 20 63 6f 6e 73 74 72 75  okenizer constru
10360 63 74 6f 72 22 29 3b 0a 20 20 20 20 7d 0a 20 20  ctor");.    }.  
10370 7d 0a 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c  }..  if( rc!=SQL
10380 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 2a 70  ITE_OK ){.    *p
10390 70 54 6f 6b 41 70 69 20 3d 20 30 3b 0a 20 20 20  pTokApi = 0;.   
103a0 20 2a 70 70 54 6f 6b 20 3d 20 30 3b 0a 20 20 7d   *ppTok = 0;.  }
103b0 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ..  return rc;.}
103c0 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 66 74  ..static void ft
103d0 73 35 4d 6f 64 75 6c 65 44 65 73 74 72 6f 79 28  s5ModuleDestroy(
103e0 76 6f 69 64 20 2a 70 43 74 78 29 7b 0a 20 20 46  void *pCtx){.  F
103f0 74 73 35 54 6f 6b 65 6e 69 7a 65 72 4d 6f 64 75  ts5TokenizerModu
10400 6c 65 20 2a 70 54 6f 6b 2c 20 2a 70 4e 65 78 74  le *pTok, *pNext
10410 54 6f 6b 3b 0a 20 20 46 74 73 35 41 75 78 69 6c  Tok;.  Fts5Auxil
10420 69 61 72 79 20 2a 70 41 75 78 2c 20 2a 70 4e 65  iary *pAux, *pNe
10430 78 74 41 75 78 3b 0a 20 20 46 74 73 35 47 6c 6f  xtAux;.  Fts5Glo
10440 62 61 6c 20 2a 70 47 6c 6f 62 61 6c 20 3d 20 28  bal *pGlobal = (
10450 46 74 73 35 47 6c 6f 62 61 6c 2a 29 70 43 74 78  Fts5Global*)pCtx
10460 3b 0a 0a 20 20 66 6f 72 28 70 41 75 78 3d 70 47  ;..  for(pAux=pG
10470 6c 6f 62 61 6c 2d 3e 70 41 75 78 3b 20 70 41 75  lobal->pAux; pAu
10480 78 3b 20 70 41 75 78 3d 70 4e 65 78 74 41 75 78  x; pAux=pNextAux
10490 29 7b 0a 20 20 20 20 70 4e 65 78 74 41 75 78 20  ){.    pNextAux 
104a0 3d 20 70 41 75 78 2d 3e 70 4e 65 78 74 3b 0a 20  = pAux->pNext;. 
104b0 20 20 20 69 66 28 20 70 41 75 78 2d 3e 78 44 65     if( pAux->xDe
104c0 73 74 72 6f 79 20 29 20 70 41 75 78 2d 3e 78 44  stroy ) pAux->xD
104d0 65 73 74 72 6f 79 28 70 41 75 78 2d 3e 70 55 73  estroy(pAux->pUs
104e0 65 72 44 61 74 61 29 3b 0a 20 20 20 20 73 71 6c  erData);.    sql
104f0 69 74 65 33 5f 66 72 65 65 28 70 41 75 78 29 3b  ite3_free(pAux);
10500 0a 20 20 7d 0a 0a 20 20 66 6f 72 28 70 54 6f 6b  .  }..  for(pTok
10510 3d 70 47 6c 6f 62 61 6c 2d 3e 70 54 6f 6b 3b 20  =pGlobal->pTok; 
10520 70 54 6f 6b 3b 20 70 54 6f 6b 3d 70 4e 65 78 74  pTok; pTok=pNext
10530 54 6f 6b 29 7b 0a 20 20 20 20 70 4e 65 78 74 54  Tok){.    pNextT
10540 6f 6b 20 3d 20 70 54 6f 6b 2d 3e 70 4e 65 78 74  ok = pTok->pNext
10550 3b 0a 20 20 20 20 69 66 28 20 70 54 6f 6b 2d 3e  ;.    if( pTok->
10560 78 44 65 73 74 72 6f 79 20 29 20 70 54 6f 6b 2d  xDestroy ) pTok-
10570 3e 78 44 65 73 74 72 6f 79 28 70 54 6f 6b 2d 3e  >xDestroy(pTok->
10580 70 55 73 65 72 44 61 74 61 29 3b 0a 20 20 20 20  pUserData);.    
10590 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 54 6f  sqlite3_free(pTo
105a0 6b 29 3b 0a 20 20 7d 0a 0a 20 20 73 71 6c 69 74  k);.  }..  sqlit
105b0 65 33 5f 66 72 65 65 28 70 47 6c 6f 62 61 6c 29  e3_free(pGlobal)
105c0 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64  ;.}..static void
105d0 20 66 74 73 35 46 74 73 35 46 75 6e 63 28 0a 20   fts5Fts5Func(. 
105e0 20 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74   sqlite3_context
105f0 20 2a 70 43 74 78 2c 20 20 20 20 20 20 20 20 20   *pCtx,         
10600 20 2f 2a 20 46 75 6e 63 74 69 6f 6e 20 63 61 6c   /* Function cal
10610 6c 20 63 6f 6e 74 65 78 74 20 2a 2f 0a 20 20 69  l context */.  i
10620 6e 74 20 6e 41 72 67 2c 20 20 20 20 20 20 20 20  nt nArg,        
10630 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
10640 2a 20 4e 75 6d 62 65 72 20 6f 66 20 61 72 67 73  * Number of args
10650 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 76 61   */.  sqlite3_va
10660 6c 75 65 20 2a 2a 61 70 56 61 6c 20 20 20 20 20  lue **apVal     
10670 20 20 20 20 20 20 2f 2a 20 46 75 6e 63 74 69 6f        /* Functio
10680 6e 20 61 72 67 75 6d 65 6e 74 73 20 2a 2f 0a 29  n arguments */.)
10690 7b 0a 20 20 46 74 73 35 47 6c 6f 62 61 6c 20 2a  {.  Fts5Global *
106a0 70 47 6c 6f 62 61 6c 20 3d 20 28 46 74 73 35 47  pGlobal = (Fts5G
106b0 6c 6f 62 61 6c 2a 29 73 71 6c 69 74 65 33 5f 75  lobal*)sqlite3_u
106c0 73 65 72 5f 64 61 74 61 28 70 43 74 78 29 3b 0a  ser_data(pCtx);.
106d0 20 20 63 68 61 72 20 62 75 66 5b 38 5d 3b 0a 20    char buf[8];. 
106e0 20 61 73 73 65 72 74 28 20 6e 41 72 67 3d 3d 30   assert( nArg==0
106f0 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 73 69   );.  assert( si
10700 7a 65 6f 66 28 62 75 66 29 3e 3d 73 69 7a 65 6f  zeof(buf)>=sizeo
10710 66 28 70 47 6c 6f 62 61 6c 29 20 29 3b 0a 20 20  f(pGlobal) );.  
10720 6d 65 6d 63 70 79 28 62 75 66 2c 20 28 76 6f 69  memcpy(buf, (voi
10730 64 2a 29 26 70 47 6c 6f 62 61 6c 2c 20 73 69 7a  d*)&pGlobal, siz
10740 65 6f 66 28 70 47 6c 6f 62 61 6c 29 29 3b 0a 20  eof(pGlobal));. 
10750 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f   sqlite3_result_
10760 62 6c 6f 62 28 70 43 74 78 2c 20 62 75 66 2c 20  blob(pCtx, buf, 
10770 73 69 7a 65 6f 66 28 70 47 6c 6f 62 61 6c 29 2c  sizeof(pGlobal),
10780 20 53 51 4c 49 54 45 5f 54 52 41 4e 53 49 45 4e   SQLITE_TRANSIEN
10790 54 29 3b 0a 7d 0a 0a 69 6e 74 20 73 71 6c 69 74  T);.}..int sqlit
107a0 65 33 46 74 73 35 49 6e 69 74 28 73 71 6c 69 74  e3Fts5Init(sqlit
107b0 65 33 20 2a 64 62 29 7b 0a 20 20 73 74 61 74 69  e3 *db){.  stati
107c0 63 20 63 6f 6e 73 74 20 73 71 6c 69 74 65 33 5f  c const sqlite3_
107d0 6d 6f 64 75 6c 65 20 66 74 73 35 4d 6f 64 20 3d  module fts5Mod =
107e0 20 7b 0a 20 20 20 20 2f 2a 20 69 56 65 72 73 69   {.    /* iVersi
107f0 6f 6e 20 20 20 20 20 20 2a 2f 20 32 2c 0a 20 20  on      */ 2,.  
10800 20 20 2f 2a 20 78 43 72 65 61 74 65 20 20 20 20    /* xCreate    
10810 20 20 20 2a 2f 20 66 74 73 35 43 72 65 61 74 65     */ fts5Create
10820 4d 65 74 68 6f 64 2c 0a 20 20 20 20 2f 2a 20 78  Method,.    /* x
10830 43 6f 6e 6e 65 63 74 20 20 20 20 20 20 2a 2f 20  Connect      */ 
10840 66 74 73 35 43 6f 6e 6e 65 63 74 4d 65 74 68 6f  fts5ConnectMetho
10850 64 2c 0a 20 20 20 20 2f 2a 20 78 42 65 73 74 49  d,.    /* xBestI
10860 6e 64 65 78 20 20 20 20 2a 2f 20 66 74 73 35 42  ndex    */ fts5B
10870 65 73 74 49 6e 64 65 78 4d 65 74 68 6f 64 2c 0a  estIndexMethod,.
10880 20 20 20 20 2f 2a 20 78 44 69 73 63 6f 6e 6e 65      /* xDisconne
10890 63 74 20 20 20 2a 2f 20 66 74 73 35 44 69 73 63  ct   */ fts5Disc
108a0 6f 6e 6e 65 63 74 4d 65 74 68 6f 64 2c 0a 20 20  onnectMethod,.  
108b0 20 20 2f 2a 20 78 44 65 73 74 72 6f 79 20 20 20    /* xDestroy   
108c0 20 20 20 2a 2f 20 66 74 73 35 44 65 73 74 72 6f     */ fts5Destro
108d0 79 4d 65 74 68 6f 64 2c 0a 20 20 20 20 2f 2a 20  yMethod,.    /* 
108e0 78 4f 70 65 6e 20 20 20 20 20 20 20 20 20 2a 2f  xOpen         */
108f0 20 66 74 73 35 4f 70 65 6e 4d 65 74 68 6f 64 2c   fts5OpenMethod,
10900 0a 20 20 20 20 2f 2a 20 78 43 6c 6f 73 65 20 20  .    /* xClose  
10910 20 20 20 20 20 20 2a 2f 20 66 74 73 35 43 6c 6f        */ fts5Clo
10920 73 65 4d 65 74 68 6f 64 2c 0a 20 20 20 20 2f 2a  seMethod,.    /*
10930 20 78 46 69 6c 74 65 72 20 20 20 20 20 20 20 2a   xFilter       *
10940 2f 20 66 74 73 35 46 69 6c 74 65 72 4d 65 74 68  / fts5FilterMeth
10950 6f 64 2c 0a 20 20 20 20 2f 2a 20 78 4e 65 78 74  od,.    /* xNext
10960 20 20 20 20 20 20 20 20 20 2a 2f 20 66 74 73 35           */ fts5
10970 4e 65 78 74 4d 65 74 68 6f 64 2c 0a 20 20 20 20  NextMethod,.    
10980 2f 2a 20 78 45 6f 66 20 20 20 20 20 20 20 20 20  /* xEof         
10990 20 2a 2f 20 66 74 73 35 45 6f 66 4d 65 74 68 6f   */ fts5EofMetho
109a0 64 2c 0a 20 20 20 20 2f 2a 20 78 43 6f 6c 75 6d  d,.    /* xColum
109b0 6e 20 20 20 20 20 20 20 2a 2f 20 66 74 73 35 43  n       */ fts5C
109c0 6f 6c 75 6d 6e 4d 65 74 68 6f 64 2c 0a 20 20 20  olumnMethod,.   
109d0 20 2f 2a 20 78 52 6f 77 69 64 20 20 20 20 20 20   /* xRowid      
109e0 20 20 2a 2f 20 66 74 73 35 52 6f 77 69 64 4d 65    */ fts5RowidMe
109f0 74 68 6f 64 2c 0a 20 20 20 20 2f 2a 20 78 55 70  thod,.    /* xUp
10a00 64 61 74 65 20 20 20 20 20 20 20 2a 2f 20 66 74  date       */ ft
10a10 73 35 55 70 64 61 74 65 4d 65 74 68 6f 64 2c 0a  s5UpdateMethod,.
10a20 20 20 20 20 2f 2a 20 78 42 65 67 69 6e 20 20 20      /* xBegin   
10a30 20 20 20 20 20 2a 2f 20 66 74 73 35 42 65 67 69       */ fts5Begi
10a40 6e 4d 65 74 68 6f 64 2c 0a 20 20 20 20 2f 2a 20  nMethod,.    /* 
10a50 78 53 79 6e 63 20 20 20 20 20 20 20 20 20 2a 2f  xSync         */
10a60 20 66 74 73 35 53 79 6e 63 4d 65 74 68 6f 64 2c   fts5SyncMethod,
10a70 0a 20 20 20 20 2f 2a 20 78 43 6f 6d 6d 69 74 20  .    /* xCommit 
10a80 20 20 20 20 20 20 2a 2f 20 66 74 73 35 43 6f 6d        */ fts5Com
10a90 6d 69 74 4d 65 74 68 6f 64 2c 0a 20 20 20 20 2f  mitMethod,.    /
10aa0 2a 20 78 52 6f 6c 6c 62 61 63 6b 20 20 20 20 20  * xRollback     
10ab0 2a 2f 20 66 74 73 35 52 6f 6c 6c 62 61 63 6b 4d  */ fts5RollbackM
10ac0 65 74 68 6f 64 2c 0a 20 20 20 20 2f 2a 20 78 46  ethod,.    /* xF
10ad0 69 6e 64 46 75 6e 63 74 69 6f 6e 20 2a 2f 20 66  indFunction */ f
10ae0 74 73 35 46 69 6e 64 46 75 6e 63 74 69 6f 6e 4d  ts5FindFunctionM
10af0 65 74 68 6f 64 2c 0a 20 20 20 20 2f 2a 20 78 52  ethod,.    /* xR
10b00 65 6e 61 6d 65 20 20 20 20 20 20 20 2a 2f 20 66  ename       */ f
10b10 74 73 35 52 65 6e 61 6d 65 4d 65 74 68 6f 64 2c  ts5RenameMethod,
10b20 0a 20 20 20 20 2f 2a 20 78 53 61 76 65 70 6f 69  .    /* xSavepoi
10b30 6e 74 20 20 20 20 2a 2f 20 66 74 73 35 53 61 76  nt    */ fts5Sav
10b40 65 70 6f 69 6e 74 4d 65 74 68 6f 64 2c 0a 20 20  epointMethod,.  
10b50 20 20 2f 2a 20 78 52 65 6c 65 61 73 65 20 20 20    /* xRelease   
10b60 20 20 20 2a 2f 20 66 74 73 35 52 65 6c 65 61 73     */ fts5Releas
10b70 65 4d 65 74 68 6f 64 2c 0a 20 20 20 20 2f 2a 20  eMethod,.    /* 
10b80 78 52 6f 6c 6c 62 61 63 6b 54 6f 20 20 20 2a 2f  xRollbackTo   */
10b90 20 66 74 73 35 52 6f 6c 6c 62 61 63 6b 54 6f 4d   fts5RollbackToM
10ba0 65 74 68 6f 64 2c 0a 20 20 7d 3b 0a 0a 20 20 69  ethod,.  };..  i
10bb0 6e 74 20 72 63 3b 0a 20 20 46 74 73 35 47 6c 6f  nt rc;.  Fts5Glo
10bc0 62 61 6c 20 2a 70 47 6c 6f 62 61 6c 20 3d 20 30  bal *pGlobal = 0
10bd0 3b 0a 20 20 70 47 6c 6f 62 61 6c 20 3d 20 28 46  ;.  pGlobal = (F
10be0 74 73 35 47 6c 6f 62 61 6c 2a 29 73 71 6c 69 74  ts5Global*)sqlit
10bf0 65 33 5f 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f 66  e3_malloc(sizeof
10c00 28 46 74 73 35 47 6c 6f 62 61 6c 29 29 3b 0a 0a  (Fts5Global));..
10c10 20 20 69 66 28 20 70 47 6c 6f 62 61 6c 3d 3d 30    if( pGlobal==0
10c20 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 53 51 4c   ){.    rc = SQL
10c30 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 65 6c  ITE_NOMEM;.  }el
10c40 73 65 7b 0a 20 20 20 20 76 6f 69 64 20 2a 70 20  se{.    void *p 
10c50 3d 20 28 76 6f 69 64 2a 29 70 47 6c 6f 62 61 6c  = (void*)pGlobal
10c60 3b 0a 20 20 20 20 6d 65 6d 73 65 74 28 70 47 6c  ;.    memset(pGl
10c70 6f 62 61 6c 2c 20 30 2c 20 73 69 7a 65 6f 66 28  obal, 0, sizeof(
10c80 46 74 73 35 47 6c 6f 62 61 6c 29 29 3b 0a 20 20  Fts5Global));.  
10c90 20 20 70 47 6c 6f 62 61 6c 2d 3e 64 62 20 3d 20    pGlobal->db = 
10ca0 64 62 3b 0a 20 20 20 20 70 47 6c 6f 62 61 6c 2d  db;.    pGlobal-
10cb0 3e 61 70 69 2e 69 56 65 72 73 69 6f 6e 20 3d 20  >api.iVersion = 
10cc0 31 3b 0a 20 20 20 20 70 47 6c 6f 62 61 6c 2d 3e  1;.    pGlobal->
10cd0 61 70 69 2e 78 43 72 65 61 74 65 46 75 6e 63 74  api.xCreateFunct
10ce0 69 6f 6e 20 3d 20 66 74 73 35 43 72 65 61 74 65  ion = fts5Create
10cf0 41 75 78 3b 0a 20 20 20 20 70 47 6c 6f 62 61 6c  Aux;.    pGlobal
10d00 2d 3e 61 70 69 2e 78 43 72 65 61 74 65 54 6f 6b  ->api.xCreateTok
10d10 65 6e 69 7a 65 72 20 3d 20 66 74 73 35 43 72 65  enizer = fts5Cre
10d20 61 74 65 54 6f 6b 65 6e 69 7a 65 72 3b 0a 20 20  ateTokenizer;.  
10d30 20 20 70 47 6c 6f 62 61 6c 2d 3e 61 70 69 2e 78    pGlobal->api.x
10d40 46 69 6e 64 54 6f 6b 65 6e 69 7a 65 72 20 3d 20  FindTokenizer = 
10d50 66 74 73 35 46 69 6e 64 54 6f 6b 65 6e 69 7a 65  fts5FindTokenize
10d60 72 3b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69  r;.    rc = sqli
10d70 74 65 33 5f 63 72 65 61 74 65 5f 6d 6f 64 75 6c  te3_create_modul
10d80 65 5f 76 32 28 64 62 2c 20 22 66 74 73 35 22 2c  e_v2(db, "fts5",
10d90 20 26 66 74 73 35 4d 6f 64 2c 20 70 2c 20 66 74   &fts5Mod, p, ft
10da0 73 35 4d 6f 64 75 6c 65 44 65 73 74 72 6f 79 29  s5ModuleDestroy)
10db0 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51  ;.    if( rc==SQ
10dc0 4c 49 54 45 5f 4f 4b 20 29 20 72 63 20 3d 20 73  LITE_OK ) rc = s
10dd0 71 6c 69 74 65 33 46 74 73 35 49 6e 64 65 78 49  qlite3Fts5IndexI
10de0 6e 69 74 28 64 62 29 3b 0a 20 20 20 20 69 66 28  nit(db);.    if(
10df0 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
10e00 20 72 63 20 3d 20 73 71 6c 69 74 65 33 46 74 73   rc = sqlite3Fts
10e10 35 45 78 70 72 49 6e 69 74 28 70 47 6c 6f 62 61  5ExprInit(pGloba
10e20 6c 2c 20 64 62 29 3b 0a 20 20 20 20 69 66 28 20  l, db);.    if( 
10e30 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20  rc==SQLITE_OK ) 
10e40 72 63 20 3d 20 73 71 6c 69 74 65 33 46 74 73 35  rc = sqlite3Fts5
10e50 41 75 78 49 6e 69 74 28 26 70 47 6c 6f 62 61 6c  AuxInit(&pGlobal
10e60 2d 3e 61 70 69 29 3b 0a 20 20 20 20 69 66 28 20  ->api);.    if( 
10e70 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20  rc==SQLITE_OK ) 
10e80 72 63 20 3d 20 73 71 6c 69 74 65 33 46 74 73 35  rc = sqlite3Fts5
10e90 54 6f 6b 65 6e 69 7a 65 72 49 6e 69 74 28 26 70  TokenizerInit(&p
10ea0 47 6c 6f 62 61 6c 2d 3e 61 70 69 29 3b 0a 20 20  Global->api);.  
10eb0 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
10ec0 5f 4f 4b 20 29 20 72 63 20 3d 20 73 71 6c 69 74  _OK ) rc = sqlit
10ed0 65 33 46 74 73 35 56 6f 63 61 62 49 6e 69 74 28  e3Fts5VocabInit(
10ee0 70 47 6c 6f 62 61 6c 2c 20 64 62 29 3b 0a 20 20  pGlobal, db);.  
10ef0 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
10f00 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72 63 20  _OK ){.      rc 
10f10 3d 20 73 71 6c 69 74 65 33 5f 63 72 65 61 74 65  = sqlite3_create
10f20 5f 66 75 6e 63 74 69 6f 6e 28 0a 20 20 20 20 20  _function(.     
10f30 20 20 20 20 20 64 62 2c 20 22 66 74 73 35 22 2c       db, "fts5",
10f40 20 30 2c 20 53 51 4c 49 54 45 5f 55 54 46 38 2c   0, SQLITE_UTF8,
10f50 20 70 2c 20 66 74 73 35 46 74 73 35 46 75 6e 63   p, fts5Fts5Func
10f60 2c 20 30 2c 20 30 0a 20 20 20 20 20 20 29 3b 0a  , 0, 0.      );.
10f70 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75      }.  }.  retu
10f80 72 6e 20 72 63 3b 0a 7d 0a 23 65 6e 64 69 66 20  rn rc;.}.#endif 
10f90 2f 2a 20 64 65 66 69 6e 65 64 28 53 51 4c 49 54  /* defined(SQLIT
10fa0 45 5f 45 4e 41 42 4c 45 5f 46 54 53 35 29 20 2a  E_ENABLE_FTS5) *
10fb0 2f 0a 0a 0a                                      /...