/ Hex Artifact Content
Login

Artifact 16177d7f81af1852cf7f477b5ae119215ad6044a:


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 0a 23 69 6e 63 6c 75 64  ch..*/...#includ
01c0: 65 20 22 66 74 73 35 49 6e 74 2e 68 22 0a 0a 0a  e "fts5Int.h"...
01d0: 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20 46  typedef struct F
01e0: 74 73 35 54 61 62 6c 65 20 46 74 73 35 54 61 62  ts5Table Fts5Tab
01f0: 6c 65 3b 0a 74 79 70 65 64 65 66 20 73 74 72 75  le;.typedef stru
0200: 63 74 20 46 74 73 35 43 75 72 73 6f 72 20 46 74  ct Fts5Cursor Ft
0210: 73 35 43 75 72 73 6f 72 3b 0a 74 79 70 65 64 65  s5Cursor;.typede
0220: 66 20 73 74 72 75 63 74 20 46 74 73 35 47 6c 6f  f struct Fts5Glo
0230: 62 61 6c 20 46 74 73 35 47 6c 6f 62 61 6c 3b 0a  bal Fts5Global;.
0240: 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20 46  typedef struct F
0250: 74 73 35 41 75 78 69 6c 69 61 72 79 20 46 74 73  ts5Auxiliary Fts
0260: 35 41 75 78 69 6c 69 61 72 79 3b 0a 74 79 70 65  5Auxiliary;.type
0270: 64 65 66 20 73 74 72 75 63 74 20 46 74 73 35 41  def struct Fts5A
0280: 75 78 64 61 74 61 20 46 74 73 35 41 75 78 64 61  uxdata Fts5Auxda
0290: 74 61 3b 0a 0a 74 79 70 65 64 65 66 20 73 74 72  ta;..typedef str
02a0: 75 63 74 20 46 74 73 35 54 6f 6b 65 6e 69 7a 65  uct Fts5Tokenize
02b0: 72 4d 6f 64 75 6c 65 20 46 74 73 35 54 6f 6b 65  rModule Fts5Toke
02c0: 6e 69 7a 65 72 4d 6f 64 75 6c 65 3b 0a 0a 2f 2a  nizerModule;../*
02d0: 0a 2a 2a 20 4e 4f 54 45 53 20 4f 4e 20 54 52 41  .** NOTES ON TRA
02e0: 4e 53 41 43 54 49 4f 4e 53 3a 20 0a 2a 2a 0a 2a  NSACTIONS: .**.*
02f0: 2a 20 53 51 4c 69 74 65 20 69 6e 76 6f 6b 65 73  * SQLite invokes
0300: 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 76   the following v
0310: 69 72 74 75 61 6c 20 74 61 62 6c 65 20 6d 65 74  irtual table met
0320: 68 6f 64 73 20 61 73 20 74 72 61 6e 73 61 63 74  hods as transact
0330: 69 6f 6e 73 20 61 72 65 20 0a 2a 2a 20 6f 70 65  ions are .** ope
0340: 6e 65 64 20 61 6e 64 20 63 6c 6f 73 65 64 20 62  ned and closed b
0350: 79 20 74 68 65 20 75 73 65 72 3a 0a 2a 2a 0a 2a  y the user:.**.*
0360: 2a 20 20 20 20 20 78 42 65 67 69 6e 28 29 3a 20  *     xBegin(): 
0370: 20 20 20 53 74 61 72 74 20 6f 66 20 61 20 6e 65     Start of a ne
0380: 77 20 74 72 61 6e 73 61 63 74 69 6f 6e 2e 0a 2a  w transaction..*
0390: 2a 20 20 20 20 20 78 53 79 6e 63 28 29 3a 20 20  *     xSync():  
03a0: 20 20 20 49 6e 69 74 69 61 6c 20 70 61 72 74 20     Initial part 
03b0: 6f 66 20 74 77 6f 2d 70 68 61 73 65 20 63 6f 6d  of two-phase com
03c0: 6d 69 74 2e 0a 2a 2a 20 20 20 20 20 78 43 6f 6d  mit..**     xCom
03d0: 6d 69 74 28 29 3a 20 20 20 46 69 6e 61 6c 20 70  mit():   Final p
03e0: 61 72 74 20 6f 66 20 74 77 6f 2d 70 68 61 73 65  art of two-phase
03f0: 20 63 6f 6d 6d 69 74 2e 0a 2a 2a 20 20 20 20 20   commit..**     
0400: 78 52 6f 6c 6c 62 61 63 6b 28 29 3a 20 52 6f 6c  xRollback(): Rol
0410: 6c 62 61 63 6b 20 74 68 65 20 74 72 61 6e 73 61  lback the transa
0420: 63 74 69 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 41 6e 79  ction..**.** Any
0430: 74 68 69 6e 67 20 74 68 61 74 20 69 73 20 72 65  thing that is re
0440: 71 75 69 72 65 64 20 61 73 20 70 61 72 74 20 6f  quired as part o
0450: 66 20 61 20 63 6f 6d 6d 69 74 20 74 68 61 74 20  f a commit that 
0460: 6d 61 79 20 66 61 69 6c 20 69 73 20 70 65 72 66  may fail is perf
0470: 6f 72 6d 65 64 0a 2a 2a 20 69 6e 20 74 68 65 20  ormed.** in the 
0480: 78 53 79 6e 63 28 29 20 63 61 6c 6c 62 61 63 6b  xSync() callback
0490: 2e 20 43 75 72 72 65 6e 74 20 76 65 72 73 69 6f  . Current versio
04a0: 6e 73 20 6f 66 20 53 51 4c 69 74 65 20 69 67 6e  ns of SQLite ign
04b0: 6f 72 65 20 61 6e 79 20 65 72 72 6f 72 73 20 0a  ore any errors .
04c0: 2a 2a 20 72 65 74 75 72 6e 65 64 20 62 79 20 78  ** returned by x
04d0: 43 6f 6d 6d 69 74 28 29 2e 0a 2a 2a 0a 2a 2a 20  Commit()..**.** 
04e0: 41 6e 64 20 61 73 20 73 75 62 2d 74 72 61 6e 73  And as sub-trans
04f0: 61 63 74 69 6f 6e 73 20 61 72 65 20 6f 70 65 6e  actions are open
0500: 65 64 2f 63 6c 6f 73 65 64 3a 0a 2a 2a 0a 2a 2a  ed/closed:.**.**
0510: 20 20 20 20 20 78 53 61 76 65 70 6f 69 6e 74 28       xSavepoint(
0520: 69 6e 74 20 53 29 3a 20 20 4f 70 65 6e 20 73 61  int S):  Open sa
0530: 76 65 70 6f 69 6e 74 20 53 2e 0a 2a 2a 20 20 20  vepoint S..**   
0540: 20 20 78 52 65 6c 65 61 73 65 28 69 6e 74 20 53    xRelease(int S
0550: 29 3a 20 20 20 20 43 6f 6d 6d 69 74 20 61 6e 64  ):    Commit and
0560: 20 63 6c 6f 73 65 20 73 61 76 65 70 6f 69 6e 74   close savepoint
0570: 20 53 2e 0a 2a 2a 20 20 20 20 20 78 52 6f 6c 6c   S..**     xRoll
0580: 62 61 63 6b 54 6f 28 69 6e 74 20 53 29 3a 20 52  backTo(int S): R
0590: 6f 6c 6c 62 61 63 6b 20 74 6f 20 73 74 61 72 74  ollback to start
05a0: 20 6f 66 20 73 61 76 65 70 6f 69 6e 74 20 53 2e   of savepoint S.
05b0: 0a 2a 2a 0a 2a 2a 20 44 75 72 69 6e 67 20 61 20  .**.** During a 
05c0: 77 72 69 74 65 2d 74 72 61 6e 73 61 63 74 69 6f  write-transactio
05d0: 6e 20 74 68 65 20 66 74 73 35 5f 69 6e 64 65 78  n the fts5_index
05e0: 2e 63 20 6d 6f 64 75 6c 65 20 6d 61 79 20 63 61  .c module may ca
05f0: 63 68 65 20 73 6f 6d 65 20 64 61 74 61 20 0a 2a  che some data .*
0600: 2a 20 69 6e 2d 6d 65 6d 6f 72 79 2e 20 49 74 20  * in-memory. It 
0610: 69 73 20 66 6c 75 73 68 65 64 20 74 6f 20 64 69  is flushed to di
0620: 73 6b 20 77 68 65 6e 65 76 65 72 20 78 53 79 6e  sk whenever xSyn
0630: 63 28 29 2c 20 78 52 65 6c 65 61 73 65 28 29 20  c(), xRelease() 
0640: 6f 72 0a 2a 2a 20 78 53 61 76 65 70 6f 69 6e 74  or.** xSavepoint
0650: 28 29 20 69 73 20 63 61 6c 6c 65 64 2e 20 41 6e  () is called. An
0660: 64 20 64 69 73 63 61 72 64 65 64 20 77 68 65 6e  d discarded when
0670: 65 76 65 72 20 78 52 6f 6c 6c 62 61 63 6b 28 29  ever xRollback()
0680: 20 6f 72 20 78 52 6f 6c 6c 62 61 63 6b 54 6f 28   or xRollbackTo(
0690: 29 20 0a 2a 2a 20 69 73 20 63 61 6c 6c 65 64 2e  ) .** is called.
06a0: 0a 2a 2a 0a 2a 2a 20 41 64 64 69 74 69 6f 6e 61  .**.** Additiona
06b0: 6c 6c 79 2c 20 69 66 20 53 51 4c 49 54 45 5f 44  lly, if SQLITE_D
06c0: 45 42 55 47 20 69 73 20 64 65 66 69 6e 65 64 2c  EBUG is defined,
06d0: 20 61 6e 20 69 6e 73 74 61 6e 63 65 20 6f 66 20   an instance of 
06e0: 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 0a 2a 2a  the following.**
06f0: 20 73 74 72 75 63 74 75 72 65 20 69 73 20 75 73   structure is us
0700: 65 64 20 74 6f 20 72 65 63 6f 72 64 20 74 68 65  ed to record the
0710: 20 63 75 72 72 65 6e 74 20 74 72 61 6e 73 61 63   current transac
0720: 74 69 6f 6e 20 73 74 61 74 65 2e 20 54 68 69 73  tion state. This
0730: 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 0a 2a 2a 20   information.** 
0740: 69 73 20 6e 6f 74 20 72 65 71 75 69 72 65 64 2c  is not required,
0750: 20 62 75 74 20 69 74 20 69 73 20 75 73 65 64 20   but it is used 
0760: 69 6e 20 74 68 65 20 61 73 73 65 72 74 28 29 20  in the assert() 
0770: 73 74 61 74 65 6d 65 6e 74 73 20 65 78 65 63 75  statements execu
0780: 74 65 64 20 62 79 0a 2a 2a 20 66 75 6e 63 74 69  ted by.** functi
0790: 6f 6e 20 66 74 73 35 43 68 65 63 6b 54 72 61 6e  on fts5CheckTran
07a0: 73 61 63 74 69 6f 6e 53 74 61 74 65 28 29 20 28  sactionState() (
07b0: 73 65 65 20 62 65 6c 6f 77 29 2e 0a 2a 2f 0a 73  see below)..*/.s
07c0: 74 72 75 63 74 20 46 74 73 35 54 72 61 6e 73 61  truct Fts5Transa
07d0: 63 74 69 6f 6e 53 74 61 74 65 20 7b 0a 20 20 69  ctionState {.  i
07e0: 6e 74 20 65 53 74 61 74 65 3b 20 20 20 20 20 20  nt eState;      
07f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
0800: 2a 20 30 3d 3d 63 6c 6f 73 65 64 2c 20 31 3d 3d  * 0==closed, 1==
0810: 6f 70 65 6e 2c 20 32 3d 3d 73 79 6e 63 65 64 20  open, 2==synced 
0820: 2a 2f 0a 20 20 69 6e 74 20 69 53 61 76 65 70 6f  */.  int iSavepo
0830: 69 6e 74 3b 20 20 20 20 20 20 20 20 20 20 20 20  int;            
0840: 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
0850: 66 20 6f 70 65 6e 20 73 61 76 65 70 6f 69 6e 74  f open savepoint
0860: 73 20 28 30 20 2d 3e 20 6e 6f 6e 65 29 20 2a 2f  s (0 -> none) */
0870: 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 41 20 73 69 6e  .};../*.** A sin
0880: 67 6c 65 20 6f 62 6a 65 63 74 20 6f 66 20 74 68  gle object of th
0890: 69 73 20 74 79 70 65 20 69 73 20 61 6c 6c 6f 63  is type is alloc
08a0: 61 74 65 64 20 77 68 65 6e 20 74 68 65 20 46 54  ated when the FT
08b0: 53 35 20 6d 6f 64 75 6c 65 20 69 73 20 0a 2a 2a  S5 module is .**
08c0: 20 72 65 67 69 73 74 65 72 65 64 20 77 69 74 68   registered with
08d0: 20 61 20 64 61 74 61 62 61 73 65 20 68 61 6e 64   a database hand
08e0: 6c 65 2e 20 49 74 20 69 73 20 75 73 65 64 20 74  le. It is used t
08f0: 6f 20 73 74 6f 72 65 20 70 6f 69 6e 74 65 72 73  o store pointers
0900: 20 74 6f 0a 2a 2a 20 61 6c 6c 20 72 65 67 69 73   to.** all regis
0910: 74 65 72 65 64 20 46 54 53 35 20 65 78 74 65 6e  tered FTS5 exten
0920: 73 69 6f 6e 73 20 2d 20 74 6f 6b 65 6e 69 7a 65  sions - tokenize
0930: 72 73 20 61 6e 64 20 61 75 78 69 6c 69 61 72 79  rs and auxiliary
0940: 20 66 75 6e 63 74 69 6f 6e 73 2e 0a 2a 2f 0a 73   functions..*/.s
0950: 74 72 75 63 74 20 46 74 73 35 47 6c 6f 62 61 6c  truct Fts5Global
0960: 20 7b 0a 20 20 66 74 73 35 5f 61 70 69 20 61 70   {.  fts5_api ap
0970: 69 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  i;              
0980: 20 20 20 20 20 2f 2a 20 55 73 65 72 20 76 69 73       /* User vis
0990: 69 62 6c 65 20 70 61 72 74 20 6f 66 20 6f 62 6a  ible part of obj
09a0: 65 63 74 20 28 73 65 65 20 66 74 73 35 2e 68 29  ect (see fts5.h)
09b0: 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 20 2a 64   */.  sqlite3 *d
09c0: 62 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  b;              
09d0: 20 20 20 20 20 20 2f 2a 20 41 73 73 6f 63 69 61        /* Associa
09e0: 74 65 64 20 64 61 74 61 62 61 73 65 20 63 6f 6e  ted database con
09f0: 6e 65 63 74 69 6f 6e 20 2a 2f 20 0a 20 20 69 36  nection */ .  i6
0a00: 34 20 69 4e 65 78 74 49 64 3b 20 20 20 20 20 20  4 iNextId;      
0a10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0a20: 20 55 73 65 64 20 74 6f 20 61 6c 6c 6f 63 61 74   Used to allocat
0a30: 65 20 75 6e 69 71 75 65 20 63 75 72 73 6f 72 20  e unique cursor 
0a40: 69 64 73 20 2a 2f 0a 20 20 46 74 73 35 41 75 78  ids */.  Fts5Aux
0a50: 69 6c 69 61 72 79 20 2a 70 41 75 78 3b 20 20 20  iliary *pAux;   
0a60: 20 20 20 20 20 20 20 20 20 2f 2a 20 46 69 72 73           /* Firs
0a70: 74 20 69 6e 20 6c 69 73 74 20 6f 66 20 61 6c 6c  t in list of all
0a80: 20 61 75 78 2e 20 66 75 6e 63 74 69 6f 6e 73 20   aux. functions 
0a90: 2a 2f 0a 20 20 46 74 73 35 54 6f 6b 65 6e 69 7a  */.  Fts5Tokeniz
0aa0: 65 72 4d 6f 64 75 6c 65 20 2a 70 54 6f 6b 3b 20  erModule *pTok; 
0ab0: 20 20 20 20 20 2f 2a 20 46 69 72 73 74 20 69 6e       /* First in
0ac0: 20 6c 69 73 74 20 6f 66 20 61 6c 6c 20 74 6f 6b   list of all tok
0ad0: 65 6e 69 7a 65 72 20 6d 6f 64 75 6c 65 73 20 2a  enizer modules *
0ae0: 2f 0a 20 20 46 74 73 35 43 75 72 73 6f 72 20 2a  /.  Fts5Cursor *
0af0: 70 43 73 72 3b 20 20 20 20 20 20 20 20 20 20 20  pCsr;           
0b00: 20 20 20 20 2f 2a 20 46 69 72 73 74 20 69 6e 20      /* First in 
0b10: 6c 69 73 74 20 6f 66 20 61 6c 6c 20 6f 70 65 6e  list of all open
0b20: 20 63 75 72 73 6f 72 73 20 2a 2f 0a 7d 3b 0a 0a   cursors */.};..
0b30: 2f 2a 0a 2a 2a 20 45 61 63 68 20 61 75 78 69 6c  /*.** Each auxil
0b40: 69 61 72 79 20 66 75 6e 63 74 69 6f 6e 20 72 65  iary function re
0b50: 67 69 73 74 65 72 65 64 20 77 69 74 68 20 74 68  gistered with th
0b60: 65 20 46 54 53 35 20 6d 6f 64 75 6c 65 20 69 73  e FTS5 module is
0b70: 20 72 65 70 72 65 73 65 6e 74 65 64 0a 2a 2a 20   represented.** 
0b80: 62 79 20 61 6e 20 6f 62 6a 65 63 74 20 6f 66 20  by an object of 
0b90: 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 74 79  the following ty
0ba0: 70 65 2e 20 41 6c 6c 20 73 75 63 68 20 6f 62 6a  pe. All such obj
0bb0: 65 63 74 73 20 61 72 65 20 73 74 6f 72 65 64 20  ects are stored 
0bc0: 61 73 20 70 61 72 74 0a 2a 2a 20 6f 66 20 74 68  as part.** of th
0bd0: 65 20 46 74 73 35 47 6c 6f 62 61 6c 2e 70 41 75  e Fts5Global.pAu
0be0: 78 20 6c 69 73 74 2e 0a 2a 2f 0a 73 74 72 75 63  x list..*/.struc
0bf0: 74 20 46 74 73 35 41 75 78 69 6c 69 61 72 79 20  t Fts5Auxiliary 
0c00: 7b 0a 20 20 46 74 73 35 47 6c 6f 62 61 6c 20 2a  {.  Fts5Global *
0c10: 70 47 6c 6f 62 61 6c 3b 20 20 20 20 20 20 20 20  pGlobal;        
0c20: 20 20 20 20 2f 2a 20 47 6c 6f 62 61 6c 20 63 6f      /* Global co
0c30: 6e 74 65 78 74 20 66 6f 72 20 74 68 69 73 20 66  ntext for this f
0c40: 75 6e 63 74 69 6f 6e 20 2a 2f 0a 20 20 63 68 61  unction */.  cha
0c50: 72 20 2a 7a 46 75 6e 63 3b 20 20 20 20 20 20 20  r *zFunc;       
0c60: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
0c70: 46 75 6e 63 74 69 6f 6e 20 6e 61 6d 65 20 28 6e  Function name (n
0c80: 75 6c 2d 74 65 72 6d 69 6e 61 74 65 64 29 20 2a  ul-terminated) *
0c90: 2f 0a 20 20 76 6f 69 64 20 2a 70 55 73 65 72 44  /.  void *pUserD
0ca0: 61 74 61 3b 20 20 20 20 20 20 20 20 20 20 20 20  ata;            
0cb0: 20 20 20 20 2f 2a 20 55 73 65 72 2d 64 61 74 61      /* User-data
0cc0: 20 70 6f 69 6e 74 65 72 20 2a 2f 0a 20 20 66 74   pointer */.  ft
0cd0: 73 35 5f 65 78 74 65 6e 73 69 6f 6e 5f 66 75 6e  s5_extension_fun
0ce0: 63 74 69 6f 6e 20 78 46 75 6e 63 3b 20 20 2f 2a  ction xFunc;  /*
0cf0: 20 43 61 6c 6c 62 61 63 6b 20 66 75 6e 63 74 69   Callback functi
0d00: 6f 6e 20 2a 2f 0a 20 20 76 6f 69 64 20 28 2a 78  on */.  void (*x
0d10: 44 65 73 74 72 6f 79 29 28 76 6f 69 64 2a 29 3b  Destroy)(void*);
0d20: 20 20 20 20 20 20 20 20 2f 2a 20 44 65 73 74 72          /* Destr
0d30: 75 63 74 6f 72 20 66 75 6e 63 74 69 6f 6e 20 2a  uctor function *
0d40: 2f 0a 20 20 46 74 73 35 41 75 78 69 6c 69 61 72  /.  Fts5Auxiliar
0d50: 79 20 2a 70 4e 65 78 74 3b 20 20 20 20 20 20 20  y *pNext;       
0d60: 20 20 20 20 2f 2a 20 4e 65 78 74 20 72 65 67 69      /* Next regi
0d70: 73 74 65 72 65 64 20 61 75 78 69 6c 69 61 72 79  stered auxiliary
0d80: 20 66 75 6e 63 74 69 6f 6e 20 2a 2f 0a 7d 3b 0a   function */.};.
0d90: 0a 2f 2a 0a 2a 2a 20 45 61 63 68 20 74 6f 6b 65  ./*.** Each toke
0da0: 6e 69 7a 65 72 20 6d 6f 64 75 6c 65 20 72 65 67  nizer module reg
0db0: 69 73 74 65 72 65 64 20 77 69 74 68 20 74 68 65  istered with the
0dc0: 20 46 54 53 35 20 6d 6f 64 75 6c 65 20 69 73 20   FTS5 module is 
0dd0: 72 65 70 72 65 73 65 6e 74 65 64 0a 2a 2a 20 62  represented.** b
0de0: 79 20 61 6e 20 6f 62 6a 65 63 74 20 6f 66 20 74  y an object of t
0df0: 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 74 79 70  he following typ
0e00: 65 2e 20 41 6c 6c 20 73 75 63 68 20 6f 62 6a 65  e. All such obje
0e10: 63 74 73 20 61 72 65 20 73 74 6f 72 65 64 20 61  cts are stored a
0e20: 73 20 70 61 72 74 0a 2a 2a 20 6f 66 20 74 68 65  s part.** of the
0e30: 20 46 74 73 35 47 6c 6f 62 61 6c 2e 70 54 6f 6b   Fts5Global.pTok
0e40: 20 6c 69 73 74 2e 0a 2a 2f 0a 73 74 72 75 63 74   list..*/.struct
0e50: 20 46 74 73 35 54 6f 6b 65 6e 69 7a 65 72 4d 6f   Fts5TokenizerMo
0e60: 64 75 6c 65 20 7b 0a 20 20 63 68 61 72 20 2a 7a  dule {.  char *z
0e70: 4e 61 6d 65 3b 20 20 20 20 20 20 20 20 20 20 20  Name;           
0e80: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65           /* Name
0e90: 20 6f 66 20 74 6f 6b 65 6e 69 7a 65 72 20 2a 2f   of tokenizer */
0ea0: 0a 20 20 76 6f 69 64 20 2a 70 55 73 65 72 44 61  .  void *pUserDa
0eb0: 74 61 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ta;             
0ec0: 20 20 20 2f 2a 20 55 73 65 72 20 70 6f 69 6e 74     /* User point
0ed0: 65 72 20 70 61 73 73 65 64 20 74 6f 20 78 43 72  er passed to xCr
0ee0: 65 61 74 65 28 29 20 2a 2f 0a 20 20 66 74 73 35  eate() */.  fts5
0ef0: 5f 74 6f 6b 65 6e 69 7a 65 72 20 78 3b 20 20 20  _tokenizer x;   
0f00: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
0f10: 6f 6b 65 6e 69 7a 65 72 20 66 75 6e 63 74 69 6f  okenizer functio
0f20: 6e 73 20 2a 2f 0a 20 20 76 6f 69 64 20 28 2a 78  ns */.  void (*x
0f30: 44 65 73 74 72 6f 79 29 28 76 6f 69 64 2a 29 3b  Destroy)(void*);
0f40: 20 20 20 20 20 20 20 20 2f 2a 20 44 65 73 74 72          /* Destr
0f50: 75 63 74 6f 72 20 66 75 6e 63 74 69 6f 6e 20 2a  uctor function *
0f60: 2f 0a 20 20 46 74 73 35 54 6f 6b 65 6e 69 7a 65  /.  Fts5Tokenize
0f70: 72 4d 6f 64 75 6c 65 20 2a 70 4e 65 78 74 3b 20  rModule *pNext; 
0f80: 20 20 20 20 2f 2a 20 4e 65 78 74 20 72 65 67 69      /* Next regi
0f90: 73 74 65 72 65 64 20 74 6f 6b 65 6e 69 7a 65 72  stered tokenizer
0fa0: 20 6d 6f 64 75 6c 65 20 2a 2f 0a 7d 3b 0a 0a 2f   module */.};../
0fb0: 2a 0a 2a 2a 20 56 69 72 74 75 61 6c 2d 74 61 62  *.** Virtual-tab
0fc0: 6c 65 20 6f 62 6a 65 63 74 2e 0a 2a 2f 0a 73 74  le object..*/.st
0fd0: 72 75 63 74 20 46 74 73 35 54 61 62 6c 65 20 7b  ruct Fts5Table {
0fe0: 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62 20  .  sqlite3_vtab 
0ff0: 62 61 73 65 3b 20 20 20 20 20 20 20 20 20 20 20  base;           
1000: 20 20 20 2f 2a 20 42 61 73 65 20 63 6c 61 73 73     /* Base class
1010: 20 75 73 65 64 20 62 79 20 53 51 4c 69 74 65 20   used by SQLite 
1020: 63 6f 72 65 20 2a 2f 0a 20 20 46 74 73 35 43 6f  core */.  Fts5Co
1030: 6e 66 69 67 20 2a 70 43 6f 6e 66 69 67 3b 20 20  nfig *pConfig;  
1040: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 56 69 72            /* Vir
1050: 74 75 61 6c 20 74 61 62 6c 65 20 63 6f 6e 66 69  tual table confi
1060: 67 75 72 61 74 69 6f 6e 20 2a 2f 0a 20 20 46 74  guration */.  Ft
1070: 73 35 49 6e 64 65 78 20 2a 70 49 6e 64 65 78 3b  s5Index *pIndex;
1080: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1090: 20 46 75 6c 6c 2d 74 65 78 74 20 69 6e 64 65 78   Full-text index
10a0: 20 2a 2f 0a 20 20 46 74 73 35 53 74 6f 72 61 67   */.  Fts5Storag
10b0: 65 20 2a 70 53 74 6f 72 61 67 65 3b 20 20 20 20  e *pStorage;    
10c0: 20 20 20 20 20 20 2f 2a 20 44 6f 63 75 6d 65 6e        /* Documen
10d0: 74 20 73 74 6f 72 65 20 2a 2f 0a 20 20 46 74 73  t store */.  Fts
10e0: 35 47 6c 6f 62 61 6c 20 2a 70 47 6c 6f 62 61 6c  5Global *pGlobal
10f0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ;            /* 
1100: 47 6c 6f 62 61 6c 20 28 63 6f 6e 6e 65 63 74 69  Global (connecti
1110: 6f 6e 20 77 69 64 65 29 20 64 61 74 61 20 2a 2f  on wide) data */
1120: 0a 20 20 46 74 73 35 43 75 72 73 6f 72 20 2a 70  .  Fts5Cursor *p
1130: 53 6f 72 74 43 73 72 3b 20 20 20 20 20 20 20 20  SortCsr;        
1140: 20 20 20 2f 2a 20 53 6f 72 74 20 64 61 74 61 20     /* Sort data 
1150: 66 72 6f 6d 20 74 68 69 73 20 63 75 72 73 6f 72  from this cursor
1160: 20 2a 2f 0a 23 69 66 64 65 66 20 53 51 4c 49 54   */.#ifdef SQLIT
1170: 45 5f 44 45 42 55 47 0a 20 20 73 74 72 75 63 74  E_DEBUG.  struct
1180: 20 46 74 73 35 54 72 61 6e 73 61 63 74 69 6f 6e   Fts5Transaction
1190: 53 74 61 74 65 20 74 73 3b 0a 23 65 6e 64 69 66  State ts;.#endif
11a0: 0a 7d 3b 0a 0a 73 74 72 75 63 74 20 46 74 73 35  .};..struct Fts5
11b0: 4d 61 74 63 68 50 68 72 61 73 65 20 7b 0a 20 20  MatchPhrase {.  
11c0: 46 74 73 35 42 75 66 66 65 72 20 2a 70 50 6f 73  Fts5Buffer *pPos
11d0: 6c 69 73 74 3b 20 20 20 20 20 20 20 20 20 20 20  list;           
11e0: 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 63 75  /* Pointer to cu
11f0: 72 72 65 6e 74 20 70 6f 73 6c 69 73 74 20 2a 2f  rrent poslist */
1200: 0a 20 20 69 6e 74 20 6e 54 65 72 6d 3b 20 20 20  .  int nTerm;   
1210: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1220: 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 70 68     /* Size of ph
1230: 72 61 73 65 20 69 6e 20 74 65 72 6d 73 20 2a 2f  rase in terms */
1240: 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 70 53 74 6d 74  .};../*.** pStmt
1250: 3a 0a 2a 2a 20 20 20 53 45 4c 45 43 54 20 72 6f  :.**   SELECT ro
1260: 77 69 64 2c 20 3c 66 74 73 3e 20 46 52 4f 4d 20  wid, <fts> FROM 
1270: 3c 66 74 73 3e 20 4f 52 44 45 52 20 42 59 20 2b  <fts> ORDER BY +
1280: 72 61 6e 6b 3b 0a 2a 2a 0a 2a 2a 20 61 49 64 78  rank;.**.** aIdx
1290: 5b 5d 3a 0a 2a 2a 20 20 20 54 68 65 72 65 20 69  []:.**   There i
12a0: 73 20 6f 6e 65 20 65 6e 74 72 79 20 69 6e 20 74  s one entry in t
12b0: 68 65 20 61 49 64 78 5b 5d 20 61 72 72 61 79 20  he aIdx[] array 
12c0: 66 6f 72 20 65 61 63 68 20 70 68 72 61 73 65 20  for each phrase 
12d0: 69 6e 20 74 68 65 20 71 75 65 72 79 2c 0a 2a 2a  in the query,.**
12e0: 20 20 20 74 68 65 20 76 61 6c 75 65 20 6f 66 20     the value of 
12f0: 77 68 69 63 68 20 69 73 20 74 68 65 20 6f 66 66  which is the off
1300: 73 65 74 20 77 69 74 68 69 6e 20 61 50 6f 73 6c  set within aPosl
1310: 69 73 74 5b 5d 20 66 6f 6c 6c 6f 77 69 6e 67 20  ist[] following 
1320: 74 68 65 20 6c 61 73 74 20 0a 2a 2a 20 20 20 62  the last .**   b
1330: 79 74 65 20 6f 66 20 74 68 65 20 70 6f 73 69 74  yte of the posit
1340: 69 6f 6e 20 6c 69 73 74 20 66 6f 72 20 74 68 65  ion list for the
1350: 20 63 6f 72 72 65 73 70 6f 6e 64 69 6e 67 20 70   corresponding p
1360: 68 72 61 73 65 2e 0a 2a 2f 0a 73 74 72 75 63 74  hrase..*/.struct
1370: 20 46 74 73 35 53 6f 72 74 65 72 20 7b 0a 20 20   Fts5Sorter {.  
1380: 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 53  sqlite3_stmt *pS
1390: 74 6d 74 3b 0a 20 20 69 36 34 20 69 52 6f 77 69  tmt;.  i64 iRowi
13a0: 64 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  d;              
13b0: 20 20 20 20 20 20 20 2f 2a 20 43 75 72 72 65 6e         /* Curren
13c0: 74 20 72 6f 77 69 64 20 2a 2f 0a 20 20 63 6f 6e  t rowid */.  con
13d0: 73 74 20 75 38 20 2a 61 50 6f 73 6c 69 73 74 3b  st u8 *aPoslist;
13e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
13f0: 50 6f 73 69 74 69 6f 6e 20 6c 69 73 74 73 20 66  Position lists f
1400: 6f 72 20 63 75 72 72 65 6e 74 20 72 6f 77 20 2a  or current row *
1410: 2f 0a 20 20 69 6e 74 20 6e 49 64 78 3b 20 20 20  /.  int nIdx;   
1420: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1430: 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66      /* Number of
1440: 20 65 6e 74 72 69 65 73 20 69 6e 20 61 49 64 78   entries in aIdx
1450: 5b 5d 20 2a 2f 0a 20 20 69 6e 74 20 61 49 64 78  [] */.  int aIdx
1460: 5b 30 5d 3b 20 20 20 20 20 20 20 20 20 20 20 20  [0];            
1470: 20 20 20 20 20 20 20 20 2f 2a 20 4f 66 66 73 65          /* Offse
1480: 74 73 20 69 6e 74 6f 20 61 50 6f 73 6c 69 73 74  ts into aPoslist
1490: 20 66 6f 72 20 63 75 72 72 65 6e 74 20 72 6f 77   for current row
14a0: 20 2a 2f 0a 7d 3b 0a 0a 0a 2f 2a 0a 2a 2a 20 56   */.};.../*.** V
14b0: 69 72 74 75 61 6c 2d 74 61 62 6c 65 20 63 75 72  irtual-table cur
14c0: 73 6f 72 20 6f 62 6a 65 63 74 2e 0a 2a 2a 0a 2a  sor object..**.*
14d0: 2a 20 7a 53 70 65 63 69 61 6c 3a 0a 2a 2a 20 20  * zSpecial:.**  
14e0: 20 49 66 20 74 68 69 73 20 69 73 20 61 20 27 73   If this is a 's
14f0: 70 65 63 69 61 6c 27 20 71 75 65 72 79 20 28 72  pecial' query (r
1500: 65 66 65 72 20 74 6f 20 66 75 6e 63 74 69 6f 6e  efer to function
1510: 20 66 74 73 35 53 70 65 63 69 61 6c 4d 61 74 63   fts5SpecialMatc
1520: 68 28 29 29 2c 20 0a 2a 2a 20 20 20 74 68 65 6e  h()), .**   then
1530: 20 74 68 69 73 20 76 61 72 69 61 62 6c 65 20 70   this variable p
1540: 6f 69 6e 74 73 20 74 6f 20 61 20 6e 75 6c 2d 74  oints to a nul-t
1550: 65 72 6d 69 6e 61 74 65 64 20 62 75 66 66 65 72  erminated buffer
1560: 20 63 6f 6e 74 61 69 6e 69 6e 67 20 74 68 65 0a   containing the.
1570: 2a 2a 20 20 20 72 65 73 75 6c 74 20 74 6f 20 72  **   result to r
1580: 65 74 75 72 6e 20 74 68 72 6f 75 67 68 20 74 68  eturn through th
1590: 65 20 74 61 62 6c 65 2d 6e 61 6d 65 20 63 6f 6c  e table-name col
15a0: 75 6d 6e 2e 20 49 74 20 69 73 20 6e 75 6c 2d 74  umn. It is nul-t
15b0: 65 72 6d 69 6e 61 74 65 64 0a 2a 2a 20 20 20 61  erminated.**   a
15c0: 6e 64 20 73 68 6f 75 6c 64 20 65 76 65 6e 74 75  nd should eventu
15d0: 61 6c 6c 79 20 62 65 20 66 72 65 65 64 20 75 73  ally be freed us
15e0: 69 6e 67 20 73 71 6c 69 74 65 33 5f 66 72 65 65  ing sqlite3_free
15f0: 28 29 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 46 74  ()..*/.struct Ft
1600: 73 35 43 75 72 73 6f 72 20 7b 0a 20 20 73 71 6c  s5Cursor {.  sql
1610: 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72  ite3_vtab_cursor
1620: 20 62 61 73 65 3b 20 20 20 20 20 20 20 2f 2a 20   base;       /* 
1630: 42 61 73 65 20 63 6c 61 73 73 20 75 73 65 64 20  Base class used 
1640: 62 79 20 53 51 4c 69 74 65 20 63 6f 72 65 20 2a  by SQLite core *
1650: 2f 0a 20 20 69 6e 74 20 69 64 78 4e 75 6d 3b 20  /.  int idxNum; 
1660: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1670: 20 20 20 20 2f 2a 20 69 64 78 4e 75 6d 20 70 61      /* idxNum pa
1680: 73 73 65 64 20 74 6f 20 78 46 69 6c 74 65 72 28  ssed to xFilter(
1690: 29 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 73  ) */.  sqlite3_s
16a0: 74 6d 74 20 2a 70 53 74 6d 74 3b 20 20 20 20 20  tmt *pStmt;     
16b0: 20 20 20 20 20 20 20 2f 2a 20 53 74 61 74 65 6d         /* Statem
16c0: 65 6e 74 20 75 73 65 64 20 74 6f 20 72 65 61 64  ent used to read
16d0: 20 25 5f 63 6f 6e 74 65 6e 74 20 2a 2f 0a 20 20   %_content */.  
16e0: 46 74 73 35 45 78 70 72 20 2a 70 45 78 70 72 3b  Fts5Expr *pExpr;
16f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1700: 2f 2a 20 45 78 70 72 65 73 73 69 6f 6e 20 66 6f  /* Expression fo
1710: 72 20 4d 41 54 43 48 20 71 75 65 72 69 65 73 20  r MATCH queries 
1720: 2a 2f 0a 20 20 46 74 73 35 53 6f 72 74 65 72 20  */.  Fts5Sorter 
1730: 2a 70 53 6f 72 74 65 72 3b 20 20 20 20 20 20 20  *pSorter;       
1740: 20 20 20 20 20 2f 2a 20 53 6f 72 74 65 72 20 66       /* Sorter f
1750: 6f 72 20 22 4f 52 44 45 52 20 42 59 20 72 61 6e  or "ORDER BY ran
1760: 6b 22 20 71 75 65 72 69 65 73 20 2a 2f 0a 20 20  k" queries */.  
1770: 69 6e 74 20 63 73 72 66 6c 61 67 73 3b 20 20 20  int csrflags;   
1780: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1790: 2f 2a 20 4d 61 73 6b 20 6f 66 20 63 75 72 73 6f  /* Mask of curso
17a0: 72 20 66 6c 61 67 73 20 28 73 65 65 20 62 65 6c  r flags (see bel
17b0: 6f 77 29 20 2a 2f 0a 20 20 46 74 73 35 43 75 72  ow) */.  Fts5Cur
17c0: 73 6f 72 20 2a 70 4e 65 78 74 3b 20 20 20 20 20  sor *pNext;     
17d0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 65 78 74           /* Next
17e0: 20 63 75 72 73 6f 72 20 69 6e 20 46 74 73 35 43   cursor in Fts5C
17f0: 75 72 73 6f 72 2e 70 43 73 72 20 6c 69 73 74 20  ursor.pCsr list 
1800: 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 53 70 65 63  */.  char *zSpec
1810: 69 61 6c 3b 20 20 20 20 20 20 20 20 20 20 20 20  ial;            
1820: 20 20 20 20 20 2f 2a 20 52 65 73 75 6c 74 20 6f       /* Result o
1830: 66 20 73 70 65 63 69 61 6c 20 71 75 65 72 79 20  f special query 
1840: 2a 2f 0a 0a 20 20 2f 2a 20 22 72 61 6e 6b 22 20  */..  /* "rank" 
1850: 66 75 6e 63 74 69 6f 6e 2e 20 50 6f 70 75 6c 61  function. Popula
1860: 74 65 64 20 6f 6e 20 64 65 6d 61 6e 64 20 66 72  ted on demand fr
1870: 6f 6d 20 76 74 61 62 2e 78 43 6f 6c 75 6d 6e 28  om vtab.xColumn(
1880: 29 2e 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 52  ). */.  char *zR
1890: 61 6e 6b 3b 20 20 20 20 20 20 20 20 20 20 20 20  ank;            
18a0: 20 20 20 20 20 20 20 20 2f 2a 20 43 75 73 74 6f          /* Custo
18b0: 6d 20 72 61 6e 6b 20 66 75 6e 63 74 69 6f 6e 20  m rank function 
18c0: 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 52 61 6e 6b  */.  char *zRank
18d0: 41 72 67 73 3b 20 20 20 20 20 20 20 20 20 20 20  Args;           
18e0: 20 20 20 20 20 2f 2a 20 43 75 73 74 6f 6d 20 72       /* Custom r
18f0: 61 6e 6b 20 66 75 6e 63 74 69 6f 6e 20 61 72 67  ank function arg
1900: 73 20 2a 2f 0a 20 20 46 74 73 35 41 75 78 69 6c  s */.  Fts5Auxil
1910: 69 61 72 79 20 2a 70 52 61 6e 6b 3b 20 20 20 20  iary *pRank;    
1920: 20 20 20 20 20 20 20 2f 2a 20 52 61 6e 6b 20 63         /* Rank c
1930: 61 6c 6c 62 61 63 6b 20 28 6f 72 20 4e 55 4c 4c  allback (or NULL
1940: 29 20 2a 2f 0a 20 20 69 6e 74 20 6e 52 61 6e 6b  ) */.  int nRank
1950: 41 72 67 3b 20 20 20 20 20 20 20 20 20 20 20 20  Arg;            
1960: 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
1970: 20 6f 66 20 74 72 61 69 6c 69 6e 67 20 61 72 67   of trailing arg
1980: 75 6d 65 6e 74 73 20 66 6f 72 20 72 61 6e 6b 28  uments for rank(
1990: 29 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 76  ) */.  sqlite3_v
19a0: 61 6c 75 65 20 2a 2a 61 70 52 61 6e 6b 41 72 67  alue **apRankArg
19b0: 3b 20 20 20 20 20 20 2f 2a 20 41 72 72 61 79 20  ;      /* Array 
19c0: 6f 66 20 74 72 61 69 6c 69 6e 67 20 61 72 67 75  of trailing argu
19d0: 6d 65 6e 74 73 20 2a 2f 0a 20 20 73 71 6c 69 74  ments */.  sqlit
19e0: 65 33 5f 73 74 6d 74 20 2a 70 52 61 6e 6b 41 72  e3_stmt *pRankAr
19f0: 67 53 74 6d 74 3b 20 20 20 20 20 2f 2a 20 4f 72  gStmt;     /* Or
1a00: 69 67 69 6e 20 6f 66 20 6f 62 6a 65 63 74 73 20  igin of objects 
1a10: 69 6e 20 61 70 52 61 6e 6b 41 72 67 5b 5d 20 2a  in apRankArg[] *
1a20: 2f 0a 0a 20 20 2f 2a 20 56 61 72 69 61 62 6c 65  /..  /* Variable
1a30: 73 20 75 73 65 64 20 62 79 20 61 75 78 69 6c 69  s used by auxili
1a40: 61 72 79 20 66 75 6e 63 74 69 6f 6e 73 20 2a 2f  ary functions */
1a50: 0a 20 20 69 36 34 20 69 43 73 72 49 64 3b 20 20  .  i64 iCsrId;  
1a60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1a70: 20 20 20 2f 2a 20 43 75 72 73 6f 72 20 69 64 20     /* Cursor id 
1a80: 2a 2f 0a 20 20 46 74 73 35 41 75 78 69 6c 69 61  */.  Fts5Auxilia
1a90: 72 79 20 2a 70 41 75 78 3b 20 20 20 20 20 20 20  ry *pAux;       
1aa0: 20 20 20 20 20 2f 2a 20 43 75 72 72 65 6e 74 6c       /* Currentl
1ab0: 79 20 65 78 65 63 75 74 69 6e 67 20 65 78 74 65  y executing exte
1ac0: 6e 73 69 6f 6e 20 66 75 6e 63 74 69 6f 6e 20 2a  nsion function *
1ad0: 2f 0a 20 20 46 74 73 35 41 75 78 64 61 74 61 20  /.  Fts5Auxdata 
1ae0: 2a 70 41 75 78 64 61 74 61 3b 20 20 20 20 20 20  *pAuxdata;      
1af0: 20 20 20 20 2f 2a 20 46 69 72 73 74 20 69 6e 20      /* First in 
1b00: 6c 69 6e 6b 65 64 20 6c 69 73 74 20 6f 66 20 73  linked list of s
1b10: 61 76 65 64 20 61 75 78 2d 64 61 74 61 20 2a 2f  aved aux-data */
1b20: 0a 20 20 69 6e 74 20 2a 61 43 6f 6c 75 6d 6e 53  .  int *aColumnS
1b30: 69 7a 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  ize;            
1b40: 20 20 20 2f 2a 20 56 61 6c 75 65 73 20 66 6f 72     /* Values for
1b50: 20 78 43 6f 6c 75 6d 6e 53 69 7a 65 28 29 20 2a   xColumnSize() *
1b60: 2f 0a 0a 20 20 69 6e 74 20 6e 49 6e 73 74 43 6f  /..  int nInstCo
1b70: 75 6e 74 3b 20 20 20 20 20 20 20 20 20 20 20 20  unt;            
1b80: 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
1b90: 66 20 70 68 72 61 73 65 20 69 6e 73 74 61 6e 63  f phrase instanc
1ba0: 65 73 20 2a 2f 0a 20 20 69 6e 74 20 2a 61 49 6e  es */.  int *aIn
1bb0: 73 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  st;             
1bc0: 20 20 20 20 20 20 20 20 2f 2a 20 33 20 69 6e 74          /* 3 int
1bd0: 65 67 65 72 73 20 70 65 72 20 70 68 72 61 73 65  egers per phrase
1be0: 20 69 6e 73 74 61 6e 63 65 20 2a 2f 0a 7d 3b 0a   instance */.};.
1bf0: 0a 2f 2a 0a 2a 2a 20 56 61 6c 75 65 73 20 66 6f  ./*.** Values fo
1c00: 72 20 46 74 73 35 43 75 72 73 6f 72 2e 63 73 72  r Fts5Cursor.csr
1c10: 66 6c 61 67 73 0a 2a 2f 0a 23 64 65 66 69 6e 65  flags.*/.#define
1c20: 20 46 54 53 35 43 53 52 5f 52 45 51 55 49 52 45   FTS5CSR_REQUIRE
1c30: 5f 43 4f 4e 54 45 4e 54 20 20 20 30 78 30 31 0a  _CONTENT   0x01.
1c40: 23 64 65 66 69 6e 65 20 46 54 53 35 43 53 52 5f  #define FTS5CSR_
1c50: 52 45 51 55 49 52 45 5f 44 4f 43 53 49 5a 45 20  REQUIRE_DOCSIZE 
1c60: 20 20 30 78 30 32 0a 23 64 65 66 69 6e 65 20 46    0x02.#define F
1c70: 54 53 35 43 53 52 5f 45 4f 46 20 20 20 20 20 20  TS5CSR_EOF      
1c80: 20 20 20 20 20 20 20 20 20 30 78 30 34 0a 23 64           0x04.#d
1c90: 65 66 69 6e 65 20 46 54 53 35 43 53 52 5f 46 52  efine FTS5CSR_FR
1ca0: 45 45 5f 5a 52 41 4e 4b 20 20 20 20 20 20 20 20  EE_ZRANK        
1cb0: 30 78 30 38 0a 0a 2f 2a 0a 2a 2a 20 4d 61 63 72  0x08../*.** Macr
1cc0: 6f 73 20 74 6f 20 53 65 74 28 29 2c 20 43 6c 65  os to Set(), Cle
1cd0: 61 72 28 29 20 61 6e 64 20 54 65 73 74 28 29 20  ar() and Test() 
1ce0: 63 75 72 73 6f 72 20 66 6c 61 67 73 2e 0a 2a 2f  cursor flags..*/
1cf0: 0a 23 64 65 66 69 6e 65 20 43 73 72 46 6c 61 67  .#define CsrFlag
1d00: 53 65 74 28 70 43 73 72 2c 20 66 6c 61 67 29 20  Set(pCsr, flag) 
1d10: 20 20 28 28 70 43 73 72 29 2d 3e 63 73 72 66 6c    ((pCsr)->csrfl
1d20: 61 67 73 20 7c 3d 20 28 66 6c 61 67 29 29 0a 23  ags |= (flag)).#
1d30: 64 65 66 69 6e 65 20 43 73 72 46 6c 61 67 43 6c  define CsrFlagCl
1d40: 65 61 72 28 70 43 73 72 2c 20 66 6c 61 67 29 20  ear(pCsr, flag) 
1d50: 28 28 70 43 73 72 29 2d 3e 63 73 72 66 6c 61 67  ((pCsr)->csrflag
1d60: 73 20 26 3d 20 7e 28 66 6c 61 67 29 29 0a 23 64  s &= ~(flag)).#d
1d70: 65 66 69 6e 65 20 43 73 72 46 6c 61 67 54 65 73  efine CsrFlagTes
1d80: 74 28 70 43 73 72 2c 20 66 6c 61 67 29 20 20 28  t(pCsr, flag)  (
1d90: 28 70 43 73 72 29 2d 3e 63 73 72 66 6c 61 67 73  (pCsr)->csrflags
1da0: 20 26 20 28 66 6c 61 67 29 29 0a 0a 73 74 72 75   & (flag))..stru
1db0: 63 74 20 46 74 73 35 41 75 78 64 61 74 61 20 7b  ct Fts5Auxdata {
1dc0: 0a 20 20 46 74 73 35 41 75 78 69 6c 69 61 72 79  .  Fts5Auxiliary
1dd0: 20 2a 70 41 75 78 3b 20 20 20 20 20 20 20 20 20   *pAux;         
1de0: 20 20 20 2f 2a 20 45 78 74 65 6e 73 69 6f 6e 20     /* Extension 
1df0: 74 6f 20 77 68 69 63 68 20 74 68 69 73 20 62 65  to which this be
1e00: 6c 6f 6e 67 73 20 2a 2f 0a 20 20 76 6f 69 64 20  longs */.  void 
1e10: 2a 70 50 74 72 3b 20 20 20 20 20 20 20 20 20 20  *pPtr;          
1e20: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 6f             /* Po
1e30: 69 6e 74 65 72 20 76 61 6c 75 65 20 2a 2f 0a 20  inter value */. 
1e40: 20 76 6f 69 64 28 2a 78 44 65 6c 65 74 65 29 28   void(*xDelete)(
1e50: 76 6f 69 64 2a 29 3b 20 20 20 20 20 20 20 20 20  void*);         
1e60: 20 2f 2a 20 44 65 73 74 72 75 63 74 6f 72 20 2a   /* Destructor *
1e70: 2f 0a 20 20 46 74 73 35 41 75 78 64 61 74 61 20  /.  Fts5Auxdata 
1e80: 2a 70 4e 65 78 74 3b 20 20 20 20 20 20 20 20 20  *pNext;         
1e90: 20 20 20 20 2f 2a 20 4e 65 78 74 20 6f 62 6a 65      /* Next obje
1ea0: 63 74 20 69 6e 20 6c 69 6e 6b 65 64 20 6c 69 73  ct in linked lis
1eb0: 74 20 2a 2f 0a 7d 3b 0a 0a 23 69 66 64 65 66 20  t */.};..#ifdef 
1ec0: 53 51 4c 49 54 45 5f 44 45 42 55 47 0a 23 64 65  SQLITE_DEBUG.#de
1ed0: 66 69 6e 65 20 46 54 53 35 5f 42 45 47 49 4e 20  fine FTS5_BEGIN 
1ee0: 20 20 20 20 20 31 0a 23 64 65 66 69 6e 65 20 46       1.#define F
1ef0: 54 53 35 5f 53 59 4e 43 20 20 20 20 20 20 20 32  TS5_SYNC       2
1f00: 0a 23 64 65 66 69 6e 65 20 46 54 53 35 5f 43 4f  .#define FTS5_CO
1f10: 4d 4d 49 54 20 20 20 20 20 33 0a 23 64 65 66 69  MMIT     3.#defi
1f20: 6e 65 20 46 54 53 35 5f 52 4f 4c 4c 42 41 43 4b  ne FTS5_ROLLBACK
1f30: 20 20 20 34 0a 23 64 65 66 69 6e 65 20 46 54 53     4.#define FTS
1f40: 35 5f 53 41 56 45 50 4f 49 4e 54 20 20 35 0a 23  5_SAVEPOINT  5.#
1f50: 64 65 66 69 6e 65 20 46 54 53 35 5f 52 45 4c 45  define FTS5_RELE
1f60: 41 53 45 20 20 20 20 36 0a 23 64 65 66 69 6e 65  ASE    6.#define
1f70: 20 46 54 53 35 5f 52 4f 4c 4c 42 41 43 4b 54 4f   FTS5_ROLLBACKTO
1f80: 20 37 0a 73 74 61 74 69 63 20 76 6f 69 64 20 66   7.static void f
1f90: 74 73 35 43 68 65 63 6b 54 72 61 6e 73 61 63 74  ts5CheckTransact
1fa0: 69 6f 6e 53 74 61 74 65 28 46 74 73 35 54 61 62  ionState(Fts5Tab
1fb0: 6c 65 20 2a 70 2c 20 69 6e 74 20 6f 70 2c 20 69  le *p, int op, i
1fc0: 6e 74 20 69 53 61 76 65 70 6f 69 6e 74 29 7b 0a  nt iSavepoint){.
1fd0: 20 20 73 77 69 74 63 68 28 20 6f 70 20 29 7b 0a    switch( op ){.
1fe0: 20 20 20 20 63 61 73 65 20 46 54 53 35 5f 42 45      case FTS5_BE
1ff0: 47 49 4e 3a 0a 20 20 20 20 20 20 61 73 73 65 72  GIN:.      asser
2000: 74 28 20 70 2d 3e 74 73 2e 65 53 74 61 74 65 3d  t( p->ts.eState=
2010: 3d 30 20 29 3b 0a 20 20 20 20 20 20 70 2d 3e 74  =0 );.      p->t
2020: 73 2e 65 53 74 61 74 65 20 3d 20 31 3b 0a 20 20  s.eState = 1;.  
2030: 20 20 20 20 70 2d 3e 74 73 2e 69 53 61 76 65 70      p->ts.iSavep
2040: 6f 69 6e 74 20 3d 20 2d 31 3b 0a 20 20 20 20 20  oint = -1;.     
2050: 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20 63 61 73   break;..    cas
2060: 65 20 46 54 53 35 5f 53 59 4e 43 3a 0a 20 20 20  e FTS5_SYNC:.   
2070: 20 20 20 61 73 73 65 72 74 28 20 70 2d 3e 74 73     assert( p->ts
2080: 2e 65 53 74 61 74 65 3d 3d 31 20 29 3b 0a 20 20  .eState==1 );.  
2090: 20 20 20 20 70 2d 3e 74 73 2e 65 53 74 61 74 65      p->ts.eState
20a0: 20 3d 20 32 3b 0a 20 20 20 20 20 20 62 72 65 61   = 2;.      brea
20b0: 6b 3b 0a 0a 20 20 20 20 63 61 73 65 20 46 54 53  k;..    case FTS
20c0: 35 5f 43 4f 4d 4d 49 54 3a 0a 20 20 20 20 20 20  5_COMMIT:.      
20d0: 61 73 73 65 72 74 28 20 70 2d 3e 74 73 2e 65 53  assert( p->ts.eS
20e0: 74 61 74 65 3d 3d 32 20 29 3b 0a 20 20 20 20 20  tate==2 );.     
20f0: 20 70 2d 3e 74 73 2e 65 53 74 61 74 65 20 3d 20   p->ts.eState = 
2100: 30 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a  0;.      break;.
2110: 0a 20 20 20 20 63 61 73 65 20 46 54 53 35 5f 52  .    case FTS5_R
2120: 4f 4c 4c 42 41 43 4b 3a 0a 20 20 20 20 20 20 61  OLLBACK:.      a
2130: 73 73 65 72 74 28 20 70 2d 3e 74 73 2e 65 53 74  ssert( p->ts.eSt
2140: 61 74 65 3d 3d 31 20 7c 7c 20 70 2d 3e 74 73 2e  ate==1 || p->ts.
2150: 65 53 74 61 74 65 3d 3d 32 20 7c 7c 20 70 2d 3e  eState==2 || p->
2160: 74 73 2e 65 53 74 61 74 65 3d 3d 30 20 29 3b 0a  ts.eState==0 );.
2170: 20 20 20 20 20 20 70 2d 3e 74 73 2e 65 53 74 61        p->ts.eSta
2180: 74 65 20 3d 20 30 3b 0a 20 20 20 20 20 20 62 72  te = 0;.      br
2190: 65 61 6b 3b 0a 0a 20 20 20 20 63 61 73 65 20 46  eak;..    case F
21a0: 54 53 35 5f 53 41 56 45 50 4f 49 4e 54 3a 0a 20  TS5_SAVEPOINT:. 
21b0: 20 20 20 20 20 61 73 73 65 72 74 28 20 70 2d 3e       assert( p->
21c0: 74 73 2e 65 53 74 61 74 65 3d 3d 31 20 29 3b 0a  ts.eState==1 );.
21d0: 20 20 20 20 20 20 61 73 73 65 72 74 28 20 69 53        assert( iS
21e0: 61 76 65 70 6f 69 6e 74 3e 3d 30 20 29 3b 0a 20  avepoint>=0 );. 
21f0: 20 20 20 20 20 61 73 73 65 72 74 28 20 69 53 61       assert( iSa
2200: 76 65 70 6f 69 6e 74 3e 70 2d 3e 74 73 2e 69 53  vepoint>p->ts.iS
2210: 61 76 65 70 6f 69 6e 74 20 29 3b 0a 20 20 20 20  avepoint );.    
2220: 20 20 70 2d 3e 74 73 2e 69 53 61 76 65 70 6f 69    p->ts.iSavepoi
2230: 6e 74 20 3d 20 69 53 61 76 65 70 6f 69 6e 74 3b  nt = iSavepoint;
2240: 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20  .      break;.  
2250: 20 20 20 20 0a 20 20 20 20 63 61 73 65 20 46 54      .    case FT
2260: 53 35 5f 52 45 4c 45 41 53 45 3a 0a 20 20 20 20  S5_RELEASE:.    
2270: 20 20 61 73 73 65 72 74 28 20 70 2d 3e 74 73 2e    assert( p->ts.
2280: 65 53 74 61 74 65 3d 3d 31 20 29 3b 0a 20 20 20  eState==1 );.   
2290: 20 20 20 61 73 73 65 72 74 28 20 69 53 61 76 65     assert( iSave
22a0: 70 6f 69 6e 74 3e 3d 30 20 29 3b 0a 20 20 20 20  point>=0 );.    
22b0: 20 20 61 73 73 65 72 74 28 20 69 53 61 76 65 70    assert( iSavep
22c0: 6f 69 6e 74 3c 3d 70 2d 3e 74 73 2e 69 53 61 76  oint<=p->ts.iSav
22d0: 65 70 6f 69 6e 74 20 29 3b 0a 20 20 20 20 20 20  epoint );.      
22e0: 70 2d 3e 74 73 2e 69 53 61 76 65 70 6f 69 6e 74  p->ts.iSavepoint
22f0: 20 3d 20 69 53 61 76 65 70 6f 69 6e 74 2d 31 3b   = iSavepoint-1;
2300: 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 0a 20  .      break;.. 
2310: 20 20 20 63 61 73 65 20 46 54 53 35 5f 52 4f 4c     case FTS5_ROL
2320: 4c 42 41 43 4b 54 4f 3a 0a 20 20 20 20 20 20 61  LBACKTO:.      a
2330: 73 73 65 72 74 28 20 70 2d 3e 74 73 2e 65 53 74  ssert( p->ts.eSt
2340: 61 74 65 3d 3d 31 20 29 3b 0a 20 20 20 20 20 20  ate==1 );.      
2350: 61 73 73 65 72 74 28 20 69 53 61 76 65 70 6f 69  assert( iSavepoi
2360: 6e 74 3e 3d 30 20 29 3b 0a 20 20 20 20 20 20 61  nt>=0 );.      a
2370: 73 73 65 72 74 28 20 69 53 61 76 65 70 6f 69 6e  ssert( iSavepoin
2380: 74 3c 3d 70 2d 3e 74 73 2e 69 53 61 76 65 70 6f  t<=p->ts.iSavepo
2390: 69 6e 74 20 29 3b 0a 20 20 20 20 20 20 70 2d 3e  int );.      p->
23a0: 74 73 2e 69 53 61 76 65 70 6f 69 6e 74 20 3d 20  ts.iSavepoint = 
23b0: 69 53 61 76 65 70 6f 69 6e 74 3b 0a 20 20 20 20  iSavepoint;.    
23c0: 20 20 62 72 65 61 6b 3b 0a 20 20 7d 0a 7d 0a 23    break;.  }.}.#
23d0: 65 6c 73 65 0a 23 20 64 65 66 69 6e 65 20 66 74  else.# define ft
23e0: 73 35 43 68 65 63 6b 54 72 61 6e 73 61 63 74 69  s5CheckTransacti
23f0: 6f 6e 53 74 61 74 65 28 78 2c 79 2c 7a 29 0a 23  onState(x,y,z).#
2400: 65 6e 64 69 66 0a 0a 0a 2f 2a 0a 2a 2a 20 43 6c  endif.../*.** Cl
2410: 6f 73 65 20 61 20 76 69 72 74 75 61 6c 20 74 61  ose a virtual ta
2420: 62 6c 65 20 68 61 6e 64 6c 65 20 6f 70 65 6e 65  ble handle opene
2430: 64 20 62 79 20 66 74 73 35 49 6e 69 74 56 74 61  d by fts5InitVta
2440: 62 28 29 2e 20 49 66 20 74 68 65 20 62 44 65 73  b(). If the bDes
2450: 74 72 6f 79 0a 2a 2a 20 61 72 67 75 6d 65 6e 74  troy.** argument
2460: 20 69 73 20 6e 6f 6e 2d 7a 65 72 6f 2c 20 61 74   is non-zero, at
2470: 74 65 6d 70 74 20 64 65 6c 65 74 65 20 74 68 65  tempt delete the
2480: 20 73 68 61 64 6f 77 20 74 61 62 6c 65 73 20 66   shadow tables f
2490: 72 6f 6d 20 74 65 68 20 64 61 74 61 62 61 73 65  rom teh database
24a0: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66  .*/.static int f
24b0: 74 73 35 46 72 65 65 56 74 61 62 28 46 74 73 35  ts5FreeVtab(Fts5
24c0: 54 61 62 6c 65 20 2a 70 54 61 62 2c 20 69 6e 74  Table *pTab, int
24d0: 20 62 44 65 73 74 72 6f 79 29 7b 0a 20 20 69 6e   bDestroy){.  in
24e0: 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b  t rc = SQLITE_OK
24f0: 3b 0a 20 20 69 66 28 20 70 54 61 62 20 29 7b 0a  ;.  if( pTab ){.
2500: 20 20 20 20 69 6e 74 20 72 63 32 3b 0a 20 20 20      int rc2;.   
2510: 20 72 63 32 20 3d 20 73 71 6c 69 74 65 33 46 74   rc2 = sqlite3Ft
2520: 73 35 49 6e 64 65 78 43 6c 6f 73 65 28 70 54 61  s5IndexClose(pTa
2530: 62 2d 3e 70 49 6e 64 65 78 2c 20 62 44 65 73 74  b->pIndex, bDest
2540: 72 6f 79 29 3b 0a 20 20 20 20 69 66 28 20 72 63  roy);.    if( rc
2550: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 63  ==SQLITE_OK ) rc
2560: 20 3d 20 72 63 32 3b 0a 20 20 20 20 72 63 32 20   = rc2;.    rc2 
2570: 3d 20 73 71 6c 69 74 65 33 46 74 73 35 53 74 6f  = sqlite3Fts5Sto
2580: 72 61 67 65 43 6c 6f 73 65 28 70 54 61 62 2d 3e  rageClose(pTab->
2590: 70 53 74 6f 72 61 67 65 2c 20 62 44 65 73 74 72  pStorage, bDestr
25a0: 6f 79 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d  oy);.    if( rc=
25b0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 63 20  =SQLITE_OK ) rc 
25c0: 3d 20 72 63 32 3b 0a 20 20 20 20 73 71 6c 69 74  = rc2;.    sqlit
25d0: 65 33 46 74 73 35 43 6f 6e 66 69 67 46 72 65 65  e3Fts5ConfigFree
25e0: 28 70 54 61 62 2d 3e 70 43 6f 6e 66 69 67 29 3b  (pTab->pConfig);
25f0: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65  .    sqlite3_fre
2600: 65 28 70 54 61 62 29 3b 0a 20 20 7d 0a 20 20 72  e(pTab);.  }.  r
2610: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
2620: 2a 2a 20 54 68 65 20 78 44 69 73 63 6f 6e 6e 65  ** The xDisconne
2630: 63 74 28 29 20 76 69 72 74 75 61 6c 20 74 61 62  ct() virtual tab
2640: 6c 65 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74  le method..*/.st
2650: 61 74 69 63 20 69 6e 74 20 66 74 73 35 44 69 73  atic int fts5Dis
2660: 63 6f 6e 6e 65 63 74 4d 65 74 68 6f 64 28 73 71  connectMethod(sq
2670: 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56 74 61  lite3_vtab *pVta
2680: 62 29 7b 0a 20 20 72 65 74 75 72 6e 20 66 74 73  b){.  return fts
2690: 35 46 72 65 65 56 74 61 62 28 28 46 74 73 35 54  5FreeVtab((Fts5T
26a0: 61 62 6c 65 2a 29 70 56 74 61 62 2c 20 30 29 3b  able*)pVtab, 0);
26b0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 78 44  .}../*.** The xD
26c0: 65 73 74 72 6f 79 28 29 20 76 69 72 74 75 61 6c  estroy() virtual
26d0: 20 74 61 62 6c 65 20 6d 65 74 68 6f 64 2e 0a 2a   table method..*
26e0: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73  /.static int fts
26f0: 35 44 65 73 74 72 6f 79 4d 65 74 68 6f 64 28 73  5DestroyMethod(s
2700: 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56 74  qlite3_vtab *pVt
2710: 61 62 29 7b 0a 20 20 72 65 74 75 72 6e 20 66 74  ab){.  return ft
2720: 73 35 46 72 65 65 56 74 61 62 28 28 46 74 73 35  s5FreeVtab((Fts5
2730: 54 61 62 6c 65 2a 29 70 56 74 61 62 2c 20 31 29  Table*)pVtab, 1)
2740: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20  ;.}../*.** This 
2750: 66 75 6e 63 74 69 6f 6e 20 69 73 20 74 68 65 20  function is the 
2760: 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f  implementation o
2770: 66 20 62 6f 74 68 20 74 68 65 20 78 43 6f 6e 6e  f both the xConn
2780: 65 63 74 20 61 6e 64 20 78 43 72 65 61 74 65 0a  ect and xCreate.
2790: 2a 2a 20 6d 65 74 68 6f 64 73 20 6f 66 20 74 68  ** methods of th
27a0: 65 20 46 54 53 33 20 76 69 72 74 75 61 6c 20 74  e FTS3 virtual t
27b0: 61 62 6c 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20  able..**.** The 
27c0: 61 72 67 76 5b 5d 20 61 72 72 61 79 20 63 6f 6e  argv[] array con
27d0: 74 61 69 6e 73 20 74 68 65 20 66 6f 6c 6c 6f 77  tains the follow
27e0: 69 6e 67 3a 0a 2a 2a 0a 2a 2a 20 20 20 61 72 67  ing:.**.**   arg
27f0: 76 5b 30 5d 20 20 20 2d 3e 20 6d 6f 64 75 6c 65  v[0]   -> module
2800: 20 6e 61 6d 65 20 20 28 22 66 74 73 35 22 29 0a   name  ("fts5").
2810: 2a 2a 20 20 20 61 72 67 76 5b 31 5d 20 20 20 2d  **   argv[1]   -
2820: 3e 20 64 61 74 61 62 61 73 65 20 6e 61 6d 65 0a  > database name.
2830: 2a 2a 20 20 20 61 72 67 76 5b 32 5d 20 20 20 2d  **   argv[2]   -
2840: 3e 20 74 61 62 6c 65 20 6e 61 6d 65 0a 2a 2a 20  > table name.** 
2850: 20 20 61 72 67 76 5b 2e 2e 2e 5d 20 2d 3e 20 22    argv[...] -> "
2860: 63 6f 6c 75 6d 6e 20 6e 61 6d 65 22 20 61 6e 64  column name" and
2870: 20 6f 74 68 65 72 20 6d 6f 64 75 6c 65 20 61 72   other module ar
2880: 67 75 6d 65 6e 74 20 66 69 65 6c 64 73 2e 0a 2a  gument fields..*
2890: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73  /.static int fts
28a0: 35 49 6e 69 74 56 74 61 62 28 0a 20 20 69 6e 74  5InitVtab(.  int
28b0: 20 62 43 72 65 61 74 65 2c 20 20 20 20 20 20 20   bCreate,       
28c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
28d0: 54 72 75 65 20 66 6f 72 20 78 43 72 65 61 74 65  True for xCreate
28e0: 2c 20 66 61 6c 73 65 20 66 6f 72 20 78 43 6f 6e  , false for xCon
28f0: 6e 65 63 74 20 2a 2f 0a 20 20 73 71 6c 69 74 65  nect */.  sqlite
2900: 33 20 2a 64 62 2c 20 20 20 20 20 20 20 20 20 20  3 *db,          
2910: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65            /* The
2920: 20 53 51 4c 69 74 65 20 64 61 74 61 62 61 73 65   SQLite database
2930: 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 2a 2f 0a 20   connection */. 
2940: 20 76 6f 69 64 20 2a 70 41 75 78 2c 20 20 20 20   void *pAux,    
2950: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2960: 20 2f 2a 20 48 61 73 68 20 74 61 62 6c 65 20 63   /* Hash table c
2970: 6f 6e 74 61 69 6e 69 6e 67 20 74 6f 6b 65 6e 69  ontaining tokeni
2980: 7a 65 72 73 20 2a 2f 0a 20 20 69 6e 74 20 61 72  zers */.  int ar
2990: 67 63 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  gc,             
29a0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d            /* Num
29b0: 62 65 72 20 6f 66 20 65 6c 65 6d 65 6e 74 73 20  ber of elements 
29c0: 69 6e 20 61 72 67 76 20 61 72 72 61 79 20 2a 2f  in argv array */
29d0: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 20  .  const char * 
29e0: 63 6f 6e 73 74 20 2a 61 72 67 76 2c 20 20 20 20  const *argv,    
29f0: 20 20 20 2f 2a 20 78 43 72 65 61 74 65 2f 78 43     /* xCreate/xC
2a00: 6f 6e 6e 65 63 74 20 61 72 67 75 6d 65 6e 74 20  onnect argument 
2a10: 61 72 72 61 79 20 2a 2f 0a 20 20 73 71 6c 69 74  array */.  sqlit
2a20: 65 33 5f 76 74 61 62 20 2a 2a 70 70 56 54 61 62  e3_vtab **ppVTab
2a30: 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20 57 72  ,          /* Wr
2a40: 69 74 65 20 74 68 65 20 72 65 73 75 6c 74 69 6e  ite the resultin
2a50: 67 20 76 74 61 62 20 73 74 72 75 63 74 75 72 65  g vtab structure
2a60: 20 68 65 72 65 20 2a 2f 0a 20 20 63 68 61 72 20   here */.  char 
2a70: 2a 2a 70 7a 45 72 72 20 20 20 20 20 20 20 20 20  **pzErr         
2a80: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 57 72             /* Wr
2a90: 69 74 65 20 61 6e 79 20 65 72 72 6f 72 20 6d 65  ite any error me
2aa0: 73 73 61 67 65 20 68 65 72 65 20 2a 2f 0a 29 7b  ssage here */.){
2ab0: 0a 20 20 46 74 73 35 47 6c 6f 62 61 6c 20 2a 70  .  Fts5Global *p
2ac0: 47 6c 6f 62 61 6c 20 3d 20 28 46 74 73 35 47 6c  Global = (Fts5Gl
2ad0: 6f 62 61 6c 2a 29 70 41 75 78 3b 0a 20 20 63 6f  obal*)pAux;.  co
2ae0: 6e 73 74 20 63 68 61 72 20 2a 2a 61 7a 43 6f 6e  nst char **azCon
2af0: 66 69 67 20 3d 20 28 63 6f 6e 73 74 20 63 68 61  fig = (const cha
2b00: 72 2a 2a 29 61 72 67 76 3b 0a 20 20 69 6e 74 20  r**)argv;.  int 
2b10: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 20  rc = SQLITE_OK; 
2b20: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52              /* R
2b30: 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20  eturn code */.  
2b40: 46 74 73 35 43 6f 6e 66 69 67 20 2a 70 43 6f 6e  Fts5Config *pCon
2b50: 66 69 67 3b 20 20 20 20 20 20 20 20 20 20 20 20  fig;            
2b60: 2f 2a 20 52 65 73 75 6c 74 73 20 6f 66 20 70 61  /* Results of pa
2b70: 72 73 69 6e 67 20 61 72 67 63 2f 61 72 67 76 20  rsing argc/argv 
2b80: 2a 2f 0a 20 20 46 74 73 35 54 61 62 6c 65 20 2a  */.  Fts5Table *
2b90: 70 54 61 62 20 3d 20 30 3b 20 20 20 20 20 20 20  pTab = 0;       
2ba0: 20 20 20 20 20 2f 2a 20 4e 65 77 20 76 69 72 74       /* New virt
2bb0: 75 61 6c 20 74 61 62 6c 65 20 6f 62 6a 65 63 74  ual table object
2bc0: 20 2a 2f 0a 0a 20 20 2f 2a 20 41 6c 6c 6f 63 61   */..  /* Alloca
2bd0: 74 65 20 74 68 65 20 6e 65 77 20 76 74 61 62 20  te the new vtab 
2be0: 6f 62 6a 65 63 74 20 61 6e 64 20 70 61 72 73 65  object and parse
2bf0: 20 74 68 65 20 63 6f 6e 66 69 67 75 72 61 74 69   the configurati
2c00: 6f 6e 20 2a 2f 0a 20 20 70 54 61 62 20 3d 20 28  on */.  pTab = (
2c10: 46 74 73 35 54 61 62 6c 65 2a 29 73 71 6c 69 74  Fts5Table*)sqlit
2c20: 65 33 46 74 73 35 4d 61 6c 6c 6f 63 5a 65 72 6f  e3Fts5MallocZero
2c30: 28 26 72 63 2c 20 73 69 7a 65 6f 66 28 46 74 73  (&rc, sizeof(Fts
2c40: 35 54 61 62 6c 65 29 29 3b 0a 20 20 69 66 28 20  5Table));.  if( 
2c50: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
2c60: 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65  .    rc = sqlite
2c70: 33 46 74 73 35 43 6f 6e 66 69 67 50 61 72 73 65  3Fts5ConfigParse
2c80: 28 70 47 6c 6f 62 61 6c 2c 20 64 62 2c 20 61 72  (pGlobal, db, ar
2c90: 67 63 2c 20 61 7a 43 6f 6e 66 69 67 2c 20 26 70  gc, azConfig, &p
2ca0: 43 6f 6e 66 69 67 2c 20 70 7a 45 72 72 29 3b 0a  Config, pzErr);.
2cb0: 20 20 20 20 61 73 73 65 72 74 28 20 28 72 63 3d      assert( (rc=
2cc0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 2a 70  =SQLITE_OK && *p
2cd0: 7a 45 72 72 3d 3d 30 29 20 7c 7c 20 70 43 6f 6e  zErr==0) || pCon
2ce0: 66 69 67 3d 3d 30 20 29 3b 0a 20 20 7d 0a 20 20  fig==0 );.  }.  
2cf0: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
2d00: 4b 20 29 7b 0a 20 20 20 20 70 54 61 62 2d 3e 70  K ){.    pTab->p
2d10: 43 6f 6e 66 69 67 20 3d 20 70 43 6f 6e 66 69 67  Config = pConfig
2d20: 3b 0a 20 20 20 20 70 54 61 62 2d 3e 70 47 6c 6f  ;.    pTab->pGlo
2d30: 62 61 6c 20 3d 20 70 47 6c 6f 62 61 6c 3b 0a 20  bal = pGlobal;. 
2d40: 20 7d 0a 0a 20 20 2f 2a 20 4f 70 65 6e 20 74 68   }..  /* Open th
2d50: 65 20 69 6e 64 65 78 20 73 75 62 2d 73 79 73 74  e index sub-syst
2d60: 65 6d 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d  em */.  if( rc==
2d70: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
2d80: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 46 74 73   rc = sqlite3Fts
2d90: 35 49 6e 64 65 78 4f 70 65 6e 28 70 43 6f 6e 66  5IndexOpen(pConf
2da0: 69 67 2c 20 62 43 72 65 61 74 65 2c 20 26 70 54  ig, bCreate, &pT
2db0: 61 62 2d 3e 70 49 6e 64 65 78 2c 20 70 7a 45 72  ab->pIndex, pzEr
2dc0: 72 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 4f 70  r);.  }..  /* Op
2dd0: 65 6e 20 74 68 65 20 73 74 6f 72 61 67 65 20 73  en the storage s
2de0: 75 62 2d 73 79 73 74 65 6d 20 2a 2f 0a 20 20 69  ub-system */.  i
2df0: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
2e00: 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c   ){.    rc = sql
2e10: 69 74 65 33 46 74 73 35 53 74 6f 72 61 67 65 4f  ite3Fts5StorageO
2e20: 70 65 6e 28 0a 20 20 20 20 20 20 20 20 70 43 6f  pen(.        pCo
2e30: 6e 66 69 67 2c 20 70 54 61 62 2d 3e 70 49 6e 64  nfig, pTab->pInd
2e40: 65 78 2c 20 62 43 72 65 61 74 65 2c 20 26 70 54  ex, bCreate, &pT
2e50: 61 62 2d 3e 70 53 74 6f 72 61 67 65 2c 20 70 7a  ab->pStorage, pz
2e60: 45 72 72 0a 20 20 20 20 29 3b 0a 20 20 7d 0a 0a  Err.    );.  }..
2e70: 20 20 2f 2a 20 43 61 6c 6c 20 73 71 6c 69 74 65    /* Call sqlite
2e80: 33 5f 64 65 63 6c 61 72 65 5f 76 74 61 62 28 29  3_declare_vtab()
2e90: 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d 53 51   */.  if( rc==SQ
2ea0: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72  LITE_OK ){.    r
2eb0: 63 20 3d 20 73 71 6c 69 74 65 33 46 74 73 35 43  c = sqlite3Fts5C
2ec0: 6f 6e 66 69 67 44 65 63 6c 61 72 65 56 74 61 62  onfigDeclareVtab
2ed0: 28 70 43 6f 6e 66 69 67 29 3b 0a 20 20 7d 0a 0a  (pConfig);.  }..
2ee0: 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
2ef0: 5f 4f 4b 20 29 7b 0a 20 20 20 20 66 74 73 35 46  _OK ){.    fts5F
2f00: 72 65 65 56 74 61 62 28 70 54 61 62 2c 20 30 29  reeVtab(pTab, 0)
2f10: 3b 0a 20 20 20 20 70 54 61 62 20 3d 20 30 3b 0a  ;.    pTab = 0;.
2f20: 20 20 7d 65 6c 73 65 20 69 66 28 20 62 43 72 65    }else if( bCre
2f30: 61 74 65 20 29 7b 0a 20 20 20 20 66 74 73 35 43  ate ){.    fts5C
2f40: 68 65 63 6b 54 72 61 6e 73 61 63 74 69 6f 6e 53  heckTransactionS
2f50: 74 61 74 65 28 70 54 61 62 2c 20 46 54 53 35 5f  tate(pTab, FTS5_
2f60: 42 45 47 49 4e 2c 20 30 29 3b 0a 20 20 7d 0a 20  BEGIN, 0);.  }. 
2f70: 20 2a 70 70 56 54 61 62 20 3d 20 28 73 71 6c 69   *ppVTab = (sqli
2f80: 74 65 33 5f 76 74 61 62 2a 29 70 54 61 62 3b 0a  te3_vtab*)pTab;.
2f90: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
2fa0: 2f 2a 0a 2a 2a 20 54 68 65 20 78 43 6f 6e 6e 65  /*.** The xConne
2fb0: 63 74 28 29 20 61 6e 64 20 78 43 72 65 61 74 65  ct() and xCreate
2fc0: 28 29 20 6d 65 74 68 6f 64 73 20 66 6f 72 20 74  () methods for t
2fd0: 68 65 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65  he virtual table
2fe0: 2e 20 41 6c 6c 20 74 68 65 0a 2a 2a 20 77 6f 72  . All the.** wor
2ff0: 6b 20 69 73 20 64 6f 6e 65 20 69 6e 20 66 75 6e  k is done in fun
3000: 63 74 69 6f 6e 20 66 74 73 35 49 6e 69 74 56 74  ction fts5InitVt
3010: 61 62 28 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ab()..*/.static 
3020: 69 6e 74 20 66 74 73 35 43 6f 6e 6e 65 63 74 4d  int fts5ConnectM
3030: 65 74 68 6f 64 28 0a 20 20 73 71 6c 69 74 65 33  ethod(.  sqlite3
3040: 20 2a 64 62 2c 20 20 20 20 20 20 20 20 20 20 20   *db,           
3050: 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61           /* Data
3060: 62 61 73 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 20  base connection 
3070: 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 41 75 78 2c  */.  void *pAux,
3080: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3090: 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20       /* Pointer 
30a0: 74 6f 20 74 6f 6b 65 6e 69 7a 65 72 20 68 61 73  to tokenizer has
30b0: 68 20 74 61 62 6c 65 20 2a 2f 0a 20 20 69 6e 74  h table */.  int
30c0: 20 61 72 67 63 2c 20 20 20 20 20 20 20 20 20 20   argc,          
30d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
30e0: 4e 75 6d 62 65 72 20 6f 66 20 65 6c 65 6d 65 6e  Number of elemen
30f0: 74 73 20 69 6e 20 61 72 67 76 20 61 72 72 61 79  ts in argv array
3100: 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72   */.  const char
3110: 20 2a 20 63 6f 6e 73 74 20 2a 61 72 67 76 2c 20   * const *argv, 
3120: 20 20 20 20 20 20 2f 2a 20 78 43 72 65 61 74 65        /* xCreate
3130: 2f 78 43 6f 6e 6e 65 63 74 20 61 72 67 75 6d 65  /xConnect argume
3140: 6e 74 20 61 72 72 61 79 20 2a 2f 0a 20 20 73 71  nt array */.  sq
3150: 6c 69 74 65 33 5f 76 74 61 62 20 2a 2a 70 70 56  lite3_vtab **ppV
3160: 74 61 62 2c 20 20 20 20 20 20 20 20 20 20 2f 2a  tab,          /*
3170: 20 4f 55 54 3a 20 4e 65 77 20 73 71 6c 69 74 65   OUT: New sqlite
3180: 33 5f 76 74 61 62 20 6f 62 6a 65 63 74 20 2a 2f  3_vtab object */
3190: 0a 20 20 63 68 61 72 20 2a 2a 70 7a 45 72 72 20  .  char **pzErr 
31a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
31b0: 20 20 20 2f 2a 20 4f 55 54 3a 20 73 71 6c 69 74     /* OUT: sqlit
31c0: 65 33 5f 6d 61 6c 6c 6f 63 27 64 20 65 72 72 6f  e3_malloc'd erro
31d0: 72 20 6d 65 73 73 61 67 65 20 2a 2f 0a 29 7b 0a  r message */.){.
31e0: 20 20 72 65 74 75 72 6e 20 66 74 73 35 49 6e 69    return fts5Ini
31f0: 74 56 74 61 62 28 30 2c 20 64 62 2c 20 70 41 75  tVtab(0, db, pAu
3200: 78 2c 20 61 72 67 63 2c 20 61 72 67 76 2c 20 70  x, argc, argv, p
3210: 70 56 74 61 62 2c 20 70 7a 45 72 72 29 3b 0a 7d  pVtab, pzErr);.}
3220: 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35  .static int fts5
3230: 43 72 65 61 74 65 4d 65 74 68 6f 64 28 0a 20 20  CreateMethod(.  
3240: 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 20 20 20  sqlite3 *db,    
3250: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3260: 2f 2a 20 44 61 74 61 62 61 73 65 20 63 6f 6e 6e  /* Database conn
3270: 65 63 74 69 6f 6e 20 2a 2f 0a 20 20 76 6f 69 64  ection */.  void
3280: 20 2a 70 41 75 78 2c 20 20 20 20 20 20 20 20 20   *pAux,         
3290: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50              /* P
32a0: 6f 69 6e 74 65 72 20 74 6f 20 74 6f 6b 65 6e 69  ointer to tokeni
32b0: 7a 65 72 20 68 61 73 68 20 74 61 62 6c 65 20 2a  zer hash table *
32c0: 2f 0a 20 20 69 6e 74 20 61 72 67 63 2c 20 20 20  /.  int argc,   
32d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
32e0: 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66      /* Number of
32f0: 20 65 6c 65 6d 65 6e 74 73 20 69 6e 20 61 72 67   elements in arg
3300: 76 20 61 72 72 61 79 20 2a 2f 0a 20 20 63 6f 6e  v array */.  con
3310: 73 74 20 63 68 61 72 20 2a 20 63 6f 6e 73 74 20  st char * const 
3320: 2a 61 72 67 76 2c 20 20 20 20 20 20 20 2f 2a 20  *argv,       /* 
3330: 78 43 72 65 61 74 65 2f 78 43 6f 6e 6e 65 63 74  xCreate/xConnect
3340: 20 61 72 67 75 6d 65 6e 74 20 61 72 72 61 79 20   argument array 
3350: 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61  */.  sqlite3_vta
3360: 62 20 2a 2a 70 70 56 74 61 62 2c 20 20 20 20 20  b **ppVtab,     
3370: 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 4e 65 77       /* OUT: New
3380: 20 73 71 6c 69 74 65 33 5f 76 74 61 62 20 6f 62   sqlite3_vtab ob
3390: 6a 65 63 74 20 2a 2f 0a 20 20 63 68 61 72 20 2a  ject */.  char *
33a0: 2a 70 7a 45 72 72 20 20 20 20 20 20 20 20 20 20  *pzErr          
33b0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54            /* OUT
33c0: 3a 20 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63  : sqlite3_malloc
33d0: 27 64 20 65 72 72 6f 72 20 6d 65 73 73 61 67 65  'd error message
33e0: 20 2a 2f 0a 29 7b 0a 20 20 72 65 74 75 72 6e 20   */.){.  return 
33f0: 66 74 73 35 49 6e 69 74 56 74 61 62 28 31 2c 20  fts5InitVtab(1, 
3400: 64 62 2c 20 70 41 75 78 2c 20 61 72 67 63 2c 20  db, pAux, argc, 
3410: 61 72 67 76 2c 20 70 70 56 74 61 62 2c 20 70 7a  argv, ppVtab, pz
3420: 45 72 72 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54  Err);.}../*.** T
3430: 68 65 20 74 68 72 65 65 20 71 75 65 72 79 20 70  he three query p
3440: 6c 61 6e 73 20 78 42 65 73 74 49 6e 64 65 78 20  lans xBestIndex 
3450: 6d 61 79 20 63 68 6f 6f 73 65 20 62 65 74 77 65  may choose betwe
3460: 65 6e 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 46  en..*/.#define F
3470: 54 53 35 5f 50 4c 41 4e 5f 53 43 41 4e 20 20 20  TS5_PLAN_SCAN   
3480: 20 20 20 20 20 20 20 20 31 20 20 20 20 20 20 20          1       
3490: 2f 2a 20 4e 6f 20 75 73 61 62 6c 65 20 63 6f 6e  /* No usable con
34a0: 73 74 72 61 69 6e 74 20 2a 2f 0a 23 64 65 66 69  straint */.#defi
34b0: 6e 65 20 46 54 53 35 5f 50 4c 41 4e 5f 4d 41 54  ne FTS5_PLAN_MAT
34c0: 43 48 20 20 20 20 20 20 20 20 20 20 32 20 20 20  CH          2   
34d0: 20 20 20 20 2f 2a 20 28 3c 74 62 6c 3e 20 4d 41      /* (<tbl> MA
34e0: 54 43 48 20 3f 29 20 2a 2f 0a 23 64 65 66 69 6e  TCH ?) */.#defin
34f0: 65 20 46 54 53 35 5f 50 4c 41 4e 5f 53 4f 52 54  e FTS5_PLAN_SORT
3500: 45 44 5f 4d 41 54 43 48 20 20 20 33 20 20 20 20  ED_MATCH   3    
3510: 20 20 20 2f 2a 20 28 3c 74 62 6c 3e 20 4d 41 54     /* (<tbl> MAT
3520: 43 48 20 3f 20 4f 52 44 45 52 20 42 59 20 72 61  CH ? ORDER BY ra
3530: 6e 6b 29 20 2a 2f 0a 23 64 65 66 69 6e 65 20 46  nk) */.#define F
3540: 54 53 35 5f 50 4c 41 4e 5f 52 4f 57 49 44 20 20  TS5_PLAN_ROWID  
3550: 20 20 20 20 20 20 20 20 34 20 20 20 20 20 20 20          4       
3560: 2f 2a 20 28 72 6f 77 69 64 20 3d 20 3f 29 20 2a  /* (rowid = ?) *
3570: 2f 0a 23 64 65 66 69 6e 65 20 46 54 53 35 5f 50  /.#define FTS5_P
3580: 4c 41 4e 5f 53 4f 55 52 43 45 20 20 20 20 20 20  LAN_SOURCE      
3590: 20 20 20 35 20 20 20 20 20 20 20 2f 2a 20 41 20     5       /* A 
35a0: 73 6f 75 72 63 65 20 63 75 72 73 6f 72 20 66 6f  source cursor fo
35b0: 72 20 53 4f 52 54 45 44 5f 4d 41 54 43 48 20 2a  r SORTED_MATCH *
35c0: 2f 0a 23 64 65 66 69 6e 65 20 46 54 53 35 5f 50  /.#define FTS5_P
35d0: 4c 41 4e 5f 53 50 45 43 49 41 4c 20 20 20 20 20  LAN_SPECIAL     
35e0: 20 20 20 36 20 20 20 20 20 20 20 2f 2a 20 41 6e     6       /* An
35f0: 20 69 6e 74 65 72 6e 61 6c 20 71 75 65 72 79 20   internal query 
3600: 2a 2f 0a 0a 23 64 65 66 69 6e 65 20 46 54 53 35  */..#define FTS5
3610: 5f 50 4c 41 4e 28 69 64 78 4e 75 6d 29 20 28 28  _PLAN(idxNum) ((
3620: 69 64 78 4e 75 6d 29 20 26 20 30 78 37 29 0a 0a  idxNum) & 0x7)..
3630: 23 64 65 66 69 6e 65 20 46 54 53 35 5f 4f 52 44  #define FTS5_ORD
3640: 45 52 5f 44 45 53 43 20 20 20 38 20 20 20 20 20  ER_DESC   8     
3650: 20 20 2f 2a 20 4f 52 44 45 52 20 42 59 20 72 6f    /* ORDER BY ro
3660: 77 69 64 20 44 45 53 43 20 2a 2f 0a 23 64 65 66  wid DESC */.#def
3670: 69 6e 65 20 46 54 53 35 5f 4f 52 44 45 52 5f 41  ine FTS5_ORDER_A
3680: 53 43 20 20 20 31 36 20 20 20 20 20 20 20 2f 2a  SC   16       /*
3690: 20 4f 52 44 45 52 20 42 59 20 72 6f 77 69 64 20   ORDER BY rowid 
36a0: 41 53 43 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 53 65  ASC */../*.** Se
36b0: 61 72 63 68 20 74 68 65 20 6f 62 6a 65 63 74 20  arch the object 
36c0: 70 61 73 73 65 64 20 61 73 20 74 68 65 20 66 69  passed as the fi
36d0: 72 73 74 20 61 72 67 75 6d 65 6e 74 20 66 6f 72  rst argument for
36e0: 20 61 20 75 73 61 62 6c 65 20 63 6f 6e 73 74 72   a usable constr
36f0: 61 69 6e 74 0a 2a 2a 20 6f 6e 20 63 6f 6c 75 6d  aint.** on colum
3700: 6e 20 69 43 6f 6c 20 75 73 69 6e 67 20 6f 70 65  n iCol using ope
3710: 72 61 74 6f 72 20 65 4f 70 2e 20 49 66 20 6f 6e  rator eOp. If on
3720: 65 20 69 73 20 66 6f 75 6e 64 2c 20 72 65 74 75  e is found, retu
3730: 72 6e 20 69 74 73 20 69 6e 64 65 78 20 69 6e 0a  rn its index in.
3740: 2a 2a 20 74 68 65 20 70 49 6e 66 6f 2d 3e 61 43  ** the pInfo->aC
3750: 6f 6e 73 74 72 61 69 6e 74 5b 5d 20 61 72 72 61  onstraint[] arra
3760: 79 2e 20 49 66 20 6e 6f 20 73 75 63 68 20 63 6f  y. If no such co
3770: 6e 73 74 72 61 69 6e 74 20 69 73 20 66 6f 75 6e  nstraint is foun
3780: 64 2c 20 72 65 74 75 72 6e 0a 2a 2a 20 61 20 6e  d, return.** a n
3790: 65 67 61 74 69 76 65 20 76 61 6c 75 65 2e 0a 2a  egative value..*
37a0: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73  /.static int fts
37b0: 35 46 69 6e 64 43 6f 6e 73 74 72 61 69 6e 74 28  5FindConstraint(
37c0: 73 71 6c 69 74 65 33 5f 69 6e 64 65 78 5f 69 6e  sqlite3_index_in
37d0: 66 6f 20 2a 70 49 6e 66 6f 2c 20 69 6e 74 20 65  fo *pInfo, int e
37e0: 4f 70 2c 20 69 6e 74 20 69 43 6f 6c 29 7b 0a 20  Op, int iCol){. 
37f0: 20 69 6e 74 20 69 3b 0a 20 20 66 6f 72 28 69 3d   int i;.  for(i=
3800: 30 3b 20 69 3c 70 49 6e 66 6f 2d 3e 6e 43 6f 6e  0; i<pInfo->nCon
3810: 73 74 72 61 69 6e 74 3b 20 69 2b 2b 29 7b 0a 20  straint; i++){. 
3820: 20 20 20 73 74 72 75 63 74 20 73 71 6c 69 74 65     struct sqlite
3830: 33 5f 69 6e 64 65 78 5f 63 6f 6e 73 74 72 61 69  3_index_constrai
3840: 6e 74 20 2a 70 20 3d 20 26 70 49 6e 66 6f 2d 3e  nt *p = &pInfo->
3850: 61 43 6f 6e 73 74 72 61 69 6e 74 5b 69 5d 3b 0a  aConstraint[i];.
3860: 20 20 20 20 69 66 28 20 70 2d 3e 75 73 61 62 6c      if( p->usabl
3870: 65 20 26 26 20 70 2d 3e 69 43 6f 6c 75 6d 6e 3d  e && p->iColumn=
3880: 3d 69 43 6f 6c 20 26 26 20 70 2d 3e 6f 70 3d 3d  =iCol && p->op==
3890: 65 4f 70 20 29 20 72 65 74 75 72 6e 20 69 3b 0a  eOp ) return i;.
38a0: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 2d 31 3b    }.  return -1;
38b0: 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 49 6d 70 6c 65  .}../* .** Imple
38c0: 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68 65  mentation of the
38d0: 20 78 42 65 73 74 49 6e 64 65 78 20 6d 65 74 68   xBestIndex meth
38e0: 6f 64 20 66 6f 72 20 46 54 53 35 20 74 61 62 6c  od for FTS5 tabl
38f0: 65 73 2e 20 54 68 65 72 65 0a 2a 2a 20 61 72 65  es. There.** are
3900: 20 74 68 72 65 65 20 70 6f 73 73 69 62 6c 65 20   three possible 
3910: 73 74 72 61 74 65 67 69 65 73 2c 20 69 6e 20 6f  strategies, in o
3920: 72 64 65 72 20 6f 66 20 70 72 65 66 65 72 65 6e  rder of preferen
3930: 63 65 3a 0a 2a 2a 0a 2a 2a 20 20 20 31 2e 20 46  ce:.**.**   1. F
3940: 75 6c 6c 2d 74 65 78 74 20 73 65 61 72 63 68 20  ull-text search 
3950: 75 73 69 6e 67 20 61 20 4d 41 54 43 48 20 6f 70  using a MATCH op
3960: 65 72 61 74 6f 72 2e 0a 2a 2a 20 20 20 32 2e 20  erator..**   2. 
3970: 41 20 62 79 2d 72 6f 77 69 64 20 6c 6f 6f 6b 75  A by-rowid looku
3980: 70 2e 0a 2a 2a 20 20 20 33 2e 20 41 20 66 75 6c  p..**   3. A ful
3990: 6c 2d 74 61 62 6c 65 20 73 63 61 6e 2e 0a 2a 2f  l-table scan..*/
39a0: 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35  .static int fts5
39b0: 42 65 73 74 49 6e 64 65 78 4d 65 74 68 6f 64 28  BestIndexMethod(
39c0: 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56  sqlite3_vtab *pV
39d0: 54 61 62 2c 20 73 71 6c 69 74 65 33 5f 69 6e 64  Tab, sqlite3_ind
39e0: 65 78 5f 69 6e 66 6f 20 2a 70 49 6e 66 6f 29 7b  ex_info *pInfo){
39f0: 0a 20 20 46 74 73 35 54 61 62 6c 65 20 2a 70 54  .  Fts5Table *pT
3a00: 61 62 20 3d 20 28 46 74 73 35 54 61 62 6c 65 2a  ab = (Fts5Table*
3a10: 29 70 56 54 61 62 3b 0a 20 20 46 74 73 35 43 6f  )pVTab;.  Fts5Co
3a20: 6e 66 69 67 20 2a 70 43 6f 6e 66 69 67 20 3d 20  nfig *pConfig = 
3a30: 70 54 61 62 2d 3e 70 43 6f 6e 66 69 67 3b 0a 20  pTab->pConfig;. 
3a40: 20 69 6e 74 20 69 43 6f 6e 73 3b 0a 20 20 69 6e   int iCons;.  in
3a50: 74 20 65 50 6c 61 6e 20 3d 20 46 54 53 35 5f 50  t ePlan = FTS5_P
3a60: 4c 41 4e 5f 53 43 41 4e 3b 0a 20 20 69 6e 74 20  LAN_SCAN;.  int 
3a70: 69 52 61 6e 6b 4d 61 74 63 68 3b 0a 0a 20 20 69  iRankMatch;..  i
3a80: 43 6f 6e 73 20 3d 20 66 74 73 35 46 69 6e 64 43  Cons = fts5FindC
3a90: 6f 6e 73 74 72 61 69 6e 74 28 70 49 6e 66 6f 2c  onstraint(pInfo,
3aa0: 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f 43 4f 4e  SQLITE_INDEX_CON
3ab0: 53 54 52 41 49 4e 54 5f 4d 41 54 43 48 2c 70 43  STRAINT_MATCH,pC
3ac0: 6f 6e 66 69 67 2d 3e 6e 43 6f 6c 29 3b 0a 20 20  onfig->nCol);.  
3ad0: 69 66 28 20 69 43 6f 6e 73 3e 3d 30 20 29 7b 0a  if( iCons>=0 ){.
3ae0: 20 20 20 20 65 50 6c 61 6e 20 3d 20 46 54 53 35      ePlan = FTS5
3af0: 5f 50 4c 41 4e 5f 4d 41 54 43 48 3b 0a 20 20 20  _PLAN_MATCH;.   
3b00: 20 70 49 6e 66 6f 2d 3e 65 73 74 69 6d 61 74 65   pInfo->estimate
3b10: 64 43 6f 73 74 20 3d 20 31 2e 30 3b 0a 20 20 7d  dCost = 1.0;.  }
3b20: 65 6c 73 65 7b 0a 20 20 20 20 69 43 6f 6e 73 20  else{.    iCons 
3b30: 3d 20 66 74 73 35 46 69 6e 64 43 6f 6e 73 74 72  = fts5FindConstr
3b40: 61 69 6e 74 28 70 49 6e 66 6f 2c 20 53 51 4c 49  aint(pInfo, SQLI
3b50: 54 45 5f 49 4e 44 45 58 5f 43 4f 4e 53 54 52 41  TE_INDEX_CONSTRA
3b60: 49 4e 54 5f 45 51 2c 20 2d 31 29 3b 0a 20 20 20  INT_EQ, -1);.   
3b70: 20 69 66 28 20 69 43 6f 6e 73 3e 3d 30 20 29 7b   if( iCons>=0 ){
3b80: 0a 20 20 20 20 20 20 65 50 6c 61 6e 20 3d 20 46  .      ePlan = F
3b90: 54 53 35 5f 50 4c 41 4e 5f 52 4f 57 49 44 3b 0a  TS5_PLAN_ROWID;.
3ba0: 20 20 20 20 20 20 70 49 6e 66 6f 2d 3e 65 73 74        pInfo->est
3bb0: 69 6d 61 74 65 64 43 6f 73 74 20 3d 20 32 2e 30  imatedCost = 2.0
3bc0: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69  ;.    }.  }..  i
3bd0: 66 28 20 69 43 6f 6e 73 3e 3d 30 20 29 7b 0a 20  f( iCons>=0 ){. 
3be0: 20 20 20 70 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74     pInfo->aConst
3bf0: 72 61 69 6e 74 55 73 61 67 65 5b 69 43 6f 6e 73  raintUsage[iCons
3c00: 5d 2e 61 72 67 76 49 6e 64 65 78 20 3d 20 31 3b  ].argvIndex = 1;
3c10: 0a 20 20 20 20 70 49 6e 66 6f 2d 3e 61 43 6f 6e  .    pInfo->aCon
3c20: 73 74 72 61 69 6e 74 55 73 61 67 65 5b 69 43 6f  straintUsage[iCo
3c30: 6e 73 5d 2e 6f 6d 69 74 20 3d 20 31 3b 0a 20 20  ns].omit = 1;.  
3c40: 7d 65 6c 73 65 7b 0a 20 20 20 20 70 49 6e 66 6f  }else{.    pInfo
3c50: 2d 3e 65 73 74 69 6d 61 74 65 64 43 6f 73 74 20  ->estimatedCost 
3c60: 3d 20 31 30 30 30 30 30 30 30 2e 30 3b 0a 20 20  = 10000000.0;.  
3c70: 7d 0a 0a 20 20 69 66 28 20 70 49 6e 66 6f 2d 3e  }..  if( pInfo->
3c80: 6e 4f 72 64 65 72 42 79 3d 3d 31 20 29 7b 0a 20  nOrderBy==1 ){. 
3c90: 20 20 20 69 6e 74 20 69 53 6f 72 74 20 3d 20 70     int iSort = p
3ca0: 49 6e 66 6f 2d 3e 61 4f 72 64 65 72 42 79 5b 30  Info->aOrderBy[0
3cb0: 5d 2e 69 43 6f 6c 75 6d 6e 3b 0a 20 20 20 20 69  ].iColumn;.    i
3cc0: 66 28 20 69 53 6f 72 74 3c 30 20 29 7b 0a 20 20  f( iSort<0 ){.  
3cd0: 20 20 20 20 2f 2a 20 4f 52 44 45 52 20 42 59 20      /* ORDER BY 
3ce0: 72 6f 77 69 64 20 5b 41 53 43 7c 44 45 53 43 5d  rowid [ASC|DESC]
3cf0: 20 2a 2f 0a 20 20 20 20 20 20 70 49 6e 66 6f 2d   */.      pInfo-
3d00: 3e 6f 72 64 65 72 42 79 43 6f 6e 73 75 6d 65 64  >orderByConsumed
3d10: 20 3d 20 31 3b 0a 20 20 20 20 7d 65 6c 73 65 20   = 1;.    }else 
3d20: 69 66 28 20 69 53 6f 72 74 3d 3d 28 70 43 6f 6e  if( iSort==(pCon
3d30: 66 69 67 2d 3e 6e 43 6f 6c 2b 31 29 20 26 26 20  fig->nCol+1) && 
3d40: 65 50 6c 61 6e 3d 3d 46 54 53 35 5f 50 4c 41 4e  ePlan==FTS5_PLAN
3d50: 5f 4d 41 54 43 48 20 29 7b 0a 20 20 20 20 20 20  _MATCH ){.      
3d60: 2f 2a 20 4f 52 44 45 52 20 42 59 20 72 61 6e 6b  /* ORDER BY rank
3d70: 20 5b 41 53 43 7c 44 45 53 43 5d 20 2a 2f 0a 20   [ASC|DESC] */. 
3d80: 20 20 20 20 20 70 49 6e 66 6f 2d 3e 6f 72 64 65       pInfo->orde
3d90: 72 42 79 43 6f 6e 73 75 6d 65 64 20 3d 20 31 3b  rByConsumed = 1;
3da0: 0a 20 20 20 20 20 20 65 50 6c 61 6e 20 3d 20 46  .      ePlan = F
3db0: 54 53 35 5f 50 4c 41 4e 5f 53 4f 52 54 45 44 5f  TS5_PLAN_SORTED_
3dc0: 4d 41 54 43 48 3b 0a 20 20 20 20 7d 0a 0a 20 20  MATCH;.    }..  
3dd0: 20 20 69 66 28 20 70 49 6e 66 6f 2d 3e 6f 72 64    if( pInfo->ord
3de0: 65 72 42 79 43 6f 6e 73 75 6d 65 64 20 29 7b 0a  erByConsumed ){.
3df0: 20 20 20 20 20 20 65 50 6c 61 6e 20 7c 3d 20 70        ePlan |= p
3e00: 49 6e 66 6f 2d 3e 61 4f 72 64 65 72 42 79 5b 30  Info->aOrderBy[0
3e10: 5d 2e 64 65 73 63 20 3f 20 46 54 53 35 5f 4f 52  ].desc ? FTS5_OR
3e20: 44 45 52 5f 44 45 53 43 20 3a 20 46 54 53 35 5f  DER_DESC : FTS5_
3e30: 4f 52 44 45 52 5f 41 53 43 3b 0a 20 20 20 20 7d  ORDER_ASC;.    }
3e40: 0a 20 20 7d 0a 0a 20 20 69 52 61 6e 6b 4d 61 74  .  }..  iRankMat
3e50: 63 68 20 3d 20 66 74 73 35 46 69 6e 64 43 6f 6e  ch = fts5FindCon
3e60: 73 74 72 61 69 6e 74 28 0a 20 20 20 20 20 20 70  straint(.      p
3e70: 49 6e 66 6f 2c 20 53 51 4c 49 54 45 5f 49 4e 44  Info, SQLITE_IND
3e80: 45 58 5f 43 4f 4e 53 54 52 41 49 4e 54 5f 4d 41  EX_CONSTRAINT_MA
3e90: 54 43 48 2c 20 70 43 6f 6e 66 69 67 2d 3e 6e 43  TCH, pConfig->nC
3ea0: 6f 6c 2b 31 0a 20 20 29 3b 0a 20 20 69 66 28 20  ol+1.  );.  if( 
3eb0: 69 52 61 6e 6b 4d 61 74 63 68 3e 3d 30 20 29 7b  iRankMatch>=0 ){
3ec0: 0a 20 20 20 20 70 49 6e 66 6f 2d 3e 61 43 6f 6e  .    pInfo->aCon
3ed0: 73 74 72 61 69 6e 74 55 73 61 67 65 5b 69 52 61  straintUsage[iRa
3ee0: 6e 6b 4d 61 74 63 68 5d 2e 61 72 67 76 49 6e 64  nkMatch].argvInd
3ef0: 65 78 20 3d 20 31 20 2b 20 28 69 43 6f 6e 73 3e  ex = 1 + (iCons>
3f00: 3d 30 29 3b 0a 20 20 20 20 70 49 6e 66 6f 2d 3e  =0);.    pInfo->
3f10: 61 43 6f 6e 73 74 72 61 69 6e 74 55 73 61 67 65  aConstraintUsage
3f20: 5b 69 52 61 6e 6b 4d 61 74 63 68 5d 2e 6f 6d 69  [iRankMatch].omi
3f30: 74 20 3d 20 31 3b 0a 20 20 7d 0a 20 20 20 0a 20  t = 1;.  }.   . 
3f40: 20 70 49 6e 66 6f 2d 3e 69 64 78 4e 75 6d 20 3d   pInfo->idxNum =
3f50: 20 65 50 6c 61 6e 3b 0a 20 20 72 65 74 75 72 6e   ePlan;.  return
3f60: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f   SQLITE_OK;.}../
3f70: 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74  *.** Implementat
3f80: 69 6f 6e 20 6f 66 20 78 4f 70 65 6e 20 6d 65 74  ion of xOpen met
3f90: 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  hod..*/.static i
3fa0: 6e 74 20 66 74 73 35 4f 70 65 6e 4d 65 74 68 6f  nt fts5OpenMetho
3fb0: 64 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a  d(sqlite3_vtab *
3fc0: 70 56 54 61 62 2c 20 73 71 6c 69 74 65 33 5f 76  pVTab, sqlite3_v
3fd0: 74 61 62 5f 63 75 72 73 6f 72 20 2a 2a 70 70 43  tab_cursor **ppC
3fe0: 73 72 29 7b 0a 20 20 46 74 73 35 54 61 62 6c 65  sr){.  Fts5Table
3ff0: 20 2a 70 54 61 62 20 3d 20 28 46 74 73 35 54 61   *pTab = (Fts5Ta
4000: 62 6c 65 2a 29 70 56 54 61 62 3b 0a 20 20 46 74  ble*)pVTab;.  Ft
4010: 73 35 43 6f 6e 66 69 67 20 2a 70 43 6f 6e 66 69  s5Config *pConfi
4020: 67 20 3d 20 70 54 61 62 2d 3e 70 43 6f 6e 66 69  g = pTab->pConfi
4030: 67 3b 0a 20 20 46 74 73 35 43 75 72 73 6f 72 20  g;.  Fts5Cursor 
4040: 2a 70 43 73 72 3b 20 20 20 20 20 20 20 20 20 20  *pCsr;          
4050: 20 20 20 20 20 2f 2a 20 4e 65 77 20 63 75 72 73       /* New curs
4060: 6f 72 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 69  or object */.  i
4070: 6e 74 20 6e 42 79 74 65 3b 20 20 20 20 20 20 20  nt nByte;       
4080: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
4090: 2a 20 42 79 74 65 73 20 6f 66 20 73 70 61 63 65  * Bytes of space
40a0: 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20 2a 2f 0a   to allocate */.
40b0: 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
40c0: 45 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20 20 20  E_OK;           
40d0: 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65    /* Return code
40e0: 20 2a 2f 0a 0a 20 20 6e 42 79 74 65 20 3d 20 73   */..  nByte = s
40f0: 69 7a 65 6f 66 28 46 74 73 35 43 75 72 73 6f 72  izeof(Fts5Cursor
4100: 29 20 2b 20 70 43 6f 6e 66 69 67 2d 3e 6e 43 6f  ) + pConfig->nCo
4110: 6c 20 2a 20 73 69 7a 65 6f 66 28 69 6e 74 29 3b  l * sizeof(int);
4120: 0a 20 20 70 43 73 72 20 3d 20 28 46 74 73 35 43  .  pCsr = (Fts5C
4130: 75 72 73 6f 72 2a 29 73 71 6c 69 74 65 33 5f 6d  ursor*)sqlite3_m
4140: 61 6c 6c 6f 63 28 6e 42 79 74 65 29 3b 0a 20 20  alloc(nByte);.  
4150: 69 66 28 20 70 43 73 72 20 29 7b 0a 20 20 20 20  if( pCsr ){.    
4160: 46 74 73 35 47 6c 6f 62 61 6c 20 2a 70 47 6c 6f  Fts5Global *pGlo
4170: 62 61 6c 20 3d 20 70 54 61 62 2d 3e 70 47 6c 6f  bal = pTab->pGlo
4180: 62 61 6c 3b 0a 20 20 20 20 6d 65 6d 73 65 74 28  bal;.    memset(
4190: 70 43 73 72 2c 20 30 2c 20 6e 42 79 74 65 29 3b  pCsr, 0, nByte);
41a0: 0a 20 20 20 20 70 43 73 72 2d 3e 61 43 6f 6c 75  .    pCsr->aColu
41b0: 6d 6e 53 69 7a 65 20 3d 20 28 69 6e 74 2a 29 26  mnSize = (int*)&
41c0: 70 43 73 72 5b 31 5d 3b 0a 20 20 20 20 70 43 73  pCsr[1];.    pCs
41d0: 72 2d 3e 70 4e 65 78 74 20 3d 20 70 47 6c 6f 62  r->pNext = pGlob
41e0: 61 6c 2d 3e 70 43 73 72 3b 0a 20 20 20 20 70 47  al->pCsr;.    pG
41f0: 6c 6f 62 61 6c 2d 3e 70 43 73 72 20 3d 20 70 43  lobal->pCsr = pC
4200: 73 72 3b 0a 20 20 20 20 70 43 73 72 2d 3e 69 43  sr;.    pCsr->iC
4210: 73 72 49 64 20 3d 20 2b 2b 70 47 6c 6f 62 61 6c  srId = ++pGlobal
4220: 2d 3e 69 4e 65 78 74 49 64 3b 0a 20 20 7d 65 6c  ->iNextId;.  }el
4230: 73 65 7b 0a 20 20 20 20 72 63 20 3d 20 53 51 4c  se{.    rc = SQL
4240: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 20  ITE_NOMEM;.  }. 
4250: 20 2a 70 70 43 73 72 20 3d 20 28 73 71 6c 69 74   *ppCsr = (sqlit
4260: 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 2a 29  e3_vtab_cursor*)
4270: 70 43 73 72 3b 0a 20 20 72 65 74 75 72 6e 20 72  pCsr;.  return r
4280: 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  c;.}..static int
4290: 20 66 74 73 35 53 74 6d 74 54 79 70 65 28 69 6e   fts5StmtType(in
42a0: 74 20 69 64 78 4e 75 6d 29 7b 0a 20 20 69 66 28  t idxNum){.  if(
42b0: 20 46 54 53 35 5f 50 4c 41 4e 28 69 64 78 4e 75   FTS5_PLAN(idxNu
42c0: 6d 29 3d 3d 46 54 53 35 5f 50 4c 41 4e 5f 53 43  m)==FTS5_PLAN_SC
42d0: 41 4e 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e  AN ){.    return
42e0: 20 28 69 64 78 4e 75 6d 26 46 54 53 35 5f 4f 52   (idxNum&FTS5_OR
42f0: 44 45 52 5f 41 53 43 29 20 3f 20 46 54 53 35 5f  DER_ASC) ? FTS5_
4300: 53 54 4d 54 5f 53 43 41 4e 5f 41 53 43 20 3a 20  STMT_SCAN_ASC : 
4310: 46 54 53 35 5f 53 54 4d 54 5f 53 43 41 4e 5f 44  FTS5_STMT_SCAN_D
4320: 45 53 43 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72  ESC;.  }.  retur
4330: 6e 20 46 54 53 35 5f 53 54 4d 54 5f 4c 4f 4f 4b  n FTS5_STMT_LOOK
4340: 55 50 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69  UP;.}../*.** Thi
4350: 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61  s function is ca
4360: 6c 6c 65 64 20 61 66 74 65 72 20 74 68 65 20 63  lled after the c
4370: 75 72 73 6f 72 20 70 61 73 73 65 64 20 61 73 20  ursor passed as 
4380: 74 68 65 20 6f 6e 6c 79 20 61 72 67 75 6d 65 6e  the only argumen
4390: 74 0a 2a 2a 20 69 73 20 6d 6f 76 65 64 20 74 6f  t.** is moved to
43a0: 20 70 6f 69 6e 74 20 61 74 20 61 20 64 69 66 66   point at a diff
43b0: 65 72 65 6e 74 20 72 6f 77 2e 20 49 74 20 63 6c  erent row. It cl
43c0: 65 61 72 73 20 61 6c 6c 20 63 61 63 68 65 64 20  ears all cached 
43d0: 64 61 74 61 20 0a 2a 2a 20 73 70 65 63 69 66 69  data .** specifi
43e0: 63 20 74 6f 20 74 68 65 20 70 72 65 76 69 6f 75  c to the previou
43f0: 73 20 72 6f 77 20 73 74 6f 72 65 64 20 62 79 20  s row stored by 
4400: 74 68 65 20 63 75 72 73 6f 72 20 6f 62 6a 65 63  the cursor objec
4410: 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  t..*/.static voi
4420: 64 20 66 74 73 35 43 73 72 4e 65 77 72 6f 77 28  d fts5CsrNewrow(
4430: 46 74 73 35 43 75 72 73 6f 72 20 2a 70 43 73 72  Fts5Cursor *pCsr
4440: 29 7b 0a 20 20 43 73 72 46 6c 61 67 53 65 74 28  ){.  CsrFlagSet(
4450: 70 43 73 72 2c 20 46 54 53 35 43 53 52 5f 52 45  pCsr, FTS5CSR_RE
4460: 51 55 49 52 45 5f 43 4f 4e 54 45 4e 54 20 7c 20  QUIRE_CONTENT | 
4470: 46 54 53 35 43 53 52 5f 52 45 51 55 49 52 45 5f  FTS5CSR_REQUIRE_
4480: 44 4f 43 53 49 5a 45 20 29 3b 0a 20 20 73 71 6c  DOCSIZE );.  sql
4490: 69 74 65 33 5f 66 72 65 65 28 70 43 73 72 2d 3e  ite3_free(pCsr->
44a0: 61 49 6e 73 74 29 3b 0a 20 20 70 43 73 72 2d 3e  aInst);.  pCsr->
44b0: 61 49 6e 73 74 20 3d 20 30 3b 0a 20 20 70 43 73  aInst = 0;.  pCs
44c0: 72 2d 3e 6e 49 6e 73 74 43 6f 75 6e 74 20 3d 20  r->nInstCount = 
44d0: 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6c 6f 73  0;.}../*.** Clos
44e0: 65 20 74 68 65 20 63 75 72 73 6f 72 2e 20 20 46  e the cursor.  F
44f0: 6f 72 20 61 64 64 69 74 69 6f 6e 61 6c 20 69 6e  or additional in
4500: 66 6f 72 6d 61 74 69 6f 6e 20 73 65 65 20 74 68  formation see th
4510: 65 20 64 6f 63 75 6d 65 6e 74 61 74 69 6f 6e 0a  e documentation.
4520: 2a 2a 20 6f 6e 20 74 68 65 20 78 43 6c 6f 73 65  ** on the xClose
4530: 20 6d 65 74 68 6f 64 20 6f 66 20 74 68 65 20 76   method of the v
4540: 69 72 74 75 61 6c 20 74 61 62 6c 65 20 69 6e 74  irtual table int
4550: 65 72 66 61 63 65 2e 0a 2a 2f 0a 73 74 61 74 69  erface..*/.stati
4560: 63 20 69 6e 74 20 66 74 73 35 43 6c 6f 73 65 4d  c int fts5CloseM
4570: 65 74 68 6f 64 28 73 71 6c 69 74 65 33 5f 76 74  ethod(sqlite3_vt
4580: 61 62 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 73  ab_cursor *pCurs
4590: 6f 72 29 7b 0a 20 20 46 74 73 35 54 61 62 6c 65  or){.  Fts5Table
45a0: 20 2a 70 54 61 62 20 3d 20 28 46 74 73 35 54 61   *pTab = (Fts5Ta
45b0: 62 6c 65 2a 29 28 70 43 75 72 73 6f 72 2d 3e 70  ble*)(pCursor->p
45c0: 56 74 61 62 29 3b 0a 20 20 46 74 73 35 43 75 72  Vtab);.  Fts5Cur
45d0: 73 6f 72 20 2a 70 43 73 72 20 3d 20 28 46 74 73  sor *pCsr = (Fts
45e0: 35 43 75 72 73 6f 72 2a 29 70 43 75 72 73 6f 72  5Cursor*)pCursor
45f0: 3b 0a 20 20 46 74 73 35 43 75 72 73 6f 72 20 2a  ;.  Fts5Cursor *
4600: 2a 70 70 3b 0a 20 20 46 74 73 35 41 75 78 64 61  *pp;.  Fts5Auxda
4610: 74 61 20 2a 70 44 61 74 61 3b 0a 20 20 46 74 73  ta *pData;.  Fts
4620: 35 41 75 78 64 61 74 61 20 2a 70 4e 65 78 74 3b  5Auxdata *pNext;
4630: 0a 0a 20 20 66 74 73 35 43 73 72 4e 65 77 72 6f  ..  fts5CsrNewro
4640: 77 28 70 43 73 72 29 3b 0a 20 20 69 66 28 20 70  w(pCsr);.  if( p
4650: 43 73 72 2d 3e 70 53 74 6d 74 20 29 7b 0a 20 20  Csr->pStmt ){.  
4660: 20 20 69 6e 74 20 65 53 74 6d 74 20 3d 20 66 74    int eStmt = ft
4670: 73 35 53 74 6d 74 54 79 70 65 28 70 43 73 72 2d  s5StmtType(pCsr-
4680: 3e 69 64 78 4e 75 6d 29 3b 0a 20 20 20 20 73 71  >idxNum);.    sq
4690: 6c 69 74 65 33 46 74 73 35 53 74 6f 72 61 67 65  lite3Fts5Storage
46a0: 53 74 6d 74 52 65 6c 65 61 73 65 28 70 54 61 62  StmtRelease(pTab
46b0: 2d 3e 70 53 74 6f 72 61 67 65 2c 20 65 53 74 6d  ->pStorage, eStm
46c0: 74 2c 20 70 43 73 72 2d 3e 70 53 74 6d 74 29 3b  t, pCsr->pStmt);
46d0: 0a 20 20 7d 0a 20 20 69 66 28 20 70 43 73 72 2d  .  }.  if( pCsr-
46e0: 3e 70 53 6f 72 74 65 72 20 29 7b 0a 20 20 20 20  >pSorter ){.    
46f0: 46 74 73 35 53 6f 72 74 65 72 20 2a 70 53 6f 72  Fts5Sorter *pSor
4700: 74 65 72 20 3d 20 70 43 73 72 2d 3e 70 53 6f 72  ter = pCsr->pSor
4710: 74 65 72 3b 0a 20 20 20 20 73 71 6c 69 74 65 33  ter;.    sqlite3
4720: 5f 66 69 6e 61 6c 69 7a 65 28 70 53 6f 72 74 65  _finalize(pSorte
4730: 72 2d 3e 70 53 74 6d 74 29 3b 0a 20 20 20 20 73  r->pStmt);.    s
4740: 71 6c 69 74 65 33 5f 66 72 65 65 28 70 53 6f 72  qlite3_free(pSor
4750: 74 65 72 29 3b 0a 20 20 7d 0a 20 20 0a 20 20 69  ter);.  }.  .  i
4760: 66 28 20 70 43 73 72 2d 3e 69 64 78 4e 75 6d 21  f( pCsr->idxNum!
4770: 3d 46 54 53 35 5f 50 4c 41 4e 5f 53 4f 55 52 43  =FTS5_PLAN_SOURC
4780: 45 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33  E ){.    sqlite3
4790: 46 74 73 35 45 78 70 72 46 72 65 65 28 70 43 73  Fts5ExprFree(pCs
47a0: 72 2d 3e 70 45 78 70 72 29 3b 0a 20 20 7d 0a 0a  r->pExpr);.  }..
47b0: 20 20 66 6f 72 28 70 44 61 74 61 3d 70 43 73 72    for(pData=pCsr
47c0: 2d 3e 70 41 75 78 64 61 74 61 3b 20 70 44 61 74  ->pAuxdata; pDat
47d0: 61 3b 20 70 44 61 74 61 3d 70 4e 65 78 74 29 7b  a; pData=pNext){
47e0: 0a 20 20 20 20 70 4e 65 78 74 20 3d 20 70 44 61  .    pNext = pDa
47f0: 74 61 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 69  ta->pNext;.    i
4800: 66 28 20 70 44 61 74 61 2d 3e 78 44 65 6c 65 74  f( pData->xDelet
4810: 65 20 29 20 70 44 61 74 61 2d 3e 78 44 65 6c 65  e ) pData->xDele
4820: 74 65 28 70 44 61 74 61 2d 3e 70 50 74 72 29 3b  te(pData->pPtr);
4830: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65  .    sqlite3_fre
4840: 65 28 70 44 61 74 61 29 3b 0a 20 20 7d 0a 0a 20  e(pData);.  }.. 
4850: 20 2f 2a 20 52 65 6d 6f 76 65 20 74 68 65 20 63   /* Remove the c
4860: 75 72 73 6f 72 20 66 72 6f 6d 20 74 68 65 20 46  ursor from the F
4870: 74 73 35 47 6c 6f 62 61 6c 2e 70 43 73 72 20 6c  ts5Global.pCsr l
4880: 69 73 74 20 2a 2f 0a 20 20 66 6f 72 28 70 70 3d  ist */.  for(pp=
4890: 26 70 54 61 62 2d 3e 70 47 6c 6f 62 61 6c 2d 3e  &pTab->pGlobal->
48a0: 70 43 73 72 3b 20 28 2a 70 70 29 21 3d 70 43 73  pCsr; (*pp)!=pCs
48b0: 72 3b 20 70 70 3d 26 28 2a 70 70 29 2d 3e 70 4e  r; pp=&(*pp)->pN
48c0: 65 78 74 29 3b 0a 20 20 2a 70 70 20 3d 20 70 43  ext);.  *pp = pC
48d0: 73 72 2d 3e 70 4e 65 78 74 3b 0a 0a 20 20 73 71  sr->pNext;..  sq
48e0: 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70  lite3_finalize(p
48f0: 43 73 72 2d 3e 70 52 61 6e 6b 41 72 67 53 74 6d  Csr->pRankArgStm
4900: 74 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72  t);.  sqlite3_fr
4910: 65 65 28 70 43 73 72 2d 3e 61 70 52 61 6e 6b 41  ee(pCsr->apRankA
4920: 72 67 29 3b 0a 0a 20 20 73 71 6c 69 74 65 33 5f  rg);..  sqlite3_
4930: 66 72 65 65 28 70 43 73 72 2d 3e 7a 53 70 65 63  free(pCsr->zSpec
4940: 69 61 6c 29 3b 0a 20 20 69 66 28 20 43 73 72 46  ial);.  if( CsrF
4950: 6c 61 67 54 65 73 74 28 70 43 73 72 2c 20 46 54  lagTest(pCsr, FT
4960: 53 35 43 53 52 5f 46 52 45 45 5f 5a 52 41 4e 4b  S5CSR_FREE_ZRANK
4970: 29 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33  ) ){.    sqlite3
4980: 5f 66 72 65 65 28 70 43 73 72 2d 3e 7a 52 61 6e  _free(pCsr->zRan
4990: 6b 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f  k);.    sqlite3_
49a0: 66 72 65 65 28 70 43 73 72 2d 3e 7a 52 61 6e 6b  free(pCsr->zRank
49b0: 41 72 67 73 29 3b 0a 20 20 7d 0a 20 20 73 71 6c  Args);.  }.  sql
49c0: 69 74 65 33 5f 66 72 65 65 28 70 43 73 72 29 3b  ite3_free(pCsr);
49d0: 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  .  return SQLITE
49e0: 5f 4f 4b 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69  _OK;.}..static i
49f0: 6e 74 20 66 74 73 35 53 6f 72 74 65 72 4e 65 78  nt fts5SorterNex
4a00: 74 28 46 74 73 35 43 75 72 73 6f 72 20 2a 70 43  t(Fts5Cursor *pC
4a10: 73 72 29 7b 0a 20 20 46 74 73 35 53 6f 72 74 65  sr){.  Fts5Sorte
4a20: 72 20 2a 70 53 6f 72 74 65 72 20 3d 20 70 43 73  r *pSorter = pCs
4a30: 72 2d 3e 70 53 6f 72 74 65 72 3b 0a 20 20 69 6e  r->pSorter;.  in
4a40: 74 20 72 63 3b 0a 0a 20 20 72 63 20 3d 20 73 71  t rc;..  rc = sq
4a50: 6c 69 74 65 33 5f 73 74 65 70 28 70 53 6f 72 74  lite3_step(pSort
4a60: 65 72 2d 3e 70 53 74 6d 74 29 3b 0a 20 20 69 66  er->pStmt);.  if
4a70: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 44 4f 4e  ( rc==SQLITE_DON
4a80: 45 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 53 51  E ){.    rc = SQ
4a90: 4c 49 54 45 5f 4f 4b 3b 0a 20 20 20 20 43 73 72  LITE_OK;.    Csr
4aa0: 46 6c 61 67 53 65 74 28 70 43 73 72 2c 20 46 54  FlagSet(pCsr, FT
4ab0: 53 35 43 53 52 5f 45 4f 46 29 3b 0a 20 20 7d 65  S5CSR_EOF);.  }e
4ac0: 6c 73 65 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  lse if( rc==SQLI
4ad0: 54 45 5f 52 4f 57 20 29 7b 0a 20 20 20 20 63 6f  TE_ROW ){.    co
4ae0: 6e 73 74 20 75 38 20 2a 61 3b 0a 20 20 20 20 63  nst u8 *a;.    c
4af0: 6f 6e 73 74 20 75 38 20 2a 61 42 6c 6f 62 3b 0a  onst u8 *aBlob;.
4b00: 20 20 20 20 69 6e 74 20 6e 42 6c 6f 62 3b 0a 20      int nBlob;. 
4b10: 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20 69 6e     int i;.    in
4b20: 74 20 69 4f 66 66 20 3d 20 30 3b 0a 20 20 20 20  t iOff = 0;.    
4b30: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  rc = SQLITE_OK;.
4b40: 0a 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 69 52  .    pSorter->iR
4b50: 6f 77 69 64 20 3d 20 73 71 6c 69 74 65 33 5f 63  owid = sqlite3_c
4b60: 6f 6c 75 6d 6e 5f 69 6e 74 36 34 28 70 53 6f 72  olumn_int64(pSor
4b70: 74 65 72 2d 3e 70 53 74 6d 74 2c 20 30 29 3b 0a  ter->pStmt, 0);.
4b80: 20 20 20 20 6e 42 6c 6f 62 20 3d 20 73 71 6c 69      nBlob = sqli
4b90: 74 65 33 5f 63 6f 6c 75 6d 6e 5f 62 79 74 65 73  te3_column_bytes
4ba0: 28 70 53 6f 72 74 65 72 2d 3e 70 53 74 6d 74 2c  (pSorter->pStmt,
4bb0: 20 31 29 3b 0a 20 20 20 20 61 42 6c 6f 62 20 3d   1);.    aBlob =
4bc0: 20 61 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f 6c   a = sqlite3_col
4bd0: 75 6d 6e 5f 62 6c 6f 62 28 70 53 6f 72 74 65 72  umn_blob(pSorter
4be0: 2d 3e 70 53 74 6d 74 2c 20 31 29 3b 0a 0a 20 20  ->pStmt, 1);..  
4bf0: 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 28 70 53    for(i=0; i<(pS
4c00: 6f 72 74 65 72 2d 3e 6e 49 64 78 2d 31 29 3b 20  orter->nIdx-1); 
4c10: 69 2b 2b 29 7b 0a 20 20 20 20 20 20 69 6e 74 20  i++){.      int 
4c20: 69 56 61 6c 3b 0a 20 20 20 20 20 20 61 20 2b 3d  iVal;.      a +=
4c30: 20 67 65 74 56 61 72 69 6e 74 33 32 28 61 2c 20   getVarint32(a, 
4c40: 69 56 61 6c 29 3b 0a 20 20 20 20 20 20 69 4f 66  iVal);.      iOf
4c50: 66 20 2b 3d 20 69 56 61 6c 3b 0a 20 20 20 20 20  f += iVal;.     
4c60: 20 70 53 6f 72 74 65 72 2d 3e 61 49 64 78 5b 69   pSorter->aIdx[i
4c70: 5d 20 3d 20 69 4f 66 66 3b 0a 20 20 20 20 7d 0a  ] = iOff;.    }.
4c80: 20 20 20 20 70 53 6f 72 74 65 72 2d 3e 61 49 64      pSorter->aId
4c90: 78 5b 69 5d 20 3d 20 26 61 42 6c 6f 62 5b 6e 42  x[i] = &aBlob[nB
4ca0: 6c 6f 62 5d 20 2d 20 61 3b 0a 0a 20 20 20 20 70  lob] - a;..    p
4cb0: 53 6f 72 74 65 72 2d 3e 61 50 6f 73 6c 69 73 74  Sorter->aPoslist
4cc0: 20 3d 20 61 3b 0a 20 20 20 20 66 74 73 35 43 73   = a;.    fts5Cs
4cd0: 72 4e 65 77 72 6f 77 28 70 43 73 72 29 3b 0a 20  rNewrow(pCsr);. 
4ce0: 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b   }..  return rc;
4cf0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 64 76 61 6e 63  .}../*.** Advanc
4d00: 65 20 74 68 65 20 63 75 72 73 6f 72 20 74 6f 20  e the cursor to 
4d10: 74 68 65 20 6e 65 78 74 20 72 6f 77 20 69 6e 20  the next row in 
4d20: 74 68 65 20 74 61 62 6c 65 20 74 68 61 74 20 6d  the table that m
4d30: 61 74 63 68 65 73 20 74 68 65 20 0a 2a 2a 20 73  atches the .** s
4d40: 65 61 72 63 68 20 63 72 69 74 65 72 69 61 2e 0a  earch criteria..
4d50: 2a 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 53 51 4c  **.** Return SQL
4d60: 49 54 45 5f 4f 4b 20 69 66 20 6e 6f 74 68 69 6e  ITE_OK if nothin
4d70: 67 20 67 6f 65 73 20 77 72 6f 6e 67 2e 20 20 53  g goes wrong.  S
4d80: 51 4c 49 54 45 5f 4f 4b 20 69 73 20 72 65 74 75  QLITE_OK is retu
4d90: 72 6e 65 64 0a 2a 2a 20 65 76 65 6e 20 69 66 20  rned.** even if 
4da0: 77 65 20 72 65 61 63 68 20 65 6e 64 2d 6f 66 2d  we reach end-of-
4db0: 66 69 6c 65 2e 20 20 54 68 65 20 66 74 73 35 45  file.  The fts5E
4dc0: 6f 66 4d 65 74 68 6f 64 28 29 20 77 69 6c 6c 20  ofMethod() will 
4dd0: 62 65 20 63 61 6c 6c 65 64 0a 2a 2a 20 73 75 62  be called.** sub
4de0: 73 65 71 75 65 6e 74 6c 79 20 74 6f 20 64 65 74  sequently to det
4df0: 65 72 6d 69 6e 65 20 77 68 65 74 68 65 72 20 6f  ermine whether o
4e00: 72 20 6e 6f 74 20 61 6e 20 45 4f 46 20 77 61 73  r not an EOF was
4e10: 20 68 69 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20   hit..*/.static 
4e20: 69 6e 74 20 66 74 73 35 4e 65 78 74 4d 65 74 68  int fts5NextMeth
4e30: 6f 64 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f  od(sqlite3_vtab_
4e40: 63 75 72 73 6f 72 20 2a 70 43 75 72 73 6f 72 29  cursor *pCursor)
4e50: 7b 0a 20 20 46 74 73 35 43 75 72 73 6f 72 20 2a  {.  Fts5Cursor *
4e60: 70 43 73 72 20 3d 20 28 46 74 73 35 43 75 72 73  pCsr = (Fts5Curs
4e70: 6f 72 2a 29 70 43 75 72 73 6f 72 3b 0a 20 20 69  or*)pCursor;.  i
4e80: 6e 74 20 65 50 6c 61 6e 20 3d 20 46 54 53 35 5f  nt ePlan = FTS5_
4e90: 50 4c 41 4e 28 70 43 73 72 2d 3e 69 64 78 4e 75  PLAN(pCsr->idxNu
4ea0: 6d 29 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53  m);.  int rc = S
4eb0: 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20 73 77 69  QLITE_OK;..  swi
4ec0: 74 63 68 28 20 65 50 6c 61 6e 20 29 7b 0a 20 20  tch( ePlan ){.  
4ed0: 20 20 63 61 73 65 20 46 54 53 35 5f 50 4c 41 4e    case FTS5_PLAN
4ee0: 5f 4d 41 54 43 48 3a 0a 20 20 20 20 63 61 73 65  _MATCH:.    case
4ef0: 20 46 54 53 35 5f 50 4c 41 4e 5f 53 4f 55 52 43   FTS5_PLAN_SOURC
4f00: 45 3a 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71  E:.      rc = sq
4f10: 6c 69 74 65 33 46 74 73 35 45 78 70 72 4e 65 78  lite3Fts5ExprNex
4f20: 74 28 70 43 73 72 2d 3e 70 45 78 70 72 29 3b 0a  t(pCsr->pExpr);.
4f30: 20 20 20 20 20 20 69 66 28 20 73 71 6c 69 74 65        if( sqlite
4f40: 33 46 74 73 35 45 78 70 72 45 6f 66 28 70 43 73  3Fts5ExprEof(pCs
4f50: 72 2d 3e 70 45 78 70 72 29 20 29 7b 0a 20 20 20  r->pExpr) ){.   
4f60: 20 20 20 20 20 43 73 72 46 6c 61 67 53 65 74 28       CsrFlagSet(
4f70: 70 43 73 72 2c 20 46 54 53 35 43 53 52 5f 45 4f  pCsr, FTS5CSR_EO
4f80: 46 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  F);.      }.    
4f90: 20 20 66 74 73 35 43 73 72 4e 65 77 72 6f 77 28    fts5CsrNewrow(
4fa0: 70 43 73 72 29 3b 0a 20 20 20 20 20 20 62 72 65  pCsr);.      bre
4fb0: 61 6b 3b 0a 0a 20 20 20 20 63 61 73 65 20 46 54  ak;..    case FT
4fc0: 53 35 5f 50 4c 41 4e 5f 53 50 45 43 49 41 4c 3a  S5_PLAN_SPECIAL:
4fd0: 20 7b 0a 20 20 20 20 20 20 43 73 72 46 6c 61 67   {.      CsrFlag
4fe0: 53 65 74 28 70 43 73 72 2c 20 46 54 53 35 43 53  Set(pCsr, FTS5CS
4ff0: 52 5f 45 4f 46 29 3b 0a 20 20 20 20 20 20 62 72  R_EOF);.      br
5000: 65 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20  eak;.    }..    
5010: 63 61 73 65 20 46 54 53 35 5f 50 4c 41 4e 5f 53  case FTS5_PLAN_S
5020: 4f 52 54 45 44 5f 4d 41 54 43 48 3a 20 7b 0a 20  ORTED_MATCH: {. 
5030: 20 20 20 20 20 72 63 20 3d 20 66 74 73 35 53 6f       rc = fts5So
5040: 72 74 65 72 4e 65 78 74 28 70 43 73 72 29 3b 0a  rterNext(pCsr);.
5050: 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20        break;.   
5060: 20 7d 0a 0a 20 20 20 20 64 65 66 61 75 6c 74 3a   }..    default:
5070: 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69  .      rc = sqli
5080: 74 65 33 5f 73 74 65 70 28 70 43 73 72 2d 3e 70  te3_step(pCsr->p
5090: 53 74 6d 74 29 3b 0a 20 20 20 20 20 20 69 66 28  Stmt);.      if(
50a0: 20 72 63 21 3d 53 51 4c 49 54 45 5f 52 4f 57 20   rc!=SQLITE_ROW 
50b0: 29 7b 0a 20 20 20 20 20 20 20 20 43 73 72 46 6c  ){.        CsrFl
50c0: 61 67 53 65 74 28 70 43 73 72 2c 20 46 54 53 35  agSet(pCsr, FTS5
50d0: 43 53 52 5f 45 4f 46 29 3b 0a 20 20 20 20 20 20  CSR_EOF);.      
50e0: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 72    rc = sqlite3_r
50f0: 65 73 65 74 28 70 43 73 72 2d 3e 70 53 74 6d 74  eset(pCsr->pStmt
5100: 29 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a  );.      }else{.
5110: 20 20 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c          rc = SQL
5120: 49 54 45 5f 4f 4b 3b 0a 20 20 20 20 20 20 7d 0a  ITE_OK;.      }.
5130: 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 7d        break;.  }
5140: 0a 20 20 0a 20 20 72 65 74 75 72 6e 20 72 63 3b  .  .  return rc;
5150: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 66  .}..static int f
5160: 74 73 35 43 75 72 73 6f 72 46 69 72 73 74 53 6f  ts5CursorFirstSo
5170: 72 74 65 64 28 46 74 73 35 54 61 62 6c 65 20 2a  rted(Fts5Table *
5180: 70 54 61 62 2c 20 46 74 73 35 43 75 72 73 6f 72  pTab, Fts5Cursor
5190: 20 2a 70 43 73 72 2c 20 69 6e 74 20 62 41 73 63   *pCsr, int bAsc
51a0: 29 7b 0a 20 20 46 74 73 35 43 6f 6e 66 69 67 20  ){.  Fts5Config 
51b0: 2a 70 43 6f 6e 66 69 67 20 3d 20 70 54 61 62 2d  *pConfig = pTab-
51c0: 3e 70 43 6f 6e 66 69 67 3b 0a 20 20 46 74 73 35  >pConfig;.  Fts5
51d0: 53 6f 72 74 65 72 20 2a 70 53 6f 72 74 65 72 3b  Sorter *pSorter;
51e0: 0a 20 20 69 6e 74 20 6e 50 68 72 61 73 65 3b 0a  .  int nPhrase;.
51f0: 20 20 69 6e 74 20 6e 42 79 74 65 3b 0a 20 20 69    int nByte;.  i
5200: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
5210: 4b 3b 0a 20 20 63 68 61 72 20 2a 7a 53 71 6c 3b  K;.  char *zSql;
5220: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
5230: 52 61 6e 6b 20 3d 20 70 43 73 72 2d 3e 7a 52 61  Rank = pCsr->zRa
5240: 6e 6b 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72  nk;.  const char
5250: 20 2a 7a 52 61 6e 6b 41 72 67 73 20 3d 20 70 43   *zRankArgs = pC
5260: 73 72 2d 3e 7a 52 61 6e 6b 41 72 67 73 3b 0a 20  sr->zRankArgs;. 
5270: 20 0a 20 20 6e 50 68 72 61 73 65 20 3d 20 73 71   .  nPhrase = sq
5280: 6c 69 74 65 33 46 74 73 35 45 78 70 72 50 68 72  lite3Fts5ExprPhr
5290: 61 73 65 43 6f 75 6e 74 28 70 43 73 72 2d 3e 70  aseCount(pCsr->p
52a0: 45 78 70 72 29 3b 0a 20 20 6e 42 79 74 65 20 3d  Expr);.  nByte =
52b0: 20 73 69 7a 65 6f 66 28 46 74 73 35 53 6f 72 74   sizeof(Fts5Sort
52c0: 65 72 29 20 2b 20 73 69 7a 65 6f 66 28 69 6e 74  er) + sizeof(int
52d0: 29 20 2a 20 6e 50 68 72 61 73 65 3b 0a 20 20 70  ) * nPhrase;.  p
52e0: 53 6f 72 74 65 72 20 3d 20 28 46 74 73 35 53 6f  Sorter = (Fts5So
52f0: 72 74 65 72 2a 29 73 71 6c 69 74 65 33 5f 6d 61  rter*)sqlite3_ma
5300: 6c 6c 6f 63 28 6e 42 79 74 65 29 3b 0a 20 20 69  lloc(nByte);.  i
5310: 66 28 20 70 53 6f 72 74 65 72 3d 3d 30 20 29 20  f( pSorter==0 ) 
5320: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f  return SQLITE_NO
5330: 4d 45 4d 3b 0a 20 20 6d 65 6d 73 65 74 28 70 53  MEM;.  memset(pS
5340: 6f 72 74 65 72 2c 20 30 2c 20 6e 42 79 74 65 29  orter, 0, nByte)
5350: 3b 0a 20 20 70 53 6f 72 74 65 72 2d 3e 6e 49 64  ;.  pSorter->nId
5360: 78 20 3d 20 6e 50 68 72 61 73 65 3b 0a 0a 20 20  x = nPhrase;..  
5370: 2f 2a 20 54 4f 44 4f 3a 20 49 74 20 77 6f 75 6c  /* TODO: It woul
5380: 64 20 62 65 20 62 65 74 74 65 72 20 74 6f 20 68  d be better to h
5390: 61 76 65 20 73 6f 6d 65 20 73 79 73 74 65 6d 20  ave some system 
53a0: 66 6f 72 20 72 65 75 73 69 6e 67 20 73 74 61 74  for reusing stat
53b0: 65 6d 65 6e 74 0a 20 20 2a 2a 20 68 61 6e 64 6c  ement.  ** handl
53c0: 65 73 20 68 65 72 65 2c 20 72 61 74 68 65 72 20  es here, rather 
53d0: 74 68 61 6e 20 70 72 65 70 61 72 69 6e 67 20 61  than preparing a
53e0: 20 6e 65 77 20 6f 6e 65 20 66 6f 72 20 65 61 63   new one for eac
53f0: 68 20 71 75 65 72 79 2e 20 42 75 74 20 74 68 61  h query. But tha
5400: 74 0a 20 20 2a 2a 20 69 73 20 6e 6f 74 20 70 6f  t.  ** is not po
5410: 73 73 69 62 6c 65 20 61 73 20 53 51 4c 69 74 65  ssible as SQLite
5420: 20 72 65 66 65 72 65 6e 63 65 20 63 6f 75 6e 74   reference count
5430: 73 20 74 68 65 20 76 69 72 74 75 61 6c 20 74 61  s the virtual ta
5440: 62 6c 65 20 6f 62 6a 65 63 74 73 2e 0a 20 20 2a  ble objects..  *
5450: 2a 20 41 6e 64 20 73 69 6e 63 65 20 74 68 65 20  * And since the 
5460: 73 74 61 74 65 6d 65 6e 74 20 72 65 71 75 69 72  statement requir
5470: 65 64 20 68 65 72 65 20 72 65 61 64 73 20 66 72  ed here reads fr
5480: 6f 6d 20 74 68 69 73 20 76 65 72 79 20 76 69 72  om this very vir
5490: 74 75 61 6c 20 0a 20 20 2a 2a 20 74 61 62 6c 65  tual .  ** table
54a0: 2c 20 73 61 76 69 6e 67 20 69 74 20 63 72 65 61  , saving it crea
54b0: 74 65 73 20 61 20 63 69 72 63 75 6c 61 72 20 72  tes a circular r
54c0: 65 66 65 72 65 6e 63 65 2e 0a 20 20 2a 2a 0a 20  eference..  **. 
54d0: 20 2a 2a 20 49 66 20 53 51 4c 69 74 65 20 61 20   ** If SQLite a 
54e0: 62 75 69 6c 74 2d 69 6e 20 73 74 61 74 65 6d 65  built-in stateme
54f0: 6e 74 20 63 61 63 68 65 2c 20 74 68 69 73 20 77  nt cache, this w
5500: 6f 75 6c 64 6e 27 74 20 62 65 20 61 20 70 72 6f  ouldn't be a pro
5510: 62 6c 65 6d 2e 20 2a 2f 0a 20 20 7a 53 71 6c 20  blem. */.  zSql 
5520: 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74  = sqlite3_mprint
5530: 66 28 22 53 45 4c 45 43 54 20 72 6f 77 69 64 2c  f("SELECT rowid,
5540: 20 72 61 6e 6b 20 46 52 4f 4d 20 25 51 2e 25 51   rank FROM %Q.%Q
5550: 20 4f 52 44 45 52 20 42 59 20 25 73 28 25 73 25   ORDER BY %s(%s%
5560: 73 25 73 29 20 25 73 22 2c 0a 20 20 20 20 20 20  s%s) %s",.      
5570: 70 43 6f 6e 66 69 67 2d 3e 7a 44 62 2c 20 70 43  pConfig->zDb, pC
5580: 6f 6e 66 69 67 2d 3e 7a 4e 61 6d 65 2c 20 7a 52  onfig->zName, zR
5590: 61 6e 6b 2c 20 70 43 6f 6e 66 69 67 2d 3e 7a 4e  ank, pConfig->zN
55a0: 61 6d 65 2c 0a 20 20 20 20 20 20 28 7a 52 61 6e  ame,.      (zRan
55b0: 6b 41 72 67 73 20 3f 20 22 2c 20 22 20 3a 20 22  kArgs ? ", " : "
55c0: 22 29 2c 0a 20 20 20 20 20 20 28 7a 52 61 6e 6b  "),.      (zRank
55d0: 41 72 67 73 20 3f 20 7a 52 61 6e 6b 41 72 67 73  Args ? zRankArgs
55e0: 20 3a 20 22 22 29 2c 0a 20 20 20 20 20 20 62 41   : ""),.      bA
55f0: 73 63 20 3f 20 22 41 53 43 22 20 3a 20 22 44 45  sc ? "ASC" : "DE
5600: 53 43 22 0a 20 20 29 3b 0a 20 20 69 66 28 20 7a  SC".  );.  if( z
5610: 53 71 6c 3d 3d 30 20 29 7b 0a 20 20 20 20 72 63  Sql==0 ){.    rc
5620: 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b   = SQLITE_NOMEM;
5630: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 72 63  .  }else{.    rc
5640: 20 3d 20 73 71 6c 69 74 65 33 5f 70 72 65 70 61   = sqlite3_prepa
5650: 72 65 5f 76 32 28 70 43 6f 6e 66 69 67 2d 3e 64  re_v2(pConfig->d
5660: 62 2c 20 7a 53 71 6c 2c 20 2d 31 2c 20 26 70 53  b, zSql, -1, &pS
5670: 6f 72 74 65 72 2d 3e 70 53 74 6d 74 2c 20 30 29  orter->pStmt, 0)
5680: 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72  ;.    sqlite3_fr
5690: 65 65 28 7a 53 71 6c 29 3b 0a 20 20 7d 0a 0a 20  ee(zSql);.  }.. 
56a0: 20 70 43 73 72 2d 3e 70 53 6f 72 74 65 72 20 3d   pCsr->pSorter =
56b0: 20 70 53 6f 72 74 65 72 3b 0a 20 20 69 66 28 20   pSorter;.  if( 
56c0: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
56d0: 0a 20 20 20 20 61 73 73 65 72 74 28 20 70 54 61  .    assert( pTa
56e0: 62 2d 3e 70 53 6f 72 74 43 73 72 3d 3d 30 20 29  b->pSortCsr==0 )
56f0: 3b 0a 20 20 20 20 70 54 61 62 2d 3e 70 53 6f 72  ;.    pTab->pSor
5700: 74 43 73 72 20 3d 20 70 43 73 72 3b 0a 20 20 20  tCsr = pCsr;.   
5710: 20 72 63 20 3d 20 66 74 73 35 53 6f 72 74 65 72   rc = fts5Sorter
5720: 4e 65 78 74 28 70 43 73 72 29 3b 0a 20 20 20 20  Next(pCsr);.    
5730: 70 54 61 62 2d 3e 70 53 6f 72 74 43 73 72 20 3d  pTab->pSortCsr =
5740: 20 30 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72   0;.  }..  if( r
5750: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c!=SQLITE_OK ){.
5760: 20 20 20 20 73 71 6c 69 74 65 33 5f 66 69 6e 61      sqlite3_fina
5770: 6c 69 7a 65 28 70 53 6f 72 74 65 72 2d 3e 70 53  lize(pSorter->pS
5780: 74 6d 74 29 3b 0a 20 20 20 20 73 71 6c 69 74 65  tmt);.    sqlite
5790: 33 5f 66 72 65 65 28 70 53 6f 72 74 65 72 29 3b  3_free(pSorter);
57a0: 0a 20 20 20 20 70 43 73 72 2d 3e 70 53 6f 72 74  .    pCsr->pSort
57b0: 65 72 20 3d 20 30 3b 0a 20 20 7d 0a 0a 20 20 72  er = 0;.  }..  r
57c0: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61  eturn rc;.}..sta
57d0: 74 69 63 20 69 6e 74 20 66 74 73 35 43 75 72 73  tic int fts5Curs
57e0: 6f 72 46 69 72 73 74 28 46 74 73 35 54 61 62 6c  orFirst(Fts5Tabl
57f0: 65 20 2a 70 54 61 62 2c 20 46 74 73 35 43 75 72  e *pTab, Fts5Cur
5800: 73 6f 72 20 2a 70 43 73 72 2c 20 69 6e 74 20 62  sor *pCsr, int b
5810: 41 73 63 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a  Asc){.  int rc;.
5820: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 46 74    rc = sqlite3Ft
5830: 73 35 45 78 70 72 46 69 72 73 74 28 70 43 73 72  s5ExprFirst(pCsr
5840: 2d 3e 70 45 78 70 72 2c 20 70 54 61 62 2d 3e 70  ->pExpr, pTab->p
5850: 49 6e 64 65 78 2c 20 62 41 73 63 29 3b 0a 20 20  Index, bAsc);.  
5860: 69 66 28 20 73 71 6c 69 74 65 33 46 74 73 35 45  if( sqlite3Fts5E
5870: 78 70 72 45 6f 66 28 70 43 73 72 2d 3e 70 45 78  xprEof(pCsr->pEx
5880: 70 72 29 20 29 7b 0a 20 20 20 20 43 73 72 46 6c  pr) ){.    CsrFl
5890: 61 67 53 65 74 28 70 43 73 72 2c 20 46 54 53 35  agSet(pCsr, FTS5
58a0: 43 53 52 5f 45 4f 46 29 3b 0a 20 20 7d 0a 20 20  CSR_EOF);.  }.  
58b0: 66 74 73 35 43 73 72 4e 65 77 72 6f 77 28 70 43  fts5CsrNewrow(pC
58c0: 73 72 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63  sr);.  return rc
58d0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 50 72 6f 63 65  ;.}../*.** Proce
58e0: 73 73 20 61 20 22 73 70 65 63 69 61 6c 22 20 71  ss a "special" q
58f0: 75 65 72 79 2e 20 41 20 73 70 65 63 69 61 6c 20  uery. A special 
5900: 71 75 65 72 79 20 69 73 20 69 64 65 6e 74 69 66  query is identif
5910: 69 65 64 20 61 73 20 6f 6e 65 20 77 69 74 68 20  ied as one with 
5920: 61 0a 2a 2a 20 4d 41 54 43 48 20 65 78 70 72 65  a.** MATCH expre
5930: 73 73 69 6f 6e 20 74 68 61 74 20 62 65 67 69 6e  ssion that begin
5940: 73 20 77 69 74 68 20 61 20 27 2a 27 20 63 68 61  s with a '*' cha
5950: 72 61 63 74 65 72 2e 20 54 68 65 20 72 65 6d 61  racter. The rema
5960: 69 6e 64 65 72 20 6f 66 0a 2a 2a 20 74 68 65 20  inder of.** the 
5970: 74 65 78 74 20 70 61 73 73 65 64 20 74 6f 20 74  text passed to t
5980: 68 65 20 4d 41 54 43 48 20 6f 70 65 72 61 74 6f  he MATCH operato
5990: 72 20 61 72 65 20 75 73 65 64 20 61 73 20 20 74  r are used as  t
59a0: 68 65 20 73 70 65 63 69 61 6c 20 71 75 65 72 79  he special query
59b0: 0a 2a 2a 20 70 61 72 61 6d 65 74 65 72 73 2e 0a  .** parameters..
59c0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74  */.static int ft
59d0: 73 35 53 70 65 63 69 61 6c 4d 61 74 63 68 28 0a  s5SpecialMatch(.
59e0: 20 20 46 74 73 35 54 61 62 6c 65 20 2a 70 54 61    Fts5Table *pTa
59f0: 62 2c 20 0a 20 20 46 74 73 35 43 75 72 73 6f 72  b, .  Fts5Cursor
5a00: 20 2a 70 43 73 72 2c 20 0a 20 20 63 6f 6e 73 74   *pCsr, .  const
5a10: 20 63 68 61 72 20 2a 7a 51 75 65 72 79 0a 29 7b   char *zQuery.){
5a20: 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49  .  int rc = SQLI
5a30: 54 45 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20 20  TE_OK;          
5a40: 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64     /* Return cod
5a50: 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61  e */.  const cha
5a60: 72 20 2a 7a 20 3d 20 7a 51 75 65 72 79 3b 20 20  r *z = zQuery;  
5a70: 20 20 20 20 20 20 20 2f 2a 20 53 70 65 63 69 61         /* Specia
5a80: 6c 20 71 75 65 72 79 20 74 65 78 74 20 2a 2f 0a  l query text */.
5a90: 20 20 69 6e 74 20 6e 3b 20 20 20 20 20 20 20 20    int n;        
5aa0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5ab0: 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 62    /* Number of b
5ac0: 79 74 65 73 20 69 6e 20 74 65 78 74 20 61 74 20  ytes in text at 
5ad0: 7a 20 2a 2f 0a 0a 20 20 77 68 69 6c 65 28 20 7a  z */..  while( z
5ae0: 5b 30 5d 3d 3d 27 20 27 20 29 20 7a 2b 2b 3b 0a  [0]==' ' ) z++;.
5af0: 20 20 66 6f 72 28 6e 3d 30 3b 20 7a 5b 6e 5d 20    for(n=0; z[n] 
5b00: 26 26 20 7a 5b 6e 5d 21 3d 27 20 27 3b 20 6e 2b  && z[n]!=' '; n+
5b10: 2b 29 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 70  +);..  assert( p
5b20: 54 61 62 2d 3e 62 61 73 65 2e 7a 45 72 72 4d 73  Tab->base.zErrMs
5b30: 67 3d 3d 30 20 29 3b 0a 20 20 61 73 73 65 72 74  g==0 );.  assert
5b40: 28 20 70 43 73 72 2d 3e 7a 53 70 65 63 69 61 6c  ( pCsr->zSpecial
5b50: 3d 3d 30 20 29 3b 0a 0a 20 20 69 66 28 20 30 3d  ==0 );..  if( 0=
5b60: 3d 73 71 6c 69 74 65 33 5f 73 74 72 6e 69 63 6d  =sqlite3_strnicm
5b70: 70 28 22 72 65 61 64 73 22 2c 20 7a 2c 20 6e 29  p("reads", z, n)
5b80: 20 29 7b 0a 20 20 20 20 70 43 73 72 2d 3e 7a 53   ){.    pCsr->zS
5b90: 70 65 63 69 61 6c 20 3d 20 73 71 6c 69 74 65 33  pecial = sqlite3
5ba0: 5f 6d 70 72 69 6e 74 66 28 22 25 64 22 2c 20 73  _mprintf("%d", s
5bb0: 71 6c 69 74 65 33 46 74 73 35 49 6e 64 65 78 52  qlite3Fts5IndexR
5bc0: 65 61 64 73 28 70 54 61 62 2d 3e 70 49 6e 64 65  eads(pTab->pInde
5bd0: 78 29 29 3b 0a 20 20 20 20 70 43 73 72 2d 3e 69  x));.    pCsr->i
5be0: 64 78 4e 75 6d 20 3d 20 46 54 53 35 5f 50 4c 41  dxNum = FTS5_PLA
5bf0: 4e 5f 53 50 45 43 49 41 4c 3b 0a 20 20 20 20 69  N_SPECIAL;.    i
5c00: 66 28 20 70 43 73 72 2d 3e 7a 53 70 65 63 69 61  f( pCsr->zSpecia
5c10: 6c 3d 3d 30 20 29 20 72 63 20 3d 20 53 51 4c 49  l==0 ) rc = SQLI
5c20: 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 20 20  TE_NOMEM;.  }.  
5c30: 65 6c 73 65 7b 0a 20 20 20 20 2f 2a 20 41 6e 20  else{.    /* An 
5c40: 75 6e 72 65 63 6f 67 6e 69 7a 65 64 20 64 69 72  unrecognized dir
5c50: 65 63 74 69 76 65 2e 20 52 65 74 75 72 6e 20 61  ective. Return a
5c60: 6e 20 65 72 72 6f 72 20 6d 65 73 73 61 67 65 2e  n error message.
5c70: 20 2a 2f 0a 20 20 20 20 70 54 61 62 2d 3e 62 61   */.    pTab->ba
5c80: 73 65 2e 7a 45 72 72 4d 73 67 20 3d 20 73 71 6c  se.zErrMsg = sql
5c90: 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 75 6e  ite3_mprintf("un
5ca0: 6b 6e 6f 77 6e 20 73 70 65 63 69 61 6c 20 71 75  known special qu
5cb0: 65 72 79 3a 20 25 2e 2a 73 22 2c 20 6e 2c 20 7a  ery: %.*s", n, z
5cc0: 29 3b 0a 20 20 20 20 72 63 20 3d 20 53 51 4c 49  );.    rc = SQLI
5cd0: 54 45 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20  TE_ERROR;.  }.. 
5ce0: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
5cf0: 2a 0a 2a 2a 20 53 65 61 72 63 68 20 66 6f 72 20  *.** Search for 
5d00: 61 6e 20 61 75 78 69 6c 69 61 72 79 20 66 75 6e  an auxiliary fun
5d10: 63 74 69 6f 6e 20 6e 61 6d 65 64 20 7a 4e 61 6d  ction named zNam
5d20: 65 20 74 68 61 74 20 63 61 6e 20 62 65 20 75 73  e that can be us
5d30: 65 64 20 77 69 74 68 20 74 61 62 6c 65 0a 2a 2a  ed with table.**
5d40: 20 70 54 61 62 2e 20 49 66 20 6f 6e 65 20 69 73   pTab. If one is
5d50: 20 66 6f 75 6e 64 2c 20 72 65 74 75 72 6e 20 61   found, return a
5d60: 20 70 6f 69 6e 74 65 72 20 74 6f 20 74 68 65 20   pointer to the 
5d70: 63 6f 72 72 65 73 70 6f 6e 64 69 6e 67 20 46 74  corresponding Ft
5d80: 73 35 41 75 78 69 6c 69 61 72 79 0a 2a 2a 20 73  s5Auxiliary.** s
5d90: 74 72 75 63 74 75 72 65 2e 20 4f 74 68 65 72 77  tructure. Otherw
5da0: 69 73 65 2c 20 69 66 20 6e 6f 20 73 75 63 68 20  ise, if no such 
5db0: 66 75 6e 63 74 69 6f 6e 20 65 78 69 73 74 73 2c  function exists,
5dc0: 20 72 65 74 75 72 6e 20 4e 55 4c 4c 2e 0a 2a 2f   return NULL..*/
5dd0: 0a 73 74 61 74 69 63 20 46 74 73 35 41 75 78 69  .static Fts5Auxi
5de0: 6c 69 61 72 79 20 2a 66 74 73 35 46 69 6e 64 41  liary *fts5FindA
5df0: 75 78 69 6c 69 61 72 79 28 46 74 73 35 54 61 62  uxiliary(Fts5Tab
5e00: 6c 65 20 2a 70 54 61 62 2c 20 63 6f 6e 73 74 20  le *pTab, const 
5e10: 63 68 61 72 20 2a 7a 4e 61 6d 65 29 7b 0a 20 20  char *zName){.  
5e20: 46 74 73 35 41 75 78 69 6c 69 61 72 79 20 2a 70  Fts5Auxiliary *p
5e30: 41 75 78 3b 0a 0a 20 20 66 6f 72 28 70 41 75 78  Aux;..  for(pAux
5e40: 3d 70 54 61 62 2d 3e 70 47 6c 6f 62 61 6c 2d 3e  =pTab->pGlobal->
5e50: 70 41 75 78 3b 20 70 41 75 78 3b 20 70 41 75 78  pAux; pAux; pAux
5e60: 3d 70 41 75 78 2d 3e 70 4e 65 78 74 29 7b 0a 20  =pAux->pNext){. 
5e70: 20 20 20 69 66 28 20 73 71 6c 69 74 65 33 5f 73     if( sqlite3_s
5e80: 74 72 69 63 6d 70 28 7a 4e 61 6d 65 2c 20 70 41  tricmp(zName, pA
5e90: 75 78 2d 3e 7a 46 75 6e 63 29 3d 3d 30 20 29 20  ux->zFunc)==0 ) 
5ea0: 72 65 74 75 72 6e 20 70 41 75 78 3b 0a 20 20 7d  return pAux;.  }
5eb0: 0a 0a 20 20 2f 2a 20 4e 6f 20 66 75 6e 63 74 69  ..  /* No functi
5ec0: 6f 6e 20 6f 66 20 74 68 65 20 73 70 65 63 69 66  on of the specif
5ed0: 69 65 64 20 6e 61 6d 65 20 77 61 73 20 66 6f 75  ied name was fou
5ee0: 6e 64 2e 20 52 65 74 75 72 6e 20 30 2e 20 2a 2f  nd. Return 0. */
5ef0: 0a 20 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a  .  return 0;.}..
5f00: 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35  .static int fts5
5f10: 46 69 6e 64 52 61 6e 6b 46 75 6e 63 74 69 6f 6e  FindRankFunction
5f20: 28 46 74 73 35 43 75 72 73 6f 72 20 2a 70 43 73  (Fts5Cursor *pCs
5f30: 72 29 7b 0a 20 20 46 74 73 35 54 61 62 6c 65 20  r){.  Fts5Table 
5f40: 2a 70 54 61 62 20 3d 20 28 46 74 73 35 54 61 62  *pTab = (Fts5Tab
5f50: 6c 65 2a 29 28 70 43 73 72 2d 3e 62 61 73 65 2e  le*)(pCsr->base.
5f60: 70 56 74 61 62 29 3b 0a 20 20 46 74 73 35 43 6f  pVtab);.  Fts5Co
5f70: 6e 66 69 67 20 2a 70 43 6f 6e 66 69 67 20 3d 20  nfig *pConfig = 
5f80: 70 54 61 62 2d 3e 70 43 6f 6e 66 69 67 3b 0a 20  pTab->pConfig;. 
5f90: 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
5fa0: 5f 4f 4b 3b 0a 20 20 46 74 73 35 41 75 78 69 6c  _OK;.  Fts5Auxil
5fb0: 69 61 72 79 20 2a 70 41 75 78 3b 0a 20 20 63 6f  iary *pAux;.  co
5fc0: 6e 73 74 20 63 68 61 72 20 2a 7a 52 61 6e 6b 20  nst char *zRank 
5fd0: 3d 20 70 43 73 72 2d 3e 7a 52 61 6e 6b 3b 0a 20  = pCsr->zRank;. 
5fe0: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 52 61   const char *zRa
5ff0: 6e 6b 41 72 67 73 20 3d 20 70 43 73 72 2d 3e 7a  nkArgs = pCsr->z
6000: 52 61 6e 6b 41 72 67 73 3b 0a 0a 20 20 69 66 28  RankArgs;..  if(
6010: 20 7a 52 61 6e 6b 41 72 67 73 20 29 7b 0a 20 20   zRankArgs ){.  
6020: 20 20 63 68 61 72 20 2a 7a 53 71 6c 20 3d 20 73    char *zSql = s
6030: 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22  qlite3_mprintf("
6040: 53 45 4c 45 43 54 20 25 73 22 2c 20 7a 52 61 6e  SELECT %s", zRan
6050: 6b 41 72 67 73 29 3b 0a 20 20 20 20 69 66 28 20  kArgs);.    if( 
6060: 7a 53 71 6c 3d 3d 30 20 29 7b 0a 20 20 20 20 20  zSql==0 ){.     
6070: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d   rc = SQLITE_NOM
6080: 45 4d 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20  EM;.    }else{. 
6090: 20 20 20 20 20 73 71 6c 69 74 65 33 5f 73 74 6d       sqlite3_stm
60a0: 74 20 2a 70 53 74 6d 74 20 3d 20 30 3b 0a 20 20  t *pStmt = 0;.  
60b0: 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
60c0: 5f 70 72 65 70 61 72 65 5f 76 32 28 70 43 6f 6e  _prepare_v2(pCon
60d0: 66 69 67 2d 3e 64 62 2c 20 7a 53 71 6c 2c 20 2d  fig->db, zSql, -
60e0: 31 2c 20 26 70 53 74 6d 74 2c 20 30 29 3b 0a 20  1, &pStmt, 0);. 
60f0: 20 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65       sqlite3_fre
6100: 65 28 7a 53 71 6c 29 3b 0a 20 20 20 20 20 20 61  e(zSql);.      a
6110: 73 73 65 72 74 28 20 72 63 3d 3d 53 51 4c 49 54  ssert( rc==SQLIT
6120: 45 5f 4f 4b 20 7c 7c 20 70 43 73 72 2d 3e 70 52  E_OK || pCsr->pR
6130: 61 6e 6b 41 72 67 53 74 6d 74 3d 3d 30 20 29 3b  ankArgStmt==0 );
6140: 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53  .      if( rc==S
6150: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
6160: 20 20 20 20 69 66 28 20 53 51 4c 49 54 45 5f 52      if( SQLITE_R
6170: 4f 57 3d 3d 73 71 6c 69 74 65 33 5f 73 74 65 70  OW==sqlite3_step
6180: 28 70 53 74 6d 74 29 20 29 7b 0a 20 20 20 20 20  (pStmt) ){.     
6190: 20 20 20 20 20 69 6e 74 20 6e 42 79 74 65 3b 0a       int nByte;.
61a0: 20 20 20 20 20 20 20 20 20 20 70 43 73 72 2d 3e            pCsr->
61b0: 6e 52 61 6e 6b 41 72 67 20 3d 20 73 71 6c 69 74  nRankArg = sqlit
61c0: 65 33 5f 63 6f 6c 75 6d 6e 5f 63 6f 75 6e 74 28  e3_column_count(
61d0: 70 53 74 6d 74 29 3b 0a 20 20 20 20 20 20 20 20  pStmt);.        
61e0: 20 20 6e 42 79 74 65 20 3d 20 73 69 7a 65 6f 66    nByte = sizeof
61f0: 28 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 2a 29  (sqlite3_value*)
6200: 2a 70 43 73 72 2d 3e 6e 52 61 6e 6b 41 72 67 3b  *pCsr->nRankArg;
6210: 0a 20 20 20 20 20 20 20 20 20 20 70 43 73 72 2d  .          pCsr-
6220: 3e 61 70 52 61 6e 6b 41 72 67 20 3d 20 28 73 71  >apRankArg = (sq
6230: 6c 69 74 65 33 5f 76 61 6c 75 65 2a 2a 29 73 71  lite3_value**)sq
6240: 6c 69 74 65 33 46 74 73 35 4d 61 6c 6c 6f 63 5a  lite3Fts5MallocZ
6250: 65 72 6f 28 26 72 63 2c 20 6e 42 79 74 65 29 3b  ero(&rc, nByte);
6260: 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20 72  .          if( r
6270: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
6280: 20 20 20 20 20 20 20 20 20 20 20 20 69 6e 74 20              int 
6290: 69 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 66  i;.            f
62a0: 6f 72 28 69 3d 30 3b 20 69 3c 70 43 73 72 2d 3e  or(i=0; i<pCsr->
62b0: 6e 52 61 6e 6b 41 72 67 3b 20 69 2b 2b 29 7b 0a  nRankArg; i++){.
62c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 70 43                pC
62d0: 73 72 2d 3e 61 70 52 61 6e 6b 41 72 67 5b 69 5d  sr->apRankArg[i]
62e0: 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d   = sqlite3_colum
62f0: 6e 5f 76 61 6c 75 65 28 70 53 74 6d 74 2c 20 69  n_value(pStmt, i
6300: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 7d  );.            }
6310: 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20  .          }.   
6320: 20 20 20 20 20 20 20 70 43 73 72 2d 3e 70 52 61         pCsr->pRa
6330: 6e 6b 41 72 67 53 74 6d 74 20 3d 20 70 53 74 6d  nkArgStmt = pStm
6340: 74 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c 73 65  t;.        }else
6350: 7b 0a 20 20 20 20 20 20 20 20 20 20 72 63 20 3d  {.          rc =
6360: 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a   sqlite3_finaliz
6370: 65 28 70 53 74 6d 74 29 3b 0a 20 20 20 20 20 20  e(pStmt);.      
6380: 20 20 20 20 61 73 73 65 72 74 28 20 72 63 21 3d      assert( rc!=
6390: 53 51 4c 49 54 45 5f 4f 4b 20 29 3b 0a 20 20 20  SQLITE_OK );.   
63a0: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20       }.      }. 
63b0: 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 66 28 20     }.  }..  if( 
63c0: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
63d0: 0a 20 20 20 20 70 41 75 78 20 3d 20 66 74 73 35  .    pAux = fts5
63e0: 46 69 6e 64 41 75 78 69 6c 69 61 72 79 28 70 54  FindAuxiliary(pT
63f0: 61 62 2c 20 7a 52 61 6e 6b 29 3b 0a 20 20 20 20  ab, zRank);.    
6400: 69 66 28 20 70 41 75 78 3d 3d 30 20 29 7b 0a 20  if( pAux==0 ){. 
6410: 20 20 20 20 20 61 73 73 65 72 74 28 20 70 54 61       assert( pTa
6420: 62 2d 3e 62 61 73 65 2e 7a 45 72 72 4d 73 67 3d  b->base.zErrMsg=
6430: 3d 30 20 29 3b 0a 20 20 20 20 20 20 70 54 61 62  =0 );.      pTab
6440: 2d 3e 62 61 73 65 2e 7a 45 72 72 4d 73 67 20 3d  ->base.zErrMsg =
6450: 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66   sqlite3_mprintf
6460: 28 22 6e 6f 20 73 75 63 68 20 66 75 6e 63 74 69  ("no such functi
6470: 6f 6e 3a 20 25 73 22 2c 20 7a 52 61 6e 6b 29 3b  on: %s", zRank);
6480: 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49  .      rc = SQLI
6490: 54 45 5f 45 52 52 4f 52 3b 0a 20 20 20 20 7d 0a  TE_ERROR;.    }.
64a0: 20 20 7d 0a 0a 20 20 70 43 73 72 2d 3e 70 52 61    }..  pCsr->pRa
64b0: 6e 6b 20 3d 20 70 41 75 78 3b 0a 20 20 72 65 74  nk = pAux;.  ret
64c0: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 0a 73 74 61 74  urn rc;.}...stat
64d0: 69 63 20 69 6e 74 20 66 74 73 35 43 75 72 73 6f  ic int fts5Curso
64e0: 72 50 61 72 73 65 52 61 6e 6b 28 0a 20 20 46 74  rParseRank(.  Ft
64f0: 73 35 43 6f 6e 66 69 67 20 2a 70 43 6f 6e 66 69  s5Config *pConfi
6500: 67 2c 0a 20 20 46 74 73 35 43 75 72 73 6f 72 20  g,.  Fts5Cursor 
6510: 2a 70 43 73 72 2c 20 0a 20 20 73 71 6c 69 74 65  *pCsr, .  sqlite
6520: 33 5f 76 61 6c 75 65 20 2a 70 52 61 6e 6b 0a 29  3_value *pRank.)
6530: 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c  {.  int rc = SQL
6540: 49 54 45 5f 4f 4b 3b 0a 20 20 69 66 28 20 70 52  ITE_OK;.  if( pR
6550: 61 6e 6b 20 29 7b 0a 20 20 20 20 63 6f 6e 73 74  ank ){.    const
6560: 20 63 68 61 72 20 2a 7a 20 3d 20 28 63 6f 6e 73   char *z = (cons
6570: 74 20 63 68 61 72 2a 29 73 71 6c 69 74 65 33 5f  t char*)sqlite3_
6580: 76 61 6c 75 65 5f 74 65 78 74 28 70 52 61 6e 6b  value_text(pRank
6590: 29 3b 0a 20 20 20 20 63 68 61 72 20 2a 7a 52 61  );.    char *zRa
65a0: 6e 6b 20 3d 20 30 3b 0a 20 20 20 20 63 68 61 72  nk = 0;.    char
65b0: 20 2a 7a 52 61 6e 6b 41 72 67 73 20 3d 20 30 3b   *zRankArgs = 0;
65c0: 0a 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74  ..    rc = sqlit
65d0: 65 33 46 74 73 35 43 6f 6e 66 69 67 50 61 72 73  e3Fts5ConfigPars
65e0: 65 52 61 6e 6b 28 7a 2c 20 26 7a 52 61 6e 6b 2c  eRank(z, &zRank,
65f0: 20 26 7a 52 61 6e 6b 41 72 67 73 29 3b 0a 20 20   &zRankArgs);.  
6600: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
6610: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 70 43 73  _OK ){.      pCs
6620: 72 2d 3e 7a 52 61 6e 6b 20 3d 20 7a 52 61 6e 6b  r->zRank = zRank
6630: 3b 0a 20 20 20 20 20 20 70 43 73 72 2d 3e 7a 52  ;.      pCsr->zR
6640: 61 6e 6b 41 72 67 73 20 3d 20 7a 52 61 6e 6b 41  ankArgs = zRankA
6650: 72 67 73 3b 0a 20 20 20 20 20 20 43 73 72 46 6c  rgs;.      CsrFl
6660: 61 67 53 65 74 28 70 43 73 72 2c 20 46 54 53 35  agSet(pCsr, FTS5
6670: 43 53 52 5f 46 52 45 45 5f 5a 52 41 4e 4b 29 3b  CSR_FREE_ZRANK);
6680: 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 72  .    }else if( r
6690: 63 3d 3d 53 51 4c 49 54 45 5f 45 52 52 4f 52 20  c==SQLITE_ERROR 
66a0: 29 7b 0a 20 20 20 20 20 20 70 43 73 72 2d 3e 62  ){.      pCsr->b
66b0: 61 73 65 2e 70 56 74 61 62 2d 3e 7a 45 72 72 4d  ase.pVtab->zErrM
66c0: 73 67 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72  sg = sqlite3_mpr
66d0: 69 6e 74 66 28 0a 20 20 20 20 20 20 20 20 20 20  intf(.          
66e0: 22 70 61 72 73 65 20 65 72 72 6f 72 20 69 6e 20  "parse error in 
66f0: 72 61 6e 6b 20 66 75 6e 63 74 69 6f 6e 3a 20 25  rank function: %
6700: 73 22 2c 20 7a 0a 20 20 20 20 20 20 29 3b 0a 20  s", z.      );. 
6710: 20 20 20 7d 0a 20 20 7d 65 6c 73 65 7b 0a 20 20     }.  }else{.  
6720: 20 20 69 66 28 20 70 43 6f 6e 66 69 67 2d 3e 7a    if( pConfig->z
6730: 52 61 6e 6b 20 29 7b 0a 20 20 20 20 20 20 70 43  Rank ){.      pC
6740: 73 72 2d 3e 7a 52 61 6e 6b 20 3d 20 28 63 68 61  sr->zRank = (cha
6750: 72 2a 29 70 43 6f 6e 66 69 67 2d 3e 7a 52 61 6e  r*)pConfig->zRan
6760: 6b 3b 0a 20 20 20 20 20 20 70 43 73 72 2d 3e 7a  k;.      pCsr->z
6770: 52 61 6e 6b 41 72 67 73 20 3d 20 28 63 68 61 72  RankArgs = (char
6780: 2a 29 70 43 6f 6e 66 69 67 2d 3e 7a 52 61 6e 6b  *)pConfig->zRank
6790: 41 72 67 73 3b 0a 20 20 20 20 7d 65 6c 73 65 7b  Args;.    }else{
67a0: 0a 20 20 20 20 20 20 70 43 73 72 2d 3e 7a 52 61  .      pCsr->zRa
67b0: 6e 6b 20 3d 20 28 63 68 61 72 2a 29 46 54 53 35  nk = (char*)FTS5
67c0: 5f 44 45 46 41 55 4c 54 5f 52 41 4e 4b 3b 0a 20  _DEFAULT_RANK;. 
67d0: 20 20 20 20 20 70 43 73 72 2d 3e 7a 52 61 6e 6b       pCsr->zRank
67e0: 41 72 67 73 20 3d 20 30 3b 0a 20 20 20 20 7d 0a  Args = 0;.    }.
67f0: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b    }.  return rc;
6800: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 69  .}../*.** This i
6810: 73 20 74 68 65 20 78 46 69 6c 74 65 72 20 69 6e  s the xFilter in
6820: 74 65 72 66 61 63 65 20 66 6f 72 20 74 68 65 20  terface for the 
6830: 76 69 72 74 75 61 6c 20 74 61 62 6c 65 2e 20 20  virtual table.  
6840: 53 65 65 0a 2a 2a 20 74 68 65 20 76 69 72 74 75  See.** the virtu
6850: 61 6c 20 74 61 62 6c 65 20 78 46 69 6c 74 65 72  al table xFilter
6860: 20 6d 65 74 68 6f 64 20 64 6f 63 75 6d 65 6e 74   method document
6870: 61 74 69 6f 6e 20 66 6f 72 20 61 64 64 69 74 69  ation for additi
6880: 6f 6e 61 6c 0a 2a 2a 20 69 6e 66 6f 72 6d 61 74  onal.** informat
6890: 69 6f 6e 2e 0a 2a 2a 20 0a 2a 2a 20 54 68 65 72  ion..** .** Ther
68a0: 65 20 61 72 65 20 74 68 72 65 65 20 70 6f 73 73  e are three poss
68b0: 69 62 6c 65 20 71 75 65 72 79 20 73 74 72 61 74  ible query strat
68c0: 65 67 69 65 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 31  egies:.**.**   1
68d0: 2e 20 46 75 6c 6c 2d 74 65 78 74 20 73 65 61 72  . Full-text sear
68e0: 63 68 20 75 73 69 6e 67 20 61 20 4d 41 54 43 48  ch using a MATCH
68f0: 20 6f 70 65 72 61 74 6f 72 2e 0a 2a 2a 20 20 20   operator..**   
6900: 32 2e 20 41 20 62 79 2d 72 6f 77 69 64 20 6c 6f  2. A by-rowid lo
6910: 6f 6b 75 70 2e 0a 2a 2a 20 20 20 33 2e 20 41 20  okup..**   3. A 
6920: 66 75 6c 6c 2d 74 61 62 6c 65 20 73 63 61 6e 2e  full-table scan.
6930: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66  .*/.static int f
6940: 74 73 35 46 69 6c 74 65 72 4d 65 74 68 6f 64 28  ts5FilterMethod(
6950: 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62 5f  .  sqlite3_vtab_
6960: 63 75 72 73 6f 72 20 2a 70 43 75 72 73 6f 72 2c  cursor *pCursor,
6970: 20 20 20 2f 2a 20 54 68 65 20 63 75 72 73 6f 72     /* The cursor
6980: 20 75 73 65 64 20 66 6f 72 20 74 68 69 73 20 71   used for this q
6990: 75 65 72 79 20 2a 2f 0a 20 20 69 6e 74 20 69 64  uery */.  int id
69a0: 78 4e 75 6d 2c 20 20 20 20 20 20 20 20 20 20 20  xNum,           
69b0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 74 72            /* Str
69c0: 61 74 65 67 79 20 69 6e 64 65 78 20 2a 2f 0a 20  ategy index */. 
69d0: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 69 64 78   const char *idx
69e0: 53 74 72 2c 20 20 20 20 20 20 20 20 20 20 20 20  Str,            
69f0: 20 2f 2a 20 55 6e 75 73 65 64 20 2a 2f 0a 20 20   /* Unused */.  
6a00: 69 6e 74 20 6e 56 61 6c 2c 20 20 20 20 20 20 20  int nVal,       
6a10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6a20: 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 65 6c 65  /* Number of ele
6a30: 6d 65 6e 74 73 20 69 6e 20 61 70 56 61 6c 20 2a  ments in apVal *
6a40: 2f 0a 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75  /.  sqlite3_valu
6a50: 65 20 2a 2a 61 70 56 61 6c 20 20 20 20 20 20 20  e **apVal       
6a60: 20 20 20 20 2f 2a 20 41 72 67 75 6d 65 6e 74 73      /* Arguments
6a70: 20 66 6f 72 20 74 68 65 20 69 6e 64 65 78 69 6e   for the indexin
6a80: 67 20 73 63 68 65 6d 65 20 2a 2f 0a 29 7b 0a 20  g scheme */.){. 
6a90: 20 46 74 73 35 54 61 62 6c 65 20 2a 70 54 61 62   Fts5Table *pTab
6aa0: 20 3d 20 28 46 74 73 35 54 61 62 6c 65 2a 29 28   = (Fts5Table*)(
6ab0: 70 43 75 72 73 6f 72 2d 3e 70 56 74 61 62 29 3b  pCursor->pVtab);
6ac0: 0a 20 20 46 74 73 35 43 75 72 73 6f 72 20 2a 70  .  Fts5Cursor *p
6ad0: 43 73 72 20 3d 20 28 46 74 73 35 43 75 72 73 6f  Csr = (Fts5Curso
6ae0: 72 2a 29 70 43 75 72 73 6f 72 3b 0a 20 20 69 6e  r*)pCursor;.  in
6af0: 74 20 62 41 73 63 20 3d 20 28 28 69 64 78 4e 75  t bAsc = ((idxNu
6b00: 6d 20 26 20 46 54 53 35 5f 4f 52 44 45 52 5f 41  m & FTS5_ORDER_A
6b10: 53 43 29 20 3f 20 31 20 3a 20 30 29 3b 0a 20 20  SC) ? 1 : 0);.  
6b20: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
6b30: 4f 4b 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 6e  OK;..  assert( n
6b40: 56 61 6c 3c 3d 32 20 29 3b 0a 20 20 61 73 73 65  Val<=2 );.  asse
6b50: 72 74 28 20 70 43 73 72 2d 3e 70 53 74 6d 74 3d  rt( pCsr->pStmt=
6b60: 3d 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  =0 );.  assert( 
6b70: 70 43 73 72 2d 3e 70 45 78 70 72 3d 3d 30 20 29  pCsr->pExpr==0 )
6b80: 3b 0a 20 20 61 73 73 65 72 74 28 20 70 43 73 72  ;.  assert( pCsr
6b90: 2d 3e 63 73 72 66 6c 61 67 73 3d 3d 30 20 29 3b  ->csrflags==0 );
6ba0: 0a 20 20 61 73 73 65 72 74 28 20 70 43 73 72 2d  .  assert( pCsr-
6bb0: 3e 70 52 61 6e 6b 3d 3d 30 20 29 3b 0a 20 20 61  >pRank==0 );.  a
6bc0: 73 73 65 72 74 28 20 70 43 73 72 2d 3e 7a 52 61  ssert( pCsr->zRa
6bd0: 6e 6b 3d 3d 30 20 29 3b 0a 20 20 61 73 73 65 72  nk==0 );.  asser
6be0: 74 28 20 70 43 73 72 2d 3e 7a 52 61 6e 6b 41 72  t( pCsr->zRankAr
6bf0: 67 73 3d 3d 30 20 29 3b 0a 0a 20 20 69 66 28 20  gs==0 );..  if( 
6c00: 70 54 61 62 2d 3e 70 53 6f 72 74 43 73 72 20 29  pTab->pSortCsr )
6c10: 7b 0a 20 20 20 20 2f 2a 20 49 66 20 70 53 6f 72  {.    /* If pSor
6c20: 74 43 73 72 20 69 73 20 6e 6f 6e 2d 4e 55 4c 4c  tCsr is non-NULL
6c30: 2c 20 74 68 65 6e 20 74 68 69 73 20 63 61 6c 6c  , then this call
6c40: 20 69 73 20 62 65 69 6e 67 20 6d 61 64 65 20 61   is being made a
6c50: 73 20 70 61 72 74 20 6f 66 20 0a 20 20 20 20 2a  s part of .    *
6c60: 2a 20 70 72 6f 63 65 73 73 69 6e 67 20 66 6f 72  * processing for
6c70: 20 61 20 22 2e 2e 2e 20 4d 41 54 43 48 20 3c 65   a "... MATCH <e
6c80: 78 70 72 3e 20 4f 52 44 45 52 20 42 59 20 72 61  xpr> ORDER BY ra
6c90: 6e 6b 22 20 71 75 65 72 79 20 28 65 50 6c 61 6e  nk" query (ePlan
6ca0: 20 69 73 0a 20 20 20 20 2a 2a 20 73 65 74 20 74   is.    ** set t
6cb0: 6f 20 46 54 53 35 5f 50 4c 41 4e 5f 53 4f 52 54  o FTS5_PLAN_SORT
6cc0: 45 44 5f 4d 41 54 43 48 29 2e 20 70 53 6f 72 74  ED_MATCH). pSort
6cd0: 43 73 72 20 69 73 20 74 68 65 20 63 75 72 73 6f  Csr is the curso
6ce0: 72 20 74 68 61 74 20 77 69 6c 6c 0a 20 20 20 20  r that will.    
6cf0: 2a 2a 20 72 65 74 75 72 6e 20 72 65 73 75 6c 74  ** return result
6d00: 73 20 74 6f 20 74 68 65 20 75 73 65 72 20 66 6f  s to the user fo
6d10: 72 20 74 68 69 73 20 71 75 65 72 79 2e 20 54 68  r this query. Th
6d20: 65 20 63 75 72 72 65 6e 74 20 63 75 72 73 6f 72  e current cursor
6d30: 20 0a 20 20 20 20 2a 2a 20 28 70 43 75 72 73 6f   .    ** (pCurso
6d40: 72 29 20 69 73 20 75 73 65 64 20 74 6f 20 65 78  r) is used to ex
6d50: 65 63 75 74 65 20 74 68 65 20 71 75 65 72 79 20  ecute the query 
6d60: 69 73 73 75 65 64 20 62 79 20 66 75 6e 63 74 69  issued by functi
6d70: 6f 6e 20 0a 20 20 20 20 2a 2a 20 66 74 73 35 43  on .    ** fts5C
6d80: 75 72 73 6f 72 46 69 72 73 74 53 6f 72 74 65 64  ursorFirstSorted
6d90: 28 29 20 61 62 6f 76 65 2e 20 20 2a 2f 0a 20 20  () above.  */.  
6da0: 20 20 61 73 73 65 72 74 28 20 46 54 53 35 5f 50    assert( FTS5_P
6db0: 4c 41 4e 28 69 64 78 4e 75 6d 29 3d 3d 46 54 53  LAN(idxNum)==FTS
6dc0: 35 5f 50 4c 41 4e 5f 53 43 41 4e 20 29 3b 0a 20  5_PLAN_SCAN );. 
6dd0: 20 20 20 70 43 73 72 2d 3e 69 64 78 4e 75 6d 20     pCsr->idxNum 
6de0: 3d 20 46 54 53 35 5f 50 4c 41 4e 5f 53 4f 55 52  = FTS5_PLAN_SOUR
6df0: 43 45 3b 0a 20 20 20 20 70 43 73 72 2d 3e 70 45  CE;.    pCsr->pE
6e00: 78 70 72 20 3d 20 70 54 61 62 2d 3e 70 53 6f 72  xpr = pTab->pSor
6e10: 74 43 73 72 2d 3e 70 45 78 70 72 3b 0a 20 20 20  tCsr->pExpr;.   
6e20: 20 72 63 20 3d 20 66 74 73 35 43 75 72 73 6f 72   rc = fts5Cursor
6e30: 46 69 72 73 74 28 70 54 61 62 2c 20 70 43 73 72  First(pTab, pCsr
6e40: 2c 20 62 41 73 63 29 3b 0a 20 20 7d 65 6c 73 65  , bAsc);.  }else
6e50: 7b 0a 20 20 20 20 69 6e 74 20 65 50 6c 61 6e 20  {.    int ePlan 
6e60: 3d 20 46 54 53 35 5f 50 4c 41 4e 28 69 64 78 4e  = FTS5_PLAN(idxN
6e70: 75 6d 29 3b 0a 20 20 20 20 70 43 73 72 2d 3e 69  um);.    pCsr->i
6e80: 64 78 4e 75 6d 20 3d 20 69 64 78 4e 75 6d 3b 0a  dxNum = idxNum;.
6e90: 20 20 20 20 69 66 28 20 65 50 6c 61 6e 3d 3d 46      if( ePlan==F
6ea0: 54 53 35 5f 50 4c 41 4e 5f 4d 41 54 43 48 20 7c  TS5_PLAN_MATCH |
6eb0: 7c 20 65 50 6c 61 6e 3d 3d 46 54 53 35 5f 50 4c  | ePlan==FTS5_PL
6ec0: 41 4e 5f 53 4f 52 54 45 44 5f 4d 41 54 43 48 20  AN_SORTED_MATCH 
6ed0: 29 7b 0a 20 20 20 20 20 20 63 6f 6e 73 74 20 63  ){.      const c
6ee0: 68 61 72 20 2a 7a 45 78 70 72 20 3d 20 28 63 6f  har *zExpr = (co
6ef0: 6e 73 74 20 63 68 61 72 2a 29 73 71 6c 69 74 65  nst char*)sqlite
6f00: 33 5f 76 61 6c 75 65 5f 74 65 78 74 28 61 70 56  3_value_text(apV
6f10: 61 6c 5b 30 5d 29 3b 0a 0a 20 20 20 20 20 20 72  al[0]);..      r
6f20: 63 20 3d 20 66 74 73 35 43 75 72 73 6f 72 50 61  c = fts5CursorPa
6f30: 72 73 65 52 61 6e 6b 28 70 54 61 62 2d 3e 70 43  rseRank(pTab->pC
6f40: 6f 6e 66 69 67 2c 20 70 43 73 72 2c 20 28 6e 56  onfig, pCsr, (nV
6f50: 61 6c 3d 3d 32 20 3f 20 61 70 56 61 6c 5b 31 5d  al==2 ? apVal[1]
6f60: 20 3a 20 30 29 29 3b 0a 20 20 20 20 20 20 69 66   : 0));.      if
6f70: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
6f80: 29 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20 7a  ){.        if( z
6f90: 45 78 70 72 5b 30 5d 3d 3d 27 2a 27 20 29 7b 0a  Expr[0]=='*' ){.
6fa0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65            /* The
6fb0: 20 75 73 65 72 20 68 61 73 20 69 73 73 75 65 64   user has issued
6fc0: 20 61 20 71 75 65 72 79 20 6f 66 20 74 68 65 20   a query of the 
6fd0: 66 6f 72 6d 20 22 4d 41 54 43 48 20 27 2a 2e 2e  form "MATCH '*..
6fe0: 2e 27 22 2e 20 54 68 69 73 0a 20 20 20 20 20 20  .'". This.      
6ff0: 20 20 20 20 2a 2a 20 69 6e 64 69 63 61 74 65 73      ** indicates
7000: 20 74 68 61 74 20 74 68 65 20 4d 41 54 43 48 20   that the MATCH 
7010: 65 78 70 72 65 73 73 69 6f 6e 20 69 73 20 6e 6f  expression is no
7020: 74 20 61 20 66 75 6c 6c 20 74 65 78 74 20 71 75  t a full text qu
7030: 65 72 79 2c 0a 20 20 20 20 20 20 20 20 20 20 2a  ery,.          *
7040: 2a 20 62 75 74 20 61 20 72 65 71 75 65 73 74 20  * but a request 
7050: 66 6f 72 20 61 6e 20 69 6e 74 65 72 6e 61 6c 20  for an internal 
7060: 70 61 72 61 6d 65 74 65 72 2e 20 20 2a 2f 0a 20  parameter.  */. 
7070: 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 66 74           rc = ft
7080: 73 35 53 70 65 63 69 61 6c 4d 61 74 63 68 28 70  s5SpecialMatch(p
7090: 54 61 62 2c 20 70 43 73 72 2c 20 26 7a 45 78 70  Tab, pCsr, &zExp
70a0: 72 5b 31 5d 29 3b 0a 20 20 20 20 20 20 20 20 7d  r[1]);.        }
70b0: 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 20 20  else{.          
70c0: 63 68 61 72 20 2a 2a 70 7a 45 72 72 20 3d 20 26  char **pzErr = &
70d0: 70 54 61 62 2d 3e 62 61 73 65 2e 7a 45 72 72 4d  pTab->base.zErrM
70e0: 73 67 3b 0a 20 20 20 20 20 20 20 20 20 20 72 63  sg;.          rc
70f0: 20 3d 20 73 71 6c 69 74 65 33 46 74 73 35 45 78   = sqlite3Fts5Ex
7100: 70 72 4e 65 77 28 70 54 61 62 2d 3e 70 43 6f 6e  prNew(pTab->pCon
7110: 66 69 67 2c 20 7a 45 78 70 72 2c 20 26 70 43 73  fig, zExpr, &pCs
7120: 72 2d 3e 70 45 78 70 72 2c 20 70 7a 45 72 72 29  r->pExpr, pzErr)
7130: 3b 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20  ;.          if( 
7140: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
7150: 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66 28  .            if(
7160: 20 65 50 6c 61 6e 3d 3d 46 54 53 35 5f 50 4c 41   ePlan==FTS5_PLA
7170: 4e 5f 4d 41 54 43 48 20 29 7b 0a 20 20 20 20 20  N_MATCH ){.     
7180: 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 66 74           rc = ft
7190: 73 35 43 75 72 73 6f 72 46 69 72 73 74 28 70 54  s5CursorFirst(pT
71a0: 61 62 2c 20 70 43 73 72 2c 20 62 41 73 63 29 3b  ab, pCsr, bAsc);
71b0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 7d 65 6c  .            }el
71c0: 73 65 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20  se{.            
71d0: 20 20 72 63 20 3d 20 66 74 73 35 43 75 72 73 6f    rc = fts5Curso
71e0: 72 46 69 72 73 74 53 6f 72 74 65 64 28 70 54 61  rFirstSorted(pTa
71f0: 62 2c 20 70 43 73 72 2c 20 62 41 73 63 29 3b 0a  b, pCsr, bAsc);.
7200: 20 20 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20              }.  
7210: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
7220: 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20    }.      }.    
7230: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 2f 2a 20  }else{.      /* 
7240: 54 68 69 73 20 69 73 20 65 69 74 68 65 72 20 61  This is either a
7250: 20 66 75 6c 6c 2d 74 61 62 6c 65 20 73 63 61 6e   full-table scan
7260: 20 28 65 50 6c 61 6e 3d 3d 46 54 53 35 5f 50 4c   (ePlan==FTS5_PL
7270: 41 4e 5f 53 43 41 4e 29 20 6f 72 20 61 20 6c 6f  AN_SCAN) or a lo
7280: 6f 6b 75 70 0a 20 20 20 20 20 20 2a 2a 20 62 79  okup.      ** by
7290: 20 72 6f 77 69 64 20 28 65 50 6c 61 6e 3d 3d 46   rowid (ePlan==F
72a0: 54 53 35 5f 50 4c 41 4e 5f 52 4f 57 49 44 29 2e  TS5_PLAN_ROWID).
72b0: 20 20 2a 2f 0a 20 20 20 20 20 20 69 6e 74 20 65    */.      int e
72c0: 53 74 6d 74 20 3d 20 66 74 73 35 53 74 6d 74 54  Stmt = fts5StmtT
72d0: 79 70 65 28 69 64 78 4e 75 6d 29 3b 0a 20 20 20  ype(idxNum);.   
72e0: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 46     rc = sqlite3F
72f0: 74 73 35 53 74 6f 72 61 67 65 53 74 6d 74 28 70  ts5StorageStmt(p
7300: 54 61 62 2d 3e 70 53 74 6f 72 61 67 65 2c 20 65  Tab->pStorage, e
7310: 53 74 6d 74 2c 20 26 70 43 73 72 2d 3e 70 53 74  Stmt, &pCsr->pSt
7320: 6d 74 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72  mt);.      if( r
7330: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
7340: 20 20 20 20 20 20 20 20 69 66 28 20 65 50 6c 61          if( ePla
7350: 6e 3d 3d 46 54 53 35 5f 50 4c 41 4e 5f 52 4f 57  n==FTS5_PLAN_ROW
7360: 49 44 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  ID ){.          
7370: 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f 76 61 6c  sqlite3_bind_val
7380: 75 65 28 70 43 73 72 2d 3e 70 53 74 6d 74 2c 20  ue(pCsr->pStmt, 
7390: 31 2c 20 61 70 56 61 6c 5b 30 5d 29 3b 0a 20 20  1, apVal[0]);.  
73a0: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20        }.        
73b0: 72 63 20 3d 20 66 74 73 35 4e 65 78 74 4d 65 74  rc = fts5NextMet
73c0: 68 6f 64 28 70 43 75 72 73 6f 72 29 3b 0a 20 20  hod(pCursor);.  
73d0: 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a      }.    }.  }.
73e0: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
73f0: 0a 2f 2a 20 0a 2a 2a 20 54 68 69 73 20 69 73 20  ./* .** This is 
7400: 74 68 65 20 78 45 6f 66 20 6d 65 74 68 6f 64 20  the xEof method 
7410: 6f 66 20 74 68 65 20 76 69 72 74 75 61 6c 20 74  of the virtual t
7420: 61 62 6c 65 2e 20 53 51 4c 69 74 65 20 63 61 6c  able. SQLite cal
7430: 6c 73 20 74 68 69 73 20 0a 2a 2a 20 72 6f 75 74  ls this .** rout
7440: 69 6e 65 20 74 6f 20 66 69 6e 64 20 6f 75 74 20  ine to find out 
7450: 69 66 20 69 74 20 68 61 73 20 72 65 61 63 68 65  if it has reache
7460: 64 20 74 68 65 20 65 6e 64 20 6f 66 20 61 20 72  d the end of a r
7470: 65 73 75 6c 74 20 73 65 74 2e 0a 2a 2f 0a 73 74  esult set..*/.st
7480: 61 74 69 63 20 69 6e 74 20 66 74 73 35 45 6f 66  atic int fts5Eof
7490: 4d 65 74 68 6f 64 28 73 71 6c 69 74 65 33 5f 76  Method(sqlite3_v
74a0: 74 61 62 5f 63 75 72 73 6f 72 20 2a 70 43 75 72  tab_cursor *pCur
74b0: 73 6f 72 29 7b 0a 20 20 46 74 73 35 43 75 72 73  sor){.  Fts5Curs
74c0: 6f 72 20 2a 70 43 73 72 20 3d 20 28 46 74 73 35  or *pCsr = (Fts5
74d0: 43 75 72 73 6f 72 2a 29 70 43 75 72 73 6f 72 3b  Cursor*)pCursor;
74e0: 0a 20 20 72 65 74 75 72 6e 20 28 43 73 72 46 6c  .  return (CsrFl
74f0: 61 67 54 65 73 74 28 70 43 73 72 2c 20 46 54 53  agTest(pCsr, FTS
7500: 35 43 53 52 5f 45 4f 46 29 20 3f 20 31 20 3a 20  5CSR_EOF) ? 1 : 
7510: 30 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74  0);.}../*.** Ret
7520: 75 72 6e 20 74 68 65 20 72 6f 77 69 64 20 74 68  urn the rowid th
7530: 61 74 20 74 68 65 20 63 75 72 73 6f 72 20 63 75  at the cursor cu
7540: 72 72 65 6e 74 6c 79 20 70 6f 69 6e 74 73 20 74  rrently points t
7550: 6f 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 36 34  o..*/.static i64
7560: 20 66 74 73 35 43 75 72 73 6f 72 52 6f 77 69 64   fts5CursorRowid
7570: 28 46 74 73 35 43 75 72 73 6f 72 20 2a 70 43 73  (Fts5Cursor *pCs
7580: 72 29 7b 0a 20 20 61 73 73 65 72 74 28 20 46 54  r){.  assert( FT
7590: 53 35 5f 50 4c 41 4e 28 70 43 73 72 2d 3e 69 64  S5_PLAN(pCsr->id
75a0: 78 4e 75 6d 29 3d 3d 46 54 53 35 5f 50 4c 41 4e  xNum)==FTS5_PLAN
75b0: 5f 4d 41 54 43 48 20 0a 20 20 20 20 20 20 20 7c  _MATCH .       |
75c0: 7c 20 46 54 53 35 5f 50 4c 41 4e 28 70 43 73 72  | FTS5_PLAN(pCsr
75d0: 2d 3e 69 64 78 4e 75 6d 29 3d 3d 46 54 53 35 5f  ->idxNum)==FTS5_
75e0: 50 4c 41 4e 5f 53 4f 52 54 45 44 5f 4d 41 54 43  PLAN_SORTED_MATC
75f0: 48 20 0a 20 20 20 20 20 20 20 7c 7c 20 46 54 53  H .       || FTS
7600: 35 5f 50 4c 41 4e 28 70 43 73 72 2d 3e 69 64 78  5_PLAN(pCsr->idx
7610: 4e 75 6d 29 3d 3d 46 54 53 35 5f 50 4c 41 4e 5f  Num)==FTS5_PLAN_
7620: 53 4f 55 52 43 45 20 0a 20 20 29 3b 0a 20 20 69  SOURCE .  );.  i
7630: 66 28 20 70 43 73 72 2d 3e 70 53 6f 72 74 65 72  f( pCsr->pSorter
7640: 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 70   ){.    return p
7650: 43 73 72 2d 3e 70 53 6f 72 74 65 72 2d 3e 69 52  Csr->pSorter->iR
7660: 6f 77 69 64 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  owid;.  }else{. 
7670: 20 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74 65     return sqlite
7680: 33 46 74 73 35 45 78 70 72 52 6f 77 69 64 28 70  3Fts5ExprRowid(p
7690: 43 73 72 2d 3e 70 45 78 70 72 29 3b 0a 20 20 7d  Csr->pExpr);.  }
76a0: 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 54 68 69 73 20  .}../* .** This 
76b0: 69 73 20 74 68 65 20 78 52 6f 77 69 64 20 6d 65  is the xRowid me
76c0: 74 68 6f 64 2e 20 54 68 65 20 53 51 4c 69 74 65  thod. The SQLite
76d0: 20 63 6f 72 65 20 63 61 6c 6c 73 20 74 68 69 73   core calls this
76e0: 20 72 6f 75 74 69 6e 65 20 74 6f 0a 2a 2a 20 72   routine to.** r
76f0: 65 74 72 69 65 76 65 20 74 68 65 20 72 6f 77 69  etrieve the rowi
7700: 64 20 66 6f 72 20 74 68 65 20 63 75 72 72 65 6e  d for the curren
7710: 74 20 72 6f 77 20 6f 66 20 74 68 65 20 72 65 73  t row of the res
7720: 75 6c 74 20 73 65 74 2e 20 66 74 73 35 0a 2a 2a  ult set. fts5.**
7730: 20 65 78 70 6f 73 65 73 20 25 5f 63 6f 6e 74 65   exposes %_conte
7740: 6e 74 2e 64 6f 63 69 64 20 61 73 20 74 68 65 20  nt.docid as the 
7750: 72 6f 77 69 64 20 66 6f 72 20 74 68 65 20 76 69  rowid for the vi
7760: 72 74 75 61 6c 20 74 61 62 6c 65 2e 20 54 68 65  rtual table. The
7770: 0a 2a 2a 20 72 6f 77 69 64 20 73 68 6f 75 6c 64  .** rowid should
7780: 20 62 65 20 77 72 69 74 74 65 6e 20 74 6f 20 2a   be written to *
7790: 70 52 6f 77 69 64 2e 0a 2a 2f 0a 73 74 61 74 69  pRowid..*/.stati
77a0: 63 20 69 6e 74 20 66 74 73 35 52 6f 77 69 64 4d  c int fts5RowidM
77b0: 65 74 68 6f 64 28 73 71 6c 69 74 65 33 5f 76 74  ethod(sqlite3_vt
77c0: 61 62 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 73  ab_cursor *pCurs
77d0: 6f 72 2c 20 73 71 6c 69 74 65 5f 69 6e 74 36 34  or, sqlite_int64
77e0: 20 2a 70 52 6f 77 69 64 29 7b 0a 20 20 46 74 73   *pRowid){.  Fts
77f0: 35 43 75 72 73 6f 72 20 2a 70 43 73 72 20 3d 20  5Cursor *pCsr = 
7800: 28 46 74 73 35 43 75 72 73 6f 72 2a 29 70 43 75  (Fts5Cursor*)pCu
7810: 72 73 6f 72 3b 0a 20 20 69 6e 74 20 65 50 6c 61  rsor;.  int ePla
7820: 6e 20 3d 20 46 54 53 35 5f 50 4c 41 4e 28 70 43  n = FTS5_PLAN(pC
7830: 73 72 2d 3e 69 64 78 4e 75 6d 29 3b 0a 20 20 0a  sr->idxNum);.  .
7840: 20 20 61 73 73 65 72 74 28 20 43 73 72 46 6c 61    assert( CsrFla
7850: 67 54 65 73 74 28 70 43 73 72 2c 20 46 54 53 35  gTest(pCsr, FTS5
7860: 43 53 52 5f 45 4f 46 29 3d 3d 30 20 29 3b 0a 20  CSR_EOF)==0 );. 
7870: 20 73 77 69 74 63 68 28 20 65 50 6c 61 6e 20 29   switch( ePlan )
7880: 7b 0a 20 20 20 20 63 61 73 65 20 46 54 53 35 5f  {.    case FTS5_
7890: 50 4c 41 4e 5f 53 50 45 43 49 41 4c 3a 0a 20 20  PLAN_SPECIAL:.  
78a0: 20 20 20 20 2a 70 52 6f 77 69 64 20 3d 20 30 3b      *pRowid = 0;
78b0: 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 0a 20  .      break;.. 
78c0: 20 20 20 63 61 73 65 20 46 54 53 35 5f 50 4c 41     case FTS5_PLA
78d0: 4e 5f 53 4f 55 52 43 45 3a 0a 20 20 20 20 63 61  N_SOURCE:.    ca
78e0: 73 65 20 46 54 53 35 5f 50 4c 41 4e 5f 4d 41 54  se FTS5_PLAN_MAT
78f0: 43 48 3a 0a 20 20 20 20 63 61 73 65 20 46 54 53  CH:.    case FTS
7900: 35 5f 50 4c 41 4e 5f 53 4f 52 54 45 44 5f 4d 41  5_PLAN_SORTED_MA
7910: 54 43 48 3a 0a 20 20 20 20 20 20 2a 70 52 6f 77  TCH:.      *pRow
7920: 69 64 20 3d 20 66 74 73 35 43 75 72 73 6f 72 52  id = fts5CursorR
7930: 6f 77 69 64 28 70 43 73 72 29 3b 0a 20 20 20 20  owid(pCsr);.    
7940: 20 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20 64 65    break;..    de
7950: 66 61 75 6c 74 3a 0a 20 20 20 20 20 20 2a 70 52  fault:.      *pR
7960: 6f 77 69 64 20 3d 20 73 71 6c 69 74 65 33 5f 63  owid = sqlite3_c
7970: 6f 6c 75 6d 6e 5f 69 6e 74 36 34 28 70 43 73 72  olumn_int64(pCsr
7980: 2d 3e 70 53 74 6d 74 2c 20 30 29 3b 0a 20 20 20  ->pStmt, 0);.   
7990: 20 20 20 62 72 65 61 6b 3b 0a 20 20 7d 0a 0a 20     break;.  }.. 
79a0: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
79b0: 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 66 20 74  K;.}../*.** If t
79c0: 68 65 20 63 75 72 73 6f 72 20 72 65 71 75 69 72  he cursor requir
79d0: 65 73 20 73 65 65 6b 69 6e 67 20 28 62 53 65 65  es seeking (bSee
79e0: 6b 52 65 71 75 69 72 65 64 20 66 6c 61 67 20 69  kRequired flag i
79f0: 73 20 73 65 74 29 2c 20 73 65 65 6b 20 69 74 2e  s set), seek it.
7a00: 0a 2a 2a 20 52 65 74 75 72 6e 20 53 51 4c 49 54  .** Return SQLIT
7a10: 45 5f 4f 4b 20 69 66 20 6e 6f 20 65 72 72 6f 72  E_OK if no error
7a20: 20 6f 63 63 75 72 73 2c 20 6f 72 20 61 6e 20 53   occurs, or an S
7a30: 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65  QLite error code
7a40: 20 6f 74 68 65 72 77 69 73 65 2e 0a 2a 2f 0a 73   otherwise..*/.s
7a50: 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 53 65  tatic int fts5Se
7a60: 65 6b 43 75 72 73 6f 72 28 46 74 73 35 43 75 72  ekCursor(Fts5Cur
7a70: 73 6f 72 20 2a 70 43 73 72 29 7b 0a 20 20 69 6e  sor *pCsr){.  in
7a80: 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b  t rc = SQLITE_OK
7a90: 3b 0a 0a 20 20 2f 2a 20 49 66 20 74 68 65 20 63  ;..  /* If the c
7aa0: 75 72 73 6f 72 20 64 6f 65 73 20 6e 6f 74 20 79  ursor does not y
7ab0: 65 74 20 68 61 76 65 20 61 20 73 74 61 74 65 6d  et have a statem
7ac0: 65 6e 74 20 68 61 6e 64 6c 65 2c 20 6f 62 74 61  ent handle, obta
7ad0: 69 6e 20 6f 6e 65 20 6e 6f 77 2e 20 2a 2f 20 0a  in one now. */ .
7ae0: 20 20 69 66 28 20 70 43 73 72 2d 3e 70 53 74 6d    if( pCsr->pStm
7af0: 74 3d 3d 30 20 29 7b 0a 20 20 20 20 46 74 73 35  t==0 ){.    Fts5
7b00: 54 61 62 6c 65 20 2a 70 54 61 62 20 3d 20 28 46  Table *pTab = (F
7b10: 74 73 35 54 61 62 6c 65 2a 29 28 70 43 73 72 2d  ts5Table*)(pCsr-
7b20: 3e 62 61 73 65 2e 70 56 74 61 62 29 3b 0a 20 20  >base.pVtab);.  
7b30: 20 20 69 6e 74 20 65 53 74 6d 74 20 3d 20 66 74    int eStmt = ft
7b40: 73 35 53 74 6d 74 54 79 70 65 28 70 43 73 72 2d  s5StmtType(pCsr-
7b50: 3e 69 64 78 4e 75 6d 29 3b 0a 20 20 20 20 72 63  >idxNum);.    rc
7b60: 20 3d 20 73 71 6c 69 74 65 33 46 74 73 35 53 74   = sqlite3Fts5St
7b70: 6f 72 61 67 65 53 74 6d 74 28 70 54 61 62 2d 3e  orageStmt(pTab->
7b80: 70 53 74 6f 72 61 67 65 2c 20 65 53 74 6d 74 2c  pStorage, eStmt,
7b90: 20 26 70 43 73 72 2d 3e 70 53 74 6d 74 29 3b 0a   &pCsr->pStmt);.
7ba0: 20 20 20 20 61 73 73 65 72 74 28 20 43 73 72 46      assert( CsrF
7bb0: 6c 61 67 54 65 73 74 28 70 43 73 72 2c 20 46 54  lagTest(pCsr, FT
7bc0: 53 35 43 53 52 5f 52 45 51 55 49 52 45 5f 43 4f  S5CSR_REQUIRE_CO
7bd0: 4e 54 45 4e 54 29 20 29 3b 0a 20 20 7d 0a 0a 20  NTENT) );.  }.. 
7be0: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
7bf0: 4f 4b 20 26 26 20 43 73 72 46 6c 61 67 54 65 73  OK && CsrFlagTes
7c00: 74 28 70 43 73 72 2c 20 46 54 53 35 43 53 52 5f  t(pCsr, FTS5CSR_
7c10: 52 45 51 55 49 52 45 5f 43 4f 4e 54 45 4e 54 29  REQUIRE_CONTENT)
7c20: 20 29 7b 0a 20 20 20 20 61 73 73 65 72 74 28 20   ){.    assert( 
7c30: 70 43 73 72 2d 3e 70 45 78 70 72 20 29 3b 0a 20  pCsr->pExpr );. 
7c40: 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 65 74     sqlite3_reset
7c50: 28 70 43 73 72 2d 3e 70 53 74 6d 74 29 3b 0a 20  (pCsr->pStmt);. 
7c60: 20 20 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f     sqlite3_bind_
7c70: 69 6e 74 36 34 28 70 43 73 72 2d 3e 70 53 74 6d  int64(pCsr->pStm
7c80: 74 2c 20 31 2c 20 66 74 73 35 43 75 72 73 6f 72  t, 1, fts5Cursor
7c90: 52 6f 77 69 64 28 70 43 73 72 29 29 3b 0a 20 20  Rowid(pCsr));.  
7ca0: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 73    rc = sqlite3_s
7cb0: 74 65 70 28 70 43 73 72 2d 3e 70 53 74 6d 74 29  tep(pCsr->pStmt)
7cc0: 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51  ;.    if( rc==SQ
7cd0: 4c 49 54 45 5f 52 4f 57 20 29 7b 0a 20 20 20 20  LITE_ROW ){.    
7ce0: 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b    rc = SQLITE_OK
7cf0: 3b 0a 20 20 20 20 20 20 43 73 72 46 6c 61 67 43  ;.      CsrFlagC
7d00: 6c 65 61 72 28 70 43 73 72 2c 20 46 54 53 35 43  lear(pCsr, FTS5C
7d10: 53 52 5f 52 45 51 55 49 52 45 5f 43 4f 4e 54 45  SR_REQUIRE_CONTE
7d20: 4e 54 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a  NT);.    }else{.
7d30: 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74        rc = sqlit
7d40: 65 33 5f 72 65 73 65 74 28 70 43 73 72 2d 3e 70  e3_reset(pCsr->p
7d50: 53 74 6d 74 29 3b 0a 20 20 20 20 20 20 69 66 28  Stmt);.      if(
7d60: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
7d70: 7b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 53  {.        rc = S
7d80: 51 4c 49 54 45 5f 43 4f 52 52 55 50 54 5f 56 54  QLITE_CORRUPT_VT
7d90: 41 42 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  AB;.      }.    
7da0: 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72  }.  }.  return r
7db0: 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73  c;.}../*.** This
7dc0: 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c   function is cal
7dd0: 6c 65 64 20 74 6f 20 68 61 6e 64 6c 65 20 61 6e  led to handle an
7de0: 20 46 54 53 20 49 4e 53 45 52 54 20 63 6f 6d 6d   FTS INSERT comm
7df0: 61 6e 64 2e 20 49 6e 20 6f 74 68 65 72 20 77 6f  and. In other wo
7e00: 72 64 73 2c 0a 2a 2a 20 61 6e 20 49 4e 53 45 52  rds,.** an INSER
7e10: 54 20 73 74 61 74 65 6d 65 6e 74 20 6f 66 20 74  T statement of t
7e20: 68 65 20 66 6f 72 6d 3a 0a 2a 2a 0a 2a 2a 20 20  he form:.**.**  
7e30: 20 20 20 49 4e 53 45 52 54 20 49 4e 54 4f 20 66     INSERT INTO f
7e40: 74 73 28 66 74 73 29 20 56 41 4c 55 45 53 28 24  ts(fts) VALUES($
7e50: 70 43 6d 64 29 0a 2a 2a 20 20 20 20 20 49 4e 53  pCmd).**     INS
7e60: 45 52 54 20 49 4e 54 4f 20 66 74 73 28 66 74 73  ERT INTO fts(fts
7e70: 2c 20 72 61 6e 6b 29 20 56 41 4c 55 45 53 28 24  , rank) VALUES($
7e80: 70 43 6d 64 2c 20 24 70 56 61 6c 29 0a 2a 2a 0a  pCmd, $pVal).**.
7e90: 2a 2a 20 41 72 67 75 6d 65 6e 74 20 70 56 61 6c  ** Argument pVal
7ea0: 20 69 73 20 74 68 65 20 76 61 6c 75 65 20 61 73   is the value as
7eb0: 73 69 67 6e 65 64 20 74 6f 20 63 6f 6c 75 6d 6e  signed to column
7ec0: 20 22 66 74 73 22 20 62 79 20 74 68 65 20 49 4e   "fts" by the IN
7ed0: 53 45 52 54 20 0a 2a 2a 20 73 74 61 74 65 6d 65  SERT .** stateme
7ee0: 6e 74 2e 20 54 68 69 73 20 66 75 6e 63 74 69 6f  nt. This functio
7ef0: 6e 20 72 65 74 75 72 6e 73 20 53 51 4c 49 54 45  n returns SQLITE
7f00: 5f 4f 4b 20 69 66 20 73 75 63 63 65 73 73 66 75  _OK if successfu
7f10: 6c 2c 20 6f 72 20 61 6e 20 53 51 4c 69 74 65 0a  l, or an SQLite.
7f20: 2a 2a 20 65 72 72 6f 72 20 63 6f 64 65 20 69 66  ** error code if
7f30: 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73   an error occurs
7f40: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 6f 6d 6d  ..**.** The comm
7f50: 61 6e 64 73 20 69 6d 70 6c 65 6d 65 6e 74 65 64  ands implemented
7f60: 20 62 79 20 74 68 69 73 20 66 75 6e 63 74 69 6f   by this functio
7f70: 6e 20 61 72 65 20 64 6f 63 75 6d 65 6e 74 65 64  n are documented
7f80: 20 69 6e 20 74 68 65 20 22 53 70 65 63 69 61 6c   in the "Special
7f90: 0a 2a 2a 20 49 4e 53 45 52 54 20 44 69 72 65 63  .** INSERT Direc
7fa0: 74 69 76 65 73 22 20 73 65 63 74 69 6f 6e 20 6f  tives" section o
7fb0: 66 20 74 68 65 20 64 6f 63 75 6d 65 6e 74 61 74  f the documentat
7fc0: 69 6f 6e 2e 20 49 74 20 73 68 6f 75 6c 64 20 62  ion. It should b
7fd0: 65 20 75 70 64 61 74 65 64 20 69 66 0a 2a 2a 20  e updated if.** 
7fe0: 6d 6f 72 65 20 63 6f 6d 6d 61 6e 64 73 20 61 72  more commands ar
7ff0: 65 20 61 64 64 65 64 20 74 6f 20 74 68 69 73 20  e added to this 
8000: 66 75 6e 63 74 69 6f 6e 2e 0a 2a 2f 0a 73 74 61  function..*/.sta
8010: 74 69 63 20 69 6e 74 20 66 74 73 35 53 70 65 63  tic int fts5Spec
8020: 69 61 6c 49 6e 73 65 72 74 28 0a 20 20 46 74 73  ialInsert(.  Fts
8030: 35 54 61 62 6c 65 20 2a 70 54 61 62 2c 20 20 20  5Table *pTab,   
8040: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
8050: 46 74 73 35 20 74 61 62 6c 65 20 6f 62 6a 65 63  Fts5 table objec
8060: 74 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 76  t */.  sqlite3_v
8070: 61 6c 75 65 20 2a 70 43 6d 64 2c 20 20 20 20 20  alue *pCmd,     
8080: 20 20 20 20 20 20 20 2f 2a 20 56 61 6c 75 65 20         /* Value 
8090: 69 6e 73 65 72 74 65 64 20 69 6e 74 6f 20 73 70  inserted into sp
80a0: 65 63 69 61 6c 20 63 6f 6c 75 6d 6e 20 2a 2f 0a  ecial column */.
80b0: 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20    sqlite3_value 
80c0: 2a 70 56 61 6c 20 20 20 20 20 20 20 20 20 20 20  *pVal           
80d0: 20 20 2f 2a 20 56 61 6c 75 65 20 69 6e 73 65 72    /* Value inser
80e0: 74 65 64 20 69 6e 74 6f 20 72 6f 77 69 64 20 63  ted into rowid c
80f0: 6f 6c 75 6d 6e 20 2a 2f 0a 29 7b 0a 20 20 63 6f  olumn */.){.  co
8100: 6e 73 74 20 63 68 61 72 20 2a 7a 20 3d 20 28 63  nst char *z = (c
8110: 6f 6e 73 74 20 63 68 61 72 2a 29 73 71 6c 69 74  onst char*)sqlit
8120: 65 33 5f 76 61 6c 75 65 5f 74 65 78 74 28 70 43  e3_value_text(pC
8130: 6d 64 29 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20  md);.  int rc = 
8140: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 6e 74  SQLITE_OK;.  int
8150: 20 62 45 72 72 6f 72 20 3d 20 30 3b 0a 0a 20 20   bError = 0;..  
8160: 69 66 28 20 30 3d 3d 73 71 6c 69 74 65 33 5f 73  if( 0==sqlite3_s
8170: 74 72 69 63 6d 70 28 22 69 6e 74 65 67 72 69 74  tricmp("integrit
8180: 79 2d 63 68 65 63 6b 22 2c 20 7a 29 20 29 7b 0a  y-check", z) ){.
8190: 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
81a0: 46 74 73 35 53 74 6f 72 61 67 65 49 6e 74 65 67  Fts5StorageInteg
81b0: 72 69 74 79 28 70 54 61 62 2d 3e 70 53 74 6f 72  rity(pTab->pStor
81c0: 61 67 65 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  age);.  }else{. 
81d0: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 46     rc = sqlite3F
81e0: 74 73 35 43 6f 6e 66 69 67 53 65 74 56 61 6c 75  ts5ConfigSetValu
81f0: 65 28 70 54 61 62 2d 3e 70 43 6f 6e 66 69 67 2c  e(pTab->pConfig,
8200: 20 7a 2c 20 70 56 61 6c 2c 20 26 62 45 72 72 6f   z, pVal, &bErro
8210: 72 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d  r);.    if( rc==
8220: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
8230: 20 20 20 69 66 28 20 62 45 72 72 6f 72 20 29 7b     if( bError ){
8240: 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 53 51  .        rc = SQ
8250: 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 20 20  LITE_ERROR;.    
8260: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20    }else{.       
8270: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 46 74 73   rc = sqlite3Fts
8280: 35 53 74 6f 72 61 67 65 43 6f 6e 66 69 67 56 61  5StorageConfigVa
8290: 6c 75 65 28 70 54 61 62 2d 3e 70 53 74 6f 72 61  lue(pTab->pStora
82a0: 67 65 2c 20 7a 2c 20 70 56 61 6c 29 3b 0a 20 20  ge, z, pVal);.  
82b0: 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a      }.    }.  }.
82c0: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
82d0: 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 53  static int fts5S
82e0: 70 65 63 69 61 6c 44 65 6c 65 74 65 28 0a 20 20  pecialDelete(.  
82f0: 46 74 73 35 54 61 62 6c 65 20 2a 70 54 61 62 2c  Fts5Table *pTab,
8300: 20 0a 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75   .  sqlite3_valu
8310: 65 20 2a 2a 61 70 56 61 6c 2c 20 0a 20 20 73 71  e **apVal, .  sq
8320: 6c 69 74 65 33 5f 69 6e 74 36 34 20 2a 70 69 52  lite3_int64 *piR
8330: 6f 77 69 64 0a 29 7b 0a 20 20 69 6e 74 20 72 63  owid.){.  int rc
8340: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20   = SQLITE_OK;.  
8350: 69 6e 74 20 65 54 79 70 65 31 20 3d 20 73 71 6c  int eType1 = sql
8360: 69 74 65 33 5f 76 61 6c 75 65 5f 74 79 70 65 28  ite3_value_type(
8370: 61 70 56 61 6c 5b 31 5d 29 3b 0a 20 20 69 66 28  apVal[1]);.  if(
8380: 20 65 54 79 70 65 31 3d 3d 53 51 4c 49 54 45 5f   eType1==SQLITE_
8390: 49 4e 54 45 47 45 52 20 29 7b 0a 20 20 20 20 73  INTEGER ){.    s
83a0: 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 69 44 65  qlite3_int64 iDe
83b0: 6c 20 3d 20 73 71 6c 69 74 65 33 5f 76 61 6c 75  l = sqlite3_valu
83c0: 65 5f 69 6e 74 36 34 28 61 70 56 61 6c 5b 31 5d  e_int64(apVal[1]
83d0: 29 3b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69  );.    rc = sqli
83e0: 74 65 33 46 74 73 35 53 74 6f 72 61 67 65 53 70  te3Fts5StorageSp
83f0: 65 63 69 61 6c 44 65 6c 65 74 65 28 70 54 61 62  ecialDelete(pTab
8400: 2d 3e 70 53 74 6f 72 61 67 65 2c 20 69 44 65 6c  ->pStorage, iDel
8410: 2c 20 26 61 70 56 61 6c 5b 32 5d 29 3b 0a 20 20  , &apVal[2]);.  
8420: 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  }.  return rc;.}
8430: 0a 0a 2f 2a 20 0a 2a 2a 20 54 68 69 73 20 66 75  ../* .** This fu
8440: 6e 63 74 69 6f 6e 20 69 73 20 74 68 65 20 69 6d  nction is the im
8450: 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20  plementation of 
8460: 74 68 65 20 78 55 70 64 61 74 65 20 63 61 6c 6c  the xUpdate call
8470: 62 61 63 6b 20 75 73 65 64 20 62 79 20 0a 2a 2a  back used by .**
8480: 20 46 54 53 33 20 76 69 72 74 75 61 6c 20 74 61   FTS3 virtual ta
8490: 62 6c 65 73 2e 20 49 74 20 69 73 20 69 6e 76 6f  bles. It is invo
84a0: 6b 65 64 20 62 79 20 53 51 4c 69 74 65 20 65 61  ked by SQLite ea
84b0: 63 68 20 74 69 6d 65 20 61 20 72 6f 77 20 69 73  ch time a row is
84c0: 20 74 6f 20 62 65 0a 2a 2a 20 69 6e 73 65 72 74   to be.** insert
84d0: 65 64 2c 20 75 70 64 61 74 65 64 20 6f 72 20 64  ed, updated or d
84e0: 65 6c 65 74 65 64 2e 0a 2a 2f 0a 73 74 61 74 69  eleted..*/.stati
84f0: 63 20 69 6e 74 20 66 74 73 35 55 70 64 61 74 65  c int fts5Update
8500: 4d 65 74 68 6f 64 28 0a 20 20 73 71 6c 69 74 65  Method(.  sqlite
8510: 33 5f 76 74 61 62 20 2a 70 56 74 61 62 2c 20 20  3_vtab *pVtab,  
8520: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 56 69 72            /* Vir
8530: 74 75 61 6c 20 74 61 62 6c 65 20 68 61 6e 64 6c  tual table handl
8540: 65 20 2a 2f 0a 20 20 69 6e 74 20 6e 41 72 67 2c  e */.  int nArg,
8550: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8560: 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f         /* Size o
8570: 66 20 61 72 67 75 6d 65 6e 74 20 61 72 72 61 79  f argument array
8580: 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 76 61   */.  sqlite3_va
8590: 6c 75 65 20 2a 2a 61 70 56 61 6c 2c 20 20 20 20  lue **apVal,    
85a0: 20 20 20 20 20 20 2f 2a 20 41 72 72 61 79 20 6f        /* Array o
85b0: 66 20 61 72 67 75 6d 65 6e 74 73 20 2a 2f 0a 20  f arguments */. 
85c0: 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 2a 70   sqlite_int64 *p
85d0: 52 6f 77 69 64 20 20 20 20 20 20 20 20 20 20 20  Rowid           
85e0: 20 2f 2a 20 4f 55 54 3a 20 54 68 65 20 61 66 66   /* OUT: The aff
85f0: 65 63 74 65 64 20 28 6f 72 20 65 66 66 65 63 74  ected (or effect
8600: 65 64 29 20 72 6f 77 69 64 20 2a 2f 0a 29 7b 0a  ed) rowid */.){.
8610: 20 20 46 74 73 35 54 61 62 6c 65 20 2a 70 54 61    Fts5Table *pTa
8620: 62 20 3d 20 28 46 74 73 35 54 61 62 6c 65 2a 29  b = (Fts5Table*)
8630: 70 56 74 61 62 3b 0a 20 20 46 74 73 35 43 6f 6e  pVtab;.  Fts5Con
8640: 66 69 67 20 2a 70 43 6f 6e 66 69 67 20 3d 20 70  fig *pConfig = p
8650: 54 61 62 2d 3e 70 43 6f 6e 66 69 67 3b 0a 20 20  Tab->pConfig;.  
8660: 69 6e 74 20 65 54 79 70 65 30 3b 20 20 20 20 20  int eType0;     
8670: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8680: 2f 2a 20 76 61 6c 75 65 5f 74 79 70 65 28 29 20  /* value_type() 
8690: 6f 66 20 61 70 56 61 6c 5b 30 5d 20 2a 2f 0a 20  of apVal[0] */. 
86a0: 20 69 6e 74 20 65 43 6f 6e 66 6c 69 63 74 3b 20   int eConflict; 
86b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
86c0: 20 2f 2a 20 4f 4e 20 43 4f 4e 46 4c 49 43 54 20   /* ON CONFLICT 
86d0: 66 6f 72 20 74 68 69 73 20 44 4d 4c 20 2a 2f 0a  for this DML */.
86e0: 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
86f0: 45 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20 20 20  E_OK;           
8700: 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65    /* Return code
8710: 20 2a 2f 0a 0a 20 20 2f 2a 20 41 20 74 72 61 6e   */..  /* A tran
8720: 73 61 63 74 69 6f 6e 20 6d 75 73 74 20 62 65 20  saction must be 
8730: 6f 70 65 6e 20 77 68 65 6e 20 74 68 69 73 20 69  open when this i
8740: 73 20 63 61 6c 6c 65 64 2e 20 2a 2f 0a 20 20 61  s called. */.  a
8750: 73 73 65 72 74 28 20 70 54 61 62 2d 3e 74 73 2e  ssert( pTab->ts.
8760: 65 53 74 61 74 65 3d 3d 31 20 29 3b 0a 0a 20 20  eState==1 );..  
8770: 2f 2a 20 41 20 64 65 6c 65 74 65 20 73 70 65 63  /* A delete spec
8780: 69 66 69 65 73 20 61 20 73 69 6e 67 6c 65 20 61  ifies a single a
8790: 72 67 75 6d 65 6e 74 20 2d 20 74 68 65 20 72 6f  rgument - the ro
87a0: 77 69 64 20 6f 66 20 74 68 65 20 72 6f 77 20 74  wid of the row t
87b0: 6f 20 72 65 6d 6f 76 65 2e 0a 20 20 2a 2a 20 55  o remove..  ** U
87c0: 70 64 61 74 65 20 61 6e 64 20 69 6e 73 65 72 74  pdate and insert
87d0: 20 6f 70 65 72 61 74 69 6f 6e 73 20 70 61 73 73   operations pass
87e0: 3a 0a 20 20 2a 2a 0a 20 20 2a 2a 20 20 20 31 2e  :.  **.  **   1.
87f0: 20 54 68 65 20 22 6f 6c 64 22 20 72 6f 77 69 64   The "old" rowid
8800: 2c 20 6f 72 20 4e 55 4c 4c 2e 0a 20 20 2a 2a 20  , or NULL..  ** 
8810: 20 20 32 2e 20 54 68 65 20 22 6e 65 77 22 20 72    2. The "new" r
8820: 6f 77 69 64 2e 0a 20 20 2a 2a 20 20 20 33 2e 20  owid..  **   3. 
8830: 56 61 6c 75 65 73 20 66 6f 72 20 65 61 63 68 20  Values for each 
8840: 6f 66 20 74 68 65 20 6e 43 6f 6c 20 6d 61 74 63  of the nCol matc
8850: 68 61 62 6c 65 20 63 6f 6c 75 6d 6e 73 2e 0a 20  hable columns.. 
8860: 20 2a 2a 20 20 20 34 2e 20 56 61 6c 75 65 73 20   **   4. Values 
8870: 66 6f 72 20 74 68 65 20 74 77 6f 20 68 69 64 64  for the two hidd
8880: 65 6e 20 63 6f 6c 75 6d 6e 73 20 28 3c 74 61 62  en columns (<tab
8890: 6c 65 6e 61 6d 65 3e 20 61 6e 64 20 22 72 61 6e  lename> and "ran
88a0: 6b 22 29 2e 0a 20 20 2a 2f 0a 20 20 61 73 73 65  k")..  */.  asse
88b0: 72 74 28 20 6e 41 72 67 3d 3d 31 20 7c 7c 20 6e  rt( nArg==1 || n
88c0: 41 72 67 3d 3d 28 32 20 2b 20 70 43 6f 6e 66 69  Arg==(2 + pConfi
88d0: 67 2d 3e 6e 43 6f 6c 20 2b 20 32 29 20 29 3b 0a  g->nCol + 2) );.
88e0: 0a 20 20 69 66 28 20 6e 41 72 67 3e 31 20 29 7b  .  if( nArg>1 ){
88f0: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 76 61 6c  .    sqlite3_val
8900: 75 65 20 2a 70 43 6d 64 20 3d 20 73 71 6c 69 74  ue *pCmd = sqlit
8910: 65 33 5f 76 61 6c 75 65 5f 74 79 70 65 28 61 70  e3_value_type(ap
8920: 56 61 6c 5b 32 20 2b 20 70 43 6f 6e 66 69 67 2d  Val[2 + pConfig-
8930: 3e 6e 43 6f 6c 5d 29 3b 0a 20 20 20 20 69 66 28  >nCol]);.    if(
8940: 20 53 51 4c 49 54 45 5f 4e 55 4c 4c 21 3d 73 71   SQLITE_NULL!=sq
8950: 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 79 70 65  lite3_value_type
8960: 28 70 43 6d 64 29 20 29 7b 0a 20 20 20 20 20 20  (pCmd) ){.      
8970: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 20 3d 20  const char *z = 
8980: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 65  sqlite3_value_te
8990: 78 74 28 70 43 6d 64 29 3b 0a 20 20 20 20 20 20  xt(pCmd);.      
89a0: 69 66 28 20 70 43 6f 6e 66 69 67 2d 3e 62 45 78  if( pConfig->bEx
89b0: 74 65 72 6e 61 6c 43 6f 6e 74 65 6e 74 20 26 26  ternalContent &&
89c0: 20 73 71 6c 69 74 65 33 5f 73 74 72 69 63 6d 70   sqlite3_stricmp
89d0: 28 22 64 65 6c 65 74 65 22 2c 20 7a 29 20 29 7b  ("delete", z) ){
89e0: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
89f0: 66 74 73 35 53 70 65 63 69 61 6c 44 65 6c 65 74  fts5SpecialDelet
8a00: 65 28 70 54 61 62 2c 20 61 70 56 61 6c 2c 20 70  e(pTab, apVal, p
8a10: 52 6f 77 69 64 29 3b 0a 20 20 20 20 20 20 7d 65  Rowid);.      }e
8a20: 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 72 65 74  lse{.        ret
8a30: 75 72 6e 20 66 74 73 35 53 70 65 63 69 61 6c 49  urn fts5SpecialI
8a40: 6e 73 65 72 74 28 70 54 61 62 2c 20 70 43 6d 64  nsert(pTab, pCmd
8a50: 2c 20 61 70 56 61 6c 5b 32 20 2b 20 70 43 6f 6e  , apVal[2 + pCon
8a60: 66 69 67 2d 3e 6e 43 6f 6c 20 2b 20 31 5d 29 3b  fig->nCol + 1]);
8a70: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
8a80: 20 7d 0a 0a 20 20 65 54 79 70 65 30 20 3d 20 73   }..  eType0 = s
8a90: 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 79 70  qlite3_value_typ
8aa0: 65 28 61 70 56 61 6c 5b 30 5d 29 3b 0a 20 20 65  e(apVal[0]);.  e
8ab0: 43 6f 6e 66 6c 69 63 74 20 3d 20 73 71 6c 69 74  Conflict = sqlit
8ac0: 65 33 5f 76 74 61 62 5f 6f 6e 5f 63 6f 6e 66 6c  e3_vtab_on_confl
8ad0: 69 63 74 28 70 43 6f 6e 66 69 67 2d 3e 64 62 29  ict(pConfig->db)
8ae0: 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 65 54 79  ;..  assert( eTy
8af0: 70 65 30 3d 3d 53 51 4c 49 54 45 5f 49 4e 54 45  pe0==SQLITE_INTE
8b00: 47 45 52 20 7c 7c 20 65 54 79 70 65 30 3d 3d 53  GER || eType0==S
8b10: 51 4c 49 54 45 5f 4e 55 4c 4c 20 29 3b 0a 20 20  QLITE_NULL );.  
8b20: 61 73 73 65 72 74 28 20 70 56 74 61 62 2d 3e 7a  assert( pVtab->z
8b30: 45 72 72 4d 73 67 3d 3d 30 20 29 3b 0a 0a 20 20  ErrMsg==0 );..  
8b40: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
8b50: 4b 20 26 26 20 65 54 79 70 65 30 3d 3d 53 51 4c  K && eType0==SQL
8b60: 49 54 45 5f 49 4e 54 45 47 45 52 20 29 7b 0a 20  ITE_INTEGER ){. 
8b70: 20 20 20 69 36 34 20 69 44 65 6c 20 3d 20 73 71     i64 iDel = sq
8b80: 6c 69 74 65 33 5f 76 61 6c 75 65 5f 69 6e 74 36  lite3_value_int6
8b90: 34 28 61 70 56 61 6c 5b 30 5d 29 3b 20 20 20 20  4(apVal[0]);    
8ba0: 2f 2a 20 52 6f 77 69 64 20 74 6f 20 64 65 6c 65  /* Rowid to dele
8bb0: 74 65 20 2a 2f 0a 20 20 20 20 72 63 20 3d 20 73  te */.    rc = s
8bc0: 71 6c 69 74 65 33 46 74 73 35 53 74 6f 72 61 67  qlite3Fts5Storag
8bd0: 65 44 65 6c 65 74 65 28 70 54 61 62 2d 3e 70 53  eDelete(pTab->pS
8be0: 74 6f 72 61 67 65 2c 20 69 44 65 6c 29 3b 0a 20  torage, iDel);. 
8bf0: 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51   }..  if( rc==SQ
8c00: 4c 49 54 45 5f 4f 4b 20 26 26 20 6e 41 72 67 3e  LITE_OK && nArg>
8c10: 31 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 73 71  1 ){.    rc = sq
8c20: 6c 69 74 65 33 46 74 73 35 53 74 6f 72 61 67 65  lite3Fts5Storage
8c30: 49 6e 73 65 72 74 28 70 54 61 62 2d 3e 70 53 74  Insert(pTab->pSt
8c40: 6f 72 61 67 65 2c 20 61 70 56 61 6c 2c 20 65 43  orage, apVal, eC
8c50: 6f 6e 66 6c 69 63 74 2c 20 70 52 6f 77 69 64 29  onflict, pRowid)
8c60: 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20  ;.  }..  return 
8c70: 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70  rc;.}../*.** Imp
8c80: 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 78  lementation of x
8c90: 53 79 6e 63 28 29 20 6d 65 74 68 6f 64 2e 20 0a  Sync() method. .
8ca0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74  */.static int ft
8cb0: 73 35 53 79 6e 63 4d 65 74 68 6f 64 28 73 71 6c  s5SyncMethod(sql
8cc0: 69 74 65 33 5f 76 74 61 62 20 2a 70 56 74 61 62  ite3_vtab *pVtab
8cd0: 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 46  ){.  int rc;.  F
8ce0: 74 73 35 54 61 62 6c 65 20 2a 70 54 61 62 20 3d  ts5Table *pTab =
8cf0: 20 28 46 74 73 35 54 61 62 6c 65 2a 29 70 56 74   (Fts5Table*)pVt
8d00: 61 62 3b 0a 20 20 66 74 73 35 43 68 65 63 6b 54  ab;.  fts5CheckT
8d10: 72 61 6e 73 61 63 74 69 6f 6e 53 74 61 74 65 28  ransactionState(
8d20: 70 54 61 62 2c 20 46 54 53 35 5f 53 59 4e 43 2c  pTab, FTS5_SYNC,
8d30: 20 30 29 3b 0a 20 20 72 63 20 3d 20 73 71 6c 69   0);.  rc = sqli
8d40: 74 65 33 46 74 73 35 53 74 6f 72 61 67 65 53 79  te3Fts5StorageSy
8d50: 6e 63 28 70 54 61 62 2d 3e 70 53 74 6f 72 61 67  nc(pTab->pStorag
8d60: 65 2c 20 31 29 3b 0a 20 20 72 65 74 75 72 6e 20  e, 1);.  return 
8d70: 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70  rc;.}../*.** Imp
8d80: 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 78  lementation of x
8d90: 42 65 67 69 6e 28 29 20 6d 65 74 68 6f 64 2e 20  Begin() method. 
8da0: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66  .*/.static int f
8db0: 74 73 35 42 65 67 69 6e 4d 65 74 68 6f 64 28 73  ts5BeginMethod(s
8dc0: 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56 74  qlite3_vtab *pVt
8dd0: 61 62 29 7b 0a 20 20 66 74 73 35 43 68 65 63 6b  ab){.  fts5Check
8de0: 54 72 61 6e 73 61 63 74 69 6f 6e 53 74 61 74 65  TransactionState
8df0: 28 28 46 74 73 35 54 61 62 6c 65 2a 29 70 56 74  ((Fts5Table*)pVt
8e00: 61 62 2c 20 46 54 53 35 5f 42 45 47 49 4e 2c 20  ab, FTS5_BEGIN, 
8e10: 30 29 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c  0);.  return SQL
8e20: 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  ITE_OK;.}../*.**
8e30: 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20   Implementation 
8e40: 6f 66 20 78 43 6f 6d 6d 69 74 28 29 20 6d 65 74  of xCommit() met
8e50: 68 6f 64 2e 20 54 68 69 73 20 69 73 20 61 20 6e  hod. This is a n
8e60: 6f 2d 6f 70 2e 20 54 68 65 20 63 6f 6e 74 65 6e  o-op. The conten
8e70: 74 73 20 6f 66 0a 2a 2a 20 74 68 65 20 70 65 6e  ts of.** the pen
8e80: 64 69 6e 67 2d 74 65 72 6d 73 20 68 61 73 68 2d  ding-terms hash-
8e90: 74 61 62 6c 65 20 68 61 76 65 20 61 6c 72 65 61  table have alrea
8ea0: 64 79 20 62 65 65 6e 20 66 6c 75 73 68 65 64 20  dy been flushed 
8eb0: 69 6e 74 6f 20 74 68 65 20 64 61 74 61 62 61 73  into the databas
8ec0: 65 0a 2a 2a 20 62 79 20 66 74 73 35 53 79 6e 63  e.** by fts5Sync
8ed0: 4d 65 74 68 6f 64 28 29 2e 0a 2a 2f 0a 73 74 61  Method()..*/.sta
8ee0: 74 69 63 20 69 6e 74 20 66 74 73 35 43 6f 6d 6d  tic int fts5Comm
8ef0: 69 74 4d 65 74 68 6f 64 28 73 71 6c 69 74 65 33  itMethod(sqlite3
8f00: 5f 76 74 61 62 20 2a 70 56 74 61 62 29 7b 0a 20  _vtab *pVtab){. 
8f10: 20 66 74 73 35 43 68 65 63 6b 54 72 61 6e 73 61   fts5CheckTransa
8f20: 63 74 69 6f 6e 53 74 61 74 65 28 28 46 74 73 35  ctionState((Fts5
8f30: 54 61 62 6c 65 2a 29 70 56 74 61 62 2c 20 46 54  Table*)pVtab, FT
8f40: 53 35 5f 43 4f 4d 4d 49 54 2c 20 30 29 3b 0a 20  S5_COMMIT, 0);. 
8f50: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
8f60: 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c  K;.}../*.** Impl
8f70: 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 78 52  ementation of xR
8f80: 6f 6c 6c 62 61 63 6b 28 29 2e 20 44 69 73 63 61  ollback(). Disca
8f90: 72 64 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20  rd the contents 
8fa0: 6f 66 20 74 68 65 20 70 65 6e 64 69 6e 67 2d 74  of the pending-t
8fb0: 65 72 6d 73 0a 2a 2a 20 68 61 73 68 2d 74 61 62  erms.** hash-tab
8fc0: 6c 65 2e 20 41 6e 79 20 63 68 61 6e 67 65 73 20  le. Any changes 
8fd0: 6d 61 64 65 20 74 6f 20 74 68 65 20 64 61 74 61  made to the data
8fe0: 62 61 73 65 20 61 72 65 20 72 65 76 65 72 74 65  base are reverte
8ff0: 64 20 62 79 20 53 51 4c 69 74 65 2e 0a 2a 2f 0a  d by SQLite..*/.
9000: 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 52  static int fts5R
9010: 6f 6c 6c 62 61 63 6b 4d 65 74 68 6f 64 28 73 71  ollbackMethod(sq
9020: 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56 74 61  lite3_vtab *pVta
9030: 62 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20  b){.  int rc;.  
9040: 46 74 73 35 54 61 62 6c 65 20 2a 70 54 61 62 20  Fts5Table *pTab 
9050: 3d 20 28 46 74 73 35 54 61 62 6c 65 2a 29 70 56  = (Fts5Table*)pV
9060: 74 61 62 3b 0a 20 20 66 74 73 35 43 68 65 63 6b  tab;.  fts5Check
9070: 54 72 61 6e 73 61 63 74 69 6f 6e 53 74 61 74 65  TransactionState
9080: 28 70 54 61 62 2c 20 46 54 53 35 5f 52 4f 4c 4c  (pTab, FTS5_ROLL
9090: 42 41 43 4b 2c 20 30 29 3b 0a 20 20 72 63 20 3d  BACK, 0);.  rc =
90a0: 20 73 71 6c 69 74 65 33 46 74 73 35 53 74 6f 72   sqlite3Fts5Stor
90b0: 61 67 65 52 6f 6c 6c 62 61 63 6b 28 70 54 61 62  ageRollback(pTab
90c0: 2d 3e 70 53 74 6f 72 61 67 65 29 3b 0a 20 20 72  ->pStorage);.  r
90d0: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61  eturn rc;.}..sta
90e0: 74 69 63 20 76 6f 69 64 20 2a 66 74 73 35 41 70  tic void *fts5Ap
90f0: 69 55 73 65 72 44 61 74 61 28 46 74 73 35 43 6f  iUserData(Fts5Co
9100: 6e 74 65 78 74 20 2a 70 43 74 78 29 7b 0a 20 20  ntext *pCtx){.  
9110: 46 74 73 35 43 75 72 73 6f 72 20 2a 70 43 73 72  Fts5Cursor *pCsr
9120: 20 3d 20 28 46 74 73 35 43 75 72 73 6f 72 2a 29   = (Fts5Cursor*)
9130: 70 43 74 78 3b 0a 20 20 72 65 74 75 72 6e 20 70  pCtx;.  return p
9140: 43 73 72 2d 3e 70 41 75 78 2d 3e 70 55 73 65 72  Csr->pAux->pUser
9150: 44 61 74 61 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  Data;.}..static 
9160: 69 6e 74 20 66 74 73 35 41 70 69 43 6f 6c 75 6d  int fts5ApiColum
9170: 6e 43 6f 75 6e 74 28 46 74 73 35 43 6f 6e 74 65  nCount(Fts5Conte
9180: 78 74 20 2a 70 43 74 78 29 7b 0a 20 20 46 74 73  xt *pCtx){.  Fts
9190: 35 43 75 72 73 6f 72 20 2a 70 43 73 72 20 3d 20  5Cursor *pCsr = 
91a0: 28 46 74 73 35 43 75 72 73 6f 72 2a 29 70 43 74  (Fts5Cursor*)pCt
91b0: 78 3b 0a 20 20 72 65 74 75 72 6e 20 28 28 46 74  x;.  return ((Ft
91c0: 73 35 54 61 62 6c 65 2a 29 28 70 43 73 72 2d 3e  s5Table*)(pCsr->
91d0: 62 61 73 65 2e 70 56 74 61 62 29 29 2d 3e 70 43  base.pVtab))->pC
91e0: 6f 6e 66 69 67 2d 3e 6e 43 6f 6c 3b 0a 7d 0a 0a  onfig->nCol;.}..
91f0: 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 41  static int fts5A
9200: 70 69 43 6f 6c 75 6d 6e 54 6f 74 61 6c 53 69 7a  piColumnTotalSiz
9210: 65 28 0a 20 20 46 74 73 35 43 6f 6e 74 65 78 74  e(.  Fts5Context
9220: 20 2a 70 43 74 78 2c 20 0a 20 20 69 6e 74 20 69   *pCtx, .  int i
9230: 43 6f 6c 2c 20 0a 20 20 73 71 6c 69 74 65 33 5f  Col, .  sqlite3_
9240: 69 6e 74 36 34 20 2a 70 6e 54 6f 6b 65 6e 0a 29  int64 *pnToken.)
9250: 7b 0a 20 20 46 74 73 35 43 75 72 73 6f 72 20 2a  {.  Fts5Cursor *
9260: 70 43 73 72 20 3d 20 28 46 74 73 35 43 75 72 73  pCsr = (Fts5Curs
9270: 6f 72 2a 29 70 43 74 78 3b 0a 20 20 46 74 73 35  or*)pCtx;.  Fts5
9280: 54 61 62 6c 65 20 2a 70 54 61 62 20 3d 20 28 46  Table *pTab = (F
9290: 74 73 35 54 61 62 6c 65 2a 29 28 70 43 73 72 2d  ts5Table*)(pCsr-
92a0: 3e 62 61 73 65 2e 70 56 74 61 62 29 3b 0a 20 20  >base.pVtab);.  
92b0: 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33 46 74  return sqlite3Ft
92c0: 73 35 53 74 6f 72 61 67 65 53 69 7a 65 28 70 54  s5StorageSize(pT
92d0: 61 62 2d 3e 70 53 74 6f 72 61 67 65 2c 20 69 43  ab->pStorage, iC
92e0: 6f 6c 2c 20 70 6e 54 6f 6b 65 6e 29 3b 0a 7d 0a  ol, pnToken);.}.
92f0: 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35  .static int fts5
9300: 41 70 69 52 6f 77 43 6f 75 6e 74 28 46 74 73 35  ApiRowCount(Fts5
9310: 43 6f 6e 74 65 78 74 20 2a 70 43 74 78 2c 20 69  Context *pCtx, i
9320: 36 34 20 2a 70 6e 52 6f 77 29 7b 0a 20 20 46 74  64 *pnRow){.  Ft
9330: 73 35 43 75 72 73 6f 72 20 2a 70 43 73 72 20 3d  s5Cursor *pCsr =
9340: 20 28 46 74 73 35 43 75 72 73 6f 72 2a 29 70 43   (Fts5Cursor*)pC
9350: 74 78 3b 0a 20 20 46 74 73 35 54 61 62 6c 65 20  tx;.  Fts5Table 
9360: 2a 70 54 61 62 20 3d 20 28 46 74 73 35 54 61 62  *pTab = (Fts5Tab
9370: 6c 65 2a 29 28 70 43 73 72 2d 3e 62 61 73 65 2e  le*)(pCsr->base.
9380: 70 56 74 61 62 29 3b 0a 20 20 72 65 74 75 72 6e  pVtab);.  return
9390: 20 73 71 6c 69 74 65 33 46 74 73 35 53 74 6f 72   sqlite3Fts5Stor
93a0: 61 67 65 52 6f 77 43 6f 75 6e 74 28 70 54 61 62  ageRowCount(pTab
93b0: 2d 3e 70 53 74 6f 72 61 67 65 2c 20 70 6e 52 6f  ->pStorage, pnRo
93c0: 77 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  w);.}..static in
93d0: 74 20 66 74 73 35 41 70 69 54 6f 6b 65 6e 69 7a  t fts5ApiTokeniz
93e0: 65 28 0a 20 20 46 74 73 35 43 6f 6e 74 65 78 74  e(.  Fts5Context
93f0: 20 2a 70 43 74 78 2c 20 0a 20 20 63 6f 6e 73 74   *pCtx, .  const
9400: 20 63 68 61 72 20 2a 70 54 65 78 74 2c 20 69 6e   char *pText, in
9410: 74 20 6e 54 65 78 74 2c 20 0a 20 20 76 6f 69 64  t nText, .  void
9420: 20 2a 70 55 73 65 72 44 61 74 61 2c 0a 20 20 69   *pUserData,.  i
9430: 6e 74 20 28 2a 78 54 6f 6b 65 6e 29 28 76 6f 69  nt (*xToken)(voi
9440: 64 2a 2c 20 63 6f 6e 73 74 20 63 68 61 72 2a 2c  d*, const char*,
9450: 20 69 6e 74 2c 20 69 6e 74 2c 20 69 6e 74 2c 20   int, int, int, 
9460: 69 6e 74 29 0a 29 7b 0a 20 20 46 74 73 35 43 75  int).){.  Fts5Cu
9470: 72 73 6f 72 20 2a 70 43 73 72 20 3d 20 28 46 74  rsor *pCsr = (Ft
9480: 73 35 43 75 72 73 6f 72 2a 29 70 43 74 78 3b 0a  s5Cursor*)pCtx;.
9490: 20 20 46 74 73 35 54 61 62 6c 65 20 2a 70 54 61    Fts5Table *pTa
94a0: 62 20 3d 20 28 46 74 73 35 54 61 62 6c 65 2a 29  b = (Fts5Table*)
94b0: 28 70 43 73 72 2d 3e 62 61 73 65 2e 70 56 74 61  (pCsr->base.pVta
94c0: 62 29 3b 0a 20 20 72 65 74 75 72 6e 20 73 71 6c  b);.  return sql
94d0: 69 74 65 33 46 74 73 35 54 6f 6b 65 6e 69 7a 65  ite3Fts5Tokenize
94e0: 28 70 54 61 62 2d 3e 70 43 6f 6e 66 69 67 2c 20  (pTab->pConfig, 
94f0: 70 54 65 78 74 2c 20 6e 54 65 78 74 2c 20 70 55  pText, nText, pU
9500: 73 65 72 44 61 74 61 2c 20 78 54 6f 6b 65 6e 29  serData, xToken)
9510: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  ;.}..static int 
9520: 66 74 73 35 41 70 69 50 68 72 61 73 65 43 6f 75  fts5ApiPhraseCou
9530: 6e 74 28 46 74 73 35 43 6f 6e 74 65 78 74 20 2a  nt(Fts5Context *
9540: 70 43 74 78 29 7b 0a 20 20 46 74 73 35 43 75 72  pCtx){.  Fts5Cur
9550: 73 6f 72 20 2a 70 43 73 72 20 3d 20 28 46 74 73  sor *pCsr = (Fts
9560: 35 43 75 72 73 6f 72 2a 29 70 43 74 78 3b 0a 20  5Cursor*)pCtx;. 
9570: 20 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33 46   return sqlite3F
9580: 74 73 35 45 78 70 72 50 68 72 61 73 65 43 6f 75  ts5ExprPhraseCou
9590: 6e 74 28 70 43 73 72 2d 3e 70 45 78 70 72 29 3b  nt(pCsr->pExpr);
95a0: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 66  .}..static int f
95b0: 74 73 35 41 70 69 50 68 72 61 73 65 53 69 7a 65  ts5ApiPhraseSize
95c0: 28 46 74 73 35 43 6f 6e 74 65 78 74 20 2a 70 43  (Fts5Context *pC
95d0: 74 78 2c 20 69 6e 74 20 69 50 68 72 61 73 65 29  tx, int iPhrase)
95e0: 7b 0a 20 20 46 74 73 35 43 75 72 73 6f 72 20 2a  {.  Fts5Cursor *
95f0: 70 43 73 72 20 3d 20 28 46 74 73 35 43 75 72 73  pCsr = (Fts5Curs
9600: 6f 72 2a 29 70 43 74 78 3b 0a 20 20 72 65 74 75  or*)pCtx;.  retu
9610: 72 6e 20 73 71 6c 69 74 65 33 46 74 73 35 45 78  rn sqlite3Fts5Ex
9620: 70 72 50 68 72 61 73 65 53 69 7a 65 28 70 43 73  prPhraseSize(pCs
9630: 72 2d 3e 70 45 78 70 72 2c 20 69 50 68 72 61 73  r->pExpr, iPhras
9640: 65 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  e);.}..static in
9650: 74 20 66 74 73 35 43 73 72 50 6f 73 6c 69 73 74  t fts5CsrPoslist
9660: 28 46 74 73 35 43 75 72 73 6f 72 20 2a 70 43 73  (Fts5Cursor *pCs
9670: 72 2c 20 69 6e 74 20 69 50 68 72 61 73 65 2c 20  r, int iPhrase, 
9680: 63 6f 6e 73 74 20 75 38 20 2a 2a 70 61 29 7b 0a  const u8 **pa){.
9690: 20 20 69 6e 74 20 6e 3b 0a 20 20 69 66 28 20 70    int n;.  if( p
96a0: 43 73 72 2d 3e 70 53 6f 72 74 65 72 20 29 7b 0a  Csr->pSorter ){.
96b0: 20 20 20 20 46 74 73 35 53 6f 72 74 65 72 20 2a      Fts5Sorter *
96c0: 70 53 6f 72 74 65 72 20 3d 20 70 43 73 72 2d 3e  pSorter = pCsr->
96d0: 70 53 6f 72 74 65 72 3b 0a 20 20 20 20 69 6e 74  pSorter;.    int
96e0: 20 69 31 20 3d 20 28 69 50 68 72 61 73 65 3d 3d   i1 = (iPhrase==
96f0: 30 20 3f 20 30 20 3a 20 70 53 6f 72 74 65 72 2d  0 ? 0 : pSorter-
9700: 3e 61 49 64 78 5b 69 50 68 72 61 73 65 2d 31 5d  >aIdx[iPhrase-1]
9710: 29 3b 0a 20 20 20 20 6e 20 3d 20 70 53 6f 72 74  );.    n = pSort
9720: 65 72 2d 3e 61 49 64 78 5b 69 50 68 72 61 73 65  er->aIdx[iPhrase
9730: 5d 20 2d 20 69 31 3b 0a 20 20 20 20 2a 70 61 20  ] - i1;.    *pa 
9740: 3d 20 26 70 53 6f 72 74 65 72 2d 3e 61 50 6f 73  = &pSorter->aPos
9750: 6c 69 73 74 5b 69 31 5d 3b 0a 20 20 7d 65 6c 73  list[i1];.  }els
9760: 65 7b 0a 20 20 20 20 6e 20 3d 20 73 71 6c 69 74  e{.    n = sqlit
9770: 65 33 46 74 73 35 45 78 70 72 50 6f 73 6c 69 73  e3Fts5ExprPoslis
9780: 74 28 70 43 73 72 2d 3e 70 45 78 70 72 2c 20 69  t(pCsr->pExpr, i
9790: 50 68 72 61 73 65 2c 20 70 61 29 3b 0a 20 20 7d  Phrase, pa);.  }
97a0: 0a 20 20 72 65 74 75 72 6e 20 6e 3b 0a 7d 0a 0a  .  return n;.}..
97b0: 2f 2a 0a 2a 2a 20 45 6e 73 75 72 65 20 74 68 61  /*.** Ensure tha
97c0: 74 20 74 68 65 20 46 74 73 35 43 75 72 73 6f 72  t the Fts5Cursor
97d0: 2e 6e 49 6e 73 74 43 6f 75 6e 74 20 61 6e 64 20  .nInstCount and 
97e0: 61 49 6e 73 74 5b 5d 20 76 61 72 69 61 62 6c 65  aInst[] variable
97f0: 73 20 61 72 65 20 70 6f 70 75 6c 61 74 65 64 0a  s are populated.
9800: 2a 2a 20 63 6f 72 72 65 63 74 6c 79 20 66 6f 72  ** correctly for
9810: 20 74 68 65 20 63 75 72 72 65 6e 74 20 76 69 65   the current vie
9820: 77 2e 20 52 65 74 75 72 6e 20 53 51 4c 49 54 45  w. Return SQLITE
9830: 5f 4f 4b 20 69 66 20 73 75 63 63 65 73 73 66 75  _OK if successfu
9840: 6c 2c 20 6f 72 20 61 6e 0a 2a 2a 20 53 51 4c 69  l, or an.** SQLi
9850: 74 65 20 65 72 72 6f 72 20 63 6f 64 65 20 6f 74  te error code ot
9860: 68 65 72 77 69 73 65 2e 0a 2a 2f 0a 73 74 61 74  herwise..*/.stat
9870: 69 63 20 69 6e 74 20 66 74 73 35 43 61 63 68 65  ic int fts5Cache
9880: 49 6e 73 74 41 72 72 61 79 28 46 74 73 35 43 75  InstArray(Fts5Cu
9890: 72 73 6f 72 20 2a 70 43 73 72 29 7b 0a 20 20 69  rsor *pCsr){.  i
98a0: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
98b0: 4b 3b 0a 20 20 69 66 28 20 70 43 73 72 2d 3e 61  K;.  if( pCsr->a
98c0: 49 6e 73 74 3d 3d 30 20 29 7b 0a 20 20 20 20 46  Inst==0 ){.    F
98d0: 74 73 35 50 6f 73 6c 69 73 74 52 65 61 64 65 72  ts5PoslistReader
98e0: 20 2a 61 49 74 65 72 3b 20 20 20 20 20 2f 2a 20   *aIter;     /* 
98f0: 4f 6e 65 20 69 74 65 72 61 74 6f 72 20 66 6f 72  One iterator for
9900: 20 65 61 63 68 20 70 68 72 61 73 65 20 2a 2f 0a   each phrase */.
9910: 20 20 20 20 69 6e 74 20 6e 49 74 65 72 3b 20 20      int nIter;  
9920: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9930: 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 69    /* Number of i
9940: 74 65 72 61 74 6f 72 73 2f 70 68 72 61 73 65 73  terators/phrases
9950: 20 2a 2f 0a 20 20 20 20 69 6e 74 20 6e 42 79 74   */.    int nByt
9960: 65 3b 0a 20 20 20 20 0a 20 20 20 20 6e 49 74 65  e;.    .    nIte
9970: 72 20 3d 20 73 71 6c 69 74 65 33 46 74 73 35 45  r = sqlite3Fts5E
9980: 78 70 72 50 68 72 61 73 65 43 6f 75 6e 74 28 70  xprPhraseCount(p
9990: 43 73 72 2d 3e 70 45 78 70 72 29 3b 0a 20 20 20  Csr->pExpr);.   
99a0: 20 6e 42 79 74 65 20 3d 20 73 69 7a 65 6f 66 28   nByte = sizeof(
99b0: 46 74 73 35 50 6f 73 6c 69 73 74 52 65 61 64 65  Fts5PoslistReade
99c0: 72 29 20 2a 20 6e 49 74 65 72 3b 0a 20 20 20 20  r) * nIter;.    
99d0: 61 49 74 65 72 20 3d 20 28 46 74 73 35 50 6f 73  aIter = (Fts5Pos
99e0: 6c 69 73 74 52 65 61 64 65 72 2a 29 73 71 6c 69  listReader*)sqli
99f0: 74 65 33 46 74 73 35 4d 61 6c 6c 6f 63 5a 65 72  te3Fts5MallocZer
9a00: 6f 28 26 72 63 2c 20 6e 42 79 74 65 29 3b 0a 20  o(&rc, nByte);. 
9a10: 20 20 20 69 66 28 20 61 49 74 65 72 20 29 7b 0a     if( aIter ){.
9a20: 20 20 20 20 20 20 46 74 73 35 42 75 66 66 65 72        Fts5Buffer
9a30: 20 62 75 66 20 3d 20 7b 30 2c 20 30 2c 20 30 7d   buf = {0, 0, 0}
9a40: 3b 20 2f 2a 20 42 75 69 6c 64 20 75 70 20 61 49  ; /* Build up aI
9a50: 6e 73 74 5b 5d 20 68 65 72 65 20 2a 2f 0a 20 20  nst[] here */.  
9a60: 20 20 20 20 69 6e 74 20 6e 49 6e 73 74 20 3d 20      int nInst = 
9a70: 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0;              
9a80: 2f 2a 20 4e 75 6d 62 65 72 20 69 6e 73 74 61 6e  /* Number instan
9a90: 63 65 73 20 73 65 65 6e 20 73 6f 20 66 61 72 20  ces seen so far 
9aa0: 2a 2f 0a 20 20 20 20 20 20 69 6e 74 20 69 3b 0a  */.      int i;.
9ab0: 0a 20 20 20 20 20 20 2f 2a 20 49 6e 69 74 69 61  .      /* Initia
9ac0: 6c 69 7a 65 20 61 6c 6c 20 69 74 65 72 61 74 6f  lize all iterato
9ad0: 72 73 20 2a 2f 0a 20 20 20 20 20 20 66 6f 72 28  rs */.      for(
9ae0: 69 3d 30 3b 20 69 3c 6e 49 74 65 72 3b 20 69 2b  i=0; i<nIter; i+
9af0: 2b 29 7b 0a 20 20 20 20 20 20 20 20 63 6f 6e 73  +){.        cons
9b00: 74 20 75 38 20 2a 61 3b 0a 20 20 20 20 20 20 20  t u8 *a;.       
9b10: 20 69 6e 74 20 6e 20 3d 20 66 74 73 35 43 73 72   int n = fts5Csr
9b20: 50 6f 73 6c 69 73 74 28 70 43 73 72 2c 20 69 2c  Poslist(pCsr, i,
9b30: 20 26 61 29 3b 0a 20 20 20 20 20 20 20 20 73 71   &a);.        sq
9b40: 6c 69 74 65 33 46 74 73 35 50 6f 73 6c 69 73 74  lite3Fts5Poslist
9b50: 52 65 61 64 65 72 49 6e 69 74 28 2d 31 2c 20 61  ReaderInit(-1, a
9b60: 2c 20 6e 2c 20 26 61 49 74 65 72 5b 69 5d 29 3b  , n, &aIter[i]);
9b70: 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20  .      }..      
9b80: 77 68 69 6c 65 28 20 31 20 29 7b 0a 20 20 20 20  while( 1 ){.    
9b90: 20 20 20 20 69 6e 74 20 2a 61 49 6e 73 74 3b 0a      int *aInst;.
9ba0: 20 20 20 20 20 20 20 20 69 6e 74 20 69 42 65 73          int iBes
9bb0: 74 20 3d 20 2d 31 3b 0a 20 20 20 20 20 20 20 20  t = -1;.        
9bc0: 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 49 74 65 72  for(i=0; i<nIter
9bd0: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20  ; i++){.        
9be0: 20 20 69 66 28 20 28 61 49 74 65 72 5b 69 5d 2e    if( (aIter[i].
9bf0: 62 45 6f 66 3d 3d 30 29 20 0a 20 20 20 20 20 20  bEof==0) .      
9c00: 20 20 20 20 20 26 26 20 28 69 42 65 73 74 3c 30       && (iBest<0
9c10: 20 7c 7c 20 61 49 74 65 72 5b 69 5d 2e 69 50 6f   || aIter[i].iPo
9c20: 73 3c 61 49 74 65 72 5b 69 42 65 73 74 5d 2e 69  s<aIter[iBest].i
9c30: 50 6f 73 29 20 0a 20 20 20 20 20 20 20 20 20 20  Pos) .          
9c40: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 69  ){.            i
9c50: 42 65 73 74 20 3d 20 69 3b 0a 20 20 20 20 20 20  Best = i;.      
9c60: 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 7d 0a      }.        }.
9c70: 0a 20 20 20 20 20 20 20 20 69 66 28 20 69 42 65  .        if( iBe
9c80: 73 74 3c 30 20 29 20 62 72 65 61 6b 3b 0a 20 20  st<0 ) break;.  
9c90: 20 20 20 20 20 20 6e 49 6e 73 74 2b 2b 3b 0a 20        nInst++;. 
9ca0: 20 20 20 20 20 20 20 69 66 28 20 73 71 6c 69 74         if( sqlit
9cb0: 65 33 46 74 73 35 42 75 66 66 65 72 47 72 6f 77  e3Fts5BufferGrow
9cc0: 28 26 72 63 2c 20 26 62 75 66 2c 20 6e 49 6e 73  (&rc, &buf, nIns
9cd0: 74 20 2a 20 73 69 7a 65 6f 66 28 69 6e 74 29 20  t * sizeof(int) 
9ce0: 2a 20 33 29 20 29 20 62 72 65 61 6b 3b 0a 0a 20  * 3) ) break;.. 
9cf0: 20 20 20 20 20 20 20 61 49 6e 73 74 20 3d 20 26         aInst = &
9d00: 28 28 69 6e 74 2a 29 62 75 66 2e 70 29 5b 33 20  ((int*)buf.p)[3 
9d10: 2a 20 28 6e 49 6e 73 74 2d 31 29 5d 3b 0a 20 20  * (nInst-1)];.  
9d20: 20 20 20 20 20 20 61 49 6e 73 74 5b 30 5d 20 3d        aInst[0] =
9d30: 20 69 42 65 73 74 3b 0a 20 20 20 20 20 20 20 20   iBest;.        
9d40: 61 49 6e 73 74 5b 31 5d 20 3d 20 46 54 53 35 5f  aInst[1] = FTS5_
9d50: 50 4f 53 32 43 4f 4c 55 4d 4e 28 61 49 74 65 72  POS2COLUMN(aIter
9d60: 5b 69 42 65 73 74 5d 2e 69 50 6f 73 29 3b 0a 20  [iBest].iPos);. 
9d70: 20 20 20 20 20 20 20 61 49 6e 73 74 5b 32 5d 20         aInst[2] 
9d80: 3d 20 46 54 53 35 5f 50 4f 53 32 4f 46 46 53 45  = FTS5_POS2OFFSE
9d90: 54 28 61 49 74 65 72 5b 69 42 65 73 74 5d 2e 69  T(aIter[iBest].i
9da0: 50 6f 73 29 3b 0a 20 20 20 20 20 20 20 20 73 71  Pos);.        sq
9db0: 6c 69 74 65 33 46 74 73 35 50 6f 73 6c 69 73 74  lite3Fts5Poslist
9dc0: 52 65 61 64 65 72 4e 65 78 74 28 26 61 49 74 65  ReaderNext(&aIte
9dd0: 72 5b 69 42 65 73 74 5d 29 3b 0a 20 20 20 20 20  r[iBest]);.     
9de0: 20 7d 0a 0a 20 20 20 20 20 20 70 43 73 72 2d 3e   }..      pCsr->
9df0: 61 49 6e 73 74 20 3d 20 28 69 6e 74 2a 29 62 75  aInst = (int*)bu
9e00: 66 2e 70 3b 0a 20 20 20 20 20 20 70 43 73 72 2d  f.p;.      pCsr-
9e10: 3e 6e 49 6e 73 74 43 6f 75 6e 74 20 3d 20 6e 49  >nInstCount = nI
9e20: 6e 73 74 3b 0a 20 20 20 20 20 20 73 71 6c 69 74  nst;.      sqlit
9e30: 65 33 5f 66 72 65 65 28 61 49 74 65 72 29 3b 0a  e3_free(aIter);.
9e40: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75      }.  }.  retu
9e50: 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63  rn rc;.}..static
9e60: 20 69 6e 74 20 66 74 73 35 41 70 69 49 6e 73 74   int fts5ApiInst
9e70: 43 6f 75 6e 74 28 46 74 73 35 43 6f 6e 74 65 78  Count(Fts5Contex
9e80: 74 20 2a 70 43 74 78 2c 20 69 6e 74 20 2a 70 6e  t *pCtx, int *pn
9e90: 49 6e 73 74 29 7b 0a 20 20 46 74 73 35 43 75 72  Inst){.  Fts5Cur
9ea0: 73 6f 72 20 2a 70 43 73 72 20 3d 20 28 46 74 73  sor *pCsr = (Fts
9eb0: 35 43 75 72 73 6f 72 2a 29 70 43 74 78 3b 0a 20  5Cursor*)pCtx;. 
9ec0: 20 69 6e 74 20 72 63 3b 0a 20 20 69 66 28 20 53   int rc;.  if( S
9ed0: 51 4c 49 54 45 5f 4f 4b 3d 3d 28 72 63 20 3d 20  QLITE_OK==(rc = 
9ee0: 66 74 73 35 43 61 63 68 65 49 6e 73 74 41 72 72  fts5CacheInstArr
9ef0: 61 79 28 70 43 73 72 29 29 20 29 7b 0a 20 20 20  ay(pCsr)) ){.   
9f00: 20 2a 70 6e 49 6e 73 74 20 3d 20 70 43 73 72 2d   *pnInst = pCsr-
9f10: 3e 6e 49 6e 73 74 43 6f 75 6e 74 3b 0a 20 20 7d  >nInstCount;.  }
9f20: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
9f30: 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35  .static int fts5
9f40: 41 70 69 49 6e 73 74 28 0a 20 20 46 74 73 35 43  ApiInst(.  Fts5C
9f50: 6f 6e 74 65 78 74 20 2a 70 43 74 78 2c 20 0a 20  ontext *pCtx, . 
9f60: 20 69 6e 74 20 69 49 64 78 2c 20 0a 20 20 69 6e   int iIdx, .  in
9f70: 74 20 2a 70 69 50 68 72 61 73 65 2c 20 0a 20 20  t *piPhrase, .  
9f80: 69 6e 74 20 2a 70 69 43 6f 6c 2c 20 0a 20 20 69  int *piCol, .  i
9f90: 6e 74 20 2a 70 69 4f 66 66 0a 29 7b 0a 20 20 46  nt *piOff.){.  F
9fa0: 74 73 35 43 75 72 73 6f 72 20 2a 70 43 73 72 20  ts5Cursor *pCsr 
9fb0: 3d 20 28 46 74 73 35 43 75 72 73 6f 72 2a 29 70  = (Fts5Cursor*)p
9fc0: 43 74 78 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 20  Ctx;.  int rc;. 
9fd0: 20 69 66 28 20 53 51 4c 49 54 45 5f 4f 4b 3d 3d   if( SQLITE_OK==
9fe0: 28 72 63 20 3d 20 66 74 73 35 43 61 63 68 65 49  (rc = fts5CacheI
9ff0: 6e 73 74 41 72 72 61 79 28 70 43 73 72 29 29 20  nstArray(pCsr)) 
a000: 29 7b 0a 20 20 20 20 69 66 28 20 69 49 64 78 3c  ){.    if( iIdx<
a010: 30 20 7c 7c 20 69 49 64 78 3e 3d 70 43 73 72 2d  0 || iIdx>=pCsr-
a020: 3e 6e 49 6e 73 74 43 6f 75 6e 74 20 29 7b 0a 20  >nInstCount ){. 
a030: 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45       rc = SQLITE
a040: 5f 52 41 4e 47 45 3b 0a 20 20 20 20 7d 65 6c 73  _RANGE;.    }els
a050: 65 7b 0a 20 20 20 20 20 20 2a 70 69 50 68 72 61  e{.      *piPhra
a060: 73 65 20 3d 20 70 43 73 72 2d 3e 61 49 6e 73 74  se = pCsr->aInst
a070: 5b 69 49 64 78 2a 33 5d 3b 0a 20 20 20 20 20 20  [iIdx*3];.      
a080: 2a 70 69 43 6f 6c 20 3d 20 70 43 73 72 2d 3e 61  *piCol = pCsr->a
a090: 49 6e 73 74 5b 69 49 64 78 2a 33 20 2b 20 31 5d  Inst[iIdx*3 + 1]
a0a0: 3b 0a 20 20 20 20 20 20 2a 70 69 4f 66 66 20 3d  ;.      *piOff =
a0b0: 20 70 43 73 72 2d 3e 61 49 6e 73 74 5b 69 49 64   pCsr->aInst[iId
a0c0: 78 2a 33 20 2b 20 32 5d 3b 0a 20 20 20 20 7d 0a  x*3 + 2];.    }.
a0d0: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b    }.  return rc;
a0e0: 0a 7d 0a 0a 73 74 61 74 69 63 20 73 71 6c 69 74  .}..static sqlit
a0f0: 65 33 5f 69 6e 74 36 34 20 66 74 73 35 41 70 69  e3_int64 fts5Api
a100: 52 6f 77 69 64 28 46 74 73 35 43 6f 6e 74 65 78  Rowid(Fts5Contex
a110: 74 20 2a 70 43 74 78 29 7b 0a 20 20 72 65 74 75  t *pCtx){.  retu
a120: 72 6e 20 66 74 73 35 43 75 72 73 6f 72 52 6f 77  rn fts5CursorRow
a130: 69 64 28 28 46 74 73 35 43 75 72 73 6f 72 2a 29  id((Fts5Cursor*)
a140: 70 43 74 78 29 3b 0a 7d 0a 0a 73 74 61 74 69 63  pCtx);.}..static
a150: 20 69 6e 74 20 66 74 73 35 41 70 69 43 6f 6c 75   int fts5ApiColu
a160: 6d 6e 54 65 78 74 28 0a 20 20 46 74 73 35 43 6f  mnText(.  Fts5Co
a170: 6e 74 65 78 74 20 2a 70 43 74 78 2c 20 0a 20 20  ntext *pCtx, .  
a180: 69 6e 74 20 69 43 6f 6c 2c 20 0a 20 20 63 6f 6e  int iCol, .  con
a190: 73 74 20 63 68 61 72 20 2a 2a 70 7a 2c 20 0a 20  st char **pz, . 
a1a0: 20 69 6e 74 20 2a 70 6e 0a 29 7b 0a 20 20 46 74   int *pn.){.  Ft
a1b0: 73 35 43 75 72 73 6f 72 20 2a 70 43 73 72 20 3d  s5Cursor *pCsr =
a1c0: 20 28 46 74 73 35 43 75 72 73 6f 72 2a 29 70 43   (Fts5Cursor*)pC
a1d0: 74 78 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 66  tx;.  int rc = f
a1e0: 74 73 35 53 65 65 6b 43 75 72 73 6f 72 28 70 43  ts5SeekCursor(pC
a1f0: 73 72 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53  sr);.  if( rc==S
a200: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
a210: 2a 70 7a 20 3d 20 28 63 6f 6e 73 74 20 63 68 61  *pz = (const cha
a220: 72 2a 29 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d  r*)sqlite3_colum
a230: 6e 5f 74 65 78 74 28 70 43 73 72 2d 3e 70 53 74  n_text(pCsr->pSt
a240: 6d 74 2c 20 69 43 6f 6c 2b 31 29 3b 0a 20 20 20  mt, iCol+1);.   
a250: 20 2a 70 6e 20 3d 20 73 71 6c 69 74 65 33 5f 63   *pn = sqlite3_c
a260: 6f 6c 75 6d 6e 5f 62 79 74 65 73 28 70 43 73 72  olumn_bytes(pCsr
a270: 2d 3e 70 53 74 6d 74 2c 20 69 43 6f 6c 2b 31 29  ->pStmt, iCol+1)
a280: 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72  ;.  }.  return r
a290: 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  c;.}..static int
a2a0: 20 66 74 73 35 41 70 69 43 6f 6c 75 6d 6e 53 69   fts5ApiColumnSi
a2b0: 7a 65 28 46 74 73 35 43 6f 6e 74 65 78 74 20 2a  ze(Fts5Context *
a2c0: 70 43 74 78 2c 20 69 6e 74 20 69 43 6f 6c 2c 20  pCtx, int iCol, 
a2d0: 69 6e 74 20 2a 70 6e 54 6f 6b 65 6e 29 7b 0a 20  int *pnToken){. 
a2e0: 20 46 74 73 35 43 75 72 73 6f 72 20 2a 70 43 73   Fts5Cursor *pCs
a2f0: 72 20 3d 20 28 46 74 73 35 43 75 72 73 6f 72 2a  r = (Fts5Cursor*
a300: 29 70 43 74 78 3b 0a 20 20 46 74 73 35 54 61 62  )pCtx;.  Fts5Tab
a310: 6c 65 20 2a 70 54 61 62 20 3d 20 28 46 74 73 35  le *pTab = (Fts5
a320: 54 61 62 6c 65 2a 29 28 70 43 73 72 2d 3e 62 61  Table*)(pCsr->ba
a330: 73 65 2e 70 56 74 61 62 29 3b 0a 20 20 69 6e 74  se.pVtab);.  int
a340: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
a350: 0a 0a 20 20 69 66 28 20 43 73 72 46 6c 61 67 54  ..  if( CsrFlagT
a360: 65 73 74 28 70 43 73 72 2c 20 46 54 53 35 43 53  est(pCsr, FTS5CS
a370: 52 5f 52 45 51 55 49 52 45 5f 44 4f 43 53 49 5a  R_REQUIRE_DOCSIZ
a380: 45 29 20 29 7b 0a 20 20 20 20 69 36 34 20 69 52  E) ){.    i64 iR
a390: 6f 77 69 64 20 3d 20 66 74 73 35 43 75 72 73 6f  owid = fts5Curso
a3a0: 72 52 6f 77 69 64 28 70 43 73 72 29 3b 0a 20 20  rRowid(pCsr);.  
a3b0: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 46 74    rc = sqlite3Ft
a3c0: 73 35 53 74 6f 72 61 67 65 44 6f 63 73 69 7a 65  s5StorageDocsize
a3d0: 28 70 54 61 62 2d 3e 70 53 74 6f 72 61 67 65 2c  (pTab->pStorage,
a3e0: 20 69 52 6f 77 69 64 2c 20 70 43 73 72 2d 3e 61   iRowid, pCsr->a
a3f0: 43 6f 6c 75 6d 6e 53 69 7a 65 29 3b 0a 20 20 7d  ColumnSize);.  }
a400: 0a 20 20 69 66 28 20 69 43 6f 6c 3c 30 20 29 7b  .  if( iCol<0 ){
a410: 0a 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20  .    int i;.    
a420: 2a 70 6e 54 6f 6b 65 6e 20 3d 20 30 3b 0a 20 20  *pnToken = 0;.  
a430: 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70 54 61    for(i=0; i<pTa
a440: 62 2d 3e 70 43 6f 6e 66 69 67 2d 3e 6e 43 6f 6c  b->pConfig->nCol
a450: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 2a 70  ; i++){.      *p
a460: 6e 54 6f 6b 65 6e 20 2b 3d 20 70 43 73 72 2d 3e  nToken += pCsr->
a470: 61 43 6f 6c 75 6d 6e 53 69 7a 65 5b 69 5d 3b 0a  aColumnSize[i];.
a480: 20 20 20 20 7d 0a 20 20 7d 65 6c 73 65 20 69 66      }.  }else if
a490: 28 20 69 43 6f 6c 3c 70 54 61 62 2d 3e 70 43 6f  ( iCol<pTab->pCo
a4a0: 6e 66 69 67 2d 3e 6e 43 6f 6c 20 29 7b 0a 20 20  nfig->nCol ){.  
a4b0: 20 20 2a 70 6e 54 6f 6b 65 6e 20 3d 20 70 43 73    *pnToken = pCs
a4c0: 72 2d 3e 61 43 6f 6c 75 6d 6e 53 69 7a 65 5b 69  r->aColumnSize[i
a4d0: 43 6f 6c 5d 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  Col];.  }else{. 
a4e0: 20 20 20 2a 70 6e 54 6f 6b 65 6e 20 3d 20 30 3b     *pnToken = 0;
a4f0: 0a 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45  .    rc = SQLITE
a500: 5f 52 41 4e 47 45 3b 0a 20 20 7d 0a 20 20 72 65  _RANGE;.  }.  re
a510: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74  turn rc;.}..stat
a520: 69 63 20 69 6e 74 20 66 74 73 35 41 70 69 53 65  ic int fts5ApiSe
a530: 74 41 75 78 64 61 74 61 28 0a 20 20 46 74 73 35  tAuxdata(.  Fts5
a540: 43 6f 6e 74 65 78 74 20 2a 70 43 74 78 2c 20 20  Context *pCtx,  
a550: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46              /* F
a560: 74 73 35 20 63 6f 6e 74 65 78 74 20 2a 2f 0a 20  ts5 context */. 
a570: 20 76 6f 69 64 20 2a 70 50 74 72 2c 20 20 20 20   void *pPtr,    
a580: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a590: 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 73   /* Pointer to s
a5a0: 61 76 65 20 61 73 20 61 75 78 64 61 74 61 20 2a  ave as auxdata *
a5b0: 2f 0a 20 20 76 6f 69 64 28 2a 78 44 65 6c 65 74  /.  void(*xDelet
a5c0: 65 29 28 76 6f 69 64 2a 29 20 20 20 20 20 20 20  e)(void*)       
a5d0: 20 20 20 20 2f 2a 20 44 65 73 74 72 75 63 74 6f      /* Destructo
a5e0: 72 20 66 6f 72 20 70 50 74 72 20 28 6f 72 20 4e  r for pPtr (or N
a5f0: 55 4c 4c 29 20 2a 2f 0a 29 7b 0a 20 20 46 74 73  ULL) */.){.  Fts
a600: 35 43 75 72 73 6f 72 20 2a 70 43 73 72 20 3d 20  5Cursor *pCsr = 
a610: 28 46 74 73 35 43 75 72 73 6f 72 2a 29 70 43 74  (Fts5Cursor*)pCt
a620: 78 3b 0a 20 20 46 74 73 35 41 75 78 64 61 74 61  x;.  Fts5Auxdata
a630: 20 2a 70 44 61 74 61 3b 0a 0a 20 20 66 6f 72 28   *pData;..  for(
a640: 70 44 61 74 61 3d 70 43 73 72 2d 3e 70 41 75 78  pData=pCsr->pAux
a650: 64 61 74 61 3b 20 70 44 61 74 61 3b 20 70 44 61  data; pData; pDa
a660: 74 61 3d 70 44 61 74 61 2d 3e 70 4e 65 78 74 29  ta=pData->pNext)
a670: 7b 0a 20 20 20 20 69 66 28 20 70 44 61 74 61 2d  {.    if( pData-
a680: 3e 70 41 75 78 3d 3d 70 43 73 72 2d 3e 70 41 75  >pAux==pCsr->pAu
a690: 78 20 29 20 62 72 65 61 6b 3b 0a 20 20 7d 0a 0a  x ) break;.  }..
a6a0: 20 20 69 66 28 20 70 44 61 74 61 20 29 7b 0a 20    if( pData ){. 
a6b0: 20 20 20 69 66 28 20 70 44 61 74 61 2d 3e 78 44     if( pData->xD
a6c0: 65 6c 65 74 65 20 29 7b 0a 20 20 20 20 20 20 70  elete ){.      p
a6d0: 44 61 74 61 2d 3e 78 44 65 6c 65 74 65 28 70 44  Data->xDelete(pD
a6e0: 61 74 61 2d 3e 70 50 74 72 29 3b 0a 20 20 20 20  ata->pPtr);.    
a6f0: 7d 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 70  }.  }else{.    p
a700: 44 61 74 61 20 3d 20 28 46 74 73 35 41 75 78 64  Data = (Fts5Auxd
a710: 61 74 61 2a 29 73 71 6c 69 74 65 33 5f 6d 61 6c  ata*)sqlite3_mal
a720: 6c 6f 63 28 73 69 7a 65 6f 66 28 46 74 73 35 41  loc(sizeof(Fts5A
a730: 75 78 64 61 74 61 29 29 3b 0a 20 20 20 20 69 66  uxdata));.    if
a740: 28 20 70 44 61 74 61 3d 3d 30 20 29 7b 0a 20 20  ( pData==0 ){.  
a750: 20 20 20 20 69 66 28 20 78 44 65 6c 65 74 65 20      if( xDelete 
a760: 29 20 78 44 65 6c 65 74 65 28 70 50 74 72 29 3b  ) xDelete(pPtr);
a770: 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 53 51  .      return SQ
a780: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20  LITE_NOMEM;.    
a790: 7d 0a 20 20 20 20 6d 65 6d 73 65 74 28 70 44 61  }.    memset(pDa
a7a0: 74 61 2c 20 30 2c 20 73 69 7a 65 6f 66 28 46 74  ta, 0, sizeof(Ft
a7b0: 73 35 41 75 78 64 61 74 61 29 29 3b 0a 20 20 20  s5Auxdata));.   
a7c0: 20 70 44 61 74 61 2d 3e 70 41 75 78 20 3d 20 70   pData->pAux = p
a7d0: 43 73 72 2d 3e 70 41 75 78 3b 0a 20 20 20 20 70  Csr->pAux;.    p
a7e0: 44 61 74 61 2d 3e 70 4e 65 78 74 20 3d 20 70 43  Data->pNext = pC
a7f0: 73 72 2d 3e 70 41 75 78 64 61 74 61 3b 0a 20 20  sr->pAuxdata;.  
a800: 20 20 70 43 73 72 2d 3e 70 41 75 78 64 61 74 61    pCsr->pAuxdata
a810: 20 3d 20 70 44 61 74 61 3b 0a 20 20 7d 0a 0a 20   = pData;.  }.. 
a820: 20 70 44 61 74 61 2d 3e 78 44 65 6c 65 74 65 20   pData->xDelete 
a830: 3d 20 78 44 65 6c 65 74 65 3b 0a 20 20 70 44 61  = xDelete;.  pDa
a840: 74 61 2d 3e 70 50 74 72 20 3d 20 70 50 74 72 3b  ta->pPtr = pPtr;
a850: 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  .  return SQLITE
a860: 5f 4f 4b 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76  _OK;.}..static v
a870: 6f 69 64 20 2a 66 74 73 35 41 70 69 47 65 74 41  oid *fts5ApiGetA
a880: 75 78 64 61 74 61 28 46 74 73 35 43 6f 6e 74 65  uxdata(Fts5Conte
a890: 78 74 20 2a 70 43 74 78 2c 20 69 6e 74 20 62 43  xt *pCtx, int bC
a8a0: 6c 65 61 72 29 7b 0a 20 20 46 74 73 35 43 75 72  lear){.  Fts5Cur
a8b0: 73 6f 72 20 2a 70 43 73 72 20 3d 20 28 46 74 73  sor *pCsr = (Fts
a8c0: 35 43 75 72 73 6f 72 2a 29 70 43 74 78 3b 0a 20  5Cursor*)pCtx;. 
a8d0: 20 46 74 73 35 41 75 78 64 61 74 61 20 2a 70 44   Fts5Auxdata *pD
a8e0: 61 74 61 3b 0a 20 20 76 6f 69 64 20 2a 70 52 65  ata;.  void *pRe
a8f0: 74 20 3d 20 30 3b 0a 0a 20 20 66 6f 72 28 70 44  t = 0;..  for(pD
a900: 61 74 61 3d 70 43 73 72 2d 3e 70 41 75 78 64 61  ata=pCsr->pAuxda
a910: 74 61 3b 20 70 44 61 74 61 3b 20 70 44 61 74 61  ta; pData; pData
a920: 3d 70 44 61 74 61 2d 3e 70 4e 65 78 74 29 7b 0a  =pData->pNext){.
a930: 20 20 20 20 69 66 28 20 70 44 61 74 61 2d 3e 70      if( pData->p
a940: 41 75 78 3d 3d 70 43 73 72 2d 3e 70 41 75 78 20  Aux==pCsr->pAux 
a950: 29 20 62 72 65 61 6b 3b 0a 20 20 7d 0a 0a 20 20  ) break;.  }..  
a960: 69 66 28 20 70 44 61 74 61 20 29 7b 0a 20 20 20  if( pData ){.   
a970: 20 70 52 65 74 20 3d 20 70 44 61 74 61 2d 3e 70   pRet = pData->p
a980: 50 74 72 3b 0a 20 20 20 20 69 66 28 20 62 43 6c  Ptr;.    if( bCl
a990: 65 61 72 20 29 7b 0a 20 20 20 20 20 20 70 44 61  ear ){.      pDa
a9a0: 74 61 2d 3e 70 50 74 72 20 3d 20 30 3b 0a 20 20  ta->pPtr = 0;.  
a9b0: 20 20 20 20 70 44 61 74 61 2d 3e 78 44 65 6c 65      pData->xDele
a9c0: 74 65 20 3d 20 30 3b 0a 20 20 20 20 7d 0a 20 20  te = 0;.    }.  
a9d0: 7d 0a 0a 20 20 72 65 74 75 72 6e 20 70 52 65 74  }..  return pRet
a9e0: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  ;.}..static int 
a9f0: 66 74 73 35 41 70 69 51 75 65 72 79 50 68 72 61  fts5ApiQueryPhra
aa00: 73 65 28 46 74 73 35 43 6f 6e 74 65 78 74 2a 2c  se(Fts5Context*,
aa10: 20 69 6e 74 2c 20 76 6f 69 64 2a 2c 20 0a 20 20   int, void*, .  
aa20: 20 20 69 6e 74 28 2a 29 28 63 6f 6e 73 74 20 46    int(*)(const F
aa30: 74 73 35 45 78 74 65 6e 73 69 6f 6e 41 70 69 2a  ts5ExtensionApi*
aa40: 2c 20 46 74 73 35 43 6f 6e 74 65 78 74 2a 2c 20  , Fts5Context*, 
aa50: 76 6f 69 64 2a 29 0a 29 3b 0a 0a 73 74 61 74 69  void*).);..stati
aa60: 63 20 63 6f 6e 73 74 20 46 74 73 35 45 78 74 65  c const Fts5Exte
aa70: 6e 73 69 6f 6e 41 70 69 20 73 46 74 73 35 41 70  nsionApi sFts5Ap
aa80: 69 20 3d 20 7b 0a 20 20 31 2c 20 20 20 20 20 20  i = {.  1,      
aa90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
aaa0: 20 20 20 20 20 20 2f 2a 20 69 56 65 72 73 69 6f        /* iVersio
aab0: 6e 20 2a 2f 0a 20 20 66 74 73 35 41 70 69 55 73  n */.  fts5ApiUs
aac0: 65 72 44 61 74 61 2c 0a 20 20 66 74 73 35 41 70  erData,.  fts5Ap
aad0: 69 43 6f 6c 75 6d 6e 43 6f 75 6e 74 2c 0a 20 20  iColumnCount,.  
aae0: 66 74 73 35 41 70 69 52 6f 77 43 6f 75 6e 74 2c  fts5ApiRowCount,
aaf0: 0a 20 20 66 74 73 35 41 70 69 43 6f 6c 75 6d 6e  .  fts5ApiColumn
ab00: 54 6f 74 61 6c 53 69 7a 65 2c 0a 20 20 66 74 73  TotalSize,.  fts
ab10: 35 41 70 69 54 6f 6b 65 6e 69 7a 65 2c 0a 20 20  5ApiTokenize,.  
ab20: 66 74 73 35 41 70 69 50 68 72 61 73 65 43 6f 75  fts5ApiPhraseCou
ab30: 6e 74 2c 0a 20 20 66 74 73 35 41 70 69 50 68 72  nt,.  fts5ApiPhr
ab40: 61 73 65 53 69 7a 65 2c 0a 20 20 66 74 73 35 41  aseSize,.  fts5A
ab50: 70 69 49 6e 73 74 43 6f 75 6e 74 2c 0a 20 20 66  piInstCount,.  f
ab60: 74 73 35 41 70 69 49 6e 73 74 2c 0a 20 20 66 74  ts5ApiInst,.  ft
ab70: 73 35 41 70 69 52 6f 77 69 64 2c 0a 20 20 66 74  s5ApiRowid,.  ft
ab80: 73 35 41 70 69 43 6f 6c 75 6d 6e 54 65 78 74 2c  s5ApiColumnText,
ab90: 0a 20 20 66 74 73 35 41 70 69 43 6f 6c 75 6d 6e  .  fts5ApiColumn
aba0: 53 69 7a 65 2c 0a 20 20 66 74 73 35 41 70 69 51  Size,.  fts5ApiQ
abb0: 75 65 72 79 50 68 72 61 73 65 2c 0a 20 20 66 74  ueryPhrase,.  ft
abc0: 73 35 41 70 69 53 65 74 41 75 78 64 61 74 61 2c  s5ApiSetAuxdata,
abd0: 0a 20 20 66 74 73 35 41 70 69 47 65 74 41 75 78  .  fts5ApiGetAux
abe0: 64 61 74 61 2c 0a 7d 3b 0a 0a 0a 2f 2a 0a 2a 2a  data,.};.../*.**
abf0: 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20   Implementation 
ac00: 6f 66 20 41 50 49 20 66 75 6e 63 74 69 6f 6e 20  of API function 
ac10: 78 51 75 65 72 79 50 68 72 61 73 65 28 29 2e 0a  xQueryPhrase()..
ac20: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74  */.static int ft
ac30: 73 35 41 70 69 51 75 65 72 79 50 68 72 61 73 65  s5ApiQueryPhrase
ac40: 28 0a 20 20 46 74 73 35 43 6f 6e 74 65 78 74 20  (.  Fts5Context 
ac50: 2a 70 43 74 78 2c 20 0a 20 20 69 6e 74 20 69 50  *pCtx, .  int iP
ac60: 68 72 61 73 65 2c 20 0a 20 20 76 6f 69 64 20 2a  hrase, .  void *
ac70: 70 55 73 65 72 44 61 74 61 2c 0a 20 20 69 6e 74  pUserData,.  int
ac80: 28 2a 78 43 61 6c 6c 62 61 63 6b 29 28 63 6f 6e  (*xCallback)(con
ac90: 73 74 20 46 74 73 35 45 78 74 65 6e 73 69 6f 6e  st Fts5Extension
aca0: 41 70 69 2a 2c 20 46 74 73 35 43 6f 6e 74 65 78  Api*, Fts5Contex
acb0: 74 2a 2c 20 76 6f 69 64 2a 29 0a 29 7b 0a 20 20  t*, void*).){.  
acc0: 46 74 73 35 43 75 72 73 6f 72 20 2a 70 43 73 72  Fts5Cursor *pCsr
acd0: 20 3d 20 28 46 74 73 35 43 75 72 73 6f 72 2a 29   = (Fts5Cursor*)
ace0: 70 43 74 78 3b 0a 20 20 46 74 73 35 54 61 62 6c  pCtx;.  Fts5Tabl
acf0: 65 20 2a 70 54 61 62 20 3d 20 28 46 74 73 35 54  e *pTab = (Fts5T
ad00: 61 62 6c 65 2a 29 28 70 43 73 72 2d 3e 62 61 73  able*)(pCsr->bas
ad10: 65 2e 70 56 74 61 62 29 3b 0a 20 20 69 6e 74 20  e.pVtab);.  int 
ad20: 72 63 3b 0a 20 20 46 74 73 35 43 75 72 73 6f 72  rc;.  Fts5Cursor
ad30: 20 2a 70 4e 65 77 20 3d 20 30 3b 0a 0a 20 20 72   *pNew = 0;..  r
ad40: 63 20 3d 20 66 74 73 35 4f 70 65 6e 4d 65 74 68  c = fts5OpenMeth
ad50: 6f 64 28 70 43 73 72 2d 3e 62 61 73 65 2e 70 56  od(pCsr->base.pV
ad60: 74 61 62 2c 20 28 73 71 6c 69 74 65 33 5f 76 74  tab, (sqlite3_vt
ad70: 61 62 5f 63 75 72 73 6f 72 2a 2a 29 26 70 4e 65  ab_cursor**)&pNe
ad80: 77 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51  w);.  if( rc==SQ
ad90: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 46  LITE_OK ){.    F
ada0: 74 73 35 43 6f 6e 66 69 67 20 2a 70 43 6f 6e 66  ts5Config *pConf
adb0: 20 3d 20 70 54 61 62 2d 3e 70 43 6f 6e 66 69 67   = pTab->pConfig
adc0: 3b 0a 20 20 20 20 70 4e 65 77 2d 3e 69 64 78 4e  ;.    pNew->idxN
add0: 75 6d 20 3d 20 46 54 53 35 5f 50 4c 41 4e 5f 4d  um = FTS5_PLAN_M
ade0: 41 54 43 48 3b 0a 20 20 20 20 70 4e 65 77 2d 3e  ATCH;.    pNew->
adf0: 62 61 73 65 2e 70 56 74 61 62 20 3d 20 28 73 71  base.pVtab = (sq
ae00: 6c 69 74 65 33 5f 76 74 61 62 2a 29 70 54 61 62  lite3_vtab*)pTab
ae10: 3b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74  ;.    rc = sqlit
ae20: 65 33 46 74 73 35 45 78 70 72 50 68 72 61 73 65  e3Fts5ExprPhrase
ae30: 45 78 70 72 28 70 43 6f 6e 66 2c 20 70 43 73 72  Expr(pConf, pCsr
ae40: 2d 3e 70 45 78 70 72 2c 20 69 50 68 72 61 73 65  ->pExpr, iPhrase
ae50: 2c 20 26 70 4e 65 77 2d 3e 70 45 78 70 72 29 3b  , &pNew->pExpr);
ae60: 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d  .  }..  if( rc==
ae70: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
ae80: 20 66 6f 72 28 72 63 20 3d 20 66 74 73 35 43 75   for(rc = fts5Cu
ae90: 72 73 6f 72 46 69 72 73 74 28 70 54 61 62 2c 20  rsorFirst(pTab, 
aea0: 70 4e 65 77 2c 20 30 29 3b 0a 20 20 20 20 20 20  pNew, 0);.      
aeb0: 20 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20    rc==SQLITE_OK 
aec0: 26 26 20 43 73 72 46 6c 61 67 54 65 73 74 28 70  && CsrFlagTest(p
aed0: 4e 65 77 2c 20 46 54 53 35 43 53 52 5f 45 4f 46  New, FTS5CSR_EOF
aee0: 29 3d 3d 30 3b 0a 20 20 20 20 20 20 20 20 72 63  )==0;.        rc
aef0: 20 3d 20 66 74 73 35 4e 65 78 74 4d 65 74 68 6f   = fts5NextMetho
af00: 64 28 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f  d((sqlite3_vtab_
af10: 63 75 72 73 6f 72 2a 29 70 4e 65 77 29 0a 20 20  cursor*)pNew).  
af20: 20 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20    ){.      rc = 
af30: 78 43 61 6c 6c 62 61 63 6b 28 26 73 46 74 73 35  xCallback(&sFts5
af40: 41 70 69 2c 20 28 46 74 73 35 43 6f 6e 74 65 78  Api, (Fts5Contex
af50: 74 2a 29 70 4e 65 77 2c 20 70 55 73 65 72 44 61  t*)pNew, pUserDa
af60: 74 61 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72  ta);.      if( r
af70: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c!=SQLITE_OK ){.
af80: 20 20 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d          if( rc==
af90: 53 51 4c 49 54 45 5f 44 4f 4e 45 20 29 20 72 63  SQLITE_DONE ) rc
afa0: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20   = SQLITE_OK;.  
afb0: 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20        break;.   
afc0: 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a     }.    }.  }..
afd0: 20 20 66 74 73 35 43 6c 6f 73 65 4d 65 74 68 6f    fts5CloseMetho
afe0: 64 28 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f  d((sqlite3_vtab_
aff0: 63 75 72 73 6f 72 2a 29 70 4e 65 77 29 3b 0a 20  cursor*)pNew);. 
b000: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73   return rc;.}..s
b010: 74 61 74 69 63 20 76 6f 69 64 20 66 74 73 35 41  tatic void fts5A
b020: 70 69 49 6e 76 6f 6b 65 28 0a 20 20 46 74 73 35  piInvoke(.  Fts5
b030: 41 75 78 69 6c 69 61 72 79 20 2a 70 41 75 78 2c  Auxiliary *pAux,
b040: 0a 20 20 46 74 73 35 43 75 72 73 6f 72 20 2a 70  .  Fts5Cursor *p
b050: 43 73 72 2c 0a 20 20 73 71 6c 69 74 65 33 5f 63  Csr,.  sqlite3_c
b060: 6f 6e 74 65 78 74 20 2a 63 6f 6e 74 65 78 74 2c  ontext *context,
b070: 0a 20 20 69 6e 74 20 61 72 67 63 2c 0a 20 20 73  .  int argc,.  s
b080: 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a 61  qlite3_value **a
b090: 72 67 76 0a 29 7b 0a 20 20 61 73 73 65 72 74 28  rgv.){.  assert(
b0a0: 20 70 43 73 72 2d 3e 70 41 75 78 3d 3d 30 20 29   pCsr->pAux==0 )
b0b0: 3b 0a 20 20 70 43 73 72 2d 3e 70 41 75 78 20 3d  ;.  pCsr->pAux =
b0c0: 20 70 41 75 78 3b 0a 20 20 70 41 75 78 2d 3e 78   pAux;.  pAux->x
b0d0: 46 75 6e 63 28 26 73 46 74 73 35 41 70 69 2c 20  Func(&sFts5Api, 
b0e0: 28 46 74 73 35 43 6f 6e 74 65 78 74 2a 29 70 43  (Fts5Context*)pC
b0f0: 73 72 2c 20 63 6f 6e 74 65 78 74 2c 20 61 72 67  sr, context, arg
b100: 63 2c 20 61 72 67 76 29 3b 0a 20 20 70 43 73 72  c, argv);.  pCsr
b110: 2d 3e 70 41 75 78 20 3d 20 30 3b 0a 7d 0a 0a 73  ->pAux = 0;.}..s
b120: 74 61 74 69 63 20 76 6f 69 64 20 66 74 73 35 41  tatic void fts5A
b130: 70 69 43 61 6c 6c 62 61 63 6b 28 0a 20 20 73 71  piCallback(.  sq
b140: 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74 20 2a 63  lite3_context *c
b150: 6f 6e 74 65 78 74 2c 0a 20 20 69 6e 74 20 61 72  ontext,.  int ar
b160: 67 63 2c 0a 20 20 73 71 6c 69 74 65 33 5f 76 61  gc,.  sqlite3_va
b170: 6c 75 65 20 2a 2a 61 72 67 76 0a 29 7b 0a 0a 20  lue **argv.){.. 
b180: 20 46 74 73 35 41 75 78 69 6c 69 61 72 79 20 2a   Fts5Auxiliary *
b190: 70 41 75 78 3b 0a 20 20 46 74 73 35 43 75 72 73  pAux;.  Fts5Curs
b1a0: 6f 72 20 2a 70 43 73 72 3b 0a 20 20 69 36 34 20  or *pCsr;.  i64 
b1b0: 69 43 73 72 49 64 3b 0a 0a 20 20 61 73 73 65 72  iCsrId;..  asser
b1c0: 74 28 20 61 72 67 63 3e 3d 31 20 29 3b 0a 20 20  t( argc>=1 );.  
b1d0: 70 41 75 78 20 3d 20 28 46 74 73 35 41 75 78 69  pAux = (Fts5Auxi
b1e0: 6c 69 61 72 79 2a 29 73 71 6c 69 74 65 33 5f 75  liary*)sqlite3_u
b1f0: 73 65 72 5f 64 61 74 61 28 63 6f 6e 74 65 78 74  ser_data(context
b200: 29 3b 0a 20 20 69 43 73 72 49 64 20 3d 20 73 71  );.  iCsrId = sq
b210: 6c 69 74 65 33 5f 76 61 6c 75 65 5f 69 6e 74 36  lite3_value_int6
b220: 34 28 61 72 67 76 5b 30 5d 29 3b 0a 0a 20 20 66  4(argv[0]);..  f
b230: 6f 72 28 70 43 73 72 3d 70 41 75 78 2d 3e 70 47  or(pCsr=pAux->pG
b240: 6c 6f 62 61 6c 2d 3e 70 43 73 72 3b 20 70 43 73  lobal->pCsr; pCs
b250: 72 3b 20 70 43 73 72 3d 70 43 73 72 2d 3e 70 4e  r; pCsr=pCsr->pN
b260: 65 78 74 29 7b 0a 20 20 20 20 69 66 28 20 70 43  ext){.    if( pC
b270: 73 72 2d 3e 69 43 73 72 49 64 3d 3d 69 43 73 72  sr->iCsrId==iCsr
b280: 49 64 20 29 20 62 72 65 61 6b 3b 0a 20 20 7d 0a  Id ) break;.  }.
b290: 20 20 69 66 28 20 70 43 73 72 3d 3d 30 20 29 7b    if( pCsr==0 ){
b2a0: 0a 20 20 20 20 63 68 61 72 20 2a 7a 45 72 72 20  .    char *zErr 
b2b0: 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74  = sqlite3_mprint
b2c0: 66 28 22 6e 6f 20 73 75 63 68 20 63 75 72 73 6f  f("no such curso
b2d0: 72 3a 20 25 6c 6c 64 22 2c 20 69 43 73 72 49 64  r: %lld", iCsrId
b2e0: 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 72  );.    sqlite3_r
b2f0: 65 73 75 6c 74 5f 65 72 72 6f 72 28 63 6f 6e 74  esult_error(cont
b300: 65 78 74 2c 20 7a 45 72 72 2c 20 2d 31 29 3b 0a  ext, zErr, -1);.
b310: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 66 74 73    }else{.    fts
b320: 35 41 70 69 49 6e 76 6f 6b 65 28 70 41 75 78 2c  5ApiInvoke(pAux,
b330: 20 70 43 73 72 2c 20 63 6f 6e 74 65 78 74 2c 20   pCsr, context, 
b340: 61 72 67 63 2d 31 2c 20 26 61 72 67 76 5b 31 5d  argc-1, &argv[1]
b350: 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  );.  }.}../*.** 
b360: 52 65 74 75 72 6e 20 61 20 22 70 6f 73 69 74 69  Return a "positi
b370: 6f 6e 2d 6c 69 73 74 20 62 6c 6f 62 22 20 63 6f  on-list blob" co
b380: 72 72 65 73 70 6f 6e 64 69 6e 67 20 74 6f 20 74  rresponding to t
b390: 68 65 20 63 75 72 72 65 6e 74 20 70 6f 73 69 74  he current posit
b3a0: 69 6f 6e 20 6f 66 0a 2a 2a 20 63 75 72 73 6f 72  ion of.** cursor
b3b0: 20 70 43 73 72 20 76 69 61 20 73 71 6c 69 74 65   pCsr via sqlite
b3c0: 33 5f 72 65 73 75 6c 74 5f 62 6c 6f 62 28 29 2e  3_result_blob().
b3d0: 20 41 20 70 6f 73 69 74 69 6f 6e 2d 6c 69 73 74   A position-list
b3e0: 20 62 6c 6f 62 20 63 6f 6e 74 61 69 6e 73 0a 2a   blob contains.*
b3f0: 2a 20 74 68 65 20 63 75 72 72 65 6e 74 20 70 6f  * the current po
b400: 73 69 74 69 6f 6e 2d 6c 69 73 74 20 66 6f 72 20  sition-list for 
b410: 65 61 63 68 20 70 68 72 61 73 65 20 69 6e 20 74  each phrase in t
b420: 68 65 20 71 75 65 72 79 20 61 73 73 6f 63 69 61  he query associa
b430: 74 65 64 20 77 69 74 68 0a 2a 2a 20 63 75 72 73  ted with.** curs
b440: 6f 72 20 70 43 73 72 2e 0a 2a 2a 0a 2a 2a 20 41  or pCsr..**.** A
b450: 20 70 6f 73 69 74 69 6f 6e 2d 6c 69 73 74 20 62   position-list b
b460: 6c 6f 62 20 62 65 67 69 6e 73 20 77 69 74 68 20  lob begins with 
b470: 28 6e 50 68 72 61 73 65 2d 31 29 20 76 61 72 69  (nPhrase-1) vari
b480: 6e 74 73 2c 20 77 68 65 72 65 20 6e 50 68 72 61  nts, where nPhra
b490: 73 65 20 69 73 0a 2a 2a 20 74 68 65 20 6e 75 6d  se is.** the num
b4a0: 62 65 72 20 6f 66 20 70 68 72 61 73 65 73 20 69  ber of phrases i
b4b0: 6e 20 74 68 65 20 71 75 65 72 79 2e 20 46 6f 6c  n the query. Fol
b4c0: 6c 6f 77 69 6e 67 20 74 68 65 20 76 61 72 69 6e  lowing the varin
b4d0: 74 73 20 61 72 65 20 74 68 65 0a 2a 2a 20 63 6f  ts are the.** co
b4e0: 6e 63 61 74 65 6e 61 74 65 64 20 70 6f 73 69 74  ncatenated posit
b4f0: 69 6f 6e 20 6c 69 73 74 73 20 66 6f 72 20 65 61  ion lists for ea
b500: 63 68 20 70 68 72 61 73 65 2c 20 69 6e 20 6f 72  ch phrase, in or
b510: 64 65 72 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 66  der..**.** The f
b520: 69 72 73 74 20 76 61 72 69 6e 74 20 28 69 66 20  irst varint (if 
b530: 69 74 20 65 78 69 73 74 73 29 20 63 6f 6e 74 61  it exists) conta
b540: 69 6e 73 20 74 68 65 20 73 69 7a 65 20 6f 66 20  ins the size of 
b550: 74 68 65 20 70 6f 73 69 74 69 6f 6e 20 6c 69 73  the position lis
b560: 74 0a 2a 2a 20 66 6f 72 20 70 68 72 61 73 65 20  t.** for phrase 
b570: 30 2e 20 54 68 65 20 73 65 63 6f 6e 64 20 28 73  0. The second (s
b580: 61 6d 65 20 64 69 73 63 6c 61 69 6d 65 72 29 20  ame disclaimer) 
b590: 63 6f 6e 74 61 69 6e 73 20 74 68 65 20 73 69 7a  contains the siz
b5a0: 65 20 6f 66 20 70 6f 73 69 74 69 6f 6e 0a 2a 2a  e of position.**
b5b0: 20 6c 69 73 74 20 31 2e 20 41 6e 64 20 73 6f 20   list 1. And so 
b5c0: 6f 6e 2e 20 54 68 65 72 65 20 69 73 20 6e 6f 20  on. There is no 
b5d0: 73 69 7a 65 20 66 69 65 6c 64 20 66 6f 72 20 74  size field for t
b5e0: 68 65 20 66 69 6e 61 6c 20 70 6f 73 69 74 69 6f  he final positio
b5f0: 6e 20 6c 69 73 74 2c 0a 2a 2a 20 61 73 20 69 74  n list,.** as it
b600: 20 63 61 6e 20 62 65 20 64 65 72 69 76 65 64 20   can be derived 
b610: 66 72 6f 6d 20 74 68 65 20 74 6f 74 61 6c 20 73  from the total s
b620: 69 7a 65 20 6f 66 20 74 68 65 20 62 6c 6f 62 2e  ize of the blob.
b630: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66  .*/.static int f
b640: 74 73 35 50 6f 73 6c 69 73 74 42 6c 6f 62 28 73  ts5PoslistBlob(s
b650: 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74 20 2a  qlite3_context *
b660: 70 43 74 78 2c 20 46 74 73 35 43 75 72 73 6f 72  pCtx, Fts5Cursor
b670: 20 2a 70 43 73 72 29 7b 0a 20 20 69 6e 74 20 69   *pCsr){.  int i
b680: 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c  ;.  int rc = SQL
b690: 49 54 45 5f 4f 4b 3b 0a 20 20 69 6e 74 20 6e 50  ITE_OK;.  int nP
b6a0: 68 72 61 73 65 20 3d 20 73 71 6c 69 74 65 33 46  hrase = sqlite3F
b6b0: 74 73 35 45 78 70 72 50 68 72 61 73 65 43 6f 75  ts5ExprPhraseCou
b6c0: 6e 74 28 70 43 73 72 2d 3e 70 45 78 70 72 29 3b  nt(pCsr->pExpr);
b6d0: 0a 20 20 46 74 73 35 42 75 66 66 65 72 20 76 61  .  Fts5Buffer va
b6e0: 6c 3b 0a 0a 20 20 6d 65 6d 73 65 74 28 26 76 61  l;..  memset(&va
b6f0: 6c 2c 20 30 2c 20 73 69 7a 65 6f 66 28 46 74 73  l, 0, sizeof(Fts
b700: 35 42 75 66 66 65 72 29 29 3b 0a 0a 20 20 2f 2a  5Buffer));..  /*
b710: 20 41 70 70 65 6e 64 20 74 68 65 20 76 61 72 69   Append the vari
b720: 6e 74 73 20 2a 2f 0a 20 20 66 6f 72 28 69 3d 30  nts */.  for(i=0
b730: 3b 20 69 3c 28 6e 50 68 72 61 73 65 2d 31 29 3b  ; i<(nPhrase-1);
b740: 20 69 2b 2b 29 7b 0a 20 20 20 20 63 6f 6e 73 74   i++){.    const
b750: 20 75 38 20 2a 64 75 6d 6d 79 3b 0a 20 20 20 20   u8 *dummy;.    
b760: 69 6e 74 20 6e 42 79 74 65 20 3d 20 73 71 6c 69  int nByte = sqli
b770: 74 65 33 46 74 73 35 45 78 70 72 50 6f 73 6c 69  te3Fts5ExprPosli
b780: 73 74 28 70 43 73 72 2d 3e 70 45 78 70 72 2c 20  st(pCsr->pExpr, 
b790: 69 2c 20 26 64 75 6d 6d 79 29 3b 0a 20 20 20 20  i, &dummy);.    
b7a0: 73 71 6c 69 74 65 33 46 74 73 35 42 75 66 66 65  sqlite3Fts5Buffe
b7b0: 72 41 70 70 65 6e 64 56 61 72 69 6e 74 28 26 72  rAppendVarint(&r
b7c0: 63 2c 20 26 76 61 6c 2c 20 6e 42 79 74 65 29 3b  c, &val, nByte);
b7d0: 0a 20 20 7d 0a 0a 20 20 2f 2a 20 41 70 70 65 6e  .  }..  /* Appen
b7e0: 64 20 74 68 65 20 70 6f 73 69 74 69 6f 6e 20 6c  d the position l
b7f0: 69 73 74 73 20 2a 2f 0a 20 20 66 6f 72 28 69 3d  ists */.  for(i=
b800: 30 3b 20 69 3c 6e 50 68 72 61 73 65 3b 20 69 2b  0; i<nPhrase; i+
b810: 2b 29 7b 0a 20 20 20 20 63 6f 6e 73 74 20 75 38  +){.    const u8
b820: 20 2a 70 50 6f 73 6c 69 73 74 3b 0a 20 20 20 20   *pPoslist;.    
b830: 69 6e 74 20 6e 50 6f 73 6c 69 73 74 3b 0a 20 20  int nPoslist;.  
b840: 20 20 6e 50 6f 73 6c 69 73 74 20 3d 20 73 71 6c    nPoslist = sql
b850: 69 74 65 33 46 74 73 35 45 78 70 72 50 6f 73 6c  ite3Fts5ExprPosl
b860: 69 73 74 28 70 43 73 72 2d 3e 70 45 78 70 72 2c  ist(pCsr->pExpr,
b870: 20 69 2c 20 26 70 50 6f 73 6c 69 73 74 29 3b 0a   i, &pPoslist);.
b880: 20 20 20 20 73 71 6c 69 74 65 33 46 74 73 35 42      sqlite3Fts5B
b890: 75 66 66 65 72 41 70 70 65 6e 64 42 6c 6f 62 28  ufferAppendBlob(
b8a0: 26 72 63 2c 20 26 76 61 6c 2c 20 6e 50 6f 73 6c  &rc, &val, nPosl
b8b0: 69 73 74 2c 20 70 50 6f 73 6c 69 73 74 29 3b 0a  ist, pPoslist);.
b8c0: 20 20 7d 0a 0a 20 20 73 71 6c 69 74 65 33 5f 72    }..  sqlite3_r
b8d0: 65 73 75 6c 74 5f 62 6c 6f 62 28 70 43 74 78 2c  esult_blob(pCtx,
b8e0: 20 76 61 6c 2e 70 2c 20 76 61 6c 2e 6e 2c 20 73   val.p, val.n, s
b8f0: 71 6c 69 74 65 33 5f 66 72 65 65 29 3b 0a 20 20  qlite3_free);.  
b900: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
b910: 20 0a 2a 2a 20 54 68 69 73 20 69 73 20 74 68 65   .** This is the
b920: 20 78 43 6f 6c 75 6d 6e 20 6d 65 74 68 6f 64 2c   xColumn method,
b930: 20 63 61 6c 6c 65 64 20 62 79 20 53 51 4c 69 74   called by SQLit
b940: 65 20 74 6f 20 72 65 71 75 65 73 74 20 61 20 76  e to request a v
b950: 61 6c 75 65 20 66 72 6f 6d 0a 2a 2a 20 74 68 65  alue from.** the
b960: 20 72 6f 77 20 74 68 61 74 20 74 68 65 20 73 75   row that the su
b970: 70 70 6c 69 65 64 20 63 75 72 73 6f 72 20 63 75  pplied cursor cu
b980: 72 72 65 6e 74 6c 79 20 70 6f 69 6e 74 73 20 74  rrently points t
b990: 6f 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  o..*/.static int
b9a0: 20 66 74 73 35 43 6f 6c 75 6d 6e 4d 65 74 68 6f   fts5ColumnMetho
b9b0: 64 28 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61  d(.  sqlite3_vta
b9c0: 62 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 73 6f  b_cursor *pCurso
b9d0: 72 2c 20 20 20 2f 2a 20 43 75 72 73 6f 72 20 74  r,   /* Cursor t
b9e0: 6f 20 72 65 74 72 69 65 76 65 20 76 61 6c 75 65  o retrieve value
b9f0: 20 66 72 6f 6d 20 2a 2f 0a 20 20 73 71 6c 69 74   from */.  sqlit
ba00: 65 33 5f 63 6f 6e 74 65 78 74 20 2a 70 43 74 78  e3_context *pCtx
ba10: 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f  ,          /* Co
ba20: 6e 74 65 78 74 20 66 6f 72 20 73 71 6c 69 74 65  ntext for sqlite
ba30: 33 5f 72 65 73 75 6c 74 5f 78 78 78 28 29 20 63  3_result_xxx() c
ba40: 61 6c 6c 73 20 2a 2f 0a 20 20 69 6e 74 20 69 43  alls */.  int iC
ba50: 6f 6c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ol              
ba60: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 6e 64            /* Ind
ba70: 65 78 20 6f 66 20 63 6f 6c 75 6d 6e 20 74 6f 20  ex of column to 
ba80: 72 65 61 64 20 76 61 6c 75 65 20 66 72 6f 6d 20  read value from 
ba90: 2a 2f 0a 29 7b 0a 20 20 46 74 73 35 43 6f 6e 66  */.){.  Fts5Conf
baa0: 69 67 20 2a 70 43 6f 6e 66 69 67 20 3d 20 28 28  ig *pConfig = ((
bab0: 46 74 73 35 54 61 62 6c 65 2a 29 28 70 43 75 72  Fts5Table*)(pCur
bac0: 73 6f 72 2d 3e 70 56 74 61 62 29 29 2d 3e 70 43  sor->pVtab))->pC
bad0: 6f 6e 66 69 67 3b 0a 20 20 46 74 73 35 43 75 72  onfig;.  Fts5Cur
bae0: 73 6f 72 20 2a 70 43 73 72 20 3d 20 28 46 74 73  sor *pCsr = (Fts
baf0: 35 43 75 72 73 6f 72 2a 29 70 43 75 72 73 6f 72  5Cursor*)pCursor
bb00: 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c  ;.  int rc = SQL
bb10: 49 54 45 5f 4f 4b 3b 0a 20 20 0a 20 20 61 73 73  ITE_OK;.  .  ass
bb20: 65 72 74 28 20 43 73 72 46 6c 61 67 54 65 73 74  ert( CsrFlagTest
bb30: 28 70 43 73 72 2c 20 46 54 53 35 43 53 52 5f 45  (pCsr, FTS5CSR_E
bb40: 4f 46 29 3d 3d 30 20 29 3b 0a 0a 20 20 69 66 28  OF)==0 );..  if(
bb50: 20 70 43 73 72 2d 3e 69 64 78 4e 75 6d 3d 3d 46   pCsr->idxNum==F
bb60: 54 53 35 5f 50 4c 41 4e 5f 53 50 45 43 49 41 4c  TS5_PLAN_SPECIAL
bb70: 20 29 7b 0a 20 20 20 20 69 66 28 20 69 43 6f 6c   ){.    if( iCol
bb80: 3d 3d 70 43 6f 6e 66 69 67 2d 3e 6e 43 6f 6c 20  ==pConfig->nCol 
bb90: 29 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33  ){.      sqlite3
bba0: 5f 72 65 73 75 6c 74 5f 74 65 78 74 28 70 43 74  _result_text(pCt
bbb0: 78 2c 20 70 43 73 72 2d 3e 7a 53 70 65 63 69 61  x, pCsr->zSpecia
bbc0: 6c 2c 20 2d 31 2c 20 53 51 4c 49 54 45 5f 54 52  l, -1, SQLITE_TR
bbd0: 41 4e 53 49 45 4e 54 29 3b 0a 20 20 20 20 7d 0a  ANSIENT);.    }.
bbe0: 20 20 7d 65 6c 73 65 0a 0a 20 20 69 66 28 20 69    }else..  if( i
bbf0: 43 6f 6c 3d 3d 70 43 6f 6e 66 69 67 2d 3e 6e 43  Col==pConfig->nC
bc00: 6f 6c 20 29 7b 0a 20 20 20 20 2f 2a 20 55 73 65  ol ){.    /* Use
bc10: 72 20 69 73 20 72 65 71 75 65 73 74 69 6e 67 20  r is requesting 
bc20: 74 68 65 20 76 61 6c 75 65 20 6f 66 20 74 68 65  the value of the
bc30: 20 73 70 65 63 69 61 6c 20 63 6f 6c 75 6d 6e 20   special column 
bc40: 77 69 74 68 20 74 68 65 20 73 61 6d 65 20 6e 61  with the same na
bc50: 6d 65 0a 20 20 20 20 2a 2a 20 61 73 20 74 68 65  me.    ** as the
bc60: 20 74 61 62 6c 65 2e 20 52 65 74 75 72 6e 20 74   table. Return t
bc70: 68 65 20 63 75 72 73 6f 72 20 69 6e 74 65 67 65  he cursor intege
bc80: 72 20 69 64 20 6e 75 6d 62 65 72 2e 20 54 68 69  r id number. Thi
bc90: 73 20 76 61 6c 75 65 20 69 73 20 6f 6e 6c 79 0a  s value is only.
bca0: 20 20 20 20 2a 2a 20 75 73 65 66 75 6c 20 69 6e      ** useful in
bcb0: 20 74 68 61 74 20 69 74 20 6d 61 79 20 62 65 20   that it may be 
bcc0: 70 61 73 73 65 64 20 61 73 20 74 68 65 20 66 69  passed as the fi
bcd0: 72 73 74 20 61 72 67 75 6d 65 6e 74 20 74 6f 20  rst argument to 
bce0: 61 6e 20 46 54 53 35 0a 20 20 20 20 2a 2a 20 61  an FTS5.    ** a
bcf0: 75 78 69 6c 69 61 72 79 20 66 75 6e 63 74 69 6f  uxiliary functio
bd00: 6e 2e 20 20 2a 2f 0a 20 20 20 20 73 71 6c 69 74  n.  */.    sqlit
bd10: 65 33 5f 72 65 73 75 6c 74 5f 69 6e 74 36 34 28  e3_result_int64(
bd20: 70 43 74 78 2c 20 70 43 73 72 2d 3e 69 43 73 72  pCtx, pCsr->iCsr
bd30: 49 64 29 3b 0a 20 20 7d 65 6c 73 65 20 69 66 28  Id);.  }else if(
bd40: 20 69 43 6f 6c 3d 3d 70 43 6f 6e 66 69 67 2d 3e   iCol==pConfig->
bd50: 6e 43 6f 6c 2b 31 20 29 7b 0a 0a 20 20 20 20 2f  nCol+1 ){..    /
bd60: 2a 20 54 68 65 20 76 61 6c 75 65 20 6f 66 20 74  * The value of t
bd70: 68 65 20 22 72 61 6e 6b 22 20 63 6f 6c 75 6d 6e  he "rank" column
bd80: 2e 20 2a 2f 0a 20 20 20 20 69 66 28 20 46 54 53  . */.    if( FTS
bd90: 35 5f 50 4c 41 4e 28 70 43 73 72 2d 3e 69 64 78  5_PLAN(pCsr->idx
bda0: 4e 75 6d 29 3d 3d 46 54 53 35 5f 50 4c 41 4e 5f  Num)==FTS5_PLAN_
bdb0: 53 4f 55 52 43 45 20 29 7b 0a 20 20 20 20 20 20  SOURCE ){.      
bdc0: 66 74 73 35 50 6f 73 6c 69 73 74 42 6c 6f 62 28  fts5PoslistBlob(
bdd0: 70 43 74 78 2c 20 70 43 73 72 29 3b 0a 20 20 20  pCtx, pCsr);.   
bde0: 20 7d 65 6c 73 65 20 69 66 28 20 0a 20 20 20 20   }else if( .    
bdf0: 20 20 20 20 46 54 53 35 5f 50 4c 41 4e 28 70 43      FTS5_PLAN(pC
be00: 73 72 2d 3e 69 64 78 4e 75 6d 29 3d 3d 46 54 53  sr->idxNum)==FTS
be10: 35 5f 50 4c 41 4e 5f 4d 41 54 43 48 0a 20 20 20  5_PLAN_MATCH.   
be20: 20 20 7c 7c 20 46 54 53 35 5f 50 4c 41 4e 28 70    || FTS5_PLAN(p
be30: 43 73 72 2d 3e 69 64 78 4e 75 6d 29 3d 3d 46 54  Csr->idxNum)==FT
be40: 53 35 5f 50 4c 41 4e 5f 53 4f 52 54 45 44 5f 4d  S5_PLAN_SORTED_M
be50: 41 54 43 48 0a 20 20 20 20 29 7b 0a 20 20 20 20  ATCH.    ){.    
be60: 20 20 69 66 28 20 70 43 73 72 2d 3e 70 52 61 6e    if( pCsr->pRan
be70: 6b 20 7c 7c 20 53 51 4c 49 54 45 5f 4f 4b 3d 3d  k || SQLITE_OK==
be80: 28 72 63 20 3d 20 66 74 73 35 46 69 6e 64 52 61  (rc = fts5FindRa
be90: 6e 6b 46 75 6e 63 74 69 6f 6e 28 70 43 73 72 29  nkFunction(pCsr)
bea0: 29 20 29 7b 0a 20 20 20 20 20 20 20 20 66 74 73  ) ){.        fts
beb0: 35 41 70 69 49 6e 76 6f 6b 65 28 70 43 73 72 2d  5ApiInvoke(pCsr-
bec0: 3e 70 52 61 6e 6b 2c 20 70 43 73 72 2c 20 70 43  >pRank, pCsr, pC
bed0: 74 78 2c 20 70 43 73 72 2d 3e 6e 52 61 6e 6b 41  tx, pCsr->nRankA
bee0: 72 67 2c 20 70 43 73 72 2d 3e 61 70 52 61 6e 6b  rg, pCsr->apRank
bef0: 41 72 67 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20  Arg);.      }.  
bf00: 20 20 7d 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20    }.  }else{.   
bf10: 20 72 63 20 3d 20 66 74 73 35 53 65 65 6b 43 75   rc = fts5SeekCu
bf20: 72 73 6f 72 28 70 43 73 72 29 3b 0a 20 20 20 20  rsor(pCsr);.    
bf30: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
bf40: 4b 20 29 7b 0a 20 20 20 20 20 20 73 71 6c 69 74  K ){.      sqlit
bf50: 65 33 5f 72 65 73 75 6c 74 5f 76 61 6c 75 65 28  e3_result_value(
bf60: 70 43 74 78 2c 20 73 71 6c 69 74 65 33 5f 63 6f  pCtx, sqlite3_co
bf70: 6c 75 6d 6e 5f 76 61 6c 75 65 28 70 43 73 72 2d  lumn_value(pCsr-
bf80: 3e 70 53 74 6d 74 2c 20 69 43 6f 6c 2b 31 29 29  >pStmt, iCol+1))
bf90: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65  ;.    }.  }.  re
bfa0: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 0a 2f 2a 0a  turn rc;.}.../*.
bfb0: 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20  ** This routine 
bfc0: 69 6d 70 6c 65 6d 65 6e 74 73 20 74 68 65 20 78  implements the x
bfd0: 46 69 6e 64 46 75 6e 63 74 69 6f 6e 20 6d 65 74  FindFunction met
bfe0: 68 6f 64 20 66 6f 72 20 74 68 65 20 46 54 53 33  hod for the FTS3
bff0: 0a 2a 2a 20 76 69 72 74 75 61 6c 20 74 61 62 6c  .** virtual tabl
c000: 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  e..*/.static int
c010: 20 66 74 73 35 46 69 6e 64 46 75 6e 63 74 69 6f   fts5FindFunctio
c020: 6e 4d 65 74 68 6f 64 28 0a 20 20 73 71 6c 69 74  nMethod(.  sqlit
c030: 65 33 5f 76 74 61 62 20 2a 70 56 74 61 62 2c 20  e3_vtab *pVtab, 
c040: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 56 69             /* Vi
c050: 72 74 75 61 6c 20 74 61 62 6c 65 20 68 61 6e 64  rtual table hand
c060: 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 6e 41 72 67  le */.  int nArg
c070: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
c080: 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65          /* Numbe
c090: 72 20 6f 66 20 53 51 4c 20 66 75 6e 63 74 69 6f  r of SQL functio
c0a0: 6e 20 61 72 67 75 6d 65 6e 74 73 20 2a 2f 0a 20  n arguments */. 
c0b0: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61   const char *zNa
c0c0: 6d 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  me,             
c0d0: 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 53 51 4c 20   /* Name of SQL 
c0e0: 66 75 6e 63 74 69 6f 6e 20 2a 2f 0a 20 20 76 6f  function */.  vo
c0f0: 69 64 20 28 2a 2a 70 78 46 75 6e 63 29 28 73 71  id (**pxFunc)(sq
c100: 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74 2a 2c 69  lite3_context*,i
c110: 6e 74 2c 73 71 6c 69 74 65 33 5f 76 61 6c 75 65  nt,sqlite3_value
c120: 2a 2a 29 2c 20 2f 2a 20 4f 55 54 3a 20 52 65 73  **), /* OUT: Res
c130: 75 6c 74 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 2a  ult */.  void **
c140: 70 70 41 72 67 20 20 20 20 20 20 20 20 20 20 20  ppArg           
c150: 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a           /* OUT:
c160: 20 55 73 65 72 20 64 61 74 61 20 66 6f 72 20 2a   User data for *
c170: 70 78 46 75 6e 63 20 2a 2f 0a 29 7b 0a 20 20 46  pxFunc */.){.  F
c180: 74 73 35 54 61 62 6c 65 20 2a 70 54 61 62 20 3d  ts5Table *pTab =
c190: 20 28 46 74 73 35 54 61 62 6c 65 2a 29 70 56 74   (Fts5Table*)pVt
c1a0: 61 62 3b 0a 20 20 46 74 73 35 41 75 78 69 6c 69  ab;.  Fts5Auxili
c1b0: 61 72 79 20 2a 70 41 75 78 3b 0a 0a 20 20 70 41  ary *pAux;..  pA
c1c0: 75 78 20 3d 20 66 74 73 35 46 69 6e 64 41 75 78  ux = fts5FindAux
c1d0: 69 6c 69 61 72 79 28 70 54 61 62 2c 20 7a 4e 61  iliary(pTab, zNa
c1e0: 6d 65 29 3b 0a 20 20 69 66 28 20 70 41 75 78 20  me);.  if( pAux 
c1f0: 29 7b 0a 20 20 20 20 2a 70 78 46 75 6e 63 20 3d  ){.    *pxFunc =
c200: 20 66 74 73 35 41 70 69 43 61 6c 6c 62 61 63 6b   fts5ApiCallback
c210: 3b 0a 20 20 20 20 2a 70 70 41 72 67 20 3d 20 28  ;.    *ppArg = (
c220: 76 6f 69 64 2a 29 70 41 75 78 3b 0a 20 20 20 20  void*)pAux;.    
c230: 72 65 74 75 72 6e 20 31 3b 0a 20 20 7d 0a 0a 20  return 1;.  }.. 
c240: 20 2f 2a 20 4e 6f 20 66 75 6e 63 74 69 6f 6e 20   /* No function 
c250: 6f 66 20 74 68 65 20 73 70 65 63 69 66 69 65 64  of the specified
c260: 20 6e 61 6d 65 20 77 61 73 20 66 6f 75 6e 64 2e   name was found.
c270: 20 52 65 74 75 72 6e 20 30 2e 20 2a 2f 0a 20 20   Return 0. */.  
c280: 72 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a 2f 2a 0a  return 0;.}../*.
c290: 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f  ** Implementatio
c2a0: 6e 20 6f 66 20 46 54 53 33 20 78 52 65 6e 61 6d  n of FTS3 xRenam
c2b0: 65 20 6d 65 74 68 6f 64 2e 20 52 65 6e 61 6d 65  e method. Rename
c2c0: 20 61 6e 20 66 74 73 35 20 74 61 62 6c 65 2e 0a   an fts5 table..
c2d0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74  */.static int ft
c2e0: 73 35 52 65 6e 61 6d 65 4d 65 74 68 6f 64 28 0a  s5RenameMethod(.
c2f0: 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a    sqlite3_vtab *
c300: 70 56 74 61 62 2c 20 20 20 20 20 20 20 20 20 20  pVtab,          
c310: 20 20 2f 2a 20 56 69 72 74 75 61 6c 20 74 61 62    /* Virtual tab
c320: 6c 65 20 68 61 6e 64 6c 65 20 2a 2f 0a 20 20 63  le handle */.  c
c330: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65  onst char *zName
c340: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
c350: 2a 20 4e 65 77 20 6e 61 6d 65 20 6f 66 20 74 61  * New name of ta
c360: 62 6c 65 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20  ble */.){.  int 
c370: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  rc = SQLITE_OK;.
c380: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
c390: 2f 2a 0a 2a 2a 20 54 68 65 20 78 53 61 76 65 70  /*.** The xSavep
c3a0: 6f 69 6e 74 28 29 20 6d 65 74 68 6f 64 2e 0a 2a  oint() method..*
c3b0: 2a 0a 2a 2a 20 46 6c 75 73 68 20 74 68 65 20 63  *.** Flush the c
c3c0: 6f 6e 74 65 6e 74 73 20 6f 66 20 74 68 65 20 70  ontents of the p
c3d0: 65 6e 64 69 6e 67 2d 74 65 72 6d 73 20 74 61 62  ending-terms tab
c3e0: 6c 65 20 74 6f 20 64 69 73 6b 2e 0a 2a 2f 0a 73  le to disk..*/.s
c3f0: 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 53 61  tatic int fts5Sa
c400: 76 65 70 6f 69 6e 74 4d 65 74 68 6f 64 28 73 71  vepointMethod(sq
c410: 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56 74 61  lite3_vtab *pVta
c420: 62 2c 20 69 6e 74 20 69 53 61 76 65 70 6f 69 6e  b, int iSavepoin
c430: 74 29 7b 0a 20 20 46 74 73 35 54 61 62 6c 65 20  t){.  Fts5Table 
c440: 2a 70 54 61 62 20 3d 20 28 46 74 73 35 54 61 62  *pTab = (Fts5Tab
c450: 6c 65 2a 29 70 56 74 61 62 3b 0a 20 20 66 74 73  le*)pVtab;.  fts
c460: 35 43 68 65 63 6b 54 72 61 6e 73 61 63 74 69 6f  5CheckTransactio
c470: 6e 53 74 61 74 65 28 70 54 61 62 2c 20 46 54 53  nState(pTab, FTS
c480: 35 5f 53 41 56 45 50 4f 49 4e 54 2c 20 69 53 61  5_SAVEPOINT, iSa
c490: 76 65 70 6f 69 6e 74 29 3b 0a 20 20 72 65 74 75  vepoint);.  retu
c4a0: 72 6e 20 73 71 6c 69 74 65 33 46 74 73 35 53 74  rn sqlite3Fts5St
c4b0: 6f 72 61 67 65 53 79 6e 63 28 70 54 61 62 2d 3e  orageSync(pTab->
c4c0: 70 53 74 6f 72 61 67 65 2c 20 30 29 3b 0a 7d 0a  pStorage, 0);.}.
c4d0: 0a 2f 2a 0a 2a 2a 20 54 68 65 20 78 52 65 6c 65  ./*.** The xRele
c4e0: 61 73 65 28 29 20 6d 65 74 68 6f 64 2e 0a 2a 2a  ase() method..**
c4f0: 0a 2a 2a 20 54 68 69 73 20 69 73 20 61 20 6e 6f  .** This is a no
c500: 2d 6f 70 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  -op..*/.static i
c510: 6e 74 20 66 74 73 35 52 65 6c 65 61 73 65 4d 65  nt fts5ReleaseMe
c520: 74 68 6f 64 28 73 71 6c 69 74 65 33 5f 76 74 61  thod(sqlite3_vta
c530: 62 20 2a 70 56 74 61 62 2c 20 69 6e 74 20 69 53  b *pVtab, int iS
c540: 61 76 65 70 6f 69 6e 74 29 7b 0a 20 20 46 74 73  avepoint){.  Fts
c550: 35 54 61 62 6c 65 20 2a 70 54 61 62 20 3d 20 28  5Table *pTab = (
c560: 46 74 73 35 54 61 62 6c 65 2a 29 70 56 74 61 62  Fts5Table*)pVtab
c570: 3b 0a 20 20 66 74 73 35 43 68 65 63 6b 54 72 61  ;.  fts5CheckTra
c580: 6e 73 61 63 74 69 6f 6e 53 74 61 74 65 28 70 54  nsactionState(pT
c590: 61 62 2c 20 46 54 53 35 5f 52 45 4c 45 41 53 45  ab, FTS5_RELEASE
c5a0: 2c 20 69 53 61 76 65 70 6f 69 6e 74 29 3b 0a 20  , iSavepoint);. 
c5b0: 20 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33 46   return sqlite3F
c5c0: 74 73 35 53 74 6f 72 61 67 65 53 79 6e 63 28 70  ts5StorageSync(p
c5d0: 54 61 62 2d 3e 70 53 74 6f 72 61 67 65 2c 20 30  Tab->pStorage, 0
c5e0: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20  );.}../*.** The 
c5f0: 78 52 6f 6c 6c 62 61 63 6b 54 6f 28 29 20 6d 65  xRollbackTo() me
c600: 74 68 6f 64 2e 0a 2a 2a 0a 2a 2a 20 44 69 73 63  thod..**.** Disc
c610: 61 72 64 20 74 68 65 20 63 6f 6e 74 65 6e 74 73  ard the contents
c620: 20 6f 66 20 74 68 65 20 70 65 6e 64 69 6e 67 20   of the pending 
c630: 74 65 72 6d 73 20 74 61 62 6c 65 2e 0a 2a 2f 0a  terms table..*/.
c640: 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 52  static int fts5R
c650: 6f 6c 6c 62 61 63 6b 54 6f 4d 65 74 68 6f 64 28  ollbackToMethod(
c660: 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56  sqlite3_vtab *pV
c670: 74 61 62 2c 20 69 6e 74 20 69 53 61 76 65 70 6f  tab, int iSavepo
c680: 69 6e 74 29 7b 0a 20 20 46 74 73 35 54 61 62 6c  int){.  Fts5Tabl
c690: 65 20 2a 70 54 61 62 20 3d 20 28 46 74 73 35 54  e *pTab = (Fts5T
c6a0: 61 62 6c 65 2a 29 70 56 74 61 62 3b 0a 20 20 66  able*)pVtab;.  f
c6b0: 74 73 35 43 68 65 63 6b 54 72 61 6e 73 61 63 74  ts5CheckTransact
c6c0: 69 6f 6e 53 74 61 74 65 28 70 54 61 62 2c 20 46  ionState(pTab, F
c6d0: 54 53 35 5f 52 4f 4c 4c 42 41 43 4b 54 4f 2c 20  TS5_ROLLBACKTO, 
c6e0: 69 53 61 76 65 70 6f 69 6e 74 29 3b 0a 20 20 72  iSavepoint);.  r
c6f0: 65 74 75 72 6e 20 73 71 6c 69 74 65 33 46 74 73  eturn sqlite3Fts
c700: 35 53 74 6f 72 61 67 65 52 6f 6c 6c 62 61 63 6b  5StorageRollback
c710: 28 70 54 61 62 2d 3e 70 53 74 6f 72 61 67 65 29  (pTab->pStorage)
c720: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 67 69 73  ;.}../*.** Regis
c730: 74 65 72 20 61 20 6e 65 77 20 61 75 78 69 6c 69  ter a new auxili
c740: 61 72 79 20 66 75 6e 63 74 69 6f 6e 20 77 69 74  ary function wit
c750: 68 20 67 6c 6f 62 61 6c 20 63 6f 6e 74 65 78 74  h global context
c760: 20 70 47 6c 6f 62 61 6c 2e 0a 2a 2f 0a 73 74 61   pGlobal..*/.sta
c770: 74 69 63 20 69 6e 74 20 66 74 73 35 43 72 65 61  tic int fts5Crea
c780: 74 65 41 75 78 28 0a 20 20 66 74 73 35 5f 61 70  teAux(.  fts5_ap
c790: 69 20 2a 70 41 70 69 2c 20 20 20 20 20 20 20 20  i *pApi,        
c7a0: 20 20 20 20 20 20 20 20 20 2f 2a 20 47 6c 6f 62           /* Glob
c7b0: 61 6c 20 63 6f 6e 74 65 78 74 20 28 6f 6e 65 20  al context (one 
c7c0: 70 65 72 20 64 62 20 68 61 6e 64 6c 65 29 20 2a  per db handle) *
c7d0: 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  /.  const char *
c7e0: 7a 4e 61 6d 65 2c 20 20 20 20 20 20 20 20 20 20  zName,          
c7f0: 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 6e      /* Name of n
c800: 65 77 20 66 75 6e 63 74 69 6f 6e 20 2a 2f 0a 20  ew function */. 
c810: 20 76 6f 69 64 20 2a 70 55 73 65 72 44 61 74 61   void *pUserData
c820: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
c830: 20 2f 2a 20 55 73 65 72 20 64 61 74 61 20 66 6f   /* User data fo
c840: 72 20 61 75 78 2e 20 66 75 6e 63 74 69 6f 6e 20  r aux. function 
c850: 2a 2f 0a 20 20 66 74 73 35 5f 65 78 74 65 6e 73  */.  fts5_extens
c860: 69 6f 6e 5f 66 75 6e 63 74 69 6f 6e 20 78 46 75  ion_function xFu
c870: 6e 63 2c 20 20 2f 2a 20 41 75 78 2e 20 66 75 6e  nc,  /* Aux. fun
c880: 63 74 69 6f 6e 20 69 6d 70 6c 65 6d 65 6e 74 61  ction implementa
c890: 74 69 6f 6e 20 2a 2f 0a 20 20 76 6f 69 64 28 2a  tion */.  void(*
c8a0: 78 44 65 73 74 72 6f 79 29 28 76 6f 69 64 2a 29  xDestroy)(void*)
c8b0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 65 73            /* Des
c8c0: 74 72 75 63 74 6f 72 20 66 6f 72 20 70 55 73 65  tructor for pUse
c8d0: 72 44 61 74 61 20 2a 2f 0a 29 7b 0a 20 20 46 74  rData */.){.  Ft
c8e0: 73 35 47 6c 6f 62 61 6c 20 2a 70 47 6c 6f 62 61  s5Global *pGloba
c8f0: 6c 20 3d 20 28 46 74 73 35 47 6c 6f 62 61 6c 2a  l = (Fts5Global*
c900: 29 70 41 70 69 3b 0a 20 20 69 6e 74 20 72 63 20  )pApi;.  int rc 
c910: 3d 20 73 71 6c 69 74 65 33 5f 6f 76 65 72 6c 6f  = sqlite3_overlo
c920: 61 64 5f 66 75 6e 63 74 69 6f 6e 28 70 47 6c 6f  ad_function(pGlo
c930: 62 61 6c 2d 3e 64 62 2c 20 7a 4e 61 6d 65 2c 20  bal->db, zName, 
c940: 2d 31 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53  -1);.  if( rc==S
c950: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
c960: 46 74 73 35 41 75 78 69 6c 69 61 72 79 20 2a 70  Fts5Auxiliary *p
c970: 41 75 78 3b 0a 20 20 20 20 69 6e 74 20 6e 42 79  Aux;.    int nBy
c980: 74 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  te;             
c990: 20 20 20 20 20 20 20 20 20 2f 2a 20 42 79 74 65           /* Byte
c9a0: 73 20 6f 66 20 73 70 61 63 65 20 74 6f 20 61 6c  s of space to al
c9b0: 6c 6f 63 61 74 65 20 2a 2f 0a 0a 20 20 20 20 6e  locate */..    n
c9c0: 42 79 74 65 20 3d 20 73 69 7a 65 6f 66 28 46 74  Byte = sizeof(Ft
c9d0: 73 35 41 75 78 69 6c 69 61 72 79 29 20 2b 20 73  s5Auxiliary) + s
c9e0: 74 72 6c 65 6e 28 7a 4e 61 6d 65 29 20 2b 20 31  trlen(zName) + 1
c9f0: 3b 0a 20 20 20 20 70 41 75 78 20 3d 20 28 46 74  ;.    pAux = (Ft
ca00: 73 35 41 75 78 69 6c 69 61 72 79 2a 29 73 71 6c  s5Auxiliary*)sql
ca10: 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 6e 42 79 74  ite3_malloc(nByt
ca20: 65 29 3b 0a 20 20 20 20 69 66 28 20 70 41 75 78  e);.    if( pAux
ca30: 20 29 7b 0a 20 20 20 20 20 20 6d 65 6d 73 65 74   ){.      memset
ca40: 28 70 41 75 78 2c 20 30 2c 20 6e 42 79 74 65 29  (pAux, 0, nByte)
ca50: 3b 0a 20 20 20 20 20 20 70 41 75 78 2d 3e 7a 46  ;.      pAux->zF
ca60: 75 6e 63 20 3d 20 28 63 68 61 72 2a 29 26 70 41  unc = (char*)&pA
ca70: 75 78 5b 31 5d 3b 0a 20 20 20 20 20 20 73 74 72  ux[1];.      str
ca80: 63 70 79 28 70 41 75 78 2d 3e 7a 46 75 6e 63 2c  cpy(pAux->zFunc,
ca90: 20 7a 4e 61 6d 65 29 3b 0a 20 20 20 20 20 20 70   zName);.      p
caa0: 41 75 78 2d 3e 70 47 6c 6f 62 61 6c 20 3d 20 70  Aux->pGlobal = p
cab0: 47 6c 6f 62 61 6c 3b 0a 20 20 20 20 20 20 70 41  Global;.      pA
cac0: 75 78 2d 3e 70 55 73 65 72 44 61 74 61 20 3d 20  ux->pUserData = 
cad0: 70 55 73 65 72 44 61 74 61 3b 0a 20 20 20 20 20  pUserData;.     
cae0: 20 70 41 75 78 2d 3e 78 46 75 6e 63 20 3d 20 78   pAux->xFunc = x
caf0: 46 75 6e 63 3b 0a 20 20 20 20 20 20 70 41 75 78  Func;.      pAux
cb00: 2d 3e 78 44 65 73 74 72 6f 79 20 3d 20 78 44 65  ->xDestroy = xDe
cb10: 73 74 72 6f 79 3b 0a 20 20 20 20 20 20 70 41 75  stroy;.      pAu
cb20: 78 2d 3e 70 4e 65 78 74 20 3d 20 70 47 6c 6f 62  x->pNext = pGlob
cb30: 61 6c 2d 3e 70 41 75 78 3b 0a 20 20 20 20 20 20  al->pAux;.      
cb40: 70 47 6c 6f 62 61 6c 2d 3e 70 41 75 78 20 3d 20  pGlobal->pAux = 
cb50: 70 41 75 78 3b 0a 20 20 20 20 7d 65 6c 73 65 7b  pAux;.    }else{
cb60: 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49  .      rc = SQLI
cb70: 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d 0a  TE_NOMEM;.    }.
cb80: 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63    }..  return rc
cb90: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 67 69 73  ;.}../*.** Regis
cba0: 74 65 72 20 61 20 6e 65 77 20 74 6f 6b 65 6e 69  ter a new tokeni
cbb0: 7a 65 72 2e 20 54 68 69 73 20 69 73 20 74 68 65  zer. This is the
cbc0: 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20   implementation 
cbd0: 6f 66 20 74 68 65 20 0a 2a 2a 20 66 74 73 35 5f  of the .** fts5_
cbe0: 61 70 69 2e 78 43 72 65 61 74 65 54 6f 6b 65 6e  api.xCreateToken
cbf0: 69 7a 65 72 28 29 20 6d 65 74 68 6f 64 2e 0a 2a  izer() method..*
cc00: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73  /.static int fts
cc10: 35 43 72 65 61 74 65 54 6f 6b 65 6e 69 7a 65 72  5CreateTokenizer
cc20: 28 0a 20 20 66 74 73 35 5f 61 70 69 20 2a 70 41  (.  fts5_api *pA
cc30: 70 69 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  pi,             
cc40: 20 20 20 20 2f 2a 20 47 6c 6f 62 61 6c 20 63 6f      /* Global co
cc50: 6e 74 65 78 74 20 28 6f 6e 65 20 70 65 72 20 64  ntext (one per d
cc60: 62 20 68 61 6e 64 6c 65 29 20 2a 2f 0a 20 20 63  b handle) */.  c
cc70: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65  onst char *zName
cc80: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  ,              /
cc90: 2a 20 4e 61 6d 65 20 6f 66 20 6e 65 77 20 66 75  * Name of new fu
cca0: 6e 63 74 69 6f 6e 20 2a 2f 0a 20 20 76 6f 69 64  nction */.  void
ccb0: 20 2a 70 55 73 65 72 44 61 74 61 2c 20 20 20 20   *pUserData,    
ccc0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 55              /* U
ccd0: 73 65 72 20 64 61 74 61 20 66 6f 72 20 61 75 78  ser data for aux
cce0: 2e 20 66 75 6e 63 74 69 6f 6e 20 2a 2f 0a 20 20  . function */.  
ccf0: 66 74 73 35 5f 74 6f 6b 65 6e 69 7a 65 72 20 2a  fts5_tokenizer *
cd00: 70 54 6f 6b 65 6e 69 7a 65 72 2c 20 20 20 20 20  pTokenizer,     
cd10: 2f 2a 20 54 6f 6b 65 6e 69 7a 65 72 20 69 6d 70  /* Tokenizer imp
cd20: 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 2a 2f 0a 20  lementation */. 
cd30: 20 76 6f 69 64 28 2a 78 44 65 73 74 72 6f 79 29   void(*xDestroy)
cd40: 28 76 6f 69 64 2a 29 20 20 20 20 20 20 20 20 20  (void*)         
cd50: 20 2f 2a 20 44 65 73 74 72 75 63 74 6f 72 20 66   /* Destructor f
cd60: 6f 72 20 70 55 73 65 72 44 61 74 61 20 2a 2f 0a  or pUserData */.
cd70: 29 7b 0a 20 20 46 74 73 35 47 6c 6f 62 61 6c 20  ){.  Fts5Global 
cd80: 2a 70 47 6c 6f 62 61 6c 20 3d 20 28 46 74 73 35  *pGlobal = (Fts5
cd90: 47 6c 6f 62 61 6c 2a 29 70 41 70 69 3b 0a 20 20  Global*)pApi;.  
cda0: 46 74 73 35 54 6f 6b 65 6e 69 7a 65 72 4d 6f 64  Fts5TokenizerMod
cdb0: 75 6c 65 20 2a 70 4e 65 77 3b 0a 20 20 69 6e 74  ule *pNew;.  int
cdc0: 20 6e 42 79 74 65 3b 20 20 20 20 20 20 20 20 20   nByte;         
cdd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
cde0: 42 79 74 65 73 20 6f 66 20 73 70 61 63 65 20 74  Bytes of space t
cdf0: 6f 20 61 6c 6c 6f 63 61 74 65 20 2a 2f 0a 20 20  o allocate */.  
ce00: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
ce10: 4f 4b 3b 0a 0a 20 20 6e 42 79 74 65 20 3d 20 73  OK;..  nByte = s
ce20: 69 7a 65 6f 66 28 46 74 73 35 54 6f 6b 65 6e 69  izeof(Fts5Tokeni
ce30: 7a 65 72 4d 6f 64 75 6c 65 29 20 2b 20 73 74 72  zerModule) + str
ce40: 6c 65 6e 28 7a 4e 61 6d 65 29 20 2b 20 31 3b 0a  len(zName) + 1;.
ce50: 20 20 70 4e 65 77 20 3d 20 28 46 74 73 35 54 6f    pNew = (Fts5To
ce60: 6b 65 6e 69 7a 65 72 4d 6f 64 75 6c 65 2a 29 73  kenizerModule*)s
ce70: 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 6e 42  qlite3_malloc(nB
ce80: 79 74 65 29 3b 0a 20 20 69 66 28 20 70 4e 65 77  yte);.  if( pNew
ce90: 20 29 7b 0a 20 20 20 20 6d 65 6d 73 65 74 28 70   ){.    memset(p
cea0: 4e 65 77 2c 20 30 2c 20 6e 42 79 74 65 29 3b 0a  New, 0, nByte);.
ceb0: 20 20 20 20 70 4e 65 77 2d 3e 7a 4e 61 6d 65 20      pNew->zName 
cec0: 3d 20 28 63 68 61 72 2a 29 26 70 4e 65 77 5b 31  = (char*)&pNew[1
ced0: 5d 3b 0a 20 20 20 20 73 74 72 63 70 79 28 70 4e  ];.    strcpy(pN
cee0: 65 77 2d 3e 7a 4e 61 6d 65 2c 20 7a 4e 61 6d 65  ew->zName, zName
cef0: 29 3b 0a 20 20 20 20 70 4e 65 77 2d 3e 70 55 73  );.    pNew->pUs
cf00: 65 72 44 61 74 61 20 3d 20 70 55 73 65 72 44 61  erData = pUserDa
cf10: 74 61 3b 0a 20 20 20 20 70 4e 65 77 2d 3e 78 20  ta;.    pNew->x 
cf20: 3d 20 2a 70 54 6f 6b 65 6e 69 7a 65 72 3b 0a 20  = *pTokenizer;. 
cf30: 20 20 20 70 4e 65 77 2d 3e 78 44 65 73 74 72 6f     pNew->xDestro
cf40: 79 20 3d 20 78 44 65 73 74 72 6f 79 3b 0a 20 20  y = xDestroy;.  
cf50: 20 20 70 4e 65 77 2d 3e 70 4e 65 78 74 20 3d 20    pNew->pNext = 
cf60: 70 47 6c 6f 62 61 6c 2d 3e 70 54 6f 6b 3b 0a 20  pGlobal->pTok;. 
cf70: 20 20 20 70 47 6c 6f 62 61 6c 2d 3e 70 54 6f 6b     pGlobal->pTok
cf80: 20 3d 20 70 4e 65 77 3b 0a 20 20 7d 65 6c 73 65   = pNew;.  }else
cf90: 7b 0a 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54  {.    rc = SQLIT
cfa0: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 0a 20 20  E_NOMEM;.  }..  
cfb0: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
cfc0: 0a 2a 2a 20 46 69 6e 64 20 61 20 74 6f 6b 65 6e  .** Find a token
cfd0: 69 7a 65 72 2e 20 54 68 69 73 20 69 73 20 74 68  izer. This is th
cfe0: 65 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e  e implementation
cff0: 20 6f 66 20 74 68 65 20 0a 2a 2a 20 66 74 73 35   of the .** fts5
d000: 5f 61 70 69 2e 78 46 69 6e 64 54 6f 6b 65 6e 69  _api.xFindTokeni
d010: 7a 65 72 28 29 20 6d 65 74 68 6f 64 2e 0a 2a 2f  zer() method..*/
d020: 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35  .static int fts5
d030: 46 69 6e 64 54 6f 6b 65 6e 69 7a 65 72 28 0a 20  FindTokenizer(. 
d040: 20 66 74 73 35 5f 61 70 69 20 2a 70 41 70 69 2c   fts5_api *pApi,
d050: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d060: 20 2f 2a 20 47 6c 6f 62 61 6c 20 63 6f 6e 74 65   /* Global conte
d070: 78 74 20 28 6f 6e 65 20 70 65 72 20 64 62 20 68  xt (one per db h
d080: 61 6e 64 6c 65 29 20 2a 2f 0a 20 20 63 6f 6e 73  andle) */.  cons
d090: 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 2c 20 20  t char *zName,  
d0a0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
d0b0: 61 6d 65 20 6f 66 20 6e 65 77 20 66 75 6e 63 74  ame of new funct
d0c0: 69 6f 6e 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 2a  ion */.  void **
d0d0: 70 70 55 73 65 72 44 61 74 61 2c 0a 20 20 66 74  ppUserData,.  ft
d0e0: 73 35 5f 74 6f 6b 65 6e 69 7a 65 72 20 2a 70 54  s5_tokenizer *pT
d0f0: 6f 6b 65 6e 69 7a 65 72 20 20 20 20 20 20 2f 2a  okenizer      /*
d100: 20 50 6f 70 75 6c 61 74 65 20 74 68 69 73 20 6f   Populate this o
d110: 62 6a 65 63 74 20 2a 2f 0a 29 7b 0a 20 20 46 74  bject */.){.  Ft
d120: 73 35 47 6c 6f 62 61 6c 20 2a 70 47 6c 6f 62 61  s5Global *pGloba
d130: 6c 20 3d 20 28 46 74 73 35 47 6c 6f 62 61 6c 2a  l = (Fts5Global*
d140: 29 70 41 70 69 3b 0a 20 20 69 6e 74 20 72 63 20  )pApi;.  int rc 
d150: 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 46  = SQLITE_OK;.  F
d160: 74 73 35 54 6f 6b 65 6e 69 7a 65 72 4d 6f 64 75  ts5TokenizerModu
d170: 6c 65 20 2a 70 54 6f 6b 3b 0a 0a 20 20 66 6f 72  le *pTok;..  for
d180: 28 70 54 6f 6b 3d 70 47 6c 6f 62 61 6c 2d 3e 70  (pTok=pGlobal->p
d190: 54 6f 6b 3b 20 70 54 6f 6b 3b 20 70 54 6f 6b 3d  Tok; pTok; pTok=
d1a0: 70 54 6f 6b 2d 3e 70 4e 65 78 74 29 7b 0a 20 20  pTok->pNext){.  
d1b0: 20 20 69 66 28 20 73 71 6c 69 74 65 33 5f 73 74    if( sqlite3_st
d1c0: 72 69 63 6d 70 28 7a 4e 61 6d 65 2c 20 70 54 6f  ricmp(zName, pTo
d1d0: 6b 2d 3e 7a 4e 61 6d 65 29 3d 3d 30 20 29 20 62  k->zName)==0 ) b
d1e0: 72 65 61 6b 3b 0a 20 20 7d 0a 0a 20 20 69 66 28  reak;.  }..  if(
d1f0: 20 70 54 6f 6b 20 29 7b 0a 20 20 20 20 2a 70 54   pTok ){.    *pT
d200: 6f 6b 65 6e 69 7a 65 72 20 3d 20 70 54 6f 6b 2d  okenizer = pTok-
d210: 3e 78 3b 0a 20 20 20 20 2a 70 70 55 73 65 72 44  >x;.    *ppUserD
d220: 61 74 61 20 3d 20 70 54 6f 6b 2d 3e 70 55 73 65  ata = pTok->pUse
d230: 72 44 61 74 61 3b 0a 20 20 7d 65 6c 73 65 7b 0a  rData;.  }else{.
d240: 20 20 20 20 6d 65 6d 73 65 74 28 70 54 6f 6b 65      memset(pToke
d250: 6e 69 7a 65 72 2c 20 30 2c 20 73 69 7a 65 6f 66  nizer, 0, sizeof
d260: 28 66 74 73 35 5f 74 6f 6b 65 6e 69 7a 65 72 29  (fts5_tokenizer)
d270: 29 3b 0a 20 20 20 20 72 63 20 3d 20 53 51 4c 49  );.    rc = SQLI
d280: 54 45 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20  TE_ERROR;.  }.. 
d290: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 69   return rc;.}..i
d2a0: 6e 74 20 73 71 6c 69 74 65 33 46 74 73 35 47 65  nt sqlite3Fts5Ge
d2b0: 74 54 6f 6b 65 6e 69 7a 65 72 28 0a 20 20 46 74  tTokenizer(.  Ft
d2c0: 73 35 47 6c 6f 62 61 6c 20 2a 70 47 6c 6f 62 61  s5Global *pGloba
d2d0: 6c 2c 20 0a 20 20 63 6f 6e 73 74 20 63 68 61 72  l, .  const char
d2e0: 20 2a 2a 61 7a 41 72 67 2c 0a 20 20 69 6e 74 20   **azArg,.  int 
d2f0: 6e 41 72 67 2c 0a 20 20 46 74 73 35 54 6f 6b 65  nArg,.  Fts5Toke
d300: 6e 69 7a 65 72 20 2a 2a 70 70 54 6f 6b 2c 0a 20  nizer **ppTok,. 
d310: 20 66 74 73 35 5f 74 6f 6b 65 6e 69 7a 65 72 20   fts5_tokenizer 
d320: 2a 2a 70 70 54 6f 6b 41 70 69 0a 29 7b 0a 20 20  **ppTokApi.){.  
d330: 46 74 73 35 54 6f 6b 65 6e 69 7a 65 72 4d 6f 64  Fts5TokenizerMod
d340: 75 6c 65 20 2a 70 4d 6f 64 20 3d 20 30 3b 0a 20  ule *pMod = 0;. 
d350: 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
d360: 5f 4f 4b 3b 0a 20 20 69 66 28 20 6e 41 72 67 3d  _OK;.  if( nArg=
d370: 3d 30 20 29 7b 0a 20 20 20 20 70 4d 6f 64 20 3d  =0 ){.    pMod =
d380: 20 70 47 6c 6f 62 61 6c 2d 3e 70 54 6f 6b 3b 0a   pGlobal->pTok;.
d390: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 66 6f 72    }else{.    for
d3a0: 28 70 4d 6f 64 3d 70 47 6c 6f 62 61 6c 2d 3e 70  (pMod=pGlobal->p
d3b0: 54 6f 6b 3b 20 70 4d 6f 64 3b 20 70 4d 6f 64 3d  Tok; pMod; pMod=
d3c0: 70 4d 6f 64 2d 3e 70 4e 65 78 74 29 7b 0a 20 20  pMod->pNext){.  
d3d0: 20 20 20 20 69 66 28 20 73 71 6c 69 74 65 33 5f      if( sqlite3_
d3e0: 73 74 72 69 63 6d 70 28 61 7a 41 72 67 5b 30 5d  stricmp(azArg[0]
d3f0: 2c 20 70 4d 6f 64 2d 3e 7a 4e 61 6d 65 29 3d 3d  , pMod->zName)==
d400: 30 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d  0 ) break;.    }
d410: 0a 20 20 7d 0a 0a 20 20 69 66 28 20 70 4d 6f 64  .  }..  if( pMod
d420: 3d 3d 30 20 29 7b 0a 20 20 20 20 72 63 20 3d 20  ==0 ){.    rc = 
d430: 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20  SQLITE_ERROR;.  
d440: 7d 65 6c 73 65 7b 0a 20 20 20 20 72 63 20 3d 20  }else{.    rc = 
d450: 70 4d 6f 64 2d 3e 78 2e 78 43 72 65 61 74 65 28  pMod->x.xCreate(
d460: 70 4d 6f 64 2d 3e 70 55 73 65 72 44 61 74 61 2c  pMod->pUserData,
d470: 20 26 61 7a 41 72 67 5b 31 5d 2c 20 28 6e 41 72   &azArg[1], (nAr
d480: 67 3f 6e 41 72 67 2d 31 3a 30 29 2c 20 70 70 54  g?nArg-1:0), ppT
d490: 6f 6b 29 3b 0a 20 20 20 20 2a 70 70 54 6f 6b 41  ok);.    *ppTokA
d4a0: 70 69 20 3d 20 26 70 4d 6f 64 2d 3e 78 3b 0a 20  pi = &pMod->x;. 
d4b0: 20 7d 0a 0a 20 20 69 66 28 20 72 63 21 3d 53 51   }..  if( rc!=SQ
d4c0: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 2a  LITE_OK ){.    *
d4d0: 70 70 54 6f 6b 41 70 69 20 3d 20 30 3b 0a 20 20  ppTokApi = 0;.  
d4e0: 20 20 2a 70 70 54 6f 6b 20 3d 20 30 3b 0a 20 20    *ppTok = 0;.  
d4f0: 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  }..  return rc;.
d500: 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 66  }..static void f
d510: 74 73 35 4d 6f 64 75 6c 65 44 65 73 74 72 6f 79  ts5ModuleDestroy
d520: 28 76 6f 69 64 20 2a 70 43 74 78 29 7b 0a 20 20  (void *pCtx){.  
d530: 46 74 73 35 54 6f 6b 65 6e 69 7a 65 72 4d 6f 64  Fts5TokenizerMod
d540: 75 6c 65 20 2a 70 54 6f 6b 2c 20 2a 70 4e 65 78  ule *pTok, *pNex
d550: 74 54 6f 6b 3b 0a 20 20 46 74 73 35 41 75 78 69  tTok;.  Fts5Auxi
d560: 6c 69 61 72 79 20 2a 70 41 75 78 2c 20 2a 70 4e  liary *pAux, *pN
d570: 65 78 74 41 75 78 3b 0a 20 20 46 74 73 35 47 6c  extAux;.  Fts5Gl
d580: 6f 62 61 6c 20 2a 70 47 6c 6f 62 61 6c 20 3d 20  obal *pGlobal = 
d590: 28 46 74 73 35 47 6c 6f 62 61 6c 2a 29 70 43 74  (Fts5Global*)pCt
d5a0: 78 3b 0a 0a 20 20 66 6f 72 28 70 41 75 78 3d 70  x;..  for(pAux=p
d5b0: 47 6c 6f 62 61 6c 2d 3e 70 41 75 78 3b 20 70 41  Global->pAux; pA
d5c0: 75 78 3b 20 70 41 75 78 3d 70 4e 65 78 74 41 75  ux; pAux=pNextAu
d5d0: 78 29 7b 0a 20 20 20 20 70 4e 65 78 74 41 75 78  x){.    pNextAux
d5e0: 20 3d 20 70 41 75 78 2d 3e 70 4e 65 78 74 3b 0a   = pAux->pNext;.
d5f0: 20 20 20 20 69 66 28 20 70 41 75 78 2d 3e 78 44      if( pAux->xD
d600: 65 73 74 72 6f 79 20 29 20 70 41 75 78 2d 3e 78  estroy ) pAux->x
d610: 44 65 73 74 72 6f 79 28 70 41 75 78 2d 3e 70 55  Destroy(pAux->pU
d620: 73 65 72 44 61 74 61 29 3b 0a 20 20 20 20 73 71  serData);.    sq
d630: 6c 69 74 65 33 5f 66 72 65 65 28 70 41 75 78 29  lite3_free(pAux)
d640: 3b 0a 20 20 7d 0a 0a 20 20 66 6f 72 28 70 54 6f  ;.  }..  for(pTo
d650: 6b 3d 70 47 6c 6f 62 61 6c 2d 3e 70 54 6f 6b 3b  k=pGlobal->pTok;
d660: 20 70 54 6f 6b 3b 20 70 54 6f 6b 3d 70 4e 65 78   pTok; pTok=pNex
d670: 74 54 6f 6b 29 7b 0a 20 20 20 20 70 4e 65 78 74  tTok){.    pNext
d680: 54 6f 6b 20 3d 20 70 54 6f 6b 2d 3e 70 4e 65 78  Tok = pTok->pNex
d690: 74 3b 0a 20 20 20 20 69 66 28 20 70 54 6f 6b 2d  t;.    if( pTok-
d6a0: 3e 78 44 65 73 74 72 6f 79 20 29 20 70 54 6f 6b  >xDestroy ) pTok
d6b0: 2d 3e 78 44 65 73 74 72 6f 79 28 70 54 6f 6b 2d  ->xDestroy(pTok-
d6c0: 3e 70 55 73 65 72 44 61 74 61 29 3b 0a 20 20 20  >pUserData);.   
d6d0: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 54   sqlite3_free(pT
d6e0: 6f 6b 29 3b 0a 20 20 7d 0a 0a 20 20 73 71 6c 69  ok);.  }..  sqli
d6f0: 74 65 33 5f 66 72 65 65 28 70 47 6c 6f 62 61 6c  te3_free(pGlobal
d700: 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69  );.}..static voi
d710: 64 20 66 74 73 35 46 74 73 35 46 75 6e 63 28 0a  d fts5Fts5Func(.
d720: 20 20 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78    sqlite3_contex
d730: 74 20 2a 70 43 74 78 2c 20 20 20 20 20 20 20 20  t *pCtx,        
d740: 20 20 2f 2a 20 46 75 6e 63 74 69 6f 6e 20 63 61    /* Function ca
d750: 6c 6c 20 63 6f 6e 74 65 78 74 20 2a 2f 0a 20 20  ll context */.  
d760: 69 6e 74 20 6e 41 72 67 2c 20 20 20 20 20 20 20  int nArg,       
d770: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d780: 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 61 72 67  /* Number of arg
d790: 73 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 76  s */.  sqlite3_v
d7a0: 61 6c 75 65 20 2a 2a 61 70 56 61 6c 20 20 20 20  alue **apVal    
d7b0: 20 20 20 20 20 20 20 2f 2a 20 46 75 6e 63 74 69         /* Functi
d7c0: 6f 6e 20 61 72 67 75 6d 65 6e 74 73 20 2a 2f 0a  on arguments */.
d7d0: 29 7b 0a 20 20 46 74 73 35 47 6c 6f 62 61 6c 20  ){.  Fts5Global 
d7e0: 2a 70 47 6c 6f 62 61 6c 20 3d 20 28 46 74 73 35  *pGlobal = (Fts5
d7f0: 47 6c 6f 62 61 6c 2a 29 73 71 6c 69 74 65 33 5f  Global*)sqlite3_
d800: 75 73 65 72 5f 64 61 74 61 28 70 43 74 78 29 3b  user_data(pCtx);
d810: 0a 20 20 63 68 61 72 20 62 75 66 5b 38 5d 3b 0a  .  char buf[8];.
d820: 20 20 61 73 73 65 72 74 28 20 6e 41 72 67 3d 3d    assert( nArg==
d830: 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 73  0 );.  assert( s
d840: 69 7a 65 6f 66 28 62 75 66 29 3e 3d 73 69 7a 65  izeof(buf)>=size
d850: 6f 66 28 70 47 6c 6f 62 61 6c 29 20 29 3b 0a 20  of(pGlobal) );. 
d860: 20 6d 65 6d 63 70 79 28 62 75 66 2c 20 28 76 6f   memcpy(buf, (vo
d870: 69 64 2a 29 26 70 47 6c 6f 62 61 6c 2c 20 73 69  id*)&pGlobal, si
d880: 7a 65 6f 66 28 70 47 6c 6f 62 61 6c 29 29 3b 0a  zeof(pGlobal));.
d890: 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74    sqlite3_result
d8a0: 5f 62 6c 6f 62 28 70 43 74 78 2c 20 62 75 66 2c  _blob(pCtx, buf,
d8b0: 20 73 69 7a 65 6f 66 28 70 47 6c 6f 62 61 6c 29   sizeof(pGlobal)
d8c0: 2c 20 53 51 4c 49 54 45 5f 54 52 41 4e 53 49 45  , SQLITE_TRANSIE
d8d0: 4e 54 29 3b 0a 7d 0a 0a 69 6e 74 20 73 71 6c 69  NT);.}..int sqli
d8e0: 74 65 33 46 74 73 35 49 6e 69 74 28 73 71 6c 69  te3Fts5Init(sqli
d8f0: 74 65 33 20 2a 64 62 29 7b 0a 20 20 73 74 61 74  te3 *db){.  stat
d900: 69 63 20 63 6f 6e 73 74 20 73 71 6c 69 74 65 33  ic const sqlite3
d910: 5f 6d 6f 64 75 6c 65 20 66 74 73 35 4d 6f 64 20  _module fts5Mod 
d920: 3d 20 7b 0a 20 20 20 20 2f 2a 20 69 56 65 72 73  = {.    /* iVers
d930: 69 6f 6e 20 20 20 20 20 20 2a 2f 20 32 2c 0a 20  ion      */ 2,. 
d940: 20 20 20 2f 2a 20 78 43 72 65 61 74 65 20 20 20     /* xCreate   
d950: 20 20 20 20 2a 2f 20 66 74 73 35 43 72 65 61 74      */ fts5Creat
d960: 65 4d 65 74 68 6f 64 2c 0a 20 20 20 20 2f 2a 20  eMethod,.    /* 
d970: 78 43 6f 6e 6e 65 63 74 20 20 20 20 20 20 2a 2f  xConnect      */
d980: 20 66 74 73 35 43 6f 6e 6e 65 63 74 4d 65 74 68   fts5ConnectMeth
d990: 6f 64 2c 0a 20 20 20 20 2f 2a 20 78 42 65 73 74  od,.    /* xBest
d9a0: 49 6e 64 65 78 20 20 20 20 2a 2f 20 66 74 73 35  Index    */ fts5
d9b0: 42 65 73 74 49 6e 64 65 78 4d 65 74 68 6f 64 2c  BestIndexMethod,
d9c0: 0a 20 20 20 20 2f 2a 20 78 44 69 73 63 6f 6e 6e  .    /* xDisconn
d9d0: 65 63 74 20 20 20 2a 2f 20 66 74 73 35 44 69 73  ect   */ fts5Dis
d9e0: 63 6f 6e 6e 65 63 74 4d 65 74 68 6f 64 2c 0a 20  connectMethod,. 
d9f0: 20 20 20 2f 2a 20 78 44 65 73 74 72 6f 79 20 20     /* xDestroy  
da00: 20 20 20 20 2a 2f 20 66 74 73 35 44 65 73 74 72      */ fts5Destr
da10: 6f 79 4d 65 74 68 6f 64 2c 0a 20 20 20 20 2f 2a  oyMethod,.    /*
da20: 20 78 4f 70 65 6e 20 20 20 20 20 20 20 20 20 2a   xOpen         *
da30: 2f 20 66 74 73 35 4f 70 65 6e 4d 65 74 68 6f 64  / fts5OpenMethod
da40: 2c 0a 20 20 20 20 2f 2a 20 78 43 6c 6f 73 65 20  ,.    /* xClose 
da50: 20 20 20 20 20 20 20 2a 2f 20 66 74 73 35 43 6c         */ fts5Cl
da60: 6f 73 65 4d 65 74 68 6f 64 2c 0a 20 20 20 20 2f  oseMethod,.    /
da70: 2a 20 78 46 69 6c 74 65 72 20 20 20 20 20 20 20  * xFilter       
da80: 2a 2f 20 66 74 73 35 46 69 6c 74 65 72 4d 65 74  */ fts5FilterMet
da90: 68 6f 64 2c 0a 20 20 20 20 2f 2a 20 78 4e 65 78  hod,.    /* xNex
daa0: 74 20 20 20 20 20 20 20 20 20 2a 2f 20 66 74 73  t         */ fts
dab0: 35 4e 65 78 74 4d 65 74 68 6f 64 2c 0a 20 20 20  5NextMethod,.   
dac0: 20 2f 2a 20 78 45 6f 66 20 20 20 20 20 20 20 20   /* xEof        
dad0: 20 20 2a 2f 20 66 74 73 35 45 6f 66 4d 65 74 68    */ fts5EofMeth
dae0: 6f 64 2c 0a 20 20 20 20 2f 2a 20 78 43 6f 6c 75  od,.    /* xColu
daf0: 6d 6e 20 20 20 20 20 20 20 2a 2f 20 66 74 73 35  mn       */ fts5
db00: 43 6f 6c 75 6d 6e 4d 65 74 68 6f 64 2c 0a 20 20  ColumnMethod,.  
db10: 20 20 2f 2a 20 78 52 6f 77 69 64 20 20 20 20 20    /* xRowid     
db20: 20 20 20 2a 2f 20 66 74 73 35 52 6f 77 69 64 4d     */ fts5RowidM
db30: 65 74 68 6f 64 2c 0a 20 20 20 20 2f 2a 20 78 55  ethod,.    /* xU
db40: 70 64 61 74 65 20 20 20 20 20 20 20 2a 2f 20 66  pdate       */ f
db50: 74 73 35 55 70 64 61 74 65 4d 65 74 68 6f 64 2c  ts5UpdateMethod,
db60: 0a 20 20 20 20 2f 2a 20 78 42 65 67 69 6e 20 20  .    /* xBegin  
db70: 20 20 20 20 20 20 2a 2f 20 66 74 73 35 42 65 67        */ fts5Beg
db80: 69 6e 4d 65 74 68 6f 64 2c 0a 20 20 20 20 2f 2a  inMethod,.    /*
db90: 20 78 53 79 6e 63 20 20 20 20 20 20 20 20 20 2a   xSync         *
dba0: 2f 20 66 74 73 35 53 79 6e 63 4d 65 74 68 6f 64  / fts5SyncMethod
dbb0: 2c 0a 20 20 20 20 2f 2a 20 78 43 6f 6d 6d 69 74  ,.    /* xCommit
dbc0: 20 20 20 20 20 20 20 2a 2f 20 66 74 73 35 43 6f         */ fts5Co
dbd0: 6d 6d 69 74 4d 65 74 68 6f 64 2c 0a 20 20 20 20  mmitMethod,.    
dbe0: 2f 2a 20 78 52 6f 6c 6c 62 61 63 6b 20 20 20 20  /* xRollback    
dbf0: 20 2a 2f 20 66 74 73 35 52 6f 6c 6c 62 61 63 6b   */ fts5Rollback
dc00: 4d 65 74 68 6f 64 2c 0a 20 20 20 20 2f 2a 20 78  Method,.    /* x
dc10: 46 69 6e 64 46 75 6e 63 74 69 6f 6e 20 2a 2f 20  FindFunction */ 
dc20: 66 74 73 35 46 69 6e 64 46 75 6e 63 74 69 6f 6e  fts5FindFunction
dc30: 4d 65 74 68 6f 64 2c 0a 20 20 20 20 2f 2a 20 78  Method,.    /* x
dc40: 52 65 6e 61 6d 65 20 20 20 20 20 20 20 2a 2f 20  Rename       */ 
dc50: 66 74 73 35 52 65 6e 61 6d 65 4d 65 74 68 6f 64  fts5RenameMethod
dc60: 2c 0a 20 20 20 20 2f 2a 20 78 53 61 76 65 70 6f  ,.    /* xSavepo
dc70: 69 6e 74 20 20 20 20 2a 2f 20 66 74 73 35 53 61  int    */ fts5Sa
dc80: 76 65 70 6f 69 6e 74 4d 65 74 68 6f 64 2c 0a 20  vepointMethod,. 
dc90: 20 20 20 2f 2a 20 78 52 65 6c 65 61 73 65 20 20     /* xRelease  
dca0: 20 20 20 20 2a 2f 20 66 74 73 35 52 65 6c 65 61      */ fts5Relea
dcb0: 73 65 4d 65 74 68 6f 64 2c 0a 20 20 20 20 2f 2a  seMethod,.    /*
dcc0: 20 78 52 6f 6c 6c 62 61 63 6b 54 6f 20 20 20 2a   xRollbackTo   *
dcd0: 2f 20 66 74 73 35 52 6f 6c 6c 62 61 63 6b 54 6f  / fts5RollbackTo
dce0: 4d 65 74 68 6f 64 2c 0a 20 20 7d 3b 0a 0a 20 20  Method,.  };..  
dcf0: 69 6e 74 20 72 63 3b 0a 20 20 46 74 73 35 47 6c  int rc;.  Fts5Gl
dd00: 6f 62 61 6c 20 2a 70 47 6c 6f 62 61 6c 20 3d 20  obal *pGlobal = 
dd10: 30 3b 0a 20 20 70 47 6c 6f 62 61 6c 20 3d 20 28  0;.  pGlobal = (
dd20: 46 74 73 35 47 6c 6f 62 61 6c 2a 29 73 71 6c 69  Fts5Global*)sqli
dd30: 74 65 33 5f 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f  te3_malloc(sizeo
dd40: 66 28 46 74 73 35 47 6c 6f 62 61 6c 29 29 3b 0a  f(Fts5Global));.
dd50: 0a 20 20 69 66 28 20 70 47 6c 6f 62 61 6c 3d 3d  .  if( pGlobal==
dd60: 30 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 53 51  0 ){.    rc = SQ
dd70: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 65  LITE_NOMEM;.  }e
dd80: 6c 73 65 7b 0a 20 20 20 20 76 6f 69 64 20 2a 70  lse{.    void *p
dd90: 20 3d 20 28 76 6f 69 64 2a 29 70 47 6c 6f 62 61   = (void*)pGloba
dda0: 6c 3b 0a 20 20 20 20 6d 65 6d 73 65 74 28 70 47  l;.    memset(pG
ddb0: 6c 6f 62 61 6c 2c 20 30 2c 20 73 69 7a 65 6f 66  lobal, 0, sizeof
ddc0: 28 46 74 73 35 47 6c 6f 62 61 6c 29 29 3b 0a 20  (Fts5Global));. 
ddd0: 20 20 20 70 47 6c 6f 62 61 6c 2d 3e 64 62 20 3d     pGlobal->db =
dde0: 20 64 62 3b 0a 20 20 20 20 70 47 6c 6f 62 61 6c   db;.    pGlobal
ddf0: 2d 3e 61 70 69 2e 69 56 65 72 73 69 6f 6e 20 3d  ->api.iVersion =
de00: 20 31 3b 0a 20 20 20 20 70 47 6c 6f 62 61 6c 2d   1;.    pGlobal-
de10: 3e 61 70 69 2e 78 43 72 65 61 74 65 46 75 6e 63  >api.xCreateFunc
de20: 74 69 6f 6e 20 3d 20 66 74 73 35 43 72 65 61 74  tion = fts5Creat
de30: 65 41 75 78 3b 0a 20 20 20 20 70 47 6c 6f 62 61  eAux;.    pGloba
de40: 6c 2d 3e 61 70 69 2e 78 43 72 65 61 74 65 54 6f  l->api.xCreateTo
de50: 6b 65 6e 69 7a 65 72 20 3d 20 66 74 73 35 43 72  kenizer = fts5Cr
de60: 65 61 74 65 54 6f 6b 65 6e 69 7a 65 72 3b 0a 20  eateTokenizer;. 
de70: 20 20 20 70 47 6c 6f 62 61 6c 2d 3e 61 70 69 2e     pGlobal->api.
de80: 78 46 69 6e 64 54 6f 6b 65 6e 69 7a 65 72 20 3d  xFindTokenizer =
de90: 20 66 74 73 35 46 69 6e 64 54 6f 6b 65 6e 69 7a   fts5FindTokeniz
dea0: 65 72 3b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c  er;.    rc = sql
deb0: 69 74 65 33 5f 63 72 65 61 74 65 5f 6d 6f 64 75  ite3_create_modu
dec0: 6c 65 5f 76 32 28 64 62 2c 20 22 66 74 73 35 22  le_v2(db, "fts5"
ded0: 2c 20 26 66 74 73 35 4d 6f 64 2c 20 70 2c 20 66  , &fts5Mod, p, f
dee0: 74 73 35 4d 6f 64 75 6c 65 44 65 73 74 72 6f 79  ts5ModuleDestroy
def0: 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53  );.    if( rc==S
df00: 51 4c 49 54 45 5f 4f 4b 20 29 20 72 63 20 3d 20  QLITE_OK ) rc = 
df10: 73 71 6c 69 74 65 33 46 74 73 35 49 6e 64 65 78  sqlite3Fts5Index
df20: 49 6e 69 74 28 64 62 29 3b 0a 20 20 20 20 69 66  Init(db);.    if
df30: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
df40: 29 20 72 63 20 3d 20 73 71 6c 69 74 65 33 46 74  ) rc = sqlite3Ft
df50: 73 35 45 78 70 72 49 6e 69 74 28 70 47 6c 6f 62  s5ExprInit(pGlob
df60: 61 6c 2c 20 64 62 29 3b 0a 20 20 20 20 69 66 28  al, db);.    if(
df70: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
df80: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 46 74 73   rc = sqlite3Fts
df90: 35 41 75 78 49 6e 69 74 28 26 70 47 6c 6f 62 61  5AuxInit(&pGloba
dfa0: 6c 2d 3e 61 70 69 29 3b 0a 20 20 20 20 69 66 28  l->api);.    if(
dfb0: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
dfc0: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 46 74 73   rc = sqlite3Fts
dfd0: 35 54 6f 6b 65 6e 69 7a 65 72 49 6e 69 74 28 26  5TokenizerInit(&
dfe0: 70 47 6c 6f 62 61 6c 2d 3e 61 70 69 29 3b 0a 20  pGlobal->api);. 
dff0: 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
e000: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72 63  E_OK ){.      rc
e010: 20 3d 20 73 71 6c 69 74 65 33 5f 63 72 65 61 74   = sqlite3_creat
e020: 65 5f 66 75 6e 63 74 69 6f 6e 28 0a 20 20 20 20  e_function(.    
e030: 20 20 20 20 20 20 64 62 2c 20 22 66 74 73 35 22        db, "fts5"
e040: 2c 20 30 2c 20 53 51 4c 49 54 45 5f 55 54 46 38  , 0, SQLITE_UTF8
e050: 2c 20 70 2c 20 66 74 73 35 46 74 73 35 46 75 6e  , p, fts5Fts5Fun
e060: 63 2c 20 30 2c 20 30 0a 20 20 20 20 20 20 29 3b  c, 0, 0.      );
e070: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74  .    }.  }.  ret
e080: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 0a              urn rc;.}...