/ Hex Artifact Content
Login

Artifact 1dae34f4a788b5760c52b914d6384d83ee027b35:


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 46 74 73 35 41 75 78 69  ). */.  Fts5Auxi
1890: 6c 69 61 72 79 20 2a 70 52 61 6e 6b 3b 20 20 20  liary *pRank;   
18a0: 20 20 20 20 20 20 20 20 2f 2a 20 52 61 6e 6b 20          /* Rank 
18b0: 63 61 6c 6c 62 61 63 6b 20 28 6f 72 20 4e 55 4c  callback (or NUL
18c0: 4c 29 20 2a 2f 0a 20 20 69 6e 74 20 6e 52 61 6e  L) */.  int nRan
18d0: 6b 41 72 67 3b 20 20 20 20 20 20 20 20 20 20 20  kArg;           
18e0: 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65          /* Numbe
18f0: 72 20 6f 66 20 74 72 61 69 6c 69 6e 67 20 61 72  r of trailing ar
1900: 67 75 6d 65 6e 74 73 20 66 6f 72 20 72 61 6e 6b  guments for rank
1910: 28 29 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f  () */.  sqlite3_
1920: 76 61 6c 75 65 20 2a 2a 61 70 52 61 6e 6b 41 72  value **apRankAr
1930: 67 3b 20 20 20 20 20 20 2f 2a 20 41 72 72 61 79  g;      /* Array
1940: 20 6f 66 20 74 72 61 69 6c 69 6e 67 20 61 72 67   of trailing arg
1950: 75 6d 65 6e 74 73 20 2a 2f 0a 20 20 73 71 6c 69  uments */.  sqli
1960: 74 65 33 5f 73 74 6d 74 20 2a 70 52 61 6e 6b 41  te3_stmt *pRankA
1970: 72 67 53 74 6d 74 3b 20 20 20 20 20 2f 2a 20 4f  rgStmt;     /* O
1980: 72 69 67 69 6e 20 6f 66 20 6f 62 6a 65 63 74 73  rigin of objects
1990: 20 69 6e 20 61 70 52 61 6e 6b 41 72 67 5b 5d 20   in apRankArg[] 
19a0: 2a 2f 0a 0a 20 20 2f 2a 20 56 61 72 69 61 62 6c  */..  /* Variabl
19b0: 65 73 20 75 73 65 64 20 62 79 20 61 75 78 69 6c  es used by auxil
19c0: 69 61 72 79 20 66 75 6e 63 74 69 6f 6e 73 20 2a  iary functions *
19d0: 2f 0a 20 20 69 36 34 20 69 43 73 72 49 64 3b 20  /.  i64 iCsrId; 
19e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
19f0: 20 20 20 20 2f 2a 20 43 75 72 73 6f 72 20 69 64      /* Cursor id
1a00: 20 2a 2f 0a 20 20 46 74 73 35 41 75 78 69 6c 69   */.  Fts5Auxili
1a10: 61 72 79 20 2a 70 41 75 78 3b 20 20 20 20 20 20  ary *pAux;      
1a20: 20 20 20 20 20 20 2f 2a 20 43 75 72 72 65 6e 74        /* Current
1a30: 6c 79 20 65 78 65 63 75 74 69 6e 67 20 65 78 74  ly executing ext
1a40: 65 6e 73 69 6f 6e 20 66 75 6e 63 74 69 6f 6e 20  ension function 
1a50: 2a 2f 0a 20 20 46 74 73 35 41 75 78 64 61 74 61  */.  Fts5Auxdata
1a60: 20 2a 70 41 75 78 64 61 74 61 3b 20 20 20 20 20   *pAuxdata;     
1a70: 20 20 20 20 20 2f 2a 20 46 69 72 73 74 20 69 6e       /* First in
1a80: 20 6c 69 6e 6b 65 64 20 6c 69 73 74 20 6f 66 20   linked list of 
1a90: 73 61 76 65 64 20 61 75 78 2d 64 61 74 61 20 2a  saved aux-data *
1aa0: 2f 0a 20 20 69 6e 74 20 2a 61 43 6f 6c 75 6d 6e  /.  int *aColumn
1ab0: 53 69 7a 65 3b 20 20 20 20 20 20 20 20 20 20 20  Size;           
1ac0: 20 20 20 20 2f 2a 20 56 61 6c 75 65 73 20 66 6f      /* Values fo
1ad0: 72 20 78 43 6f 6c 75 6d 6e 53 69 7a 65 28 29 20  r xColumnSize() 
1ae0: 2a 2f 0a 0a 20 20 69 6e 74 20 6e 49 6e 73 74 43  */..  int nInstC
1af0: 6f 75 6e 74 3b 20 20 20 20 20 20 20 20 20 20 20  ount;           
1b00: 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20        /* Number 
1b10: 6f 66 20 70 68 72 61 73 65 20 69 6e 73 74 61 6e  of phrase instan
1b20: 63 65 73 20 2a 2f 0a 20 20 69 6e 74 20 2a 61 49  ces */.  int *aI
1b30: 6e 73 74 3b 20 20 20 20 20 20 20 20 20 20 20 20  nst;            
1b40: 20 20 20 20 20 20 20 20 20 2f 2a 20 33 20 69 6e           /* 3 in
1b50: 74 65 67 65 72 73 20 70 65 72 20 70 68 72 61 73  tegers per phras
1b60: 65 20 69 6e 73 74 61 6e 63 65 20 2a 2f 0a 7d 3b  e instance */.};
1b70: 0a 0a 2f 2a 0a 2a 2a 20 56 61 6c 75 65 73 20 66  ../*.** Values f
1b80: 6f 72 20 46 74 73 35 43 75 72 73 6f 72 2e 63 73  or Fts5Cursor.cs
1b90: 72 66 6c 61 67 73 0a 2a 2f 0a 23 64 65 66 69 6e  rflags.*/.#defin
1ba0: 65 20 46 54 53 35 43 53 52 5f 52 45 51 55 49 52  e FTS5CSR_REQUIR
1bb0: 45 5f 43 4f 4e 54 45 4e 54 20 20 20 30 78 30 31  E_CONTENT   0x01
1bc0: 0a 23 64 65 66 69 6e 65 20 46 54 53 35 43 53 52  .#define FTS5CSR
1bd0: 5f 52 45 51 55 49 52 45 5f 44 4f 43 53 49 5a 45  _REQUIRE_DOCSIZE
1be0: 20 20 20 30 78 30 32 0a 23 64 65 66 69 6e 65 20     0x02.#define 
1bf0: 46 54 53 35 43 53 52 5f 45 4f 46 20 20 20 20 20  FTS5CSR_EOF     
1c00: 20 20 20 20 20 20 20 20 20 20 30 78 30 34 0a 0a            0x04..
1c10: 2f 2a 0a 2a 2a 20 4d 61 63 72 6f 73 20 74 6f 20  /*.** Macros to 
1c20: 53 65 74 28 29 2c 20 43 6c 65 61 72 28 29 20 61  Set(), Clear() a
1c30: 6e 64 20 54 65 73 74 28 29 20 63 75 72 73 6f 72  nd Test() cursor
1c40: 20 66 6c 61 67 73 2e 0a 2a 2f 0a 23 64 65 66 69   flags..*/.#defi
1c50: 6e 65 20 43 73 72 46 6c 61 67 53 65 74 28 70 43  ne CsrFlagSet(pC
1c60: 73 72 2c 20 66 6c 61 67 29 20 20 20 28 28 70 43  sr, flag)   ((pC
1c70: 73 72 29 2d 3e 63 73 72 66 6c 61 67 73 20 7c 3d  sr)->csrflags |=
1c80: 20 28 66 6c 61 67 29 29 0a 23 64 65 66 69 6e 65   (flag)).#define
1c90: 20 43 73 72 46 6c 61 67 43 6c 65 61 72 28 70 43   CsrFlagClear(pC
1ca0: 73 72 2c 20 66 6c 61 67 29 20 28 28 70 43 73 72  sr, flag) ((pCsr
1cb0: 29 2d 3e 63 73 72 66 6c 61 67 73 20 26 3d 20 7e  )->csrflags &= ~
1cc0: 28 66 6c 61 67 29 29 0a 23 64 65 66 69 6e 65 20  (flag)).#define 
1cd0: 43 73 72 46 6c 61 67 54 65 73 74 28 70 43 73 72  CsrFlagTest(pCsr
1ce0: 2c 20 66 6c 61 67 29 20 20 28 28 70 43 73 72 29  , flag)  ((pCsr)
1cf0: 2d 3e 63 73 72 66 6c 61 67 73 20 26 20 28 66 6c  ->csrflags & (fl
1d00: 61 67 29 29 0a 0a 73 74 72 75 63 74 20 46 74 73  ag))..struct Fts
1d10: 35 41 75 78 64 61 74 61 20 7b 0a 20 20 46 74 73  5Auxdata {.  Fts
1d20: 35 41 75 78 69 6c 69 61 72 79 20 2a 70 41 75 78  5Auxiliary *pAux
1d30: 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ;            /* 
1d40: 45 78 74 65 6e 73 69 6f 6e 20 74 6f 20 77 68 69  Extension to whi
1d50: 63 68 20 74 68 69 73 20 62 65 6c 6f 6e 67 73 20  ch this belongs 
1d60: 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 50 74 72 3b  */.  void *pPtr;
1d70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1d80: 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20       /* Pointer 
1d90: 76 61 6c 75 65 20 2a 2f 0a 20 20 76 6f 69 64 28  value */.  void(
1da0: 2a 78 44 65 6c 65 74 65 29 28 76 6f 69 64 2a 29  *xDelete)(void*)
1db0: 3b 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 65  ;          /* De
1dc0: 73 74 72 75 63 74 6f 72 20 2a 2f 0a 20 20 46 74  structor */.  Ft
1dd0: 73 35 41 75 78 64 61 74 61 20 2a 70 4e 65 78 74  s5Auxdata *pNext
1de0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ;             /*
1df0: 20 4e 65 78 74 20 6f 62 6a 65 63 74 20 69 6e 20   Next object in 
1e00: 6c 69 6e 6b 65 64 20 6c 69 73 74 20 2a 2f 0a 7d  linked list */.}
1e10: 3b 0a 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45  ;..#ifdef SQLITE
1e20: 5f 44 45 42 55 47 0a 23 64 65 66 69 6e 65 20 46  _DEBUG.#define F
1e30: 54 53 35 5f 42 45 47 49 4e 20 20 20 20 20 20 31  TS5_BEGIN      1
1e40: 0a 23 64 65 66 69 6e 65 20 46 54 53 35 5f 53 59  .#define FTS5_SY
1e50: 4e 43 20 20 20 20 20 20 20 32 0a 23 64 65 66 69  NC       2.#defi
1e60: 6e 65 20 46 54 53 35 5f 43 4f 4d 4d 49 54 20 20  ne FTS5_COMMIT  
1e70: 20 20 20 33 0a 23 64 65 66 69 6e 65 20 46 54 53     3.#define FTS
1e80: 35 5f 52 4f 4c 4c 42 41 43 4b 20 20 20 34 0a 23  5_ROLLBACK   4.#
1e90: 64 65 66 69 6e 65 20 46 54 53 35 5f 53 41 56 45  define FTS5_SAVE
1ea0: 50 4f 49 4e 54 20 20 35 0a 23 64 65 66 69 6e 65  POINT  5.#define
1eb0: 20 46 54 53 35 5f 52 45 4c 45 41 53 45 20 20 20   FTS5_RELEASE   
1ec0: 20 36 0a 23 64 65 66 69 6e 65 20 46 54 53 35 5f   6.#define FTS5_
1ed0: 52 4f 4c 4c 42 41 43 4b 54 4f 20 37 0a 73 74 61  ROLLBACKTO 7.sta
1ee0: 74 69 63 20 76 6f 69 64 20 66 74 73 35 43 68 65  tic void fts5Che
1ef0: 63 6b 54 72 61 6e 73 61 63 74 69 6f 6e 53 74 61  ckTransactionSta
1f00: 74 65 28 46 74 73 35 54 61 62 6c 65 20 2a 70 2c  te(Fts5Table *p,
1f10: 20 69 6e 74 20 6f 70 2c 20 69 6e 74 20 69 53 61   int op, int iSa
1f20: 76 65 70 6f 69 6e 74 29 7b 0a 20 20 73 77 69 74  vepoint){.  swit
1f30: 63 68 28 20 6f 70 20 29 7b 0a 20 20 20 20 63 61  ch( op ){.    ca
1f40: 73 65 20 46 54 53 35 5f 42 45 47 49 4e 3a 0a 20  se FTS5_BEGIN:. 
1f50: 20 20 20 20 20 61 73 73 65 72 74 28 20 70 2d 3e       assert( p->
1f60: 74 73 2e 65 53 74 61 74 65 3d 3d 30 20 29 3b 0a  ts.eState==0 );.
1f70: 20 20 20 20 20 20 70 2d 3e 74 73 2e 65 53 74 61        p->ts.eSta
1f80: 74 65 20 3d 20 31 3b 0a 20 20 20 20 20 20 70 2d  te = 1;.      p-
1f90: 3e 74 73 2e 69 53 61 76 65 70 6f 69 6e 74 20 3d  >ts.iSavepoint =
1fa0: 20 2d 31 3b 0a 20 20 20 20 20 20 62 72 65 61 6b   -1;.      break
1fb0: 3b 0a 0a 20 20 20 20 63 61 73 65 20 46 54 53 35  ;..    case FTS5
1fc0: 5f 53 59 4e 43 3a 0a 20 20 20 20 20 20 61 73 73  _SYNC:.      ass
1fd0: 65 72 74 28 20 70 2d 3e 74 73 2e 65 53 74 61 74  ert( p->ts.eStat
1fe0: 65 3d 3d 31 20 29 3b 0a 20 20 20 20 20 20 70 2d  e==1 );.      p-
1ff0: 3e 74 73 2e 65 53 74 61 74 65 20 3d 20 32 3b 0a  >ts.eState = 2;.
2000: 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 0a 20 20        break;..  
2010: 20 20 63 61 73 65 20 46 54 53 35 5f 43 4f 4d 4d    case FTS5_COMM
2020: 49 54 3a 0a 20 20 20 20 20 20 61 73 73 65 72 74  IT:.      assert
2030: 28 20 70 2d 3e 74 73 2e 65 53 74 61 74 65 3d 3d  ( p->ts.eState==
2040: 32 20 29 3b 0a 20 20 20 20 20 20 70 2d 3e 74 73  2 );.      p->ts
2050: 2e 65 53 74 61 74 65 20 3d 20 30 3b 0a 20 20 20  .eState = 0;.   
2060: 20 20 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20 63     break;..    c
2070: 61 73 65 20 46 54 53 35 5f 52 4f 4c 4c 42 41 43  ase FTS5_ROLLBAC
2080: 4b 3a 0a 20 20 20 20 20 20 61 73 73 65 72 74 28  K:.      assert(
2090: 20 70 2d 3e 74 73 2e 65 53 74 61 74 65 3d 3d 31   p->ts.eState==1
20a0: 20 7c 7c 20 70 2d 3e 74 73 2e 65 53 74 61 74 65   || p->ts.eState
20b0: 3d 3d 32 20 29 3b 0a 20 20 20 20 20 20 70 2d 3e  ==2 );.      p->
20c0: 74 73 2e 65 53 74 61 74 65 20 3d 20 30 3b 0a 20  ts.eState = 0;. 
20d0: 20 20 20 20 20 62 72 65 61 6b 3b 0a 0a 20 20 20       break;..   
20e0: 20 63 61 73 65 20 46 54 53 35 5f 53 41 56 45 50   case FTS5_SAVEP
20f0: 4f 49 4e 54 3a 0a 20 20 20 20 20 20 61 73 73 65  OINT:.      asse
2100: 72 74 28 20 70 2d 3e 74 73 2e 65 53 74 61 74 65  rt( p->ts.eState
2110: 3d 3d 31 20 29 3b 0a 20 20 20 20 20 20 61 73 73  ==1 );.      ass
2120: 65 72 74 28 20 69 53 61 76 65 70 6f 69 6e 74 3e  ert( iSavepoint>
2130: 3d 30 20 29 3b 0a 20 20 20 20 20 20 61 73 73 65  =0 );.      asse
2140: 72 74 28 20 69 53 61 76 65 70 6f 69 6e 74 3e 70  rt( iSavepoint>p
2150: 2d 3e 74 73 2e 69 53 61 76 65 70 6f 69 6e 74 20  ->ts.iSavepoint 
2160: 29 3b 0a 20 20 20 20 20 20 70 2d 3e 74 73 2e 69  );.      p->ts.i
2170: 53 61 76 65 70 6f 69 6e 74 20 3d 20 69 53 61 76  Savepoint = iSav
2180: 65 70 6f 69 6e 74 3b 0a 20 20 20 20 20 20 62 72  epoint;.      br
2190: 65 61 6b 3b 0a 20 20 20 20 20 20 0a 20 20 20 20  eak;.      .    
21a0: 63 61 73 65 20 46 54 53 35 5f 52 45 4c 45 41 53  case FTS5_RELEAS
21b0: 45 3a 0a 20 20 20 20 20 20 61 73 73 65 72 74 28  E:.      assert(
21c0: 20 70 2d 3e 74 73 2e 65 53 74 61 74 65 3d 3d 31   p->ts.eState==1
21d0: 20 29 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74   );.      assert
21e0: 28 20 69 53 61 76 65 70 6f 69 6e 74 3e 3d 30 20  ( iSavepoint>=0 
21f0: 29 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74 28  );.      assert(
2200: 20 69 53 61 76 65 70 6f 69 6e 74 3c 3d 70 2d 3e   iSavepoint<=p->
2210: 74 73 2e 69 53 61 76 65 70 6f 69 6e 74 20 29 3b  ts.iSavepoint );
2220: 0a 20 20 20 20 20 20 70 2d 3e 74 73 2e 69 53 61  .      p->ts.iSa
2230: 76 65 70 6f 69 6e 74 20 3d 20 69 53 61 76 65 70  vepoint = iSavep
2240: 6f 69 6e 74 2d 31 3b 0a 20 20 20 20 20 20 62 72  oint-1;.      br
2250: 65 61 6b 3b 0a 0a 20 20 20 20 63 61 73 65 20 46  eak;..    case F
2260: 54 53 35 5f 52 4f 4c 4c 42 41 43 4b 54 4f 3a 0a  TS5_ROLLBACKTO:.
2270: 20 20 20 20 20 20 61 73 73 65 72 74 28 20 70 2d        assert( p-
2280: 3e 74 73 2e 65 53 74 61 74 65 3d 3d 31 20 29 3b  >ts.eState==1 );
2290: 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20 69  .      assert( i
22a0: 53 61 76 65 70 6f 69 6e 74 3e 3d 30 20 29 3b 0a  Savepoint>=0 );.
22b0: 20 20 20 20 20 20 61 73 73 65 72 74 28 20 69 53        assert( iS
22c0: 61 76 65 70 6f 69 6e 74 3c 3d 70 2d 3e 74 73 2e  avepoint<=p->ts.
22d0: 69 53 61 76 65 70 6f 69 6e 74 20 29 3b 0a 20 20  iSavepoint );.  
22e0: 20 20 20 20 70 2d 3e 74 73 2e 69 53 61 76 65 70      p->ts.iSavep
22f0: 6f 69 6e 74 20 3d 20 69 53 61 76 65 70 6f 69 6e  oint = iSavepoin
2300: 74 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a  t;.      break;.
2310: 20 20 7d 0a 7d 0a 23 65 6c 73 65 0a 23 20 64 65    }.}.#else.# de
2320: 66 69 6e 65 20 66 74 73 35 43 68 65 63 6b 54 72  fine fts5CheckTr
2330: 61 6e 73 61 63 74 69 6f 6e 53 74 61 74 65 28 78  ansactionState(x
2340: 2c 79 2c 7a 29 0a 23 65 6e 64 69 66 0a 0a 0a 2f  ,y,z).#endif.../
2350: 2a 0a 2a 2a 20 43 6c 6f 73 65 20 61 20 76 69 72  *.** Close a vir
2360: 74 75 61 6c 20 74 61 62 6c 65 20 68 61 6e 64 6c  tual table handl
2370: 65 20 6f 70 65 6e 65 64 20 62 79 20 66 74 73 35  e opened by fts5
2380: 49 6e 69 74 56 74 61 62 28 29 2e 20 49 66 20 74  InitVtab(). If t
2390: 68 65 20 62 44 65 73 74 72 6f 79 0a 2a 2a 20 61  he bDestroy.** a
23a0: 72 67 75 6d 65 6e 74 20 69 73 20 6e 6f 6e 2d 7a  rgument is non-z
23b0: 65 72 6f 2c 20 61 74 74 65 6d 70 74 20 64 65 6c  ero, attempt del
23c0: 65 74 65 20 74 68 65 20 73 68 61 64 6f 77 20 74  ete the shadow t
23d0: 61 62 6c 65 73 20 66 72 6f 6d 20 74 65 68 20 64  ables from teh d
23e0: 61 74 61 62 61 73 65 0a 2a 2f 0a 73 74 61 74 69  atabase.*/.stati
23f0: 63 20 69 6e 74 20 66 74 73 35 46 72 65 65 56 74  c int fts5FreeVt
2400: 61 62 28 46 74 73 35 54 61 62 6c 65 20 2a 70 54  ab(Fts5Table *pT
2410: 61 62 2c 20 69 6e 74 20 62 44 65 73 74 72 6f 79  ab, int bDestroy
2420: 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51  ){.  int rc = SQ
2430: 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 66 28 20 70  LITE_OK;.  if( p
2440: 54 61 62 20 29 7b 0a 20 20 20 20 69 6e 74 20 72  Tab ){.    int r
2450: 63 32 3b 0a 20 20 20 20 72 63 32 20 3d 20 73 71  c2;.    rc2 = sq
2460: 6c 69 74 65 33 46 74 73 35 49 6e 64 65 78 43 6c  lite3Fts5IndexCl
2470: 6f 73 65 28 70 54 61 62 2d 3e 70 49 6e 64 65 78  ose(pTab->pIndex
2480: 2c 20 62 44 65 73 74 72 6f 79 29 3b 0a 20 20 20  , bDestroy);.   
2490: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
24a0: 4f 4b 20 29 20 72 63 20 3d 20 72 63 32 3b 0a 20  OK ) rc = rc2;. 
24b0: 20 20 20 72 63 32 20 3d 20 73 71 6c 69 74 65 33     rc2 = sqlite3
24c0: 46 74 73 35 53 74 6f 72 61 67 65 43 6c 6f 73 65  Fts5StorageClose
24d0: 28 70 54 61 62 2d 3e 70 53 74 6f 72 61 67 65 2c  (pTab->pStorage,
24e0: 20 62 44 65 73 74 72 6f 79 29 3b 0a 20 20 20 20   bDestroy);.    
24f0: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
2500: 4b 20 29 20 72 63 20 3d 20 72 63 32 3b 0a 20 20  K ) rc = rc2;.  
2510: 20 20 73 71 6c 69 74 65 33 46 74 73 35 43 6f 6e    sqlite3Fts5Con
2520: 66 69 67 46 72 65 65 28 70 54 61 62 2d 3e 70 43  figFree(pTab->pC
2530: 6f 6e 66 69 67 29 3b 0a 20 20 20 20 73 71 6c 69  onfig);.    sqli
2540: 74 65 33 5f 66 72 65 65 28 70 54 61 62 29 3b 0a  te3_free(pTab);.
2550: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b    }.  return rc;
2560: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 78 44  .}../*.** The xD
2570: 69 73 63 6f 6e 6e 65 63 74 28 29 20 76 69 72 74  isconnect() virt
2580: 75 61 6c 20 74 61 62 6c 65 20 6d 65 74 68 6f 64  ual table method
2590: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
25a0: 66 74 73 35 44 69 73 63 6f 6e 6e 65 63 74 4d 65  fts5DisconnectMe
25b0: 74 68 6f 64 28 73 71 6c 69 74 65 33 5f 76 74 61  thod(sqlite3_vta
25c0: 62 20 2a 70 56 74 61 62 29 7b 0a 20 20 72 65 74  b *pVtab){.  ret
25d0: 75 72 6e 20 66 74 73 35 46 72 65 65 56 74 61 62  urn fts5FreeVtab
25e0: 28 28 46 74 73 35 54 61 62 6c 65 2a 29 70 56 74  ((Fts5Table*)pVt
25f0: 61 62 2c 20 30 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  ab, 0);.}../*.**
2600: 20 54 68 65 20 78 44 65 73 74 72 6f 79 28 29 20   The xDestroy() 
2610: 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20 6d 65  virtual table me
2620: 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  thod..*/.static 
2630: 69 6e 74 20 66 74 73 35 44 65 73 74 72 6f 79 4d  int fts5DestroyM
2640: 65 74 68 6f 64 28 73 71 6c 69 74 65 33 5f 76 74  ethod(sqlite3_vt
2650: 61 62 20 2a 70 56 74 61 62 29 7b 0a 20 20 72 65  ab *pVtab){.  re
2660: 74 75 72 6e 20 66 74 73 35 46 72 65 65 56 74 61  turn fts5FreeVta
2670: 62 28 28 46 74 73 35 54 61 62 6c 65 2a 29 70 56  b((Fts5Table*)pV
2680: 74 61 62 2c 20 31 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  tab, 1);.}../*.*
2690: 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  * This function 
26a0: 69 73 20 74 68 65 20 69 6d 70 6c 65 6d 65 6e 74  is the implement
26b0: 61 74 69 6f 6e 20 6f 66 20 62 6f 74 68 20 74 68  ation of both th
26c0: 65 20 78 43 6f 6e 6e 65 63 74 20 61 6e 64 20 78  e xConnect and x
26d0: 43 72 65 61 74 65 0a 2a 2a 20 6d 65 74 68 6f 64  Create.** method
26e0: 73 20 6f 66 20 74 68 65 20 46 54 53 33 20 76 69  s of the FTS3 vi
26f0: 72 74 75 61 6c 20 74 61 62 6c 65 2e 0a 2a 2a 0a  rtual table..**.
2700: 2a 2a 20 54 68 65 20 61 72 67 76 5b 5d 20 61 72  ** The argv[] ar
2710: 72 61 79 20 63 6f 6e 74 61 69 6e 73 20 74 68 65  ray contains the
2720: 20 66 6f 6c 6c 6f 77 69 6e 67 3a 0a 2a 2a 0a 2a   following:.**.*
2730: 2a 20 20 20 61 72 67 76 5b 30 5d 20 20 20 2d 3e  *   argv[0]   ->
2740: 20 6d 6f 64 75 6c 65 20 6e 61 6d 65 20 20 28 22   module name  ("
2750: 66 74 73 35 22 29 0a 2a 2a 20 20 20 61 72 67 76  fts5").**   argv
2760: 5b 31 5d 20 20 20 2d 3e 20 64 61 74 61 62 61 73  [1]   -> databas
2770: 65 20 6e 61 6d 65 0a 2a 2a 20 20 20 61 72 67 76  e name.**   argv
2780: 5b 32 5d 20 20 20 2d 3e 20 74 61 62 6c 65 20 6e  [2]   -> table n
2790: 61 6d 65 0a 2a 2a 20 20 20 61 72 67 76 5b 2e 2e  ame.**   argv[..
27a0: 2e 5d 20 2d 3e 20 22 63 6f 6c 75 6d 6e 20 6e 61  .] -> "column na
27b0: 6d 65 22 20 61 6e 64 20 6f 74 68 65 72 20 6d 6f  me" and other mo
27c0: 64 75 6c 65 20 61 72 67 75 6d 65 6e 74 20 66 69  dule argument fi
27d0: 65 6c 64 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  elds..*/.static 
27e0: 69 6e 74 20 66 74 73 35 49 6e 69 74 56 74 61 62  int fts5InitVtab
27f0: 28 0a 20 20 69 6e 74 20 62 43 72 65 61 74 65 2c  (.  int bCreate,
2800: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2810: 20 20 20 20 2f 2a 20 54 72 75 65 20 66 6f 72 20      /* True for 
2820: 78 43 72 65 61 74 65 2c 20 66 61 6c 73 65 20 66  xCreate, false f
2830: 6f 72 20 78 43 6f 6e 6e 65 63 74 20 2a 2f 0a 20  or xConnect */. 
2840: 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 20 20   sqlite3 *db,   
2850: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2860: 20 2f 2a 20 54 68 65 20 53 51 4c 69 74 65 20 64   /* The SQLite d
2870: 61 74 61 62 61 73 65 20 63 6f 6e 6e 65 63 74 69  atabase connecti
2880: 6f 6e 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 41  on */.  void *pA
2890: 75 78 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ux,             
28a0: 20 20 20 20 20 20 20 20 2f 2a 20 48 61 73 68 20          /* Hash 
28b0: 74 61 62 6c 65 20 63 6f 6e 74 61 69 6e 69 6e 67  table containing
28c0: 20 74 6f 6b 65 6e 69 7a 65 72 73 20 2a 2f 0a 20   tokenizers */. 
28d0: 20 69 6e 74 20 61 72 67 63 2c 20 20 20 20 20 20   int argc,      
28e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
28f0: 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 65 6c   /* Number of el
2900: 65 6d 65 6e 74 73 20 69 6e 20 61 72 67 76 20 61  ements in argv a
2910: 72 72 61 79 20 2a 2f 0a 20 20 63 6f 6e 73 74 20  rray */.  const 
2920: 63 68 61 72 20 2a 20 63 6f 6e 73 74 20 2a 61 72  char * const *ar
2930: 67 76 2c 20 20 20 20 20 20 20 2f 2a 20 78 43 72  gv,       /* xCr
2940: 65 61 74 65 2f 78 43 6f 6e 6e 65 63 74 20 61 72  eate/xConnect ar
2950: 67 75 6d 65 6e 74 20 61 72 72 61 79 20 2a 2f 0a  gument array */.
2960: 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a    sqlite3_vtab *
2970: 2a 70 70 56 54 61 62 2c 20 20 20 20 20 20 20 20  *ppVTab,        
2980: 20 20 2f 2a 20 57 72 69 74 65 20 74 68 65 20 72    /* Write the r
2990: 65 73 75 6c 74 69 6e 67 20 76 74 61 62 20 73 74  esulting vtab st
29a0: 72 75 63 74 75 72 65 20 68 65 72 65 20 2a 2f 0a  ructure here */.
29b0: 20 20 63 68 61 72 20 2a 2a 70 7a 45 72 72 20 20    char **pzErr  
29c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
29d0: 20 20 2f 2a 20 57 72 69 74 65 20 61 6e 79 20 65    /* Write any e
29e0: 72 72 6f 72 20 6d 65 73 73 61 67 65 20 68 65 72  rror message her
29f0: 65 20 2a 2f 0a 29 7b 0a 20 20 46 74 73 35 47 6c  e */.){.  Fts5Gl
2a00: 6f 62 61 6c 20 2a 70 47 6c 6f 62 61 6c 20 3d 20  obal *pGlobal = 
2a10: 28 46 74 73 35 47 6c 6f 62 61 6c 2a 29 70 41 75  (Fts5Global*)pAu
2a20: 78 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  x;.  const char 
2a30: 2a 2a 61 7a 43 6f 6e 66 69 67 20 3d 20 28 63 6f  **azConfig = (co
2a40: 6e 73 74 20 63 68 61 72 2a 2a 29 61 72 67 76 3b  nst char**)argv;
2a50: 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49  .  int rc = SQLI
2a60: 54 45 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20 20  TE_OK;          
2a70: 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64     /* Return cod
2a80: 65 20 2a 2f 0a 20 20 46 74 73 35 43 6f 6e 66 69  e */.  Fts5Confi
2a90: 67 20 2a 70 43 6f 6e 66 69 67 3b 20 20 20 20 20  g *pConfig;     
2aa0: 20 20 20 20 20 20 20 2f 2a 20 52 65 73 75 6c 74         /* Result
2ab0: 73 20 6f 66 20 70 61 72 73 69 6e 67 20 61 72 67  s of parsing arg
2ac0: 63 2f 61 72 67 76 20 2a 2f 0a 20 20 46 74 73 35  c/argv */.  Fts5
2ad0: 54 61 62 6c 65 20 2a 70 54 61 62 20 3d 20 30 3b  Table *pTab = 0;
2ae0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
2af0: 65 77 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65  ew virtual table
2b00: 20 6f 62 6a 65 63 74 20 2a 2f 0a 0a 20 20 2f 2a   object */..  /*
2b10: 20 41 6c 6c 6f 63 61 74 65 20 74 68 65 20 6e 65   Allocate the ne
2b20: 77 20 76 74 61 62 20 6f 62 6a 65 63 74 20 61 6e  w vtab object an
2b30: 64 20 70 61 72 73 65 20 74 68 65 20 63 6f 6e 66  d parse the conf
2b40: 69 67 75 72 61 74 69 6f 6e 20 2a 2f 0a 20 20 70  iguration */.  p
2b50: 54 61 62 20 3d 20 28 46 74 73 35 54 61 62 6c 65  Tab = (Fts5Table
2b60: 2a 29 73 71 6c 69 74 65 33 46 74 73 35 4d 61 6c  *)sqlite3Fts5Mal
2b70: 6c 6f 63 5a 65 72 6f 28 26 72 63 2c 20 73 69 7a  locZero(&rc, siz
2b80: 65 6f 66 28 46 74 73 35 54 61 62 6c 65 29 29 3b  eof(Fts5Table));
2b90: 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
2ba0: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d  E_OK ){.    rc =
2bb0: 20 73 71 6c 69 74 65 33 46 74 73 35 43 6f 6e 66   sqlite3Fts5Conf
2bc0: 69 67 50 61 72 73 65 28 70 47 6c 6f 62 61 6c 2c  igParse(pGlobal,
2bd0: 20 64 62 2c 20 61 72 67 63 2c 20 61 7a 43 6f 6e   db, argc, azCon
2be0: 66 69 67 2c 20 26 70 43 6f 6e 66 69 67 2c 20 70  fig, &pConfig, p
2bf0: 7a 45 72 72 29 3b 0a 20 20 20 20 61 73 73 65 72  zErr);.    asser
2c00: 74 28 20 28 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  t( (rc==SQLITE_O
2c10: 4b 20 26 26 20 2a 70 7a 45 72 72 3d 3d 30 29 20  K && *pzErr==0) 
2c20: 7c 7c 20 70 43 6f 6e 66 69 67 3d 3d 30 20 29 3b  || pConfig==0 );
2c30: 0a 20 20 7d 0a 20 20 69 66 28 20 72 63 3d 3d 53  .  }.  if( rc==S
2c40: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
2c50: 70 54 61 62 2d 3e 70 43 6f 6e 66 69 67 20 3d 20  pTab->pConfig = 
2c60: 70 43 6f 6e 66 69 67 3b 0a 20 20 20 20 70 54 61  pConfig;.    pTa
2c70: 62 2d 3e 70 47 6c 6f 62 61 6c 20 3d 20 70 47 6c  b->pGlobal = pGl
2c80: 6f 62 61 6c 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20  obal;.  }..  /* 
2c90: 4f 70 65 6e 20 74 68 65 20 69 6e 64 65 78 20 73  Open the index s
2ca0: 75 62 2d 73 79 73 74 65 6d 20 2a 2f 0a 20 20 69  ub-system */.  i
2cb0: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
2cc0: 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c   ){.    rc = sql
2cd0: 69 74 65 33 46 74 73 35 49 6e 64 65 78 4f 70 65  ite3Fts5IndexOpe
2ce0: 6e 28 70 43 6f 6e 66 69 67 2c 20 62 43 72 65 61  n(pConfig, bCrea
2cf0: 74 65 2c 20 26 70 54 61 62 2d 3e 70 49 6e 64 65  te, &pTab->pInde
2d00: 78 2c 20 70 7a 45 72 72 29 3b 0a 20 20 7d 0a 0a  x, pzErr);.  }..
2d10: 20 20 2f 2a 20 4f 70 65 6e 20 74 68 65 20 73 74    /* Open the st
2d20: 6f 72 61 67 65 20 73 75 62 2d 73 79 73 74 65 6d  orage sub-system
2d30: 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d 53 51   */.  if( rc==SQ
2d40: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72  LITE_OK ){.    r
2d50: 63 20 3d 20 73 71 6c 69 74 65 33 46 74 73 35 53  c = sqlite3Fts5S
2d60: 74 6f 72 61 67 65 4f 70 65 6e 28 0a 20 20 20 20  torageOpen(.    
2d70: 20 20 20 20 70 43 6f 6e 66 69 67 2c 20 70 54 61      pConfig, pTa
2d80: 62 2d 3e 70 49 6e 64 65 78 2c 20 62 43 72 65 61  b->pIndex, bCrea
2d90: 74 65 2c 20 26 70 54 61 62 2d 3e 70 53 74 6f 72  te, &pTab->pStor
2da0: 61 67 65 2c 20 70 7a 45 72 72 0a 20 20 20 20 29  age, pzErr.    )
2db0: 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 43 61 6c 6c  ;.  }..  /* Call
2dc0: 20 73 71 6c 69 74 65 33 5f 64 65 63 6c 61 72 65   sqlite3_declare
2dd0: 5f 76 74 61 62 28 29 20 2a 2f 0a 20 20 69 66 28  _vtab() */.  if(
2de0: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
2df0: 7b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74  {.    rc = sqlit
2e00: 65 33 46 74 73 35 43 6f 6e 66 69 67 44 65 63 6c  e3Fts5ConfigDecl
2e10: 61 72 65 56 74 61 62 28 70 43 6f 6e 66 69 67 29  areVtab(pConfig)
2e20: 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 21  ;.  }..  if( rc!
2e30: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
2e40: 20 20 66 74 73 35 46 72 65 65 56 74 61 62 28 70    fts5FreeVtab(p
2e50: 54 61 62 2c 20 30 29 3b 0a 20 20 20 20 70 54 61  Tab, 0);.    pTa
2e60: 62 20 3d 20 30 3b 0a 20 20 7d 65 6c 73 65 20 69  b = 0;.  }else i
2e70: 66 28 20 62 43 72 65 61 74 65 20 29 7b 0a 20 20  f( bCreate ){.  
2e80: 20 20 66 74 73 35 43 68 65 63 6b 54 72 61 6e 73    fts5CheckTrans
2e90: 61 63 74 69 6f 6e 53 74 61 74 65 28 70 54 61 62  actionState(pTab
2ea0: 2c 20 46 54 53 35 5f 42 45 47 49 4e 2c 20 30 29  , FTS5_BEGIN, 0)
2eb0: 3b 0a 20 20 7d 0a 20 20 2a 70 70 56 54 61 62 20  ;.  }.  *ppVTab 
2ec0: 3d 20 28 73 71 6c 69 74 65 33 5f 76 74 61 62 2a  = (sqlite3_vtab*
2ed0: 29 70 54 61 62 3b 0a 20 20 72 65 74 75 72 6e 20  )pTab;.  return 
2ee0: 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65  rc;.}../*.** The
2ef0: 20 78 43 6f 6e 6e 65 63 74 28 29 20 61 6e 64 20   xConnect() and 
2f00: 78 43 72 65 61 74 65 28 29 20 6d 65 74 68 6f 64  xCreate() method
2f10: 73 20 66 6f 72 20 74 68 65 20 76 69 72 74 75 61  s for the virtua
2f20: 6c 20 74 61 62 6c 65 2e 20 41 6c 6c 20 74 68 65  l table. All the
2f30: 0a 2a 2a 20 77 6f 72 6b 20 69 73 20 64 6f 6e 65  .** work is done
2f40: 20 69 6e 20 66 75 6e 63 74 69 6f 6e 20 66 74 73   in function fts
2f50: 35 49 6e 69 74 56 74 61 62 28 29 2e 0a 2a 2f 0a  5InitVtab()..*/.
2f60: 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 43  static int fts5C
2f70: 6f 6e 6e 65 63 74 4d 65 74 68 6f 64 28 0a 20 20  onnectMethod(.  
2f80: 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 20 20 20  sqlite3 *db,    
2f90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2fa0: 2f 2a 20 44 61 74 61 62 61 73 65 20 63 6f 6e 6e  /* Database conn
2fb0: 65 63 74 69 6f 6e 20 2a 2f 0a 20 20 76 6f 69 64  ection */.  void
2fc0: 20 2a 70 41 75 78 2c 20 20 20 20 20 20 20 20 20   *pAux,         
2fd0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50              /* P
2fe0: 6f 69 6e 74 65 72 20 74 6f 20 74 6f 6b 65 6e 69  ointer to tokeni
2ff0: 7a 65 72 20 68 61 73 68 20 74 61 62 6c 65 20 2a  zer hash table *
3000: 2f 0a 20 20 69 6e 74 20 61 72 67 63 2c 20 20 20  /.  int argc,   
3010: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3020: 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66      /* Number of
3030: 20 65 6c 65 6d 65 6e 74 73 20 69 6e 20 61 72 67   elements in arg
3040: 76 20 61 72 72 61 79 20 2a 2f 0a 20 20 63 6f 6e  v array */.  con
3050: 73 74 20 63 68 61 72 20 2a 20 63 6f 6e 73 74 20  st char * const 
3060: 2a 61 72 67 76 2c 20 20 20 20 20 20 20 2f 2a 20  *argv,       /* 
3070: 78 43 72 65 61 74 65 2f 78 43 6f 6e 6e 65 63 74  xCreate/xConnect
3080: 20 61 72 67 75 6d 65 6e 74 20 61 72 72 61 79 20   argument array 
3090: 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61  */.  sqlite3_vta
30a0: 62 20 2a 2a 70 70 56 74 61 62 2c 20 20 20 20 20  b **ppVtab,     
30b0: 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 4e 65 77       /* OUT: New
30c0: 20 73 71 6c 69 74 65 33 5f 76 74 61 62 20 6f 62   sqlite3_vtab ob
30d0: 6a 65 63 74 20 2a 2f 0a 20 20 63 68 61 72 20 2a  ject */.  char *
30e0: 2a 70 7a 45 72 72 20 20 20 20 20 20 20 20 20 20  *pzErr          
30f0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54            /* OUT
3100: 3a 20 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63  : sqlite3_malloc
3110: 27 64 20 65 72 72 6f 72 20 6d 65 73 73 61 67 65  'd error message
3120: 20 2a 2f 0a 29 7b 0a 20 20 72 65 74 75 72 6e 20   */.){.  return 
3130: 66 74 73 35 49 6e 69 74 56 74 61 62 28 30 2c 20  fts5InitVtab(0, 
3140: 64 62 2c 20 70 41 75 78 2c 20 61 72 67 63 2c 20  db, pAux, argc, 
3150: 61 72 67 76 2c 20 70 70 56 74 61 62 2c 20 70 7a  argv, ppVtab, pz
3160: 45 72 72 29 3b 0a 7d 0a 73 74 61 74 69 63 20 69  Err);.}.static i
3170: 6e 74 20 66 74 73 35 43 72 65 61 74 65 4d 65 74  nt fts5CreateMet
3180: 68 6f 64 28 0a 20 20 73 71 6c 69 74 65 33 20 2a  hod(.  sqlite3 *
3190: 64 62 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  db,             
31a0: 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61         /* Databa
31b0: 73 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 2a 2f  se connection */
31c0: 0a 20 20 76 6f 69 64 20 2a 70 41 75 78 2c 20 20  .  void *pAux,  
31d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
31e0: 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f     /* Pointer to
31f0: 20 74 6f 6b 65 6e 69 7a 65 72 20 68 61 73 68 20   tokenizer hash 
3200: 74 61 62 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 61  table */.  int a
3210: 72 67 63 2c 20 20 20 20 20 20 20 20 20 20 20 20  rgc,            
3220: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75             /* Nu
3230: 6d 62 65 72 20 6f 66 20 65 6c 65 6d 65 6e 74 73  mber of elements
3240: 20 69 6e 20 61 72 67 76 20 61 72 72 61 79 20 2a   in argv array *
3250: 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  /.  const char *
3260: 20 63 6f 6e 73 74 20 2a 61 72 67 76 2c 20 20 20   const *argv,   
3270: 20 20 20 20 2f 2a 20 78 43 72 65 61 74 65 2f 78      /* xCreate/x
3280: 43 6f 6e 6e 65 63 74 20 61 72 67 75 6d 65 6e 74  Connect argument
3290: 20 61 72 72 61 79 20 2a 2f 0a 20 20 73 71 6c 69   array */.  sqli
32a0: 74 65 33 5f 76 74 61 62 20 2a 2a 70 70 56 74 61  te3_vtab **ppVta
32b0: 62 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f  b,          /* O
32c0: 55 54 3a 20 4e 65 77 20 73 71 6c 69 74 65 33 5f  UT: New sqlite3_
32d0: 76 74 61 62 20 6f 62 6a 65 63 74 20 2a 2f 0a 20  vtab object */. 
32e0: 20 63 68 61 72 20 2a 2a 70 7a 45 72 72 20 20 20   char **pzErr   
32f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3300: 20 2f 2a 20 4f 55 54 3a 20 73 71 6c 69 74 65 33   /* OUT: sqlite3
3310: 5f 6d 61 6c 6c 6f 63 27 64 20 65 72 72 6f 72 20  _malloc'd error 
3320: 6d 65 73 73 61 67 65 20 2a 2f 0a 29 7b 0a 20 20  message */.){.  
3330: 72 65 74 75 72 6e 20 66 74 73 35 49 6e 69 74 56  return fts5InitV
3340: 74 61 62 28 31 2c 20 64 62 2c 20 70 41 75 78 2c  tab(1, db, pAux,
3350: 20 61 72 67 63 2c 20 61 72 67 76 2c 20 70 70 56   argc, argv, ppV
3360: 74 61 62 2c 20 70 7a 45 72 72 29 3b 0a 7d 0a 0a  tab, pzErr);.}..
3370: 2f 2a 0a 2a 2a 20 54 68 65 20 74 68 72 65 65 20  /*.** The three 
3380: 71 75 65 72 79 20 70 6c 61 6e 73 20 78 42 65 73  query plans xBes
3390: 74 49 6e 64 65 78 20 6d 61 79 20 63 68 6f 6f 73  tIndex may choos
33a0: 65 20 62 65 74 77 65 65 6e 2e 0a 2a 2f 0a 23 64  e between..*/.#d
33b0: 65 66 69 6e 65 20 46 54 53 35 5f 50 4c 41 4e 5f  efine FTS5_PLAN_
33c0: 53 43 41 4e 20 20 20 20 20 20 20 20 20 20 20 31  SCAN           1
33d0: 20 20 20 20 20 20 20 2f 2a 20 4e 6f 20 75 73 61         /* No usa
33e0: 62 6c 65 20 63 6f 6e 73 74 72 61 69 6e 74 20 2a  ble constraint *
33f0: 2f 0a 23 64 65 66 69 6e 65 20 46 54 53 35 5f 50  /.#define FTS5_P
3400: 4c 41 4e 5f 4d 41 54 43 48 20 20 20 20 20 20 20  LAN_MATCH       
3410: 20 20 20 32 20 20 20 20 20 20 20 2f 2a 20 28 3c     2       /* (<
3420: 74 62 6c 3e 20 4d 41 54 43 48 20 3f 29 20 2a 2f  tbl> MATCH ?) */
3430: 0a 23 64 65 66 69 6e 65 20 46 54 53 35 5f 50 4c  .#define FTS5_PL
3440: 41 4e 5f 53 4f 52 54 45 44 5f 4d 41 54 43 48 20  AN_SORTED_MATCH 
3450: 20 20 33 20 20 20 20 20 20 20 2f 2a 20 28 3c 74    3       /* (<t
3460: 62 6c 3e 20 4d 41 54 43 48 20 3f 20 4f 52 44 45  bl> MATCH ? ORDE
3470: 52 20 42 59 20 72 61 6e 6b 29 20 2a 2f 0a 23 64  R BY rank) */.#d
3480: 65 66 69 6e 65 20 46 54 53 35 5f 50 4c 41 4e 5f  efine FTS5_PLAN_
3490: 52 4f 57 49 44 20 20 20 20 20 20 20 20 20 20 34  ROWID          4
34a0: 20 20 20 20 20 20 20 2f 2a 20 28 72 6f 77 69 64         /* (rowid
34b0: 20 3d 20 3f 29 20 2a 2f 0a 23 64 65 66 69 6e 65   = ?) */.#define
34c0: 20 46 54 53 35 5f 50 4c 41 4e 5f 53 4f 55 52 43   FTS5_PLAN_SOURC
34d0: 45 20 20 20 20 20 20 20 20 20 35 20 20 20 20 20  E         5     
34e0: 20 20 2f 2a 20 41 20 73 6f 75 72 63 65 20 63 75    /* A source cu
34f0: 72 73 6f 72 20 66 6f 72 20 53 4f 52 54 45 44 5f  rsor for SORTED_
3500: 4d 41 54 43 48 20 2a 2f 0a 23 64 65 66 69 6e 65  MATCH */.#define
3510: 20 46 54 53 35 5f 50 4c 41 4e 5f 53 50 45 43 49   FTS5_PLAN_SPECI
3520: 41 4c 20 20 20 20 20 20 20 20 36 20 20 20 20 20  AL        6     
3530: 20 20 2f 2a 20 41 6e 20 69 6e 74 65 72 6e 61 6c    /* An internal
3540: 20 71 75 65 72 79 20 2a 2f 0a 0a 23 64 65 66 69   query */..#defi
3550: 6e 65 20 46 54 53 35 5f 50 4c 41 4e 28 69 64 78  ne FTS5_PLAN(idx
3560: 4e 75 6d 29 20 28 28 69 64 78 4e 75 6d 29 20 26  Num) ((idxNum) &
3570: 20 30 78 37 29 0a 0a 23 64 65 66 69 6e 65 20 46   0x7)..#define F
3580: 54 53 35 5f 4f 52 44 45 52 5f 44 45 53 43 20 20  TS5_ORDER_DESC  
3590: 20 38 20 20 20 20 20 20 20 2f 2a 20 4f 52 44 45   8       /* ORDE
35a0: 52 20 42 59 20 72 6f 77 69 64 20 44 45 53 43 20  R BY rowid DESC 
35b0: 2a 2f 0a 23 64 65 66 69 6e 65 20 46 54 53 35 5f  */.#define FTS5_
35c0: 4f 52 44 45 52 5f 41 53 43 20 20 20 31 36 20 20  ORDER_ASC   16  
35d0: 20 20 20 20 20 2f 2a 20 4f 52 44 45 52 20 42 59       /* ORDER BY
35e0: 20 72 6f 77 69 64 20 41 53 43 20 2a 2f 0a 0a 2f   rowid ASC */../
35f0: 2a 0a 2a 2a 20 53 65 61 72 63 68 20 74 68 65 20  *.** Search the 
3600: 6f 62 6a 65 63 74 20 70 61 73 73 65 64 20 61 73  object passed as
3610: 20 74 68 65 20 66 69 72 73 74 20 61 72 67 75 6d   the first argum
3620: 65 6e 74 20 66 6f 72 20 61 20 75 73 61 62 6c 65  ent for a usable
3630: 20 63 6f 6e 73 74 72 61 69 6e 74 0a 2a 2a 20 6f   constraint.** o
3640: 6e 20 63 6f 6c 75 6d 6e 20 69 43 6f 6c 20 75 73  n column iCol us
3650: 69 6e 67 20 6f 70 65 72 61 74 6f 72 20 65 4f 70  ing operator eOp
3660: 2e 20 49 66 20 6f 6e 65 20 69 73 20 66 6f 75 6e  . If one is foun
3670: 64 2c 20 72 65 74 75 72 6e 20 69 74 73 20 69 6e  d, return its in
3680: 64 65 78 20 69 6e 0a 2a 2a 20 74 68 65 20 70 49  dex in.** the pI
3690: 6e 66 6f 2d 3e 61 43 6f 6e 73 74 72 61 69 6e 74  nfo->aConstraint
36a0: 5b 5d 20 61 72 72 61 79 2e 20 49 66 20 6e 6f 20  [] array. If no 
36b0: 73 75 63 68 20 63 6f 6e 73 74 72 61 69 6e 74 20  such constraint 
36c0: 69 73 20 66 6f 75 6e 64 2c 20 72 65 74 75 72 6e  is found, return
36d0: 0a 2a 2a 20 61 20 6e 65 67 61 74 69 76 65 20 76  .** a negative v
36e0: 61 6c 75 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  alue..*/.static 
36f0: 69 6e 74 20 66 74 73 35 46 69 6e 64 43 6f 6e 73  int fts5FindCons
3700: 74 72 61 69 6e 74 28 73 71 6c 69 74 65 33 5f 69  traint(sqlite3_i
3710: 6e 64 65 78 5f 69 6e 66 6f 20 2a 70 49 6e 66 6f  ndex_info *pInfo
3720: 2c 20 69 6e 74 20 65 4f 70 2c 20 69 6e 74 20 69  , int eOp, int i
3730: 43 6f 6c 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20  Col){.  int i;. 
3740: 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70 49 6e 66   for(i=0; i<pInf
3750: 6f 2d 3e 6e 43 6f 6e 73 74 72 61 69 6e 74 3b 20  o->nConstraint; 
3760: 69 2b 2b 29 7b 0a 20 20 20 20 73 74 72 75 63 74  i++){.    struct
3770: 20 73 71 6c 69 74 65 33 5f 69 6e 64 65 78 5f 63   sqlite3_index_c
3780: 6f 6e 73 74 72 61 69 6e 74 20 2a 70 20 3d 20 26  onstraint *p = &
3790: 70 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74 72 61 69  pInfo->aConstrai
37a0: 6e 74 5b 69 5d 3b 0a 20 20 20 20 69 66 28 20 70  nt[i];.    if( p
37b0: 2d 3e 75 73 61 62 6c 65 20 26 26 20 70 2d 3e 69  ->usable && p->i
37c0: 43 6f 6c 75 6d 6e 3d 3d 69 43 6f 6c 20 26 26 20  Column==iCol && 
37d0: 70 2d 3e 6f 70 3d 3d 65 4f 70 20 29 20 72 65 74  p->op==eOp ) ret
37e0: 75 72 6e 20 69 3b 0a 20 20 7d 0a 20 20 72 65 74  urn i;.  }.  ret
37f0: 75 72 6e 20 2d 31 3b 0a 7d 0a 0a 2f 2a 20 0a 2a  urn -1;.}../* .*
3800: 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e  * Implementation
3810: 20 6f 66 20 74 68 65 20 78 42 65 73 74 49 6e 64   of the xBestInd
3820: 65 78 20 6d 65 74 68 6f 64 20 66 6f 72 20 46 54  ex method for FT
3830: 53 35 20 74 61 62 6c 65 73 2e 20 54 68 65 72 65  S5 tables. There
3840: 0a 2a 2a 20 61 72 65 20 74 68 72 65 65 20 70 6f  .** are three po
3850: 73 73 69 62 6c 65 20 73 74 72 61 74 65 67 69 65  ssible strategie
3860: 73 2c 20 69 6e 20 6f 72 64 65 72 20 6f 66 20 70  s, in order of p
3870: 72 65 66 65 72 65 6e 63 65 3a 0a 2a 2a 0a 2a 2a  reference:.**.**
3880: 20 20 20 31 2e 20 46 75 6c 6c 2d 74 65 78 74 20     1. Full-text 
3890: 73 65 61 72 63 68 20 75 73 69 6e 67 20 61 20 4d  search using a M
38a0: 41 54 43 48 20 6f 70 65 72 61 74 6f 72 2e 0a 2a  ATCH operator..*
38b0: 2a 20 20 20 32 2e 20 41 20 62 79 2d 72 6f 77 69  *   2. A by-rowi
38c0: 64 20 6c 6f 6f 6b 75 70 2e 0a 2a 2a 20 20 20 33  d lookup..**   3
38d0: 2e 20 41 20 66 75 6c 6c 2d 74 61 62 6c 65 20 73  . A full-table s
38e0: 63 61 6e 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  can..*/.static i
38f0: 6e 74 20 66 74 73 35 42 65 73 74 49 6e 64 65 78  nt fts5BestIndex
3900: 4d 65 74 68 6f 64 28 73 71 6c 69 74 65 33 5f 76  Method(sqlite3_v
3910: 74 61 62 20 2a 70 56 54 61 62 2c 20 73 71 6c 69  tab *pVTab, sqli
3920: 74 65 33 5f 69 6e 64 65 78 5f 69 6e 66 6f 20 2a  te3_index_info *
3930: 70 49 6e 66 6f 29 7b 0a 20 20 46 74 73 35 54 61  pInfo){.  Fts5Ta
3940: 62 6c 65 20 2a 70 54 61 62 20 3d 20 28 46 74 73  ble *pTab = (Fts
3950: 35 54 61 62 6c 65 2a 29 70 56 54 61 62 3b 0a 20  5Table*)pVTab;. 
3960: 20 46 74 73 35 43 6f 6e 66 69 67 20 2a 70 43 6f   Fts5Config *pCo
3970: 6e 66 69 67 20 3d 20 70 54 61 62 2d 3e 70 43 6f  nfig = pTab->pCo
3980: 6e 66 69 67 3b 0a 20 20 69 6e 74 20 69 43 6f 6e  nfig;.  int iCon
3990: 73 3b 0a 20 20 69 6e 74 20 65 50 6c 61 6e 20 3d  s;.  int ePlan =
39a0: 20 46 54 53 35 5f 50 4c 41 4e 5f 53 43 41 4e 3b   FTS5_PLAN_SCAN;
39b0: 0a 0a 20 20 69 43 6f 6e 73 20 3d 20 66 74 73 35  ..  iCons = fts5
39c0: 46 69 6e 64 43 6f 6e 73 74 72 61 69 6e 74 28 70  FindConstraint(p
39d0: 49 6e 66 6f 2c 53 51 4c 49 54 45 5f 49 4e 44 45  Info,SQLITE_INDE
39e0: 58 5f 43 4f 4e 53 54 52 41 49 4e 54 5f 4d 41 54  X_CONSTRAINT_MAT
39f0: 43 48 2c 70 43 6f 6e 66 69 67 2d 3e 6e 43 6f 6c  CH,pConfig->nCol
3a00: 29 3b 0a 20 20 69 66 28 20 69 43 6f 6e 73 3e 3d  );.  if( iCons>=
3a10: 30 20 29 7b 0a 20 20 20 20 65 50 6c 61 6e 20 3d  0 ){.    ePlan =
3a20: 20 46 54 53 35 5f 50 4c 41 4e 5f 4d 41 54 43 48   FTS5_PLAN_MATCH
3a30: 3b 0a 20 20 20 20 70 49 6e 66 6f 2d 3e 65 73 74  ;.    pInfo->est
3a40: 69 6d 61 74 65 64 43 6f 73 74 20 3d 20 31 2e 30  imatedCost = 1.0
3a50: 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69  ;.  }else{.    i
3a60: 43 6f 6e 73 20 3d 20 66 74 73 35 46 69 6e 64 43  Cons = fts5FindC
3a70: 6f 6e 73 74 72 61 69 6e 74 28 70 49 6e 66 6f 2c  onstraint(pInfo,
3a80: 20 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f 43 4f   SQLITE_INDEX_CO
3a90: 4e 53 54 52 41 49 4e 54 5f 45 51 2c 20 2d 31 29  NSTRAINT_EQ, -1)
3aa0: 3b 0a 20 20 20 20 69 66 28 20 69 43 6f 6e 73 3e  ;.    if( iCons>
3ab0: 3d 30 20 29 7b 0a 20 20 20 20 20 20 65 50 6c 61  =0 ){.      ePla
3ac0: 6e 20 3d 20 46 54 53 35 5f 50 4c 41 4e 5f 52 4f  n = FTS5_PLAN_RO
3ad0: 57 49 44 3b 0a 20 20 20 20 20 20 70 49 6e 66 6f  WID;.      pInfo
3ae0: 2d 3e 65 73 74 69 6d 61 74 65 64 43 6f 73 74 20  ->estimatedCost 
3af0: 3d 20 32 2e 30 3b 0a 20 20 20 20 7d 0a 20 20 7d  = 2.0;.    }.  }
3b00: 0a 0a 20 20 69 66 28 20 69 43 6f 6e 73 3e 3d 30  ..  if( iCons>=0
3b10: 20 29 7b 0a 20 20 20 20 70 49 6e 66 6f 2d 3e 61   ){.    pInfo->a
3b20: 43 6f 6e 73 74 72 61 69 6e 74 55 73 61 67 65 5b  ConstraintUsage[
3b30: 69 43 6f 6e 73 5d 2e 61 72 67 76 49 6e 64 65 78  iCons].argvIndex
3b40: 20 3d 20 31 3b 0a 20 20 20 20 70 49 6e 66 6f 2d   = 1;.    pInfo-
3b50: 3e 61 43 6f 6e 73 74 72 61 69 6e 74 55 73 61 67  >aConstraintUsag
3b60: 65 5b 69 43 6f 6e 73 5d 2e 6f 6d 69 74 20 3d 20  e[iCons].omit = 
3b70: 31 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  1;.  }else{.    
3b80: 70 49 6e 66 6f 2d 3e 65 73 74 69 6d 61 74 65 64  pInfo->estimated
3b90: 43 6f 73 74 20 3d 20 31 30 30 30 30 30 30 30 2e  Cost = 10000000.
3ba0: 30 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 70 49  0;.  }..  if( pI
3bb0: 6e 66 6f 2d 3e 6e 4f 72 64 65 72 42 79 3d 3d 31  nfo->nOrderBy==1
3bc0: 20 29 7b 0a 20 20 20 20 69 6e 74 20 69 53 6f 72   ){.    int iSor
3bd0: 74 20 3d 20 70 49 6e 66 6f 2d 3e 61 4f 72 64 65  t = pInfo->aOrde
3be0: 72 42 79 5b 30 5d 2e 69 43 6f 6c 75 6d 6e 3b 0a  rBy[0].iColumn;.
3bf0: 20 20 20 20 69 66 28 20 69 53 6f 72 74 3c 30 20      if( iSort<0 
3c00: 29 7b 0a 20 20 20 20 20 20 2f 2a 20 4f 52 44 45  ){.      /* ORDE
3c10: 52 20 42 59 20 72 6f 77 69 64 20 5b 41 53 43 7c  R BY rowid [ASC|
3c20: 44 45 53 43 5d 20 2a 2f 0a 20 20 20 20 20 20 70  DESC] */.      p
3c30: 49 6e 66 6f 2d 3e 6f 72 64 65 72 42 79 43 6f 6e  Info->orderByCon
3c40: 73 75 6d 65 64 20 3d 20 31 3b 0a 20 20 20 20 7d  sumed = 1;.    }
3c50: 65 6c 73 65 20 69 66 28 20 69 53 6f 72 74 3d 3d  else if( iSort==
3c60: 28 70 43 6f 6e 66 69 67 2d 3e 6e 43 6f 6c 2b 31  (pConfig->nCol+1
3c70: 29 20 26 26 20 65 50 6c 61 6e 3d 3d 46 54 53 35  ) && ePlan==FTS5
3c80: 5f 50 4c 41 4e 5f 4d 41 54 43 48 20 29 7b 0a 20  _PLAN_MATCH ){. 
3c90: 20 20 20 20 20 2f 2a 20 4f 52 44 45 52 20 42 59       /* ORDER BY
3ca0: 20 72 61 6e 6b 20 5b 41 53 43 7c 44 45 53 43 5d   rank [ASC|DESC]
3cb0: 20 2a 2f 0a 20 20 20 20 20 20 70 49 6e 66 6f 2d   */.      pInfo-
3cc0: 3e 6f 72 64 65 72 42 79 43 6f 6e 73 75 6d 65 64  >orderByConsumed
3cd0: 20 3d 20 31 3b 0a 20 20 20 20 20 20 65 50 6c 61   = 1;.      ePla
3ce0: 6e 20 3d 20 46 54 53 35 5f 50 4c 41 4e 5f 53 4f  n = FTS5_PLAN_SO
3cf0: 52 54 45 44 5f 4d 41 54 43 48 3b 0a 20 20 20 20  RTED_MATCH;.    
3d00: 7d 0a 0a 20 20 20 20 69 66 28 20 70 49 6e 66 6f  }..    if( pInfo
3d10: 2d 3e 6f 72 64 65 72 42 79 43 6f 6e 73 75 6d 65  ->orderByConsume
3d20: 64 20 29 7b 0a 20 20 20 20 20 20 65 50 6c 61 6e  d ){.      ePlan
3d30: 20 7c 3d 20 70 49 6e 66 6f 2d 3e 61 4f 72 64 65   |= pInfo->aOrde
3d40: 72 42 79 5b 30 5d 2e 64 65 73 63 20 3f 20 46 54  rBy[0].desc ? FT
3d50: 53 35 5f 4f 52 44 45 52 5f 44 45 53 43 20 3a 20  S5_ORDER_DESC : 
3d60: 46 54 53 35 5f 4f 52 44 45 52 5f 41 53 43 3b 0a  FTS5_ORDER_ASC;.
3d70: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 20 0a 20 20      }.  }.   .  
3d80: 70 49 6e 66 6f 2d 3e 69 64 78 4e 75 6d 20 3d 20  pInfo->idxNum = 
3d90: 65 50 6c 61 6e 3b 0a 20 20 72 65 74 75 72 6e 20  ePlan;.  return 
3da0: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a  SQLITE_OK;.}../*
3db0: 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69  .** Implementati
3dc0: 6f 6e 20 6f 66 20 78 4f 70 65 6e 20 6d 65 74 68  on of xOpen meth
3dd0: 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  od..*/.static in
3de0: 74 20 66 74 73 35 4f 70 65 6e 4d 65 74 68 6f 64  t fts5OpenMethod
3df0: 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70  (sqlite3_vtab *p
3e00: 56 54 61 62 2c 20 73 71 6c 69 74 65 33 5f 76 74  VTab, sqlite3_vt
3e10: 61 62 5f 63 75 72 73 6f 72 20 2a 2a 70 70 43 73  ab_cursor **ppCs
3e20: 72 29 7b 0a 20 20 46 74 73 35 54 61 62 6c 65 20  r){.  Fts5Table 
3e30: 2a 70 54 61 62 20 3d 20 28 46 74 73 35 54 61 62  *pTab = (Fts5Tab
3e40: 6c 65 2a 29 70 56 54 61 62 3b 0a 20 20 46 74 73  le*)pVTab;.  Fts
3e50: 35 43 6f 6e 66 69 67 20 2a 70 43 6f 6e 66 69 67  5Config *pConfig
3e60: 20 3d 20 70 54 61 62 2d 3e 70 43 6f 6e 66 69 67   = pTab->pConfig
3e70: 3b 0a 20 20 46 74 73 35 43 75 72 73 6f 72 20 2a  ;.  Fts5Cursor *
3e80: 70 43 73 72 3b 20 20 20 20 20 20 20 20 20 20 20  pCsr;           
3e90: 20 20 20 20 2f 2a 20 4e 65 77 20 63 75 72 73 6f      /* New curso
3ea0: 72 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 69 6e  r object */.  in
3eb0: 74 20 6e 42 79 74 65 3b 20 20 20 20 20 20 20 20  t nByte;        
3ec0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
3ed0: 20 42 79 74 65 73 20 6f 66 20 73 70 61 63 65 20   Bytes of space 
3ee0: 74 6f 20 61 6c 6c 6f 63 61 74 65 20 2a 2f 0a 20  to allocate */. 
3ef0: 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
3f00: 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20 20 20 20  _OK;            
3f10: 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20   /* Return code 
3f20: 2a 2f 0a 0a 20 20 6e 42 79 74 65 20 3d 20 73 69  */..  nByte = si
3f30: 7a 65 6f 66 28 46 74 73 35 43 75 72 73 6f 72 29  zeof(Fts5Cursor)
3f40: 20 2b 20 70 43 6f 6e 66 69 67 2d 3e 6e 43 6f 6c   + pConfig->nCol
3f50: 20 2a 20 73 69 7a 65 6f 66 28 69 6e 74 29 3b 0a   * sizeof(int);.
3f60: 20 20 70 43 73 72 20 3d 20 28 46 74 73 35 43 75    pCsr = (Fts5Cu
3f70: 72 73 6f 72 2a 29 73 71 6c 69 74 65 33 5f 6d 61  rsor*)sqlite3_ma
3f80: 6c 6c 6f 63 28 6e 42 79 74 65 29 3b 0a 20 20 69  lloc(nByte);.  i
3f90: 66 28 20 70 43 73 72 20 29 7b 0a 20 20 20 20 46  f( pCsr ){.    F
3fa0: 74 73 35 47 6c 6f 62 61 6c 20 2a 70 47 6c 6f 62  ts5Global *pGlob
3fb0: 61 6c 20 3d 20 70 54 61 62 2d 3e 70 47 6c 6f 62  al = pTab->pGlob
3fc0: 61 6c 3b 0a 20 20 20 20 6d 65 6d 73 65 74 28 70  al;.    memset(p
3fd0: 43 73 72 2c 20 30 2c 20 6e 42 79 74 65 29 3b 0a  Csr, 0, nByte);.
3fe0: 20 20 20 20 70 43 73 72 2d 3e 61 43 6f 6c 75 6d      pCsr->aColum
3ff0: 6e 53 69 7a 65 20 3d 20 28 69 6e 74 2a 29 26 70  nSize = (int*)&p
4000: 43 73 72 5b 31 5d 3b 0a 20 20 20 20 70 43 73 72  Csr[1];.    pCsr
4010: 2d 3e 70 4e 65 78 74 20 3d 20 70 47 6c 6f 62 61  ->pNext = pGloba
4020: 6c 2d 3e 70 43 73 72 3b 0a 20 20 20 20 70 47 6c  l->pCsr;.    pGl
4030: 6f 62 61 6c 2d 3e 70 43 73 72 20 3d 20 70 43 73  obal->pCsr = pCs
4040: 72 3b 0a 20 20 20 20 70 43 73 72 2d 3e 69 43 73  r;.    pCsr->iCs
4050: 72 49 64 20 3d 20 2b 2b 70 47 6c 6f 62 61 6c 2d  rId = ++pGlobal-
4060: 3e 69 4e 65 78 74 49 64 3b 0a 20 20 7d 65 6c 73  >iNextId;.  }els
4070: 65 7b 0a 20 20 20 20 72 63 20 3d 20 53 51 4c 49  e{.    rc = SQLI
4080: 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 20 20  TE_NOMEM;.  }.  
4090: 2a 70 70 43 73 72 20 3d 20 28 73 71 6c 69 74 65  *ppCsr = (sqlite
40a0: 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 2a 29 70  3_vtab_cursor*)p
40b0: 43 73 72 3b 0a 20 20 72 65 74 75 72 6e 20 72 63  Csr;.  return rc
40c0: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  ;.}..static int 
40d0: 66 74 73 35 53 74 6d 74 54 79 70 65 28 69 6e 74  fts5StmtType(int
40e0: 20 69 64 78 4e 75 6d 29 7b 0a 20 20 69 66 28 20   idxNum){.  if( 
40f0: 46 54 53 35 5f 50 4c 41 4e 28 69 64 78 4e 75 6d  FTS5_PLAN(idxNum
4100: 29 3d 3d 46 54 53 35 5f 50 4c 41 4e 5f 53 43 41  )==FTS5_PLAN_SCA
4110: 4e 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  N ){.    return 
4120: 28 69 64 78 4e 75 6d 26 46 54 53 35 5f 4f 52 44  (idxNum&FTS5_ORD
4130: 45 52 5f 41 53 43 29 20 3f 20 46 54 53 35 5f 53  ER_ASC) ? FTS5_S
4140: 54 4d 54 5f 53 43 41 4e 5f 41 53 43 20 3a 20 46  TMT_SCAN_ASC : F
4150: 54 53 35 5f 53 54 4d 54 5f 53 43 41 4e 5f 44 45  TS5_STMT_SCAN_DE
4160: 53 43 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  SC;.  }.  return
4170: 20 46 54 53 35 5f 53 54 4d 54 5f 4c 4f 4f 4b 55   FTS5_STMT_LOOKU
4180: 50 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73  P;.}../*.** This
4190: 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c   function is cal
41a0: 6c 65 64 20 61 66 74 65 72 20 74 68 65 20 63 75  led after the cu
41b0: 72 73 6f 72 20 70 61 73 73 65 64 20 61 73 20 74  rsor passed as t
41c0: 68 65 20 6f 6e 6c 79 20 61 72 67 75 6d 65 6e 74  he only argument
41d0: 0a 2a 2a 20 69 73 20 6d 6f 76 65 64 20 74 6f 20  .** is moved to 
41e0: 70 6f 69 6e 74 20 61 74 20 61 20 64 69 66 66 65  point at a diffe
41f0: 72 65 6e 74 20 72 6f 77 2e 20 49 74 20 63 6c 65  rent row. It cle
4200: 61 72 73 20 61 6c 6c 20 63 61 63 68 65 64 20 64  ars all cached d
4210: 61 74 61 20 0a 2a 2a 20 73 70 65 63 69 66 69 63  ata .** specific
4220: 20 74 6f 20 74 68 65 20 70 72 65 76 69 6f 75 73   to the previous
4230: 20 72 6f 77 20 73 74 6f 72 65 64 20 62 79 20 74   row stored by t
4240: 68 65 20 63 75 72 73 6f 72 20 6f 62 6a 65 63 74  he cursor object
4250: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
4260: 20 66 74 73 35 43 73 72 4e 65 77 72 6f 77 28 46   fts5CsrNewrow(F
4270: 74 73 35 43 75 72 73 6f 72 20 2a 70 43 73 72 29  ts5Cursor *pCsr)
4280: 7b 0a 20 20 43 73 72 46 6c 61 67 53 65 74 28 70  {.  CsrFlagSet(p
4290: 43 73 72 2c 20 46 54 53 35 43 53 52 5f 52 45 51  Csr, FTS5CSR_REQ
42a0: 55 49 52 45 5f 43 4f 4e 54 45 4e 54 20 7c 20 46  UIRE_CONTENT | F
42b0: 54 53 35 43 53 52 5f 52 45 51 55 49 52 45 5f 44  TS5CSR_REQUIRE_D
42c0: 4f 43 53 49 5a 45 20 29 3b 0a 20 20 73 71 6c 69  OCSIZE );.  sqli
42d0: 74 65 33 5f 66 72 65 65 28 70 43 73 72 2d 3e 61  te3_free(pCsr->a
42e0: 49 6e 73 74 29 3b 0a 20 20 70 43 73 72 2d 3e 61  Inst);.  pCsr->a
42f0: 49 6e 73 74 20 3d 20 30 3b 0a 20 20 70 43 73 72  Inst = 0;.  pCsr
4300: 2d 3e 6e 49 6e 73 74 43 6f 75 6e 74 20 3d 20 30  ->nInstCount = 0
4310: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6c 6f 73 65  ;.}../*.** Close
4320: 20 74 68 65 20 63 75 72 73 6f 72 2e 20 20 46 6f   the cursor.  Fo
4330: 72 20 61 64 64 69 74 69 6f 6e 61 6c 20 69 6e 66  r additional inf
4340: 6f 72 6d 61 74 69 6f 6e 20 73 65 65 20 74 68 65  ormation see the
4350: 20 64 6f 63 75 6d 65 6e 74 61 74 69 6f 6e 0a 2a   documentation.*
4360: 2a 20 6f 6e 20 74 68 65 20 78 43 6c 6f 73 65 20  * on the xClose 
4370: 6d 65 74 68 6f 64 20 6f 66 20 74 68 65 20 76 69  method of the vi
4380: 72 74 75 61 6c 20 74 61 62 6c 65 20 69 6e 74 65  rtual table inte
4390: 72 66 61 63 65 2e 0a 2a 2f 0a 73 74 61 74 69 63  rface..*/.static
43a0: 20 69 6e 74 20 66 74 73 35 43 6c 6f 73 65 4d 65   int fts5CloseMe
43b0: 74 68 6f 64 28 73 71 6c 69 74 65 33 5f 76 74 61  thod(sqlite3_vta
43c0: 62 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 73 6f  b_cursor *pCurso
43d0: 72 29 7b 0a 20 20 46 74 73 35 54 61 62 6c 65 20  r){.  Fts5Table 
43e0: 2a 70 54 61 62 20 3d 20 28 46 74 73 35 54 61 62  *pTab = (Fts5Tab
43f0: 6c 65 2a 29 28 70 43 75 72 73 6f 72 2d 3e 70 56  le*)(pCursor->pV
4400: 74 61 62 29 3b 0a 20 20 46 74 73 35 43 75 72 73  tab);.  Fts5Curs
4410: 6f 72 20 2a 70 43 73 72 20 3d 20 28 46 74 73 35  or *pCsr = (Fts5
4420: 43 75 72 73 6f 72 2a 29 70 43 75 72 73 6f 72 3b  Cursor*)pCursor;
4430: 0a 20 20 46 74 73 35 43 75 72 73 6f 72 20 2a 2a  .  Fts5Cursor **
4440: 70 70 3b 0a 20 20 46 74 73 35 41 75 78 64 61 74  pp;.  Fts5Auxdat
4450: 61 20 2a 70 44 61 74 61 3b 0a 20 20 46 74 73 35  a *pData;.  Fts5
4460: 41 75 78 64 61 74 61 20 2a 70 4e 65 78 74 3b 0a  Auxdata *pNext;.
4470: 0a 20 20 66 74 73 35 43 73 72 4e 65 77 72 6f 77  .  fts5CsrNewrow
4480: 28 70 43 73 72 29 3b 0a 20 20 69 66 28 20 70 43  (pCsr);.  if( pC
4490: 73 72 2d 3e 70 53 74 6d 74 20 29 7b 0a 20 20 20  sr->pStmt ){.   
44a0: 20 69 6e 74 20 65 53 74 6d 74 20 3d 20 66 74 73   int eStmt = fts
44b0: 35 53 74 6d 74 54 79 70 65 28 70 43 73 72 2d 3e  5StmtType(pCsr->
44c0: 69 64 78 4e 75 6d 29 3b 0a 20 20 20 20 73 71 6c  idxNum);.    sql
44d0: 69 74 65 33 46 74 73 35 53 74 6f 72 61 67 65 53  ite3Fts5StorageS
44e0: 74 6d 74 52 65 6c 65 61 73 65 28 70 54 61 62 2d  tmtRelease(pTab-
44f0: 3e 70 53 74 6f 72 61 67 65 2c 20 65 53 74 6d 74  >pStorage, eStmt
4500: 2c 20 70 43 73 72 2d 3e 70 53 74 6d 74 29 3b 0a  , pCsr->pStmt);.
4510: 20 20 7d 0a 20 20 69 66 28 20 70 43 73 72 2d 3e    }.  if( pCsr->
4520: 70 53 6f 72 74 65 72 20 29 7b 0a 20 20 20 20 46  pSorter ){.    F
4530: 74 73 35 53 6f 72 74 65 72 20 2a 70 53 6f 72 74  ts5Sorter *pSort
4540: 65 72 20 3d 20 70 43 73 72 2d 3e 70 53 6f 72 74  er = pCsr->pSort
4550: 65 72 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f  er;.    sqlite3_
4560: 66 69 6e 61 6c 69 7a 65 28 70 53 6f 72 74 65 72  finalize(pSorter
4570: 2d 3e 70 53 74 6d 74 29 3b 0a 20 20 20 20 73 71  ->pStmt);.    sq
4580: 6c 69 74 65 33 5f 66 72 65 65 28 70 53 6f 72 74  lite3_free(pSort
4590: 65 72 29 3b 0a 20 20 7d 0a 20 20 0a 20 20 69 66  er);.  }.  .  if
45a0: 28 20 70 43 73 72 2d 3e 69 64 78 4e 75 6d 21 3d  ( pCsr->idxNum!=
45b0: 46 54 53 35 5f 50 4c 41 4e 5f 53 4f 55 52 43 45  FTS5_PLAN_SOURCE
45c0: 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 46   ){.    sqlite3F
45d0: 74 73 35 45 78 70 72 46 72 65 65 28 70 43 73 72  ts5ExprFree(pCsr
45e0: 2d 3e 70 45 78 70 72 29 3b 0a 20 20 7d 0a 0a 20  ->pExpr);.  }.. 
45f0: 20 66 6f 72 28 70 44 61 74 61 3d 70 43 73 72 2d   for(pData=pCsr-
4600: 3e 70 41 75 78 64 61 74 61 3b 20 70 44 61 74 61  >pAuxdata; pData
4610: 3b 20 70 44 61 74 61 3d 70 4e 65 78 74 29 7b 0a  ; pData=pNext){.
4620: 20 20 20 20 70 4e 65 78 74 20 3d 20 70 44 61 74      pNext = pDat
4630: 61 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 69 66  a->pNext;.    if
4640: 28 20 70 44 61 74 61 2d 3e 78 44 65 6c 65 74 65  ( pData->xDelete
4650: 20 29 20 70 44 61 74 61 2d 3e 78 44 65 6c 65 74   ) pData->xDelet
4660: 65 28 70 44 61 74 61 2d 3e 70 50 74 72 29 3b 0a  e(pData->pPtr);.
4670: 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65      sqlite3_free
4680: 28 70 44 61 74 61 29 3b 0a 20 20 7d 0a 0a 20 20  (pData);.  }..  
4690: 2f 2a 20 52 65 6d 6f 76 65 20 74 68 65 20 63 75  /* Remove the cu
46a0: 72 73 6f 72 20 66 72 6f 6d 20 74 68 65 20 46 74  rsor from the Ft
46b0: 73 35 47 6c 6f 62 61 6c 2e 70 43 73 72 20 6c 69  s5Global.pCsr li
46c0: 73 74 20 2a 2f 0a 20 20 66 6f 72 28 70 70 3d 26  st */.  for(pp=&
46d0: 70 54 61 62 2d 3e 70 47 6c 6f 62 61 6c 2d 3e 70  pTab->pGlobal->p
46e0: 43 73 72 3b 20 28 2a 70 70 29 21 3d 70 43 73 72  Csr; (*pp)!=pCsr
46f0: 3b 20 70 70 3d 26 28 2a 70 70 29 2d 3e 70 4e 65  ; pp=&(*pp)->pNe
4700: 78 74 29 3b 0a 20 20 2a 70 70 20 3d 20 70 43 73  xt);.  *pp = pCs
4710: 72 2d 3e 70 4e 65 78 74 3b 0a 0a 20 20 73 71 6c  r->pNext;..  sql
4720: 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70 43  ite3_finalize(pC
4730: 73 72 2d 3e 70 52 61 6e 6b 41 72 67 53 74 6d 74  sr->pRankArgStmt
4740: 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65  );.  sqlite3_fre
4750: 65 28 70 43 73 72 2d 3e 61 70 52 61 6e 6b 41 72  e(pCsr->apRankAr
4760: 67 29 3b 0a 0a 20 20 73 71 6c 69 74 65 33 5f 66  g);..  sqlite3_f
4770: 72 65 65 28 70 43 73 72 2d 3e 7a 53 70 65 63 69  ree(pCsr->zSpeci
4780: 61 6c 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66  al);.  sqlite3_f
4790: 72 65 65 28 70 43 73 72 29 3b 0a 20 20 72 65 74  ree(pCsr);.  ret
47a0: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
47b0: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73  ..static int fts
47c0: 35 53 6f 72 74 65 72 4e 65 78 74 28 46 74 73 35  5SorterNext(Fts5
47d0: 43 75 72 73 6f 72 20 2a 70 43 73 72 29 7b 0a 20  Cursor *pCsr){. 
47e0: 20 46 74 73 35 53 6f 72 74 65 72 20 2a 70 53 6f   Fts5Sorter *pSo
47f0: 72 74 65 72 20 3d 20 70 43 73 72 2d 3e 70 53 6f  rter = pCsr->pSo
4800: 72 74 65 72 3b 0a 20 20 69 6e 74 20 72 63 3b 0a  rter;.  int rc;.
4810: 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f  .  rc = sqlite3_
4820: 73 74 65 70 28 70 53 6f 72 74 65 72 2d 3e 70 53  step(pSorter->pS
4830: 74 6d 74 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d  tmt);.  if( rc==
4840: 53 51 4c 49 54 45 5f 44 4f 4e 45 20 29 7b 0a 20  SQLITE_DONE ){. 
4850: 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f     rc = SQLITE_O
4860: 4b 3b 0a 20 20 20 20 43 73 72 46 6c 61 67 53 65  K;.    CsrFlagSe
4870: 74 28 70 43 73 72 2c 20 46 54 53 35 43 53 52 5f  t(pCsr, FTS5CSR_
4880: 45 4f 46 29 3b 0a 20 20 7d 65 6c 73 65 20 69 66  EOF);.  }else if
4890: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 52 4f 57  ( rc==SQLITE_ROW
48a0: 20 29 7b 0a 20 20 20 20 63 6f 6e 73 74 20 75 38   ){.    const u8
48b0: 20 2a 61 3b 0a 20 20 20 20 63 6f 6e 73 74 20 75   *a;.    const u
48c0: 38 20 2a 61 42 6c 6f 62 3b 0a 20 20 20 20 69 6e  8 *aBlob;.    in
48d0: 74 20 6e 42 6c 6f 62 3b 0a 20 20 20 20 69 6e 74  t nBlob;.    int
48e0: 20 69 3b 0a 20 20 20 20 69 6e 74 20 69 4f 66 66   i;.    int iOff
48f0: 20 3d 20 30 3b 0a 20 20 20 20 72 63 20 3d 20 53   = 0;.    rc = S
4900: 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20 20 20 70  QLITE_OK;..    p
4910: 53 6f 72 74 65 72 2d 3e 69 52 6f 77 69 64 20 3d  Sorter->iRowid =
4920: 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f   sqlite3_column_
4930: 69 6e 74 36 34 28 70 53 6f 72 74 65 72 2d 3e 70  int64(pSorter->p
4940: 53 74 6d 74 2c 20 30 29 3b 0a 20 20 20 20 6e 42  Stmt, 0);.    nB
4950: 6c 6f 62 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f  lob = sqlite3_co
4960: 6c 75 6d 6e 5f 62 79 74 65 73 28 70 53 6f 72 74  lumn_bytes(pSort
4970: 65 72 2d 3e 70 53 74 6d 74 2c 20 31 29 3b 0a 20  er->pStmt, 1);. 
4980: 20 20 20 61 42 6c 6f 62 20 3d 20 61 20 3d 20 73     aBlob = a = s
4990: 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 62 6c  qlite3_column_bl
49a0: 6f 62 28 70 53 6f 72 74 65 72 2d 3e 70 53 74 6d  ob(pSorter->pStm
49b0: 74 2c 20 31 29 3b 0a 0a 20 20 20 20 66 6f 72 28  t, 1);..    for(
49c0: 69 3d 30 3b 20 69 3c 28 70 53 6f 72 74 65 72 2d  i=0; i<(pSorter-
49d0: 3e 6e 49 64 78 2d 31 29 3b 20 69 2b 2b 29 7b 0a  >nIdx-1); i++){.
49e0: 20 20 20 20 20 20 69 6e 74 20 69 56 61 6c 3b 0a        int iVal;.
49f0: 20 20 20 20 20 20 61 20 2b 3d 20 67 65 74 56 61        a += getVa
4a00: 72 69 6e 74 33 32 28 61 2c 20 69 56 61 6c 29 3b  rint32(a, iVal);
4a10: 0a 20 20 20 20 20 20 69 4f 66 66 20 2b 3d 20 69  .      iOff += i
4a20: 56 61 6c 3b 0a 20 20 20 20 20 20 70 53 6f 72 74  Val;.      pSort
4a30: 65 72 2d 3e 61 49 64 78 5b 69 5d 20 3d 20 69 4f  er->aIdx[i] = iO
4a40: 66 66 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 53  ff;.    }.    pS
4a50: 6f 72 74 65 72 2d 3e 61 49 64 78 5b 69 5d 20 3d  orter->aIdx[i] =
4a60: 20 26 61 42 6c 6f 62 5b 6e 42 6c 6f 62 5d 20 2d   &aBlob[nBlob] -
4a70: 20 61 3b 0a 0a 20 20 20 20 70 53 6f 72 74 65 72   a;..    pSorter
4a80: 2d 3e 61 50 6f 73 6c 69 73 74 20 3d 20 61 3b 0a  ->aPoslist = a;.
4a90: 20 20 20 20 66 74 73 35 43 73 72 4e 65 77 72 6f      fts5CsrNewro
4aa0: 77 28 70 43 73 72 29 3b 0a 20 20 7d 0a 0a 20 20  w(pCsr);.  }..  
4ab0: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
4ac0: 0a 2a 2a 20 41 64 76 61 6e 63 65 20 74 68 65 20  .** Advance the 
4ad0: 63 75 72 73 6f 72 20 74 6f 20 74 68 65 20 6e 65  cursor to the ne
4ae0: 78 74 20 72 6f 77 20 69 6e 20 74 68 65 20 74 61  xt row in the ta
4af0: 62 6c 65 20 74 68 61 74 20 6d 61 74 63 68 65 73  ble that matches
4b00: 20 74 68 65 20 0a 2a 2a 20 73 65 61 72 63 68 20   the .** search 
4b10: 63 72 69 74 65 72 69 61 2e 0a 2a 2a 0a 2a 2a 20  criteria..**.** 
4b20: 52 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  Return SQLITE_OK
4b30: 20 69 66 20 6e 6f 74 68 69 6e 67 20 67 6f 65 73   if nothing goes
4b40: 20 77 72 6f 6e 67 2e 20 20 53 51 4c 49 54 45 5f   wrong.  SQLITE_
4b50: 4f 4b 20 69 73 20 72 65 74 75 72 6e 65 64 0a 2a  OK is returned.*
4b60: 2a 20 65 76 65 6e 20 69 66 20 77 65 20 72 65 61  * even if we rea
4b70: 63 68 20 65 6e 64 2d 6f 66 2d 66 69 6c 65 2e 20  ch end-of-file. 
4b80: 20 54 68 65 20 66 74 73 35 45 6f 66 4d 65 74 68   The fts5EofMeth
4b90: 6f 64 28 29 20 77 69 6c 6c 20 62 65 20 63 61 6c  od() will be cal
4ba0: 6c 65 64 0a 2a 2a 20 73 75 62 73 65 71 75 65 6e  led.** subsequen
4bb0: 74 6c 79 20 74 6f 20 64 65 74 65 72 6d 69 6e 65  tly to determine
4bc0: 20 77 68 65 74 68 65 72 20 6f 72 20 6e 6f 74 20   whether or not 
4bd0: 61 6e 20 45 4f 46 20 77 61 73 20 68 69 74 2e 0a  an EOF was hit..
4be0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74  */.static int ft
4bf0: 73 35 4e 65 78 74 4d 65 74 68 6f 64 28 73 71 6c  s5NextMethod(sql
4c00: 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72  ite3_vtab_cursor
4c10: 20 2a 70 43 75 72 73 6f 72 29 7b 0a 20 20 46 74   *pCursor){.  Ft
4c20: 73 35 43 75 72 73 6f 72 20 2a 70 43 73 72 20 3d  s5Cursor *pCsr =
4c30: 20 28 46 74 73 35 43 75 72 73 6f 72 2a 29 70 43   (Fts5Cursor*)pC
4c40: 75 72 73 6f 72 3b 0a 20 20 69 6e 74 20 65 50 6c  ursor;.  int ePl
4c50: 61 6e 20 3d 20 46 54 53 35 5f 50 4c 41 4e 28 70  an = FTS5_PLAN(p
4c60: 43 73 72 2d 3e 69 64 78 4e 75 6d 29 3b 0a 20 20  Csr->idxNum);.  
4c70: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
4c80: 4f 4b 3b 0a 0a 20 20 73 77 69 74 63 68 28 20 65  OK;..  switch( e
4c90: 50 6c 61 6e 20 29 7b 0a 20 20 20 20 63 61 73 65  Plan ){.    case
4ca0: 20 46 54 53 35 5f 50 4c 41 4e 5f 4d 41 54 43 48   FTS5_PLAN_MATCH
4cb0: 3a 0a 20 20 20 20 63 61 73 65 20 46 54 53 35 5f  :.    case FTS5_
4cc0: 50 4c 41 4e 5f 53 4f 55 52 43 45 3a 0a 20 20 20  PLAN_SOURCE:.   
4cd0: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 46     rc = sqlite3F
4ce0: 74 73 35 45 78 70 72 4e 65 78 74 28 70 43 73 72  ts5ExprNext(pCsr
4cf0: 2d 3e 70 45 78 70 72 29 3b 0a 20 20 20 20 20 20  ->pExpr);.      
4d00: 69 66 28 20 73 71 6c 69 74 65 33 46 74 73 35 45  if( sqlite3Fts5E
4d10: 78 70 72 45 6f 66 28 70 43 73 72 2d 3e 70 45 78  xprEof(pCsr->pEx
4d20: 70 72 29 20 29 7b 0a 20 20 20 20 20 20 20 20 43  pr) ){.        C
4d30: 73 72 46 6c 61 67 53 65 74 28 70 43 73 72 2c 20  srFlagSet(pCsr, 
4d40: 46 54 53 35 43 53 52 5f 45 4f 46 29 3b 0a 20 20  FTS5CSR_EOF);.  
4d50: 20 20 20 20 7d 0a 20 20 20 20 20 20 66 74 73 35      }.      fts5
4d60: 43 73 72 4e 65 77 72 6f 77 28 70 43 73 72 29 3b  CsrNewrow(pCsr);
4d70: 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 0a 20  .      break;.. 
4d80: 20 20 20 63 61 73 65 20 46 54 53 35 5f 50 4c 41     case FTS5_PLA
4d90: 4e 5f 53 50 45 43 49 41 4c 3a 20 7b 0a 20 20 20  N_SPECIAL: {.   
4da0: 20 20 20 43 73 72 46 6c 61 67 53 65 74 28 70 43     CsrFlagSet(pC
4db0: 73 72 2c 20 46 54 53 35 43 53 52 5f 45 4f 46 29  sr, FTS5CSR_EOF)
4dc0: 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20  ;.      break;. 
4dd0: 20 20 20 7d 0a 0a 20 20 20 20 63 61 73 65 20 46     }..    case F
4de0: 54 53 35 5f 50 4c 41 4e 5f 53 4f 52 54 45 44 5f  TS5_PLAN_SORTED_
4df0: 4d 41 54 43 48 3a 20 7b 0a 20 20 20 20 20 20 72  MATCH: {.      r
4e00: 63 20 3d 20 66 74 73 35 53 6f 72 74 65 72 4e 65  c = fts5SorterNe
4e10: 78 74 28 70 43 73 72 29 3b 0a 20 20 20 20 20 20  xt(pCsr);.      
4e20: 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20  break;.    }..  
4e30: 20 20 64 65 66 61 75 6c 74 3a 0a 20 20 20 20 20    default:.     
4e40: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 73 74   rc = sqlite3_st
4e50: 65 70 28 70 43 73 72 2d 3e 70 53 74 6d 74 29 3b  ep(pCsr->pStmt);
4e60: 0a 20 20 20 20 20 20 69 66 28 20 72 63 21 3d 53  .      if( rc!=S
4e70: 51 4c 49 54 45 5f 52 4f 57 20 29 7b 0a 20 20 20  QLITE_ROW ){.   
4e80: 20 20 20 20 20 43 73 72 46 6c 61 67 53 65 74 28       CsrFlagSet(
4e90: 70 43 73 72 2c 20 46 54 53 35 43 53 52 5f 45 4f  pCsr, FTS5CSR_EO
4ea0: 46 29 3b 0a 20 20 20 20 20 20 20 20 72 63 20 3d  F);.        rc =
4eb0: 20 73 71 6c 69 74 65 33 5f 72 65 73 65 74 28 70   sqlite3_reset(p
4ec0: 43 73 72 2d 3e 70 53 74 6d 74 29 3b 0a 20 20 20  Csr->pStmt);.   
4ed0: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
4ee0: 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b    rc = SQLITE_OK
4ef0: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
4f00: 62 72 65 61 6b 3b 0a 20 20 7d 0a 20 20 0a 20 20  break;.  }.  .  
4f10: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74  return rc;.}..st
4f20: 61 74 69 63 20 69 6e 74 20 66 74 73 35 43 75 72  atic int fts5Cur
4f30: 73 6f 72 46 69 72 73 74 53 6f 72 74 65 64 28 46  sorFirstSorted(F
4f40: 74 73 35 54 61 62 6c 65 20 2a 70 54 61 62 2c 20  ts5Table *pTab, 
4f50: 46 74 73 35 43 75 72 73 6f 72 20 2a 70 43 73 72  Fts5Cursor *pCsr
4f60: 2c 20 69 6e 74 20 62 41 73 63 29 7b 0a 20 20 46  , int bAsc){.  F
4f70: 74 73 35 43 6f 6e 66 69 67 20 2a 70 43 6f 6e 66  ts5Config *pConf
4f80: 69 67 20 3d 20 70 54 61 62 2d 3e 70 43 6f 6e 66  ig = pTab->pConf
4f90: 69 67 3b 0a 20 20 46 74 73 35 53 6f 72 74 65 72  ig;.  Fts5Sorter
4fa0: 20 2a 70 53 6f 72 74 65 72 3b 0a 20 20 69 6e 74   *pSorter;.  int
4fb0: 20 6e 50 68 72 61 73 65 3b 0a 20 20 69 6e 74 20   nPhrase;.  int 
4fc0: 6e 42 79 74 65 3b 0a 20 20 69 6e 74 20 72 63 20  nByte;.  int rc 
4fd0: 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 63  = SQLITE_OK;.  c
4fe0: 68 61 72 20 2a 7a 53 71 6c 3b 0a 20 20 63 6f 6e  har *zSql;.  con
4ff0: 73 74 20 63 68 61 72 20 2a 7a 52 61 6e 6b 20 3d  st char *zRank =
5000: 20 70 43 6f 6e 66 69 67 2d 3e 7a 52 61 6e 6b 20   pConfig->zRank 
5010: 3f 20 70 43 6f 6e 66 69 67 2d 3e 7a 52 61 6e 6b  ? pConfig->zRank
5020: 20 3a 20 46 54 53 35 5f 44 45 46 41 55 4c 54 5f   : FTS5_DEFAULT_
5030: 52 41 4e 4b 3b 0a 20 20 0a 20 20 6e 50 68 72 61  RANK;.  .  nPhra
5040: 73 65 20 3d 20 73 71 6c 69 74 65 33 46 74 73 35  se = sqlite3Fts5
5050: 45 78 70 72 50 68 72 61 73 65 43 6f 75 6e 74 28  ExprPhraseCount(
5060: 70 43 73 72 2d 3e 70 45 78 70 72 29 3b 0a 20 20  pCsr->pExpr);.  
5070: 6e 42 79 74 65 20 3d 20 73 69 7a 65 6f 66 28 46  nByte = sizeof(F
5080: 74 73 35 53 6f 72 74 65 72 29 20 2b 20 73 69 7a  ts5Sorter) + siz
5090: 65 6f 66 28 69 6e 74 29 20 2a 20 6e 50 68 72 61  eof(int) * nPhra
50a0: 73 65 3b 0a 20 20 70 53 6f 72 74 65 72 20 3d 20  se;.  pSorter = 
50b0: 28 46 74 73 35 53 6f 72 74 65 72 2a 29 73 71 6c  (Fts5Sorter*)sql
50c0: 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 6e 42 79 74  ite3_malloc(nByt
50d0: 65 29 3b 0a 20 20 69 66 28 20 70 53 6f 72 74 65  e);.  if( pSorte
50e0: 72 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53 51  r==0 ) return SQ
50f0: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 6d 65  LITE_NOMEM;.  me
5100: 6d 73 65 74 28 70 53 6f 72 74 65 72 2c 20 30 2c  mset(pSorter, 0,
5110: 20 6e 42 79 74 65 29 3b 0a 20 20 70 53 6f 72 74   nByte);.  pSort
5120: 65 72 2d 3e 6e 49 64 78 20 3d 20 6e 50 68 72 61  er->nIdx = nPhra
5130: 73 65 3b 0a 0a 20 20 2f 2a 20 54 4f 44 4f 3a 20  se;..  /* TODO: 
5140: 49 74 20 77 6f 75 6c 64 20 62 65 20 62 65 74 74  It would be bett
5150: 65 72 20 74 6f 20 68 61 76 65 20 73 6f 6d 65 20  er to have some 
5160: 73 79 73 74 65 6d 20 66 6f 72 20 72 65 75 73 69  system for reusi
5170: 6e 67 20 73 74 61 74 65 6d 65 6e 74 0a 20 20 2a  ng statement.  *
5180: 2a 20 68 61 6e 64 6c 65 73 20 68 65 72 65 2c 20  * handles here, 
5190: 72 61 74 68 65 72 20 74 68 61 6e 20 70 72 65 70  rather than prep
51a0: 61 72 69 6e 67 20 61 20 6e 65 77 20 6f 6e 65 20  aring a new one 
51b0: 66 6f 72 20 65 61 63 68 20 71 75 65 72 79 2e 20  for each query. 
51c0: 42 75 74 20 74 68 61 74 0a 20 20 2a 2a 20 69 73  But that.  ** is
51d0: 20 6e 6f 74 20 70 6f 73 73 69 62 6c 65 20 61 73   not possible as
51e0: 20 53 51 4c 69 74 65 20 72 65 66 65 72 65 6e 63   SQLite referenc
51f0: 65 20 63 6f 75 6e 74 73 20 74 68 65 20 76 69 72  e counts the vir
5200: 74 75 61 6c 20 74 61 62 6c 65 20 6f 62 6a 65 63  tual table objec
5210: 74 73 2e 0a 20 20 2a 2a 20 41 6e 64 20 73 69 6e  ts..  ** And sin
5220: 63 65 20 74 68 65 20 73 74 61 74 65 6d 65 6e 74  ce the statement
5230: 20 72 65 71 75 69 72 65 64 20 68 65 72 65 20 72   required here r
5240: 65 61 64 73 20 66 72 6f 6d 20 74 68 69 73 20 76  eads from this v
5250: 65 72 79 20 76 69 72 74 75 61 6c 20 0a 20 20 2a  ery virtual .  *
5260: 2a 20 74 61 62 6c 65 2c 20 73 61 76 69 6e 67 20  * table, saving 
5270: 69 74 20 63 72 65 61 74 65 73 20 61 20 63 69 72  it creates a cir
5280: 63 75 6c 61 72 20 72 65 66 65 72 65 6e 63 65 2e  cular reference.
5290: 0a 20 20 2a 2a 0a 20 20 2a 2a 20 49 66 20 53 51  .  **.  ** If SQ
52a0: 4c 69 74 65 20 61 20 62 75 69 6c 74 2d 69 6e 20  Lite a built-in 
52b0: 73 74 61 74 65 6d 65 6e 74 20 63 61 63 68 65 2c  statement cache,
52c0: 20 74 68 69 73 20 77 6f 75 6c 64 6e 27 74 20 62   this wouldn't b
52d0: 65 20 61 20 70 72 6f 62 6c 65 6d 2e 20 2a 2f 0a  e a problem. */.
52e0: 20 20 7a 53 71 6c 20 3d 20 73 71 6c 69 74 65 33    zSql = sqlite3
52f0: 5f 6d 70 72 69 6e 74 66 28 22 53 45 4c 45 43 54  _mprintf("SELECT
5300: 20 72 6f 77 69 64 2c 20 72 61 6e 6b 20 46 52 4f   rowid, rank FRO
5310: 4d 20 25 51 2e 25 51 20 4f 52 44 45 52 20 42 59  M %Q.%Q ORDER BY
5320: 20 25 73 28 25 73 25 73 25 73 29 20 25 73 22 2c   %s(%s%s%s) %s",
5330: 0a 20 20 20 20 20 20 70 43 6f 6e 66 69 67 2d 3e  .      pConfig->
5340: 7a 44 62 2c 20 70 43 6f 6e 66 69 67 2d 3e 7a 4e  zDb, pConfig->zN
5350: 61 6d 65 2c 20 7a 52 61 6e 6b 2c 20 70 43 6f 6e  ame, zRank, pCon
5360: 66 69 67 2d 3e 7a 4e 61 6d 65 2c 0a 20 20 20 20  fig->zName,.    
5370: 20 20 28 70 43 6f 6e 66 69 67 2d 3e 7a 52 61 6e    (pConfig->zRan
5380: 6b 41 72 67 73 20 3f 20 22 2c 20 22 20 3a 20 22  kArgs ? ", " : "
5390: 22 29 2c 0a 20 20 20 20 20 20 28 70 43 6f 6e 66  "),.      (pConf
53a0: 69 67 2d 3e 7a 52 61 6e 6b 41 72 67 73 20 3f 20  ig->zRankArgs ? 
53b0: 70 43 6f 6e 66 69 67 2d 3e 7a 52 61 6e 6b 41 72  pConfig->zRankAr
53c0: 67 73 20 3a 20 22 22 29 2c 0a 20 20 20 20 20 20  gs : ""),.      
53d0: 62 41 73 63 20 3f 20 22 41 53 43 22 20 3a 20 22  bAsc ? "ASC" : "
53e0: 44 45 53 43 22 0a 20 20 29 3b 0a 20 20 69 66 28  DESC".  );.  if(
53f0: 20 7a 53 71 6c 3d 3d 30 20 29 7b 0a 20 20 20 20   zSql==0 ){.    
5400: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  rc = SQLITE_NOME
5410: 4d 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  M;.  }else{.    
5420: 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 70 72 65  rc = sqlite3_pre
5430: 70 61 72 65 5f 76 32 28 70 43 6f 6e 66 69 67 2d  pare_v2(pConfig-
5440: 3e 64 62 2c 20 7a 53 71 6c 2c 20 2d 31 2c 20 26  >db, zSql, -1, &
5450: 70 53 6f 72 74 65 72 2d 3e 70 53 74 6d 74 2c 20  pSorter->pStmt, 
5460: 30 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f  0);.    sqlite3_
5470: 66 72 65 65 28 7a 53 71 6c 29 3b 0a 20 20 7d 0a  free(zSql);.  }.
5480: 0a 20 20 70 43 73 72 2d 3e 70 53 6f 72 74 65 72  .  pCsr->pSorter
5490: 20 3d 20 70 53 6f 72 74 65 72 3b 0a 20 20 69 66   = pSorter;.  if
54a0: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
54b0: 29 7b 0a 20 20 20 20 61 73 73 65 72 74 28 20 70  ){.    assert( p
54c0: 54 61 62 2d 3e 70 53 6f 72 74 43 73 72 3d 3d 30  Tab->pSortCsr==0
54d0: 20 29 3b 0a 20 20 20 20 70 54 61 62 2d 3e 70 53   );.    pTab->pS
54e0: 6f 72 74 43 73 72 20 3d 20 70 43 73 72 3b 0a 20  ortCsr = pCsr;. 
54f0: 20 20 20 72 63 20 3d 20 66 74 73 35 53 6f 72 74     rc = fts5Sort
5500: 65 72 4e 65 78 74 28 70 43 73 72 29 3b 0a 20 20  erNext(pCsr);.  
5510: 20 20 70 54 61 62 2d 3e 70 53 6f 72 74 43 73 72    pTab->pSortCsr
5520: 20 3d 20 30 3b 0a 20 20 7d 0a 0a 20 20 69 66 28   = 0;.  }..  if(
5530: 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
5540: 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 69  {.    sqlite3_fi
5550: 6e 61 6c 69 7a 65 28 70 53 6f 72 74 65 72 2d 3e  nalize(pSorter->
5560: 70 53 74 6d 74 29 3b 0a 20 20 20 20 73 71 6c 69  pStmt);.    sqli
5570: 74 65 33 5f 66 72 65 65 28 70 53 6f 72 74 65 72  te3_free(pSorter
5580: 29 3b 0a 20 20 20 20 70 43 73 72 2d 3e 70 53 6f  );.    pCsr->pSo
5590: 72 74 65 72 20 3d 20 30 3b 0a 20 20 7d 0a 0a 20  rter = 0;.  }.. 
55a0: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73   return rc;.}..s
55b0: 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 43 75  tatic int fts5Cu
55c0: 72 73 6f 72 46 69 72 73 74 28 46 74 73 35 54 61  rsorFirst(Fts5Ta
55d0: 62 6c 65 20 2a 70 54 61 62 2c 20 46 74 73 35 43  ble *pTab, Fts5C
55e0: 75 72 73 6f 72 20 2a 70 43 73 72 2c 20 69 6e 74  ursor *pCsr, int
55f0: 20 62 41 73 63 29 7b 0a 20 20 69 6e 74 20 72 63   bAsc){.  int rc
5600: 3b 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33  ;.  rc = sqlite3
5610: 46 74 73 35 45 78 70 72 46 69 72 73 74 28 70 43  Fts5ExprFirst(pC
5620: 73 72 2d 3e 70 45 78 70 72 2c 20 70 54 61 62 2d  sr->pExpr, pTab-
5630: 3e 70 49 6e 64 65 78 2c 20 62 41 73 63 29 3b 0a  >pIndex, bAsc);.
5640: 20 20 69 66 28 20 73 71 6c 69 74 65 33 46 74 73    if( sqlite3Fts
5650: 35 45 78 70 72 45 6f 66 28 70 43 73 72 2d 3e 70  5ExprEof(pCsr->p
5660: 45 78 70 72 29 20 29 7b 0a 20 20 20 20 43 73 72  Expr) ){.    Csr
5670: 46 6c 61 67 53 65 74 28 70 43 73 72 2c 20 46 54  FlagSet(pCsr, FT
5680: 53 35 43 53 52 5f 45 4f 46 29 3b 0a 20 20 7d 0a  S5CSR_EOF);.  }.
5690: 20 20 66 74 73 35 43 73 72 4e 65 77 72 6f 77 28    fts5CsrNewrow(
56a0: 70 43 73 72 29 3b 0a 20 20 72 65 74 75 72 6e 20  pCsr);.  return 
56b0: 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 50 72 6f  rc;.}../*.** Pro
56c0: 63 65 73 73 20 61 20 22 73 70 65 63 69 61 6c 22  cess a "special"
56d0: 20 71 75 65 72 79 2e 20 41 20 73 70 65 63 69 61   query. A specia
56e0: 6c 20 71 75 65 72 79 20 69 73 20 69 64 65 6e 74  l query is ident
56f0: 69 66 69 65 64 20 61 73 20 6f 6e 65 20 77 69 74  ified as one wit
5700: 68 20 61 0a 2a 2a 20 4d 41 54 43 48 20 65 78 70  h a.** MATCH exp
5710: 72 65 73 73 69 6f 6e 20 74 68 61 74 20 62 65 67  ression that beg
5720: 69 6e 73 20 77 69 74 68 20 61 20 27 2a 27 20 63  ins with a '*' c
5730: 68 61 72 61 63 74 65 72 2e 20 54 68 65 20 72 65  haracter. The re
5740: 6d 61 69 6e 64 65 72 20 6f 66 0a 2a 2a 20 74 68  mainder of.** th
5750: 65 20 74 65 78 74 20 70 61 73 73 65 64 20 74 6f  e text passed to
5760: 20 74 68 65 20 4d 41 54 43 48 20 6f 70 65 72 61   the MATCH opera
5770: 74 6f 72 20 61 72 65 20 75 73 65 64 20 61 73 20  tor are used as 
5780: 20 74 68 65 20 73 70 65 63 69 61 6c 20 71 75 65   the special que
5790: 72 79 0a 2a 2a 20 70 61 72 61 6d 65 74 65 72 73  ry.** parameters
57a0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
57b0: 66 74 73 35 53 70 65 63 69 61 6c 4d 61 74 63 68  fts5SpecialMatch
57c0: 28 0a 20 20 46 74 73 35 54 61 62 6c 65 20 2a 70  (.  Fts5Table *p
57d0: 54 61 62 2c 20 0a 20 20 46 74 73 35 43 75 72 73  Tab, .  Fts5Curs
57e0: 6f 72 20 2a 70 43 73 72 2c 20 0a 20 20 63 6f 6e  or *pCsr, .  con
57f0: 73 74 20 63 68 61 72 20 2a 7a 51 75 65 72 79 0a  st char *zQuery.
5800: 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51  ){.  int rc = SQ
5810: 4c 49 54 45 5f 4f 4b 3b 20 20 20 20 20 20 20 20  LITE_OK;        
5820: 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63       /* Return c
5830: 6f 64 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63  ode */.  const c
5840: 68 61 72 20 2a 7a 20 3d 20 7a 51 75 65 72 79 3b  har *z = zQuery;
5850: 20 20 20 20 20 20 20 20 20 2f 2a 20 53 70 65 63           /* Spec
5860: 69 61 6c 20 71 75 65 72 79 20 74 65 78 74 20 2a  ial query text *
5870: 2f 0a 20 20 69 6e 74 20 6e 3b 20 20 20 20 20 20  /.  int n;      
5880: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5890: 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66      /* Number of
58a0: 20 62 79 74 65 73 20 69 6e 20 74 65 78 74 20 61   bytes in text a
58b0: 74 20 7a 20 2a 2f 0a 0a 20 20 77 68 69 6c 65 28  t z */..  while(
58c0: 20 7a 5b 30 5d 3d 3d 27 20 27 20 29 20 7a 2b 2b   z[0]==' ' ) z++
58d0: 3b 0a 20 20 66 6f 72 28 6e 3d 30 3b 20 7a 5b 6e  ;.  for(n=0; z[n
58e0: 5d 20 26 26 20 7a 5b 6e 5d 21 3d 27 20 27 3b 20  ] && z[n]!=' '; 
58f0: 6e 2b 2b 29 3b 0a 0a 20 20 61 73 73 65 72 74 28  n++);..  assert(
5900: 20 70 54 61 62 2d 3e 62 61 73 65 2e 7a 45 72 72   pTab->base.zErr
5910: 4d 73 67 3d 3d 30 20 29 3b 0a 20 20 61 73 73 65  Msg==0 );.  asse
5920: 72 74 28 20 70 43 73 72 2d 3e 7a 53 70 65 63 69  rt( pCsr->zSpeci
5930: 61 6c 3d 3d 30 20 29 3b 0a 0a 20 20 69 66 28 20  al==0 );..  if( 
5940: 30 3d 3d 73 71 6c 69 74 65 33 5f 73 74 72 6e 69  0==sqlite3_strni
5950: 63 6d 70 28 22 72 65 61 64 73 22 2c 20 7a 2c 20  cmp("reads", z, 
5960: 6e 29 20 29 7b 0a 20 20 20 20 70 43 73 72 2d 3e  n) ){.    pCsr->
5970: 7a 53 70 65 63 69 61 6c 20 3d 20 73 71 6c 69 74  zSpecial = sqlit
5980: 65 33 5f 6d 70 72 69 6e 74 66 28 22 25 64 22 2c  e3_mprintf("%d",
5990: 20 73 71 6c 69 74 65 33 46 74 73 35 49 6e 64 65   sqlite3Fts5Inde
59a0: 78 52 65 61 64 73 28 70 54 61 62 2d 3e 70 49 6e  xReads(pTab->pIn
59b0: 64 65 78 29 29 3b 0a 20 20 20 20 70 43 73 72 2d  dex));.    pCsr-
59c0: 3e 69 64 78 4e 75 6d 20 3d 20 46 54 53 35 5f 50  >idxNum = FTS5_P
59d0: 4c 41 4e 5f 53 50 45 43 49 41 4c 3b 0a 20 20 20  LAN_SPECIAL;.   
59e0: 20 69 66 28 20 70 43 73 72 2d 3e 7a 53 70 65 63   if( pCsr->zSpec
59f0: 69 61 6c 3d 3d 30 20 29 20 72 63 20 3d 20 53 51  ial==0 ) rc = SQ
5a00: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a  LITE_NOMEM;.  }.
5a10: 20 20 65 6c 73 65 7b 0a 20 20 20 20 2f 2a 20 41    else{.    /* A
5a20: 6e 20 75 6e 72 65 63 6f 67 6e 69 7a 65 64 20 64  n unrecognized d
5a30: 69 72 65 63 74 69 76 65 2e 20 52 65 74 75 72 6e  irective. Return
5a40: 20 61 6e 20 65 72 72 6f 72 20 6d 65 73 73 61 67   an error messag
5a50: 65 2e 20 2a 2f 0a 20 20 20 20 70 54 61 62 2d 3e  e. */.    pTab->
5a60: 62 61 73 65 2e 7a 45 72 72 4d 73 67 20 3d 20 73  base.zErrMsg = s
5a70: 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22  qlite3_mprintf("
5a80: 75 6e 6b 6e 6f 77 6e 20 73 70 65 63 69 61 6c 20  unknown special 
5a90: 71 75 65 72 79 3a 20 25 2e 2a 73 22 2c 20 6e 2c  query: %.*s", n,
5aa0: 20 7a 29 3b 0a 20 20 20 20 72 63 20 3d 20 53 51   z);.    rc = SQ
5ab0: 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a  LITE_ERROR;.  }.
5ac0: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
5ad0: 0a 2f 2a 0a 2a 2a 20 53 65 61 72 63 68 20 66 6f  ./*.** Search fo
5ae0: 72 20 61 6e 20 61 75 78 69 6c 69 61 72 79 20 66  r an auxiliary f
5af0: 75 6e 63 74 69 6f 6e 20 6e 61 6d 65 64 20 7a 4e  unction named zN
5b00: 61 6d 65 20 74 68 61 74 20 63 61 6e 20 62 65 20  ame that can be 
5b10: 75 73 65 64 20 77 69 74 68 20 74 61 62 6c 65 0a  used with table.
5b20: 2a 2a 20 70 54 61 62 2e 20 49 66 20 6f 6e 65 20  ** pTab. If one 
5b30: 69 73 20 66 6f 75 6e 64 2c 20 72 65 74 75 72 6e  is found, return
5b40: 20 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 74 68   a pointer to th
5b50: 65 20 63 6f 72 72 65 73 70 6f 6e 64 69 6e 67 20  e corresponding 
5b60: 46 74 73 35 41 75 78 69 6c 69 61 72 79 0a 2a 2a  Fts5Auxiliary.**
5b70: 20 73 74 72 75 63 74 75 72 65 2e 20 4f 74 68 65   structure. Othe
5b80: 72 77 69 73 65 2c 20 69 66 20 6e 6f 20 73 75 63  rwise, if no suc
5b90: 68 20 66 75 6e 63 74 69 6f 6e 20 65 78 69 73 74  h function exist
5ba0: 73 2c 20 72 65 74 75 72 6e 20 4e 55 4c 4c 2e 0a  s, return NULL..
5bb0: 2a 2f 0a 73 74 61 74 69 63 20 46 74 73 35 41 75  */.static Fts5Au
5bc0: 78 69 6c 69 61 72 79 20 2a 66 74 73 35 46 69 6e  xiliary *fts5Fin
5bd0: 64 41 75 78 69 6c 69 61 72 79 28 46 74 73 35 54  dAuxiliary(Fts5T
5be0: 61 62 6c 65 20 2a 70 54 61 62 2c 20 63 6f 6e 73  able *pTab, cons
5bf0: 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 29 7b 0a  t char *zName){.
5c00: 20 20 46 74 73 35 41 75 78 69 6c 69 61 72 79 20    Fts5Auxiliary 
5c10: 2a 70 41 75 78 3b 0a 0a 20 20 66 6f 72 28 70 41  *pAux;..  for(pA
5c20: 75 78 3d 70 54 61 62 2d 3e 70 47 6c 6f 62 61 6c  ux=pTab->pGlobal
5c30: 2d 3e 70 41 75 78 3b 20 70 41 75 78 3b 20 70 41  ->pAux; pAux; pA
5c40: 75 78 3d 70 41 75 78 2d 3e 70 4e 65 78 74 29 7b  ux=pAux->pNext){
5c50: 0a 20 20 20 20 69 66 28 20 73 71 6c 69 74 65 33  .    if( sqlite3
5c60: 5f 73 74 72 69 63 6d 70 28 7a 4e 61 6d 65 2c 20  _stricmp(zName, 
5c70: 70 41 75 78 2d 3e 7a 46 75 6e 63 29 3d 3d 30 20  pAux->zFunc)==0 
5c80: 29 20 72 65 74 75 72 6e 20 70 41 75 78 3b 0a 20  ) return pAux;. 
5c90: 20 7d 0a 0a 20 20 2f 2a 20 4e 6f 20 66 75 6e 63   }..  /* No func
5ca0: 74 69 6f 6e 20 6f 66 20 74 68 65 20 73 70 65 63  tion of the spec
5cb0: 69 66 69 65 64 20 6e 61 6d 65 20 77 61 73 20 66  ified name was f
5cc0: 6f 75 6e 64 2e 20 52 65 74 75 72 6e 20 30 2e 20  ound. Return 0. 
5cd0: 2a 2f 0a 20 20 72 65 74 75 72 6e 20 30 3b 0a 7d  */.  return 0;.}
5ce0: 0a 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74  ...static int ft
5cf0: 73 35 46 69 6e 64 52 61 6e 6b 46 75 6e 63 74 69  s5FindRankFuncti
5d00: 6f 6e 28 46 74 73 35 43 75 72 73 6f 72 20 2a 70  on(Fts5Cursor *p
5d10: 43 73 72 29 7b 0a 20 20 46 74 73 35 54 61 62 6c  Csr){.  Fts5Tabl
5d20: 65 20 2a 70 54 61 62 20 3d 20 28 46 74 73 35 54  e *pTab = (Fts5T
5d30: 61 62 6c 65 2a 29 28 70 43 73 72 2d 3e 62 61 73  able*)(pCsr->bas
5d40: 65 2e 70 56 74 61 62 29 3b 0a 20 20 46 74 73 35  e.pVtab);.  Fts5
5d50: 43 6f 6e 66 69 67 20 2a 70 43 6f 6e 66 69 67 20  Config *pConfig 
5d60: 3d 20 70 54 61 62 2d 3e 70 43 6f 6e 66 69 67 3b  = pTab->pConfig;
5d70: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
5d80: 52 61 6e 6b 20 3d 20 70 43 6f 6e 66 69 67 2d 3e  Rank = pConfig->
5d90: 7a 52 61 6e 6b 3b 0a 20 20 69 6e 74 20 72 63 20  zRank;.  int rc 
5da0: 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 46  = SQLITE_OK;.  F
5db0: 74 73 35 41 75 78 69 6c 69 61 72 79 20 2a 70 41  ts5Auxiliary *pA
5dc0: 75 78 3b 0a 0a 20 20 69 66 28 20 7a 52 61 6e 6b  ux;..  if( zRank
5dd0: 3d 3d 30 20 29 20 7a 52 61 6e 6b 20 3d 20 46 54  ==0 ) zRank = FT
5de0: 53 35 5f 44 45 46 41 55 4c 54 5f 52 41 4e 4b 3b  S5_DEFAULT_RANK;
5df0: 0a 0a 20 20 69 66 28 20 70 54 61 62 2d 3e 70 43  ..  if( pTab->pC
5e00: 6f 6e 66 69 67 2d 3e 7a 52 61 6e 6b 41 72 67 73  onfig->zRankArgs
5e10: 20 29 7b 0a 20 20 20 20 63 68 61 72 20 2a 7a 53   ){.    char *zS
5e20: 71 6c 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72  ql = sqlite3_mpr
5e30: 69 6e 74 66 28 22 53 45 4c 45 43 54 20 25 73 22  intf("SELECT %s"
5e40: 2c 20 70 54 61 62 2d 3e 70 43 6f 6e 66 69 67 2d  , pTab->pConfig-
5e50: 3e 7a 52 61 6e 6b 41 72 67 73 29 3b 0a 20 20 20  >zRankArgs);.   
5e60: 20 69 66 28 20 7a 53 71 6c 3d 3d 30 20 29 7b 0a   if( zSql==0 ){.
5e70: 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54        rc = SQLIT
5e80: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d 65 6c  E_NOMEM;.    }el
5e90: 73 65 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65  se{.      sqlite
5ea0: 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74 20 3d 20  3_stmt *pStmt = 
5eb0: 30 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71  0;.      rc = sq
5ec0: 6c 69 74 65 33 5f 70 72 65 70 61 72 65 5f 76 32  lite3_prepare_v2
5ed0: 28 70 43 6f 6e 66 69 67 2d 3e 64 62 2c 20 7a 53  (pConfig->db, zS
5ee0: 71 6c 2c 20 2d 31 2c 20 26 70 53 74 6d 74 2c 20  ql, -1, &pStmt, 
5ef0: 30 29 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65  0);.      sqlite
5f00: 33 5f 66 72 65 65 28 7a 53 71 6c 29 3b 0a 20 20  3_free(zSql);.  
5f10: 20 20 20 20 61 73 73 65 72 74 28 20 72 63 3d 3d      assert( rc==
5f20: 53 51 4c 49 54 45 5f 4f 4b 20 7c 7c 20 70 43 73  SQLITE_OK || pCs
5f30: 72 2d 3e 70 52 61 6e 6b 41 72 67 53 74 6d 74 3d  r->pRankArgStmt=
5f40: 3d 30 20 29 3b 0a 20 20 20 20 20 20 69 66 28 20  =0 );.      if( 
5f50: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
5f60: 0a 20 20 20 20 20 20 20 20 69 66 28 20 53 51 4c  .        if( SQL
5f70: 49 54 45 5f 52 4f 57 3d 3d 73 71 6c 69 74 65 33  ITE_ROW==sqlite3
5f80: 5f 73 74 65 70 28 70 53 74 6d 74 29 20 29 7b 0a  _step(pStmt) ){.
5f90: 20 20 20 20 20 20 20 20 20 20 69 6e 74 20 6e 42            int nB
5fa0: 79 74 65 3b 0a 20 20 20 20 20 20 20 20 20 20 70  yte;.          p
5fb0: 43 73 72 2d 3e 6e 52 61 6e 6b 41 72 67 20 3d 20  Csr->nRankArg = 
5fc0: 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 63  sqlite3_column_c
5fd0: 6f 75 6e 74 28 70 53 74 6d 74 29 3b 0a 20 20 20  ount(pStmt);.   
5fe0: 20 20 20 20 20 20 20 6e 42 79 74 65 20 3d 20 73         nByte = s
5ff0: 69 7a 65 6f 66 28 73 71 6c 69 74 65 33 5f 76 61  izeof(sqlite3_va
6000: 6c 75 65 2a 29 2a 70 43 73 72 2d 3e 6e 52 61 6e  lue*)*pCsr->nRan
6010: 6b 41 72 67 3b 0a 20 20 20 20 20 20 20 20 20 20  kArg;.          
6020: 70 43 73 72 2d 3e 61 70 52 61 6e 6b 41 72 67 20  pCsr->apRankArg 
6030: 3d 20 28 73 71 6c 69 74 65 33 5f 76 61 6c 75 65  = (sqlite3_value
6040: 2a 2a 29 73 71 6c 69 74 65 33 46 74 73 35 4d 61  **)sqlite3Fts5Ma
6050: 6c 6c 6f 63 5a 65 72 6f 28 26 72 63 2c 20 6e 42  llocZero(&rc, nB
6060: 79 74 65 29 3b 0a 20 20 20 20 20 20 20 20 20 20  yte);.          
6070: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
6080: 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20  K ){.           
6090: 20 69 6e 74 20 69 3b 0a 20 20 20 20 20 20 20 20   int i;.        
60a0: 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70      for(i=0; i<p
60b0: 43 73 72 2d 3e 6e 52 61 6e 6b 41 72 67 3b 20 69  Csr->nRankArg; i
60c0: 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20  ++){.           
60d0: 20 20 20 70 43 73 72 2d 3e 61 70 52 61 6e 6b 41     pCsr->apRankA
60e0: 72 67 5b 69 5d 20 3d 20 73 71 6c 69 74 65 33 5f  rg[i] = sqlite3_
60f0: 63 6f 6c 75 6d 6e 5f 76 61 6c 75 65 28 70 53 74  column_value(pSt
6100: 6d 74 2c 20 69 29 3b 0a 20 20 20 20 20 20 20 20  mt, i);.        
6110: 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 20 20      }.          
6120: 7d 0a 20 20 20 20 20 20 20 20 20 20 70 43 73 72  }.          pCsr
6130: 2d 3e 70 52 61 6e 6b 41 72 67 53 74 6d 74 20 3d  ->pRankArgStmt =
6140: 20 70 53 74 6d 74 3b 0a 20 20 20 20 20 20 20 20   pStmt;.        
6150: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 20  }else{.         
6160: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 66 69   rc = sqlite3_fi
6170: 6e 61 6c 69 7a 65 28 70 53 74 6d 74 29 3b 0a 20  nalize(pStmt);. 
6180: 20 20 20 20 20 20 20 20 20 61 73 73 65 72 74 28           assert(
6190: 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
61a0: 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
61b0: 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20    }.    }.  }.. 
61c0: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
61d0: 4f 4b 20 29 7b 0a 20 20 20 20 70 41 75 78 20 3d  OK ){.    pAux =
61e0: 20 66 74 73 35 46 69 6e 64 41 75 78 69 6c 69 61   fts5FindAuxilia
61f0: 72 79 28 70 54 61 62 2c 20 7a 52 61 6e 6b 29 3b  ry(pTab, zRank);
6200: 0a 20 20 20 20 69 66 28 20 70 41 75 78 3d 3d 30  .    if( pAux==0
6210: 20 29 7b 0a 20 20 20 20 20 20 61 73 73 65 72 74   ){.      assert
6220: 28 20 70 54 61 62 2d 3e 62 61 73 65 2e 7a 45 72  ( pTab->base.zEr
6230: 72 4d 73 67 3d 3d 30 20 29 3b 0a 20 20 20 20 20  rMsg==0 );.     
6240: 20 70 54 61 62 2d 3e 62 61 73 65 2e 7a 45 72 72   pTab->base.zErr
6250: 4d 73 67 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70  Msg = sqlite3_mp
6260: 72 69 6e 74 66 28 22 6e 6f 20 73 75 63 68 20 66  rintf("no such f
6270: 75 6e 63 74 69 6f 6e 3a 20 25 73 22 2c 20 7a 52  unction: %s", zR
6280: 61 6e 6b 29 3b 0a 20 20 20 20 20 20 72 63 20 3d  ank);.      rc =
6290: 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20   SQLITE_ERROR;. 
62a0: 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 70 43 73 72     }.  }..  pCsr
62b0: 2d 3e 70 52 61 6e 6b 20 3d 20 70 41 75 78 3b 0a  ->pRank = pAux;.
62c0: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
62d0: 2f 2a 0a 2a 2a 20 54 68 69 73 20 69 73 20 74 68  /*.** This is th
62e0: 65 20 78 46 69 6c 74 65 72 20 69 6e 74 65 72 66  e xFilter interf
62f0: 61 63 65 20 66 6f 72 20 74 68 65 20 76 69 72 74  ace for the virt
6300: 75 61 6c 20 74 61 62 6c 65 2e 20 20 53 65 65 0a  ual table.  See.
6310: 2a 2a 20 74 68 65 20 76 69 72 74 75 61 6c 20 74  ** the virtual t
6320: 61 62 6c 65 20 78 46 69 6c 74 65 72 20 6d 65 74  able xFilter met
6330: 68 6f 64 20 64 6f 63 75 6d 65 6e 74 61 74 69 6f  hod documentatio
6340: 6e 20 66 6f 72 20 61 64 64 69 74 69 6f 6e 61 6c  n for additional
6350: 0a 2a 2a 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 2e  .** information.
6360: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66  .*/.static int f
6370: 74 73 35 46 69 6c 74 65 72 4d 65 74 68 6f 64 28  ts5FilterMethod(
6380: 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62 5f  .  sqlite3_vtab_
6390: 63 75 72 73 6f 72 20 2a 70 43 75 72 73 6f 72 2c  cursor *pCursor,
63a0: 20 20 20 2f 2a 20 54 68 65 20 63 75 72 73 6f 72     /* The cursor
63b0: 20 75 73 65 64 20 66 6f 72 20 74 68 69 73 20 71   used for this q
63c0: 75 65 72 79 20 2a 2f 0a 20 20 69 6e 74 20 69 64  uery */.  int id
63d0: 78 4e 75 6d 2c 20 20 20 20 20 20 20 20 20 20 20  xNum,           
63e0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 74 72            /* Str
63f0: 61 74 65 67 79 20 69 6e 64 65 78 20 2a 2f 0a 20  ategy index */. 
6400: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 69 64 78   const char *idx
6410: 53 74 72 2c 20 20 20 20 20 20 20 20 20 20 20 20  Str,            
6420: 20 2f 2a 20 55 6e 75 73 65 64 20 2a 2f 0a 20 20   /* Unused */.  
6430: 69 6e 74 20 6e 56 61 6c 2c 20 20 20 20 20 20 20  int nVal,       
6440: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6450: 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 65 6c 65  /* Number of ele
6460: 6d 65 6e 74 73 20 69 6e 20 61 70 56 61 6c 20 2a  ments in apVal *
6470: 2f 0a 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75  /.  sqlite3_valu
6480: 65 20 2a 2a 61 70 56 61 6c 20 20 20 20 20 20 20  e **apVal       
6490: 20 20 20 20 2f 2a 20 41 72 67 75 6d 65 6e 74 73      /* Arguments
64a0: 20 66 6f 72 20 74 68 65 20 69 6e 64 65 78 69 6e   for the indexin
64b0: 67 20 73 63 68 65 6d 65 20 2a 2f 0a 29 7b 0a 20  g scheme */.){. 
64c0: 20 46 74 73 35 54 61 62 6c 65 20 2a 70 54 61 62   Fts5Table *pTab
64d0: 20 3d 20 28 46 74 73 35 54 61 62 6c 65 2a 29 28   = (Fts5Table*)(
64e0: 70 43 75 72 73 6f 72 2d 3e 70 56 74 61 62 29 3b  pCursor->pVtab);
64f0: 0a 20 20 46 74 73 35 43 75 72 73 6f 72 20 2a 70  .  Fts5Cursor *p
6500: 43 73 72 20 3d 20 28 46 74 73 35 43 75 72 73 6f  Csr = (Fts5Curso
6510: 72 2a 29 70 43 75 72 73 6f 72 3b 0a 20 20 69 6e  r*)pCursor;.  in
6520: 74 20 62 41 73 63 20 3d 20 28 28 69 64 78 4e 75  t bAsc = ((idxNu
6530: 6d 20 26 20 46 54 53 35 5f 4f 52 44 45 52 5f 41  m & FTS5_ORDER_A
6540: 53 43 29 20 3f 20 31 20 3a 20 30 29 3b 0a 20 20  SC) ? 1 : 0);.  
6550: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
6560: 4f 4b 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 70  OK;..  assert( p
6570: 43 73 72 2d 3e 70 53 74 6d 74 3d 3d 30 20 29 3b  Csr->pStmt==0 );
6580: 0a 20 20 61 73 73 65 72 74 28 20 70 43 73 72 2d  .  assert( pCsr-
6590: 3e 70 45 78 70 72 3d 3d 30 20 29 3b 0a 20 20 61  >pExpr==0 );.  a
65a0: 73 73 65 72 74 28 20 70 43 73 72 2d 3e 63 73 72  ssert( pCsr->csr
65b0: 66 6c 61 67 73 3d 3d 30 20 29 3b 0a 20 20 61 73  flags==0 );.  as
65c0: 73 65 72 74 28 20 70 43 73 72 2d 3e 70 52 61 6e  sert( pCsr->pRan
65d0: 6b 3d 3d 30 20 29 3b 0a 0a 20 20 69 66 28 20 70  k==0 );..  if( p
65e0: 54 61 62 2d 3e 70 53 6f 72 74 43 73 72 20 29 7b  Tab->pSortCsr ){
65f0: 0a 20 20 20 20 2f 2a 20 49 66 20 70 53 6f 72 74  .    /* If pSort
6600: 43 73 72 20 69 73 20 6e 6f 6e 2d 4e 55 4c 4c 2c  Csr is non-NULL,
6610: 20 74 68 65 6e 20 74 68 69 73 20 63 61 6c 6c 20   then this call 
6620: 69 73 20 62 65 69 6e 67 20 6d 61 64 65 20 61 73  is being made as
6630: 20 70 61 72 74 20 6f 66 20 0a 20 20 20 20 2a 2a   part of .    **
6640: 20 70 72 6f 63 65 73 73 69 6e 67 20 66 6f 72 20   processing for 
6650: 61 20 22 2e 2e 2e 20 4d 41 54 43 48 20 3c 65 78  a "... MATCH <ex
6660: 70 72 3e 20 4f 52 44 45 52 20 42 59 20 72 61 6e  pr> ORDER BY ran
6670: 6b 22 20 71 75 65 72 79 20 28 65 50 6c 61 6e 20  k" query (ePlan 
6680: 69 73 0a 20 20 20 20 2a 2a 20 73 65 74 20 74 6f  is.    ** set to
6690: 20 46 54 53 35 5f 50 4c 41 4e 5f 53 4f 52 54 45   FTS5_PLAN_SORTE
66a0: 44 5f 4d 41 54 43 48 29 2e 20 70 53 6f 72 74 43  D_MATCH). pSortC
66b0: 73 72 20 69 73 20 74 68 65 20 63 75 72 73 6f 72  sr is the cursor
66c0: 20 74 68 61 74 20 77 69 6c 6c 0a 20 20 20 20 2a   that will.    *
66d0: 2a 20 72 65 74 75 72 6e 20 72 65 73 75 6c 74 73  * return results
66e0: 20 74 6f 20 74 68 65 20 75 73 65 72 20 66 6f 72   to the user for
66f0: 20 74 68 69 73 20 71 75 65 72 79 2e 20 54 68 65   this query. The
6700: 20 63 75 72 72 65 6e 74 20 63 75 72 73 6f 72 20   current cursor 
6710: 0a 20 20 20 20 2a 2a 20 28 70 43 75 72 73 6f 72  .    ** (pCursor
6720: 29 20 69 73 20 75 73 65 64 20 74 6f 20 65 78 65  ) is used to exe
6730: 63 75 74 65 20 74 68 65 20 71 75 65 72 79 20 69  cute the query i
6740: 73 73 75 65 64 20 62 79 20 66 75 6e 63 74 69 6f  ssued by functio
6750: 6e 20 0a 20 20 20 20 2a 2a 20 66 74 73 35 43 75  n .    ** fts5Cu
6760: 72 73 6f 72 46 69 72 73 74 53 6f 72 74 65 64 28  rsorFirstSorted(
6770: 29 20 61 62 6f 76 65 2e 20 20 2a 2f 0a 20 20 20  ) above.  */.   
6780: 20 61 73 73 65 72 74 28 20 46 54 53 35 5f 50 4c   assert( FTS5_PL
6790: 41 4e 28 69 64 78 4e 75 6d 29 3d 3d 46 54 53 35  AN(idxNum)==FTS5
67a0: 5f 50 4c 41 4e 5f 53 43 41 4e 20 29 3b 0a 20 20  _PLAN_SCAN );.  
67b0: 20 20 70 43 73 72 2d 3e 69 64 78 4e 75 6d 20 3d    pCsr->idxNum =
67c0: 20 46 54 53 35 5f 50 4c 41 4e 5f 53 4f 55 52 43   FTS5_PLAN_SOURC
67d0: 45 3b 0a 20 20 20 20 70 43 73 72 2d 3e 70 45 78  E;.    pCsr->pEx
67e0: 70 72 20 3d 20 70 54 61 62 2d 3e 70 53 6f 72 74  pr = pTab->pSort
67f0: 43 73 72 2d 3e 70 45 78 70 72 3b 0a 20 20 20 20  Csr->pExpr;.    
6800: 72 63 20 3d 20 66 74 73 35 43 75 72 73 6f 72 46  rc = fts5CursorF
6810: 69 72 73 74 28 70 54 61 62 2c 20 70 43 73 72 2c  irst(pTab, pCsr,
6820: 20 62 41 73 63 29 3b 0a 20 20 7d 65 6c 73 65 7b   bAsc);.  }else{
6830: 0a 20 20 20 20 69 6e 74 20 65 50 6c 61 6e 20 3d  .    int ePlan =
6840: 20 46 54 53 35 5f 50 4c 41 4e 28 69 64 78 4e 75   FTS5_PLAN(idxNu
6850: 6d 29 3b 0a 20 20 20 20 70 43 73 72 2d 3e 69 64  m);.    pCsr->id
6860: 78 4e 75 6d 20 3d 20 69 64 78 4e 75 6d 3b 0a 20  xNum = idxNum;. 
6870: 20 20 20 69 66 28 20 65 50 6c 61 6e 3d 3d 46 54     if( ePlan==FT
6880: 53 35 5f 50 4c 41 4e 5f 4d 41 54 43 48 20 7c 7c  S5_PLAN_MATCH ||
6890: 20 65 50 6c 61 6e 3d 3d 46 54 53 35 5f 50 4c 41   ePlan==FTS5_PLA
68a0: 4e 5f 53 4f 52 54 45 44 5f 4d 41 54 43 48 20 29  N_SORTED_MATCH )
68b0: 7b 0a 20 20 20 20 20 20 63 6f 6e 73 74 20 63 68  {.      const ch
68c0: 61 72 20 2a 7a 45 78 70 72 20 3d 20 28 63 6f 6e  ar *zExpr = (con
68d0: 73 74 20 63 68 61 72 2a 29 73 71 6c 69 74 65 33  st char*)sqlite3
68e0: 5f 76 61 6c 75 65 5f 74 65 78 74 28 61 70 56 61  _value_text(apVa
68f0: 6c 5b 30 5d 29 3b 0a 0a 20 20 20 20 20 20 69 66  l[0]);..      if
6900: 28 20 7a 45 78 70 72 5b 30 5d 3d 3d 27 2a 27 20  ( zExpr[0]=='*' 
6910: 29 7b 0a 20 20 20 20 20 20 20 20 2f 2a 20 54 68  ){.        /* Th
6920: 65 20 75 73 65 72 20 68 61 73 20 69 73 73 75 65  e user has issue
6930: 64 20 61 20 71 75 65 72 79 20 6f 66 20 74 68 65  d a query of the
6940: 20 66 6f 72 6d 20 22 4d 41 54 43 48 20 27 2a 2e   form "MATCH '*.
6950: 2e 2e 27 22 2e 20 54 68 69 73 0a 20 20 20 20 20  ..'". This.     
6960: 20 20 20 2a 2a 20 69 6e 64 69 63 61 74 65 73 20     ** indicates 
6970: 74 68 61 74 20 74 68 65 20 4d 41 54 43 48 20 65  that the MATCH e
6980: 78 70 72 65 73 73 69 6f 6e 20 69 73 20 6e 6f 74  xpression is not
6990: 20 61 20 66 75 6c 6c 20 74 65 78 74 20 71 75 65   a full text que
69a0: 72 79 2c 0a 20 20 20 20 20 20 20 20 2a 2a 20 62  ry,.        ** b
69b0: 75 74 20 61 20 72 65 71 75 65 73 74 20 66 6f 72  ut a request for
69c0: 20 61 6e 20 69 6e 74 65 72 6e 61 6c 20 70 61 72   an internal par
69d0: 61 6d 65 74 65 72 2e 20 20 2a 2f 0a 20 20 20 20  ameter.  */.    
69e0: 20 20 20 20 72 63 20 3d 20 66 74 73 35 53 70 65      rc = fts5Spe
69f0: 63 69 61 6c 4d 61 74 63 68 28 70 54 61 62 2c 20  cialMatch(pTab, 
6a00: 70 43 73 72 2c 20 26 7a 45 78 70 72 5b 31 5d 29  pCsr, &zExpr[1])
6a10: 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20  ;.      }else{. 
6a20: 20 20 20 20 20 20 20 63 68 61 72 20 2a 2a 70 7a         char **pz
6a30: 45 72 72 20 3d 20 26 70 54 61 62 2d 3e 62 61 73  Err = &pTab->bas
6a40: 65 2e 7a 45 72 72 4d 73 67 3b 0a 20 20 20 20 20  e.zErrMsg;.     
6a50: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 46     rc = sqlite3F
6a60: 74 73 35 45 78 70 72 4e 65 77 28 70 54 61 62 2d  ts5ExprNew(pTab-
6a70: 3e 70 43 6f 6e 66 69 67 2c 20 7a 45 78 70 72 2c  >pConfig, zExpr,
6a80: 20 26 70 43 73 72 2d 3e 70 45 78 70 72 2c 20 70   &pCsr->pExpr, p
6a90: 7a 45 72 72 29 3b 0a 20 20 20 20 20 20 20 20 69  zErr);.        i
6aa0: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
6ab0: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 69 66   ){.          if
6ac0: 28 20 65 50 6c 61 6e 3d 3d 46 54 53 35 5f 50 4c  ( ePlan==FTS5_PL
6ad0: 41 4e 5f 4d 41 54 43 48 20 29 7b 0a 20 20 20 20  AN_MATCH ){.    
6ae0: 20 20 20 20 20 20 20 20 72 63 20 3d 20 66 74 73          rc = fts
6af0: 35 43 75 72 73 6f 72 46 69 72 73 74 28 70 54 61  5CursorFirst(pTa
6b00: 62 2c 20 70 43 73 72 2c 20 62 41 73 63 29 3b 0a  b, pCsr, bAsc);.
6b10: 20 20 20 20 20 20 20 20 20 20 7d 65 6c 73 65 7b            }else{
6b20: 0a 20 20 20 20 20 20 20 20 20 20 20 20 72 63 20  .            rc 
6b30: 3d 20 66 74 73 35 43 75 72 73 6f 72 46 69 72 73  = fts5CursorFirs
6b40: 74 53 6f 72 74 65 64 28 70 54 61 62 2c 20 70 43  tSorted(pTab, pC
6b50: 73 72 2c 20 62 41 73 63 29 3b 0a 20 20 20 20 20  sr, bAsc);.     
6b60: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 7d       }.        }
6b70: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 65 6c  .      }.    }el
6b80: 73 65 7b 0a 20 20 20 20 20 20 2f 2a 20 54 68 69  se{.      /* Thi
6b90: 73 20 69 73 20 65 69 74 68 65 72 20 61 20 66 75  s is either a fu
6ba0: 6c 6c 2d 74 61 62 6c 65 20 73 63 61 6e 20 28 65  ll-table scan (e
6bb0: 50 6c 61 6e 3d 3d 46 54 53 35 5f 50 4c 41 4e 5f  Plan==FTS5_PLAN_
6bc0: 53 43 41 4e 29 20 6f 72 20 61 20 6c 6f 6f 6b 75  SCAN) or a looku
6bd0: 70 0a 20 20 20 20 20 20 2a 2a 20 62 79 20 72 6f  p.      ** by ro
6be0: 77 69 64 20 28 65 50 6c 61 6e 3d 3d 46 54 53 35  wid (ePlan==FTS5
6bf0: 5f 50 4c 41 4e 5f 52 4f 57 49 44 29 2e 20 20 2a  _PLAN_ROWID).  *
6c00: 2f 0a 20 20 20 20 20 20 69 6e 74 20 65 53 74 6d  /.      int eStm
6c10: 74 20 3d 20 66 74 73 35 53 74 6d 74 54 79 70 65  t = fts5StmtType
6c20: 28 69 64 78 4e 75 6d 29 3b 0a 20 20 20 20 20 20  (idxNum);.      
6c30: 72 63 20 3d 20 73 71 6c 69 74 65 33 46 74 73 35  rc = sqlite3Fts5
6c40: 53 74 6f 72 61 67 65 53 74 6d 74 28 70 54 61 62  StorageStmt(pTab
6c50: 2d 3e 70 53 74 6f 72 61 67 65 2c 20 65 53 74 6d  ->pStorage, eStm
6c60: 74 2c 20 26 70 43 73 72 2d 3e 70 53 74 6d 74 29  t, &pCsr->pStmt)
6c70: 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d  ;.      if( rc==
6c80: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
6c90: 20 20 20 20 20 69 66 28 20 65 50 6c 61 6e 3d 3d       if( ePlan==
6ca0: 46 54 53 35 5f 50 4c 41 4e 5f 52 4f 57 49 44 20  FTS5_PLAN_ROWID 
6cb0: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 73 71 6c  ){.          sql
6cc0: 69 74 65 33 5f 62 69 6e 64 5f 76 61 6c 75 65 28  ite3_bind_value(
6cd0: 70 43 73 72 2d 3e 70 53 74 6d 74 2c 20 31 2c 20  pCsr->pStmt, 1, 
6ce0: 61 70 56 61 6c 5b 30 5d 29 3b 0a 20 20 20 20 20  apVal[0]);.     
6cf0: 20 20 20 7d 0a 20 20 20 20 20 20 20 20 72 63 20     }.        rc 
6d00: 3d 20 66 74 73 35 4e 65 78 74 4d 65 74 68 6f 64  = fts5NextMethod
6d10: 28 70 43 75 72 73 6f 72 29 3b 0a 20 20 20 20 20  (pCursor);.     
6d20: 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20   }.    }.  }..  
6d30: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
6d40: 20 0a 2a 2a 20 54 68 69 73 20 69 73 20 74 68 65   .** This is the
6d50: 20 78 45 6f 66 20 6d 65 74 68 6f 64 20 6f 66 20   xEof method of 
6d60: 74 68 65 20 76 69 72 74 75 61 6c 20 74 61 62 6c  the virtual tabl
6d70: 65 2e 20 53 51 4c 69 74 65 20 63 61 6c 6c 73 20  e. SQLite calls 
6d80: 74 68 69 73 20 0a 2a 2a 20 72 6f 75 74 69 6e 65  this .** routine
6d90: 20 74 6f 20 66 69 6e 64 20 6f 75 74 20 69 66 20   to find out if 
6da0: 69 74 20 68 61 73 20 72 65 61 63 68 65 64 20 74  it has reached t
6db0: 68 65 20 65 6e 64 20 6f 66 20 61 20 72 65 73 75  he end of a resu
6dc0: 6c 74 20 73 65 74 2e 0a 2a 2f 0a 73 74 61 74 69  lt set..*/.stati
6dd0: 63 20 69 6e 74 20 66 74 73 35 45 6f 66 4d 65 74  c int fts5EofMet
6de0: 68 6f 64 28 73 71 6c 69 74 65 33 5f 76 74 61 62  hod(sqlite3_vtab
6df0: 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 73 6f 72  _cursor *pCursor
6e00: 29 7b 0a 20 20 46 74 73 35 43 75 72 73 6f 72 20  ){.  Fts5Cursor 
6e10: 2a 70 43 73 72 20 3d 20 28 46 74 73 35 43 75 72  *pCsr = (Fts5Cur
6e20: 73 6f 72 2a 29 70 43 75 72 73 6f 72 3b 0a 20 20  sor*)pCursor;.  
6e30: 72 65 74 75 72 6e 20 28 43 73 72 46 6c 61 67 54  return (CsrFlagT
6e40: 65 73 74 28 70 43 73 72 2c 20 46 54 53 35 43 53  est(pCsr, FTS5CS
6e50: 52 5f 45 4f 46 29 20 3f 20 31 20 3a 20 30 29 3b  R_EOF) ? 1 : 0);
6e60: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e  .}../*.** Return
6e70: 20 74 68 65 20 72 6f 77 69 64 20 74 68 61 74 20   the rowid that 
6e80: 74 68 65 20 63 75 72 73 6f 72 20 63 75 72 72 65  the cursor curre
6e90: 6e 74 6c 79 20 70 6f 69 6e 74 73 20 74 6f 2e 0a  ntly points to..
6ea0: 2a 2f 0a 73 74 61 74 69 63 20 69 36 34 20 66 74  */.static i64 ft
6eb0: 73 35 43 75 72 73 6f 72 52 6f 77 69 64 28 46 74  s5CursorRowid(Ft
6ec0: 73 35 43 75 72 73 6f 72 20 2a 70 43 73 72 29 7b  s5Cursor *pCsr){
6ed0: 0a 20 20 61 73 73 65 72 74 28 20 46 54 53 35 5f  .  assert( FTS5_
6ee0: 50 4c 41 4e 28 70 43 73 72 2d 3e 69 64 78 4e 75  PLAN(pCsr->idxNu
6ef0: 6d 29 3d 3d 46 54 53 35 5f 50 4c 41 4e 5f 4d 41  m)==FTS5_PLAN_MA
6f00: 54 43 48 20 0a 20 20 20 20 20 20 20 7c 7c 20 46  TCH .       || F
6f10: 54 53 35 5f 50 4c 41 4e 28 70 43 73 72 2d 3e 69  TS5_PLAN(pCsr->i
6f20: 64 78 4e 75 6d 29 3d 3d 46 54 53 35 5f 50 4c 41  dxNum)==FTS5_PLA
6f30: 4e 5f 53 4f 52 54 45 44 5f 4d 41 54 43 48 20 0a  N_SORTED_MATCH .
6f40: 20 20 20 20 20 20 20 7c 7c 20 46 54 53 35 5f 50         || FTS5_P
6f50: 4c 41 4e 28 70 43 73 72 2d 3e 69 64 78 4e 75 6d  LAN(pCsr->idxNum
6f60: 29 3d 3d 46 54 53 35 5f 50 4c 41 4e 5f 53 4f 55  )==FTS5_PLAN_SOU
6f70: 52 43 45 20 0a 20 20 29 3b 0a 20 20 69 66 28 20  RCE .  );.  if( 
6f80: 70 43 73 72 2d 3e 70 53 6f 72 74 65 72 20 29 7b  pCsr->pSorter ){
6f90: 0a 20 20 20 20 72 65 74 75 72 6e 20 70 43 73 72  .    return pCsr
6fa0: 2d 3e 70 53 6f 72 74 65 72 2d 3e 69 52 6f 77 69  ->pSorter->iRowi
6fb0: 64 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  d;.  }else{.    
6fc0: 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33 46 74  return sqlite3Ft
6fd0: 73 35 45 78 70 72 52 6f 77 69 64 28 70 43 73 72  s5ExprRowid(pCsr
6fe0: 2d 3e 70 45 78 70 72 29 3b 0a 20 20 7d 0a 7d 0a  ->pExpr);.  }.}.
6ff0: 0a 2f 2a 20 0a 2a 2a 20 54 68 69 73 20 69 73 20  ./* .** This is 
7000: 74 68 65 20 78 52 6f 77 69 64 20 6d 65 74 68 6f  the xRowid metho
7010: 64 2e 20 54 68 65 20 53 51 4c 69 74 65 20 63 6f  d. The SQLite co
7020: 72 65 20 63 61 6c 6c 73 20 74 68 69 73 20 72 6f  re calls this ro
7030: 75 74 69 6e 65 20 74 6f 0a 2a 2a 20 72 65 74 72  utine to.** retr
7040: 69 65 76 65 20 74 68 65 20 72 6f 77 69 64 20 66  ieve the rowid f
7050: 6f 72 20 74 68 65 20 63 75 72 72 65 6e 74 20 72  or the current r
7060: 6f 77 20 6f 66 20 74 68 65 20 72 65 73 75 6c 74  ow of the result
7070: 20 73 65 74 2e 20 66 74 73 35 0a 2a 2a 20 65 78   set. fts5.** ex
7080: 70 6f 73 65 73 20 25 5f 63 6f 6e 74 65 6e 74 2e  poses %_content.
7090: 64 6f 63 69 64 20 61 73 20 74 68 65 20 72 6f 77  docid as the row
70a0: 69 64 20 66 6f 72 20 74 68 65 20 76 69 72 74 75  id for the virtu
70b0: 61 6c 20 74 61 62 6c 65 2e 20 54 68 65 0a 2a 2a  al table. The.**
70c0: 20 72 6f 77 69 64 20 73 68 6f 75 6c 64 20 62 65   rowid should be
70d0: 20 77 72 69 74 74 65 6e 20 74 6f 20 2a 70 52 6f   written to *pRo
70e0: 77 69 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  wid..*/.static i
70f0: 6e 74 20 66 74 73 35 52 6f 77 69 64 4d 65 74 68  nt fts5RowidMeth
7100: 6f 64 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f  od(sqlite3_vtab_
7110: 63 75 72 73 6f 72 20 2a 70 43 75 72 73 6f 72 2c  cursor *pCursor,
7120: 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 2a 70   sqlite_int64 *p
7130: 52 6f 77 69 64 29 7b 0a 20 20 46 74 73 35 43 75  Rowid){.  Fts5Cu
7140: 72 73 6f 72 20 2a 70 43 73 72 20 3d 20 28 46 74  rsor *pCsr = (Ft
7150: 73 35 43 75 72 73 6f 72 2a 29 70 43 75 72 73 6f  s5Cursor*)pCurso
7160: 72 3b 0a 20 20 69 6e 74 20 65 50 6c 61 6e 20 3d  r;.  int ePlan =
7170: 20 46 54 53 35 5f 50 4c 41 4e 28 70 43 73 72 2d   FTS5_PLAN(pCsr-
7180: 3e 69 64 78 4e 75 6d 29 3b 0a 20 20 0a 20 20 61  >idxNum);.  .  a
7190: 73 73 65 72 74 28 20 43 73 72 46 6c 61 67 54 65  ssert( CsrFlagTe
71a0: 73 74 28 70 43 73 72 2c 20 46 54 53 35 43 53 52  st(pCsr, FTS5CSR
71b0: 5f 45 4f 46 29 3d 3d 30 20 29 3b 0a 20 20 73 77  _EOF)==0 );.  sw
71c0: 69 74 63 68 28 20 65 50 6c 61 6e 20 29 7b 0a 20  itch( ePlan ){. 
71d0: 20 20 20 63 61 73 65 20 46 54 53 35 5f 50 4c 41     case FTS5_PLA
71e0: 4e 5f 53 50 45 43 49 41 4c 3a 0a 20 20 20 20 20  N_SPECIAL:.     
71f0: 20 2a 70 52 6f 77 69 64 20 3d 20 30 3b 0a 20 20   *pRowid = 0;.  
7200: 20 20 20 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20      break;..    
7210: 63 61 73 65 20 46 54 53 35 5f 50 4c 41 4e 5f 53  case FTS5_PLAN_S
7220: 4f 55 52 43 45 3a 0a 20 20 20 20 63 61 73 65 20  OURCE:.    case 
7230: 46 54 53 35 5f 50 4c 41 4e 5f 4d 41 54 43 48 3a  FTS5_PLAN_MATCH:
7240: 0a 20 20 20 20 63 61 73 65 20 46 54 53 35 5f 50  .    case FTS5_P
7250: 4c 41 4e 5f 53 4f 52 54 45 44 5f 4d 41 54 43 48  LAN_SORTED_MATCH
7260: 3a 0a 20 20 20 20 20 20 2a 70 52 6f 77 69 64 20  :.      *pRowid 
7270: 3d 20 66 74 73 35 43 75 72 73 6f 72 52 6f 77 69  = fts5CursorRowi
7280: 64 28 70 43 73 72 29 3b 0a 20 20 20 20 20 20 62  d(pCsr);.      b
7290: 72 65 61 6b 3b 0a 0a 20 20 20 20 64 65 66 61 75  reak;..    defau
72a0: 6c 74 3a 0a 20 20 20 20 20 20 2a 70 52 6f 77 69  lt:.      *pRowi
72b0: 64 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75  d = sqlite3_colu
72c0: 6d 6e 5f 69 6e 74 36 34 28 70 43 73 72 2d 3e 70  mn_int64(pCsr->p
72d0: 53 74 6d 74 2c 20 30 29 3b 0a 20 20 20 20 20 20  Stmt, 0);.      
72e0: 62 72 65 61 6b 3b 0a 20 20 7d 0a 0a 20 20 72 65  break;.  }..  re
72f0: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
7300: 7d 0a 0a 2f 2a 0a 2a 2a 20 49 66 20 74 68 65 20  }../*.** If the 
7310: 63 75 72 73 6f 72 20 72 65 71 75 69 72 65 73 20  cursor requires 
7320: 73 65 65 6b 69 6e 67 20 28 62 53 65 65 6b 52 65  seeking (bSeekRe
7330: 71 75 69 72 65 64 20 66 6c 61 67 20 69 73 20 73  quired flag is s
7340: 65 74 29 2c 20 73 65 65 6b 20 69 74 2e 0a 2a 2a  et), seek it..**
7350: 20 52 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   Return SQLITE_O
7360: 4b 20 69 66 20 6e 6f 20 65 72 72 6f 72 20 6f 63  K if no error oc
7370: 63 75 72 73 2c 20 6f 72 20 61 6e 20 53 51 4c 69  curs, or an SQLi
7380: 74 65 20 65 72 72 6f 72 20 63 6f 64 65 20 6f 74  te error code ot
7390: 68 65 72 77 69 73 65 2e 0a 2a 2f 0a 73 74 61 74  herwise..*/.stat
73a0: 69 63 20 69 6e 74 20 66 74 73 35 53 65 65 6b 43  ic int fts5SeekC
73b0: 75 72 73 6f 72 28 46 74 73 35 43 75 72 73 6f 72  ursor(Fts5Cursor
73c0: 20 2a 70 43 73 72 29 7b 0a 20 20 69 6e 74 20 72   *pCsr){.  int r
73d0: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 0a  c = SQLITE_OK;..
73e0: 20 20 2f 2a 20 49 66 20 74 68 65 20 63 75 72 73    /* If the curs
73f0: 6f 72 20 64 6f 65 73 20 6e 6f 74 20 79 65 74 20  or does not yet 
7400: 68 61 76 65 20 61 20 73 74 61 74 65 6d 65 6e 74  have a statement
7410: 20 68 61 6e 64 6c 65 2c 20 6f 62 74 61 69 6e 20   handle, obtain 
7420: 6f 6e 65 20 6e 6f 77 2e 20 2a 2f 20 0a 20 20 69  one now. */ .  i
7430: 66 28 20 70 43 73 72 2d 3e 70 53 74 6d 74 3d 3d  f( pCsr->pStmt==
7440: 30 20 29 7b 0a 20 20 20 20 46 74 73 35 54 61 62  0 ){.    Fts5Tab
7450: 6c 65 20 2a 70 54 61 62 20 3d 20 28 46 74 73 35  le *pTab = (Fts5
7460: 54 61 62 6c 65 2a 29 28 70 43 73 72 2d 3e 62 61  Table*)(pCsr->ba
7470: 73 65 2e 70 56 74 61 62 29 3b 0a 20 20 20 20 69  se.pVtab);.    i
7480: 6e 74 20 65 53 74 6d 74 20 3d 20 66 74 73 35 53  nt eStmt = fts5S
7490: 74 6d 74 54 79 70 65 28 70 43 73 72 2d 3e 69 64  tmtType(pCsr->id
74a0: 78 4e 75 6d 29 3b 0a 20 20 20 20 72 63 20 3d 20  xNum);.    rc = 
74b0: 73 71 6c 69 74 65 33 46 74 73 35 53 74 6f 72 61  sqlite3Fts5Stora
74c0: 67 65 53 74 6d 74 28 70 54 61 62 2d 3e 70 53 74  geStmt(pTab->pSt
74d0: 6f 72 61 67 65 2c 20 65 53 74 6d 74 2c 20 26 70  orage, eStmt, &p
74e0: 43 73 72 2d 3e 70 53 74 6d 74 29 3b 0a 20 20 20  Csr->pStmt);.   
74f0: 20 61 73 73 65 72 74 28 20 43 73 72 46 6c 61 67   assert( CsrFlag
7500: 54 65 73 74 28 70 43 73 72 2c 20 46 54 53 35 43  Test(pCsr, FTS5C
7510: 53 52 5f 52 45 51 55 49 52 45 5f 43 4f 4e 54 45  SR_REQUIRE_CONTE
7520: 4e 54 29 20 29 3b 0a 20 20 7d 0a 0a 20 20 69 66  NT) );.  }..  if
7530: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
7540: 26 26 20 43 73 72 46 6c 61 67 54 65 73 74 28 70  && CsrFlagTest(p
7550: 43 73 72 2c 20 46 54 53 35 43 53 52 5f 52 45 51  Csr, FTS5CSR_REQ
7560: 55 49 52 45 5f 43 4f 4e 54 45 4e 54 29 20 29 7b  UIRE_CONTENT) ){
7570: 0a 20 20 20 20 61 73 73 65 72 74 28 20 70 43 73  .    assert( pCs
7580: 72 2d 3e 70 45 78 70 72 20 29 3b 0a 20 20 20 20  r->pExpr );.    
7590: 73 71 6c 69 74 65 33 5f 72 65 73 65 74 28 70 43  sqlite3_reset(pC
75a0: 73 72 2d 3e 70 53 74 6d 74 29 3b 0a 20 20 20 20  sr->pStmt);.    
75b0: 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f 69 6e 74  sqlite3_bind_int
75c0: 36 34 28 70 43 73 72 2d 3e 70 53 74 6d 74 2c 20  64(pCsr->pStmt, 
75d0: 31 2c 20 66 74 73 35 43 75 72 73 6f 72 52 6f 77  1, fts5CursorRow
75e0: 69 64 28 70 43 73 72 29 29 3b 0a 20 20 20 20 72  id(pCsr));.    r
75f0: 63 20 3d 20 73 71 6c 69 74 65 33 5f 73 74 65 70  c = sqlite3_step
7600: 28 70 43 73 72 2d 3e 70 53 74 6d 74 29 3b 0a 20  (pCsr->pStmt);. 
7610: 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
7620: 45 5f 52 4f 57 20 29 7b 0a 20 20 20 20 20 20 72  E_ROW ){.      r
7630: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  c = SQLITE_OK;. 
7640: 20 20 20 20 20 43 73 72 46 6c 61 67 43 6c 65 61       CsrFlagClea
7650: 72 28 70 43 73 72 2c 20 46 54 53 35 43 53 52 5f  r(pCsr, FTS5CSR_
7660: 52 45 51 55 49 52 45 5f 43 4f 4e 54 45 4e 54 29  REQUIRE_CONTENT)
7670: 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ;.    }else{.   
7680: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f     rc = sqlite3_
7690: 72 65 73 65 74 28 70 43 73 72 2d 3e 70 53 74 6d  reset(pCsr->pStm
76a0: 74 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63  t);.      if( rc
76b0: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
76c0: 20 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49         rc = SQLI
76d0: 54 45 5f 43 4f 52 52 55 50 54 5f 56 54 41 42 3b  TE_CORRUPT_VTAB;
76e0: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
76f0: 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a   }.  return rc;.
7700: 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75  }../*.** This fu
7710: 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64  nction is called
7720: 20 74 6f 20 68 61 6e 64 6c 65 20 61 6e 20 46 54   to handle an FT
7730: 53 20 49 4e 53 45 52 54 20 63 6f 6d 6d 61 6e 64  S INSERT command
7740: 2e 20 49 6e 20 6f 74 68 65 72 20 77 6f 72 64 73  . In other words
7750: 2c 0a 2a 2a 20 61 6e 20 49 4e 53 45 52 54 20 73  ,.** an INSERT s
7760: 74 61 74 65 6d 65 6e 74 20 6f 66 20 74 68 65 20  tatement of the 
7770: 66 6f 72 6d 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20  form:.**.**     
7780: 49 4e 53 45 52 54 20 49 4e 54 4f 20 66 74 73 28  INSERT INTO fts(
7790: 66 74 73 29 20 56 41 4c 55 45 53 28 24 70 43 6d  fts) VALUES($pCm
77a0: 64 29 0a 2a 2a 20 20 20 20 20 49 4e 53 45 52 54  d).**     INSERT
77b0: 20 49 4e 54 4f 20 66 74 73 28 66 74 73 2c 20 72   INTO fts(fts, r
77c0: 61 6e 6b 29 20 56 41 4c 55 45 53 28 24 70 43 6d  ank) VALUES($pCm
77d0: 64 2c 20 24 70 56 61 6c 29 0a 2a 2a 0a 2a 2a 20  d, $pVal).**.** 
77e0: 41 72 67 75 6d 65 6e 74 20 70 56 61 6c 20 69 73  Argument pVal is
77f0: 20 74 68 65 20 76 61 6c 75 65 20 61 73 73 69 67   the value assig
7800: 6e 65 64 20 74 6f 20 63 6f 6c 75 6d 6e 20 22 66  ned to column "f
7810: 74 73 22 20 62 79 20 74 68 65 20 49 4e 53 45 52  ts" by the INSER
7820: 54 20 0a 2a 2a 20 73 74 61 74 65 6d 65 6e 74 2e  T .** statement.
7830: 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 72   This function r
7840: 65 74 75 72 6e 73 20 53 51 4c 49 54 45 5f 4f 4b  eturns SQLITE_OK
7850: 20 69 66 20 73 75 63 63 65 73 73 66 75 6c 2c 20   if successful, 
7860: 6f 72 20 61 6e 20 53 51 4c 69 74 65 0a 2a 2a 20  or an SQLite.** 
7870: 65 72 72 6f 72 20 63 6f 64 65 20 69 66 20 61 6e  error code if an
7880: 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2e 0a 2a   error occurs..*
7890: 2a 0a 2a 2a 20 54 68 65 20 63 6f 6d 6d 61 6e 64  *.** The command
78a0: 73 20 69 6d 70 6c 65 6d 65 6e 74 65 64 20 62 79  s implemented by
78b0: 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 61   this function a
78c0: 72 65 20 64 6f 63 75 6d 65 6e 74 65 64 20 69 6e  re documented in
78d0: 20 74 68 65 20 22 53 70 65 63 69 61 6c 0a 2a 2a   the "Special.**
78e0: 20 49 4e 53 45 52 54 20 44 69 72 65 63 74 69 76   INSERT Directiv
78f0: 65 73 22 20 73 65 63 74 69 6f 6e 20 6f 66 20 74  es" section of t
7900: 68 65 20 64 6f 63 75 6d 65 6e 74 61 74 69 6f 6e  he documentation
7910: 2e 20 49 74 20 73 68 6f 75 6c 64 20 62 65 20 75  . It should be u
7920: 70 64 61 74 65 64 20 69 66 0a 2a 2a 20 6d 6f 72  pdated if.** mor
7930: 65 20 63 6f 6d 6d 61 6e 64 73 20 61 72 65 20 61  e commands are a
7940: 64 64 65 64 20 74 6f 20 74 68 69 73 20 66 75 6e  dded to this fun
7950: 63 74 69 6f 6e 2e 0a 2a 2f 0a 73 74 61 74 69 63  ction..*/.static
7960: 20 69 6e 74 20 66 74 73 35 53 70 65 63 69 61 6c   int fts5Special
7970: 49 6e 73 65 72 74 28 0a 20 20 46 74 73 35 54 61  Insert(.  Fts5Ta
7980: 62 6c 65 20 2a 70 54 61 62 2c 20 20 20 20 20 20  ble *pTab,      
7990: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 74 73            /* Fts
79a0: 35 20 74 61 62 6c 65 20 6f 62 6a 65 63 74 20 2a  5 table object *
79b0: 2f 0a 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75  /.  sqlite3_valu
79c0: 65 20 2a 70 43 6d 64 2c 20 20 20 20 20 20 20 20  e *pCmd,        
79d0: 20 20 20 20 2f 2a 20 56 61 6c 75 65 20 69 6e 73      /* Value ins
79e0: 65 72 74 65 64 20 69 6e 74 6f 20 73 70 65 63 69  erted into speci
79f0: 61 6c 20 63 6f 6c 75 6d 6e 20 2a 2f 0a 20 20 73  al column */.  s
7a00: 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 70 56  qlite3_value *pV
7a10: 61 6c 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  al             /
7a20: 2a 20 56 61 6c 75 65 20 69 6e 73 65 72 74 65 64  * Value inserted
7a30: 20 69 6e 74 6f 20 72 6f 77 69 64 20 63 6f 6c 75   into rowid colu
7a40: 6d 6e 20 2a 2f 0a 29 7b 0a 20 20 63 6f 6e 73 74  mn */.){.  const
7a50: 20 63 68 61 72 20 2a 7a 20 3d 20 28 63 6f 6e 73   char *z = (cons
7a60: 74 20 63 68 61 72 2a 29 73 71 6c 69 74 65 33 5f  t char*)sqlite3_
7a70: 76 61 6c 75 65 5f 74 65 78 74 28 70 43 6d 64 29  value_text(pCmd)
7a80: 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c  ;.  int rc = SQL
7a90: 49 54 45 5f 4f 4b 3b 0a 20 20 69 6e 74 20 62 45  ITE_OK;.  int bE
7aa0: 72 72 6f 72 20 3d 20 30 3b 0a 0a 20 20 69 66 28  rror = 0;..  if(
7ab0: 20 30 3d 3d 73 71 6c 69 74 65 33 5f 73 74 72 69   0==sqlite3_stri
7ac0: 63 6d 70 28 22 69 6e 74 65 67 72 69 74 79 2d 63  cmp("integrity-c
7ad0: 68 65 63 6b 22 2c 20 7a 29 20 29 7b 0a 20 20 20  heck", z) ){.   
7ae0: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 46 74 73   rc = sqlite3Fts
7af0: 35 53 74 6f 72 61 67 65 49 6e 74 65 67 72 69 74  5StorageIntegrit
7b00: 79 28 70 54 61 62 2d 3e 70 53 74 6f 72 61 67 65  y(pTab->pStorage
7b10: 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  );.  }else{.    
7b20: 72 63 20 3d 20 73 71 6c 69 74 65 33 46 74 73 35  rc = sqlite3Fts5
7b30: 43 6f 6e 66 69 67 53 65 74 56 61 6c 75 65 28 70  ConfigSetValue(p
7b40: 54 61 62 2d 3e 70 43 6f 6e 66 69 67 2c 20 7a 2c  Tab->pConfig, z,
7b50: 20 70 56 61 6c 2c 20 26 62 45 72 72 6f 72 29 3b   pVal, &bError);
7b60: 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  .    if( rc==SQL
7b70: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20  ITE_OK ){.      
7b80: 69 66 28 20 62 45 72 72 6f 72 20 29 7b 0a 20 20  if( bError ){.  
7b90: 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54        rc = SQLIT
7ba0: 45 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20 20 7d  E_ERROR;.      }
7bb0: 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 72 63  else{.        rc
7bc0: 20 3d 20 73 71 6c 69 74 65 33 46 74 73 35 53 74   = sqlite3Fts5St
7bd0: 6f 72 61 67 65 43 6f 6e 66 69 67 56 61 6c 75 65  orageConfigValue
7be0: 28 70 54 61 62 2d 3e 70 53 74 6f 72 61 67 65 2c  (pTab->pStorage,
7bf0: 20 7a 2c 20 70 56 61 6c 29 3b 0a 20 20 20 20 20   z, pVal);.     
7c00: 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72   }.    }.  }.  r
7c10: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20  eturn rc;.}../* 
7c20: 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f  .** This functio
7c30: 6e 20 69 73 20 74 68 65 20 69 6d 70 6c 65 6d 65  n is the impleme
7c40: 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 78  ntation of the x
7c50: 55 70 64 61 74 65 20 63 61 6c 6c 62 61 63 6b 20  Update callback 
7c60: 75 73 65 64 20 62 79 20 0a 2a 2a 20 46 54 53 33  used by .** FTS3
7c70: 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 73 2e   virtual tables.
7c80: 20 49 74 20 69 73 20 69 6e 76 6f 6b 65 64 20 62   It is invoked b
7c90: 79 20 53 51 4c 69 74 65 20 65 61 63 68 20 74 69  y SQLite each ti
7ca0: 6d 65 20 61 20 72 6f 77 20 69 73 20 74 6f 20 62  me a row is to b
7cb0: 65 0a 2a 2a 20 69 6e 73 65 72 74 65 64 2c 20 75  e.** inserted, u
7cc0: 70 64 61 74 65 64 20 6f 72 20 64 65 6c 65 74 65  pdated or delete
7cd0: 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  d..*/.static int
7ce0: 20 66 74 73 35 55 70 64 61 74 65 4d 65 74 68 6f   fts5UpdateMetho
7cf0: 64 28 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61  d(.  sqlite3_vta
7d00: 62 20 2a 70 56 74 61 62 2c 20 20 20 20 20 20 20  b *pVtab,       
7d10: 20 20 20 20 20 2f 2a 20 56 69 72 74 75 61 6c 20       /* Virtual 
7d20: 74 61 62 6c 65 20 68 61 6e 64 6c 65 20 2a 2f 0a  table handle */.
7d30: 20 20 69 6e 74 20 6e 41 72 67 2c 20 20 20 20 20    int nArg,     
7d40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7d50: 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 61 72 67    /* Size of arg
7d60: 75 6d 65 6e 74 20 61 72 72 61 79 20 2a 2f 0a 20  ument array */. 
7d70: 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a   sqlite3_value *
7d80: 2a 61 70 56 61 6c 2c 20 20 20 20 20 20 20 20 20  *apVal,         
7d90: 20 2f 2a 20 41 72 72 61 79 20 6f 66 20 61 72 67   /* Array of arg
7da0: 75 6d 65 6e 74 73 20 2a 2f 0a 20 20 73 71 6c 69  uments */.  sqli
7db0: 74 65 5f 69 6e 74 36 34 20 2a 70 52 6f 77 69 64  te_int64 *pRowid
7dc0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f              /* O
7dd0: 55 54 3a 20 54 68 65 20 61 66 66 65 63 74 65 64  UT: The affected
7de0: 20 28 6f 72 20 65 66 66 65 63 74 65 64 29 20 72   (or effected) r
7df0: 6f 77 69 64 20 2a 2f 0a 29 7b 0a 20 20 46 74 73  owid */.){.  Fts
7e00: 35 54 61 62 6c 65 20 2a 70 54 61 62 20 3d 20 28  5Table *pTab = (
7e10: 46 74 73 35 54 61 62 6c 65 2a 29 70 56 74 61 62  Fts5Table*)pVtab
7e20: 3b 0a 20 20 46 74 73 35 43 6f 6e 66 69 67 20 2a  ;.  Fts5Config *
7e30: 70 43 6f 6e 66 69 67 20 3d 20 70 54 61 62 2d 3e  pConfig = pTab->
7e40: 70 43 6f 6e 66 69 67 3b 0a 20 20 69 6e 74 20 65  pConfig;.  int e
7e50: 54 79 70 65 30 3b 20 20 20 20 20 20 20 20 20 20  Type0;          
7e60: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 76 61             /* va
7e70: 6c 75 65 5f 74 79 70 65 28 29 20 6f 66 20 61 70  lue_type() of ap
7e80: 56 61 6c 5b 30 5d 20 2a 2f 0a 20 20 69 6e 74 20  Val[0] */.  int 
7e90: 65 43 6f 6e 66 6c 69 63 74 3b 20 20 20 20 20 20  eConflict;      
7ea0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f              /* O
7eb0: 4e 20 43 4f 4e 46 4c 49 43 54 20 66 6f 72 20 74  N CONFLICT for t
7ec0: 68 69 73 20 44 4d 4c 20 2a 2f 0a 20 20 69 6e 74  his DML */.  int
7ed0: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
7ee0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
7ef0: 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 0a  Return code */..
7f00: 20 20 2f 2a 20 41 20 74 72 61 6e 73 61 63 74 69    /* A transacti
7f10: 6f 6e 20 6d 75 73 74 20 62 65 20 6f 70 65 6e 20  on must be open 
7f20: 77 68 65 6e 20 74 68 69 73 20 69 73 20 63 61 6c  when this is cal
7f30: 6c 65 64 2e 20 2a 2f 0a 20 20 61 73 73 65 72 74  led. */.  assert
7f40: 28 20 70 54 61 62 2d 3e 74 73 2e 65 53 74 61 74  ( pTab->ts.eStat
7f50: 65 3d 3d 31 20 29 3b 0a 0a 20 20 2f 2a 20 41 20  e==1 );..  /* A 
7f60: 64 65 6c 65 74 65 20 73 70 65 63 69 66 69 65 73  delete specifies
7f70: 20 61 20 73 69 6e 67 6c 65 20 61 72 67 75 6d 65   a single argume
7f80: 6e 74 20 2d 20 74 68 65 20 72 6f 77 69 64 20 6f  nt - the rowid o
7f90: 66 20 74 68 65 20 72 6f 77 20 74 6f 20 72 65 6d  f the row to rem
7fa0: 6f 76 65 2e 0a 20 20 2a 2a 20 55 70 64 61 74 65  ove..  ** Update
7fb0: 20 61 6e 64 20 69 6e 73 65 72 74 20 6f 70 65 72   and insert oper
7fc0: 61 74 69 6f 6e 73 20 70 61 73 73 3a 0a 20 20 2a  ations pass:.  *
7fd0: 2a 0a 20 20 2a 2a 20 20 20 31 2e 20 54 68 65 20  *.  **   1. The 
7fe0: 22 6f 6c 64 22 20 72 6f 77 69 64 2c 20 6f 72 20  "old" rowid, or 
7ff0: 4e 55 4c 4c 2e 0a 20 20 2a 2a 20 20 20 32 2e 20  NULL..  **   2. 
8000: 54 68 65 20 22 6e 65 77 22 20 72 6f 77 69 64 2e  The "new" rowid.
8010: 0a 20 20 2a 2a 20 20 20 33 2e 20 56 61 6c 75 65  .  **   3. Value
8020: 73 20 66 6f 72 20 65 61 63 68 20 6f 66 20 74 68  s for each of th
8030: 65 20 6e 43 6f 6c 20 6d 61 74 63 68 61 62 6c 65  e nCol matchable
8040: 20 63 6f 6c 75 6d 6e 73 2e 0a 20 20 2a 2a 20 20   columns..  **  
8050: 20 34 2e 20 56 61 6c 75 65 73 20 66 6f 72 20 74   4. Values for t
8060: 68 65 20 74 77 6f 20 68 69 64 64 65 6e 20 63 6f  he two hidden co
8070: 6c 75 6d 6e 73 20 28 3c 74 61 62 6c 65 6e 61 6d  lumns (<tablenam
8080: 65 3e 20 61 6e 64 20 22 72 61 6e 6b 22 29 2e 0a  e> and "rank")..
8090: 20 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 6e    */.  assert( n
80a0: 41 72 67 3d 3d 31 20 7c 7c 20 6e 41 72 67 3d 3d  Arg==1 || nArg==
80b0: 28 32 20 2b 20 70 43 6f 6e 66 69 67 2d 3e 6e 43  (2 + pConfig->nC
80c0: 6f 6c 20 2b 20 32 29 20 29 3b 0a 0a 20 20 69 66  ol + 2) );..  if
80d0: 28 20 6e 41 72 67 3e 31 20 26 26 20 53 51 4c 49  ( nArg>1 && SQLI
80e0: 54 45 5f 4e 55 4c 4c 21 3d 73 71 6c 69 74 65 33  TE_NULL!=sqlite3
80f0: 5f 76 61 6c 75 65 5f 74 79 70 65 28 61 70 56 61  _value_type(apVa
8100: 6c 5b 32 20 2b 20 70 43 6f 6e 66 69 67 2d 3e 6e  l[2 + pConfig->n
8110: 43 6f 6c 5d 29 20 29 7b 0a 20 20 20 20 72 65 74  Col]) ){.    ret
8120: 75 72 6e 20 66 74 73 35 53 70 65 63 69 61 6c 49  urn fts5SpecialI
8130: 6e 73 65 72 74 28 70 54 61 62 2c 20 0a 20 20 20  nsert(pTab, .   
8140: 20 20 20 20 20 61 70 56 61 6c 5b 32 20 2b 20 70       apVal[2 + p
8150: 43 6f 6e 66 69 67 2d 3e 6e 43 6f 6c 5d 2c 20 61  Config->nCol], a
8160: 70 56 61 6c 5b 32 20 2b 20 70 43 6f 6e 66 69 67  pVal[2 + pConfig
8170: 2d 3e 6e 43 6f 6c 20 2b 20 31 5d 0a 20 20 20 20  ->nCol + 1].    
8180: 29 3b 0a 20 20 7d 0a 0a 20 20 65 54 79 70 65 30  );.  }..  eType0
8190: 20 3d 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65   = sqlite3_value
81a0: 5f 74 79 70 65 28 61 70 56 61 6c 5b 30 5d 29 3b  _type(apVal[0]);
81b0: 0a 20 20 65 43 6f 6e 66 6c 69 63 74 20 3d 20 73  .  eConflict = s
81c0: 71 6c 69 74 65 33 5f 76 74 61 62 5f 6f 6e 5f 63  qlite3_vtab_on_c
81d0: 6f 6e 66 6c 69 63 74 28 70 43 6f 6e 66 69 67 2d  onflict(pConfig-
81e0: 3e 64 62 29 3b 0a 0a 20 20 61 73 73 65 72 74 28  >db);..  assert(
81f0: 20 65 54 79 70 65 30 3d 3d 53 51 4c 49 54 45 5f   eType0==SQLITE_
8200: 49 4e 54 45 47 45 52 20 7c 7c 20 65 54 79 70 65  INTEGER || eType
8210: 30 3d 3d 53 51 4c 49 54 45 5f 4e 55 4c 4c 20 29  0==SQLITE_NULL )
8220: 3b 0a 20 20 69 66 28 20 65 54 79 70 65 30 3d 3d  ;.  if( eType0==
8230: 53 51 4c 49 54 45 5f 49 4e 54 45 47 45 52 20 29  SQLITE_INTEGER )
8240: 7b 0a 20 20 20 20 69 36 34 20 69 44 65 6c 20 3d  {.    i64 iDel =
8250: 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 69   sqlite3_value_i
8260: 6e 74 36 34 28 61 70 56 61 6c 5b 30 5d 29 3b 20  nt64(apVal[0]); 
8270: 20 20 20 2f 2a 20 52 6f 77 69 64 20 74 6f 20 64     /* Rowid to d
8280: 65 6c 65 74 65 20 2a 2f 0a 20 20 20 20 72 63 20  elete */.    rc 
8290: 3d 20 73 71 6c 69 74 65 33 46 74 73 35 53 74 6f  = sqlite3Fts5Sto
82a0: 72 61 67 65 44 65 6c 65 74 65 28 70 54 61 62 2d  rageDelete(pTab-
82b0: 3e 70 53 74 6f 72 61 67 65 2c 20 69 44 65 6c 29  >pStorage, iDel)
82c0: 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d  ;.  }..  if( rc=
82d0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 6e 41  =SQLITE_OK && nA
82e0: 72 67 3e 31 20 29 7b 0a 20 20 20 20 72 63 20 3d  rg>1 ){.    rc =
82f0: 20 73 71 6c 69 74 65 33 46 74 73 35 53 74 6f 72   sqlite3Fts5Stor
8300: 61 67 65 49 6e 73 65 72 74 28 70 54 61 62 2d 3e  ageInsert(pTab->
8310: 70 53 74 6f 72 61 67 65 2c 20 61 70 56 61 6c 2c  pStorage, apVal,
8320: 20 65 43 6f 6e 66 6c 69 63 74 2c 20 70 52 6f 77   eConflict, pRow
8330: 69 64 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75  id);.  }..  retu
8340: 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  rn rc;.}../*.** 
8350: 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f  Implementation o
8360: 66 20 78 53 79 6e 63 28 29 20 6d 65 74 68 6f 64  f xSync() method
8370: 2e 20 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  . .*/.static int
8380: 20 66 74 73 35 53 79 6e 63 4d 65 74 68 6f 64 28   fts5SyncMethod(
8390: 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56  sqlite3_vtab *pV
83a0: 74 61 62 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a  tab){.  int rc;.
83b0: 20 20 46 74 73 35 54 61 62 6c 65 20 2a 70 54 61    Fts5Table *pTa
83c0: 62 20 3d 20 28 46 74 73 35 54 61 62 6c 65 2a 29  b = (Fts5Table*)
83d0: 70 56 74 61 62 3b 0a 20 20 66 74 73 35 43 68 65  pVtab;.  fts5Che
83e0: 63 6b 54 72 61 6e 73 61 63 74 69 6f 6e 53 74 61  ckTransactionSta
83f0: 74 65 28 70 54 61 62 2c 20 46 54 53 35 5f 53 59  te(pTab, FTS5_SY
8400: 4e 43 2c 20 30 29 3b 0a 20 20 72 63 20 3d 20 73  NC, 0);.  rc = s
8410: 71 6c 69 74 65 33 46 74 73 35 53 74 6f 72 61 67  qlite3Fts5Storag
8420: 65 53 79 6e 63 28 70 54 61 62 2d 3e 70 53 74 6f  eSync(pTab->pSto
8430: 72 61 67 65 2c 20 31 29 3b 0a 20 20 72 65 74 75  rage, 1);.  retu
8440: 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  rn rc;.}../*.** 
8450: 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f  Implementation o
8460: 66 20 78 42 65 67 69 6e 28 29 20 6d 65 74 68 6f  f xBegin() metho
8470: 64 2e 20 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  d. .*/.static in
8480: 74 20 66 74 73 35 42 65 67 69 6e 4d 65 74 68 6f  t fts5BeginMetho
8490: 64 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a  d(sqlite3_vtab *
84a0: 70 56 74 61 62 29 7b 0a 20 20 66 74 73 35 43 68  pVtab){.  fts5Ch
84b0: 65 63 6b 54 72 61 6e 73 61 63 74 69 6f 6e 53 74  eckTransactionSt
84c0: 61 74 65 28 28 46 74 73 35 54 61 62 6c 65 2a 29  ate((Fts5Table*)
84d0: 70 56 74 61 62 2c 20 46 54 53 35 5f 42 45 47 49  pVtab, FTS5_BEGI
84e0: 4e 2c 20 30 29 3b 0a 20 20 72 65 74 75 72 6e 20  N, 0);.  return 
84f0: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a  SQLITE_OK;.}../*
8500: 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69  .** Implementati
8510: 6f 6e 20 6f 66 20 78 43 6f 6d 6d 69 74 28 29 20  on of xCommit() 
8520: 6d 65 74 68 6f 64 2e 20 54 68 69 73 20 69 73 20  method. This is 
8530: 61 20 6e 6f 2d 6f 70 2e 20 54 68 65 20 63 6f 6e  a no-op. The con
8540: 74 65 6e 74 73 20 6f 66 0a 2a 2a 20 74 68 65 20  tents of.** the 
8550: 70 65 6e 64 69 6e 67 2d 74 65 72 6d 73 20 68 61  pending-terms ha
8560: 73 68 2d 74 61 62 6c 65 20 68 61 76 65 20 61 6c  sh-table have al
8570: 72 65 61 64 79 20 62 65 65 6e 20 66 6c 75 73 68  ready been flush
8580: 65 64 20 69 6e 74 6f 20 74 68 65 20 64 61 74 61  ed into the data
8590: 62 61 73 65 0a 2a 2a 20 62 79 20 66 74 73 35 53  base.** by fts5S
85a0: 79 6e 63 4d 65 74 68 6f 64 28 29 2e 0a 2a 2f 0a  yncMethod()..*/.
85b0: 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 43  static int fts5C
85c0: 6f 6d 6d 69 74 4d 65 74 68 6f 64 28 73 71 6c 69  ommitMethod(sqli
85d0: 74 65 33 5f 76 74 61 62 20 2a 70 56 74 61 62 29  te3_vtab *pVtab)
85e0: 7b 0a 20 20 66 74 73 35 43 68 65 63 6b 54 72 61  {.  fts5CheckTra
85f0: 6e 73 61 63 74 69 6f 6e 53 74 61 74 65 28 28 46  nsactionState((F
8600: 74 73 35 54 61 62 6c 65 2a 29 70 56 74 61 62 2c  ts5Table*)pVtab,
8610: 20 46 54 53 35 5f 43 4f 4d 4d 49 54 2c 20 30 29   FTS5_COMMIT, 0)
8620: 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54  ;.  return SQLIT
8630: 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49  E_OK;.}../*.** I
8640: 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66  mplementation of
8650: 20 78 52 6f 6c 6c 62 61 63 6b 28 29 2e 20 44 69   xRollback(). Di
8660: 73 63 61 72 64 20 74 68 65 20 63 6f 6e 74 65 6e  scard the conten
8670: 74 73 20 6f 66 20 74 68 65 20 70 65 6e 64 69 6e  ts of the pendin
8680: 67 2d 74 65 72 6d 73 0a 2a 2a 20 68 61 73 68 2d  g-terms.** hash-
8690: 74 61 62 6c 65 2e 20 41 6e 79 20 63 68 61 6e 67  table. Any chang
86a0: 65 73 20 6d 61 64 65 20 74 6f 20 74 68 65 20 64  es made to the d
86b0: 61 74 61 62 61 73 65 20 61 72 65 20 72 65 76 65  atabase are reve
86c0: 72 74 65 64 20 62 79 20 53 51 4c 69 74 65 2e 0a  rted by SQLite..
86d0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74  */.static int ft
86e0: 73 35 52 6f 6c 6c 62 61 63 6b 4d 65 74 68 6f 64  s5RollbackMethod
86f0: 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70  (sqlite3_vtab *p
8700: 56 74 61 62 29 7b 0a 20 20 69 6e 74 20 72 63 3b  Vtab){.  int rc;
8710: 0a 20 20 46 74 73 35 54 61 62 6c 65 20 2a 70 54  .  Fts5Table *pT
8720: 61 62 20 3d 20 28 46 74 73 35 54 61 62 6c 65 2a  ab = (Fts5Table*
8730: 29 70 56 74 61 62 3b 0a 20 20 66 74 73 35 43 68  )pVtab;.  fts5Ch
8740: 65 63 6b 54 72 61 6e 73 61 63 74 69 6f 6e 53 74  eckTransactionSt
8750: 61 74 65 28 70 54 61 62 2c 20 46 54 53 35 5f 52  ate(pTab, FTS5_R
8760: 4f 4c 4c 42 41 43 4b 2c 20 30 29 3b 0a 20 20 72  OLLBACK, 0);.  r
8770: 63 20 3d 20 73 71 6c 69 74 65 33 46 74 73 35 53  c = sqlite3Fts5S
8780: 74 6f 72 61 67 65 52 6f 6c 6c 62 61 63 6b 28 70  torageRollback(p
8790: 54 61 62 2d 3e 70 53 74 6f 72 61 67 65 29 3b 0a  Tab->pStorage);.
87a0: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
87b0: 73 74 61 74 69 63 20 76 6f 69 64 20 2a 66 74 73  static void *fts
87c0: 35 41 70 69 55 73 65 72 44 61 74 61 28 46 74 73  5ApiUserData(Fts
87d0: 35 43 6f 6e 74 65 78 74 20 2a 70 43 74 78 29 7b  5Context *pCtx){
87e0: 0a 20 20 46 74 73 35 43 75 72 73 6f 72 20 2a 70  .  Fts5Cursor *p
87f0: 43 73 72 20 3d 20 28 46 74 73 35 43 75 72 73 6f  Csr = (Fts5Curso
8800: 72 2a 29 70 43 74 78 3b 0a 20 20 72 65 74 75 72  r*)pCtx;.  retur
8810: 6e 20 70 43 73 72 2d 3e 70 41 75 78 2d 3e 70 55  n pCsr->pAux->pU
8820: 73 65 72 44 61 74 61 3b 0a 7d 0a 0a 73 74 61 74  serData;.}..stat
8830: 69 63 20 69 6e 74 20 66 74 73 35 41 70 69 43 6f  ic int fts5ApiCo
8840: 6c 75 6d 6e 43 6f 75 6e 74 28 46 74 73 35 43 6f  lumnCount(Fts5Co
8850: 6e 74 65 78 74 20 2a 70 43 74 78 29 7b 0a 20 20  ntext *pCtx){.  
8860: 46 74 73 35 43 75 72 73 6f 72 20 2a 70 43 73 72  Fts5Cursor *pCsr
8870: 20 3d 20 28 46 74 73 35 43 75 72 73 6f 72 2a 29   = (Fts5Cursor*)
8880: 70 43 74 78 3b 0a 20 20 72 65 74 75 72 6e 20 28  pCtx;.  return (
8890: 28 46 74 73 35 54 61 62 6c 65 2a 29 28 70 43 73  (Fts5Table*)(pCs
88a0: 72 2d 3e 62 61 73 65 2e 70 56 74 61 62 29 29 2d  r->base.pVtab))-
88b0: 3e 70 43 6f 6e 66 69 67 2d 3e 6e 43 6f 6c 3b 0a  >pConfig->nCol;.
88c0: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74  }..static int ft
88d0: 73 35 41 70 69 43 6f 6c 75 6d 6e 54 6f 74 61 6c  s5ApiColumnTotal
88e0: 53 69 7a 65 28 0a 20 20 46 74 73 35 43 6f 6e 74  Size(.  Fts5Cont
88f0: 65 78 74 20 2a 70 43 74 78 2c 20 0a 20 20 69 6e  ext *pCtx, .  in
8900: 74 20 69 43 6f 6c 2c 20 0a 20 20 73 71 6c 69 74  t iCol, .  sqlit
8910: 65 33 5f 69 6e 74 36 34 20 2a 70 6e 54 6f 6b 65  e3_int64 *pnToke
8920: 6e 0a 29 7b 0a 20 20 46 74 73 35 43 75 72 73 6f  n.){.  Fts5Curso
8930: 72 20 2a 70 43 73 72 20 3d 20 28 46 74 73 35 43  r *pCsr = (Fts5C
8940: 75 72 73 6f 72 2a 29 70 43 74 78 3b 0a 20 20 46  ursor*)pCtx;.  F
8950: 74 73 35 54 61 62 6c 65 20 2a 70 54 61 62 20 3d  ts5Table *pTab =
8960: 20 28 46 74 73 35 54 61 62 6c 65 2a 29 28 70 43   (Fts5Table*)(pC
8970: 73 72 2d 3e 62 61 73 65 2e 70 56 74 61 62 29 3b  sr->base.pVtab);
8980: 0a 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74 65  .  return sqlite
8990: 33 46 74 73 35 53 74 6f 72 61 67 65 53 69 7a 65  3Fts5StorageSize
89a0: 28 70 54 61 62 2d 3e 70 53 74 6f 72 61 67 65 2c  (pTab->pStorage,
89b0: 20 69 43 6f 6c 2c 20 70 6e 54 6f 6b 65 6e 29 3b   iCol, pnToken);
89c0: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 66  .}..static int f
89d0: 74 73 35 41 70 69 52 6f 77 43 6f 75 6e 74 28 46  ts5ApiRowCount(F
89e0: 74 73 35 43 6f 6e 74 65 78 74 20 2a 70 43 74 78  ts5Context *pCtx
89f0: 2c 20 69 36 34 20 2a 70 6e 52 6f 77 29 7b 0a 20  , i64 *pnRow){. 
8a00: 20 46 74 73 35 43 75 72 73 6f 72 20 2a 70 43 73   Fts5Cursor *pCs
8a10: 72 20 3d 20 28 46 74 73 35 43 75 72 73 6f 72 2a  r = (Fts5Cursor*
8a20: 29 70 43 74 78 3b 0a 20 20 46 74 73 35 54 61 62  )pCtx;.  Fts5Tab
8a30: 6c 65 20 2a 70 54 61 62 20 3d 20 28 46 74 73 35  le *pTab = (Fts5
8a40: 54 61 62 6c 65 2a 29 28 70 43 73 72 2d 3e 62 61  Table*)(pCsr->ba
8a50: 73 65 2e 70 56 74 61 62 29 3b 0a 20 20 72 65 74  se.pVtab);.  ret
8a60: 75 72 6e 20 73 71 6c 69 74 65 33 46 74 73 35 53  urn sqlite3Fts5S
8a70: 74 6f 72 61 67 65 52 6f 77 43 6f 75 6e 74 28 70  torageRowCount(p
8a80: 54 61 62 2d 3e 70 53 74 6f 72 61 67 65 2c 20 70  Tab->pStorage, p
8a90: 6e 52 6f 77 29 3b 0a 7d 0a 0a 73 74 61 74 69 63  nRow);.}..static
8aa0: 20 69 6e 74 20 66 74 73 35 41 70 69 54 6f 6b 65   int fts5ApiToke
8ab0: 6e 69 7a 65 28 0a 20 20 46 74 73 35 43 6f 6e 74  nize(.  Fts5Cont
8ac0: 65 78 74 20 2a 70 43 74 78 2c 20 0a 20 20 63 6f  ext *pCtx, .  co
8ad0: 6e 73 74 20 63 68 61 72 20 2a 70 54 65 78 74 2c  nst char *pText,
8ae0: 20 69 6e 74 20 6e 54 65 78 74 2c 20 0a 20 20 76   int nText, .  v
8af0: 6f 69 64 20 2a 70 55 73 65 72 44 61 74 61 2c 0a  oid *pUserData,.
8b00: 20 20 69 6e 74 20 28 2a 78 54 6f 6b 65 6e 29 28    int (*xToken)(
8b10: 76 6f 69 64 2a 2c 20 63 6f 6e 73 74 20 63 68 61  void*, const cha
8b20: 72 2a 2c 20 69 6e 74 2c 20 69 6e 74 2c 20 69 6e  r*, int, int, in
8b30: 74 2c 20 69 6e 74 29 0a 29 7b 0a 20 20 46 74 73  t, int).){.  Fts
8b40: 35 43 75 72 73 6f 72 20 2a 70 43 73 72 20 3d 20  5Cursor *pCsr = 
8b50: 28 46 74 73 35 43 75 72 73 6f 72 2a 29 70 43 74  (Fts5Cursor*)pCt
8b60: 78 3b 0a 20 20 46 74 73 35 54 61 62 6c 65 20 2a  x;.  Fts5Table *
8b70: 70 54 61 62 20 3d 20 28 46 74 73 35 54 61 62 6c  pTab = (Fts5Tabl
8b80: 65 2a 29 28 70 43 73 72 2d 3e 62 61 73 65 2e 70  e*)(pCsr->base.p
8b90: 56 74 61 62 29 3b 0a 20 20 72 65 74 75 72 6e 20  Vtab);.  return 
8ba0: 73 71 6c 69 74 65 33 46 74 73 35 54 6f 6b 65 6e  sqlite3Fts5Token
8bb0: 69 7a 65 28 70 54 61 62 2d 3e 70 43 6f 6e 66 69  ize(pTab->pConfi
8bc0: 67 2c 20 70 54 65 78 74 2c 20 6e 54 65 78 74 2c  g, pText, nText,
8bd0: 20 70 55 73 65 72 44 61 74 61 2c 20 78 54 6f 6b   pUserData, xTok
8be0: 65 6e 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69  en);.}..static i
8bf0: 6e 74 20 66 74 73 35 41 70 69 50 68 72 61 73 65  nt fts5ApiPhrase
8c00: 43 6f 75 6e 74 28 46 74 73 35 43 6f 6e 74 65 78  Count(Fts5Contex
8c10: 74 20 2a 70 43 74 78 29 7b 0a 20 20 46 74 73 35  t *pCtx){.  Fts5
8c20: 43 75 72 73 6f 72 20 2a 70 43 73 72 20 3d 20 28  Cursor *pCsr = (
8c30: 46 74 73 35 43 75 72 73 6f 72 2a 29 70 43 74 78  Fts5Cursor*)pCtx
8c40: 3b 0a 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74  ;.  return sqlit
8c50: 65 33 46 74 73 35 45 78 70 72 50 68 72 61 73 65  e3Fts5ExprPhrase
8c60: 43 6f 75 6e 74 28 70 43 73 72 2d 3e 70 45 78 70  Count(pCsr->pExp
8c70: 72 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  r);.}..static in
8c80: 74 20 66 74 73 35 41 70 69 50 68 72 61 73 65 53  t fts5ApiPhraseS
8c90: 69 7a 65 28 46 74 73 35 43 6f 6e 74 65 78 74 20  ize(Fts5Context 
8ca0: 2a 70 43 74 78 2c 20 69 6e 74 20 69 50 68 72 61  *pCtx, int iPhra
8cb0: 73 65 29 7b 0a 20 20 46 74 73 35 43 75 72 73 6f  se){.  Fts5Curso
8cc0: 72 20 2a 70 43 73 72 20 3d 20 28 46 74 73 35 43  r *pCsr = (Fts5C
8cd0: 75 72 73 6f 72 2a 29 70 43 74 78 3b 0a 20 20 72  ursor*)pCtx;.  r
8ce0: 65 74 75 72 6e 20 73 71 6c 69 74 65 33 46 74 73  eturn sqlite3Fts
8cf0: 35 45 78 70 72 50 68 72 61 73 65 53 69 7a 65 28  5ExprPhraseSize(
8d00: 70 43 73 72 2d 3e 70 45 78 70 72 2c 20 69 50 68  pCsr->pExpr, iPh
8d10: 72 61 73 65 29 3b 0a 7d 0a 0a 73 74 61 74 69 63  rase);.}..static
8d20: 20 69 6e 74 20 66 74 73 35 43 73 72 50 6f 73 6c   int fts5CsrPosl
8d30: 69 73 74 28 46 74 73 35 43 75 72 73 6f 72 20 2a  ist(Fts5Cursor *
8d40: 70 43 73 72 2c 20 69 6e 74 20 69 50 68 72 61 73  pCsr, int iPhras
8d50: 65 2c 20 63 6f 6e 73 74 20 75 38 20 2a 2a 70 61  e, const u8 **pa
8d60: 29 7b 0a 20 20 69 6e 74 20 6e 3b 0a 20 20 69 66  ){.  int n;.  if
8d70: 28 20 70 43 73 72 2d 3e 70 53 6f 72 74 65 72 20  ( pCsr->pSorter 
8d80: 29 7b 0a 20 20 20 20 46 74 73 35 53 6f 72 74 65  ){.    Fts5Sorte
8d90: 72 20 2a 70 53 6f 72 74 65 72 20 3d 20 70 43 73  r *pSorter = pCs
8da0: 72 2d 3e 70 53 6f 72 74 65 72 3b 0a 20 20 20 20  r->pSorter;.    
8db0: 69 6e 74 20 69 31 20 3d 20 28 69 50 68 72 61 73  int i1 = (iPhras
8dc0: 65 3d 3d 30 20 3f 20 30 20 3a 20 70 53 6f 72 74  e==0 ? 0 : pSort
8dd0: 65 72 2d 3e 61 49 64 78 5b 69 50 68 72 61 73 65  er->aIdx[iPhrase
8de0: 2d 31 5d 29 3b 0a 20 20 20 20 6e 20 3d 20 70 53  -1]);.    n = pS
8df0: 6f 72 74 65 72 2d 3e 61 49 64 78 5b 69 50 68 72  orter->aIdx[iPhr
8e00: 61 73 65 5d 20 2d 20 69 31 3b 0a 20 20 20 20 2a  ase] - i1;.    *
8e10: 70 61 20 3d 20 26 70 53 6f 72 74 65 72 2d 3e 61  pa = &pSorter->a
8e20: 50 6f 73 6c 69 73 74 5b 69 31 5d 3b 0a 20 20 7d  Poslist[i1];.  }
8e30: 65 6c 73 65 7b 0a 20 20 20 20 6e 20 3d 20 73 71  else{.    n = sq
8e40: 6c 69 74 65 33 46 74 73 35 45 78 70 72 50 6f 73  lite3Fts5ExprPos
8e50: 6c 69 73 74 28 70 43 73 72 2d 3e 70 45 78 70 72  list(pCsr->pExpr
8e60: 2c 20 69 50 68 72 61 73 65 2c 20 70 61 29 3b 0a  , iPhrase, pa);.
8e70: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 6e 3b 0a    }.  return n;.
8e80: 7d 0a 0a 2f 2a 0a 2a 2a 20 45 6e 73 75 72 65 20  }../*.** Ensure 
8e90: 74 68 61 74 20 74 68 65 20 46 74 73 35 43 75 72  that the Fts5Cur
8ea0: 73 6f 72 2e 6e 49 6e 73 74 43 6f 75 6e 74 20 61  sor.nInstCount a
8eb0: 6e 64 20 61 49 6e 73 74 5b 5d 20 76 61 72 69 61  nd aInst[] varia
8ec0: 62 6c 65 73 20 61 72 65 20 70 6f 70 75 6c 61 74  bles are populat
8ed0: 65 64 0a 2a 2a 20 63 6f 72 72 65 63 74 6c 79 20  ed.** correctly 
8ee0: 66 6f 72 20 74 68 65 20 63 75 72 72 65 6e 74 20  for the current 
8ef0: 76 69 65 77 2e 20 52 65 74 75 72 6e 20 53 51 4c  view. Return SQL
8f00: 49 54 45 5f 4f 4b 20 69 66 20 73 75 63 63 65 73  ITE_OK if succes
8f10: 73 66 75 6c 2c 20 6f 72 20 61 6e 0a 2a 2a 20 53  sful, or an.** S
8f20: 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65  QLite error code
8f30: 20 6f 74 68 65 72 77 69 73 65 2e 0a 2a 2f 0a 73   otherwise..*/.s
8f40: 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 43 61  tatic int fts5Ca
8f50: 63 68 65 49 6e 73 74 41 72 72 61 79 28 46 74 73  cheInstArray(Fts
8f60: 35 43 75 72 73 6f 72 20 2a 70 43 73 72 29 7b 0a  5Cursor *pCsr){.
8f70: 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
8f80: 45 5f 4f 4b 3b 0a 20 20 69 66 28 20 70 43 73 72  E_OK;.  if( pCsr
8f90: 2d 3e 61 49 6e 73 74 3d 3d 30 20 29 7b 0a 20 20  ->aInst==0 ){.  
8fa0: 20 20 46 74 73 35 50 6f 73 6c 69 73 74 52 65 61    Fts5PoslistRea
8fb0: 64 65 72 20 2a 61 49 74 65 72 3b 20 20 20 20 20  der *aIter;     
8fc0: 2f 2a 20 4f 6e 65 20 69 74 65 72 61 74 6f 72 20  /* One iterator 
8fd0: 66 6f 72 20 65 61 63 68 20 70 68 72 61 73 65 20  for each phrase 
8fe0: 2a 2f 0a 20 20 20 20 69 6e 74 20 6e 49 74 65 72  */.    int nIter
8ff0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
9000: 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
9010: 66 20 69 74 65 72 61 74 6f 72 73 2f 70 68 72 61  f iterators/phra
9020: 73 65 73 20 2a 2f 0a 20 20 20 20 69 6e 74 20 6e  ses */.    int n
9030: 42 79 74 65 3b 0a 20 20 20 20 0a 20 20 20 20 6e  Byte;.    .    n
9040: 49 74 65 72 20 3d 20 73 71 6c 69 74 65 33 46 74  Iter = sqlite3Ft
9050: 73 35 45 78 70 72 50 68 72 61 73 65 43 6f 75 6e  s5ExprPhraseCoun
9060: 74 28 70 43 73 72 2d 3e 70 45 78 70 72 29 3b 0a  t(pCsr->pExpr);.
9070: 20 20 20 20 6e 42 79 74 65 20 3d 20 73 69 7a 65      nByte = size
9080: 6f 66 28 46 74 73 35 50 6f 73 6c 69 73 74 52 65  of(Fts5PoslistRe
9090: 61 64 65 72 29 20 2a 20 6e 49 74 65 72 3b 0a 20  ader) * nIter;. 
90a0: 20 20 20 61 49 74 65 72 20 3d 20 28 46 74 73 35     aIter = (Fts5
90b0: 50 6f 73 6c 69 73 74 52 65 61 64 65 72 2a 29 73  PoslistReader*)s
90c0: 71 6c 69 74 65 33 46 74 73 35 4d 61 6c 6c 6f 63  qlite3Fts5Malloc
90d0: 5a 65 72 6f 28 26 72 63 2c 20 6e 42 79 74 65 29  Zero(&rc, nByte)
90e0: 3b 0a 20 20 20 20 69 66 28 20 61 49 74 65 72 20  ;.    if( aIter 
90f0: 29 7b 0a 20 20 20 20 20 20 46 74 73 35 42 75 66  ){.      Fts5Buf
9100: 66 65 72 20 62 75 66 20 3d 20 7b 30 2c 20 30 2c  fer buf = {0, 0,
9110: 20 30 7d 3b 20 2f 2a 20 42 75 69 6c 64 20 75 70   0}; /* Build up
9120: 20 61 49 6e 73 74 5b 5d 20 68 65 72 65 20 2a 2f   aInst[] here */
9130: 0a 20 20 20 20 20 20 69 6e 74 20 6e 49 6e 73 74  .      int nInst
9140: 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20   = 0;           
9150: 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 69 6e 73     /* Number ins
9160: 74 61 6e 63 65 73 20 73 65 65 6e 20 73 6f 20 66  tances seen so f
9170: 61 72 20 2a 2f 0a 20 20 20 20 20 20 69 6e 74 20  ar */.      int 
9180: 69 3b 0a 0a 20 20 20 20 20 20 2f 2a 20 49 6e 69  i;..      /* Ini
9190: 74 69 61 6c 69 7a 65 20 61 6c 6c 20 69 74 65 72  tialize all iter
91a0: 61 74 6f 72 73 20 2a 2f 0a 20 20 20 20 20 20 66  ators */.      f
91b0: 6f 72 28 69 3d 30 3b 20 69 3c 6e 49 74 65 72 3b  or(i=0; i<nIter;
91c0: 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 63   i++){.        c
91d0: 6f 6e 73 74 20 75 38 20 2a 61 3b 0a 20 20 20 20  onst u8 *a;.    
91e0: 20 20 20 20 69 6e 74 20 6e 20 3d 20 66 74 73 35      int n = fts5
91f0: 43 73 72 50 6f 73 6c 69 73 74 28 70 43 73 72 2c  CsrPoslist(pCsr,
9200: 20 69 2c 20 26 61 29 3b 0a 20 20 20 20 20 20 20   i, &a);.       
9210: 20 73 71 6c 69 74 65 33 46 74 73 35 50 6f 73 6c   sqlite3Fts5Posl
9220: 69 73 74 52 65 61 64 65 72 49 6e 69 74 28 2d 31  istReaderInit(-1
9230: 2c 20 61 2c 20 6e 2c 20 26 61 49 74 65 72 5b 69  , a, n, &aIter[i
9240: 5d 29 3b 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20  ]);.      }..   
9250: 20 20 20 77 68 69 6c 65 28 20 31 20 29 7b 0a 20     while( 1 ){. 
9260: 20 20 20 20 20 20 20 69 6e 74 20 2a 61 49 6e 73         int *aIns
9270: 74 3b 0a 20 20 20 20 20 20 20 20 69 6e 74 20 69  t;.        int i
9280: 42 65 73 74 20 3d 20 2d 31 3b 0a 20 20 20 20 20  Best = -1;.     
9290: 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 49     for(i=0; i<nI
92a0: 74 65 72 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20  ter; i++){.     
92b0: 20 20 20 20 20 69 66 28 20 28 61 49 74 65 72 5b       if( (aIter[
92c0: 69 5d 2e 62 45 6f 66 3d 3d 30 29 20 0a 20 20 20  i].bEof==0) .   
92d0: 20 20 20 20 20 20 20 20 26 26 20 28 69 42 65 73          && (iBes
92e0: 74 3c 30 20 7c 7c 20 61 49 74 65 72 5b 69 5d 2e  t<0 || aIter[i].
92f0: 69 50 6f 73 3c 61 49 74 65 72 5b 69 42 65 73 74  iPos<aIter[iBest
9300: 5d 2e 69 50 6f 73 29 20 0a 20 20 20 20 20 20 20  ].iPos) .       
9310: 20 20 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20     ){.          
9320: 20 20 69 42 65 73 74 20 3d 20 69 3b 0a 20 20 20    iBest = i;.   
9330: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20         }.       
9340: 20 7d 0a 0a 20 20 20 20 20 20 20 20 69 66 28 20   }..        if( 
9350: 69 42 65 73 74 3c 30 20 29 20 62 72 65 61 6b 3b  iBest<0 ) break;
9360: 0a 20 20 20 20 20 20 20 20 6e 49 6e 73 74 2b 2b  .        nInst++
9370: 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 73 71  ;.        if( sq
9380: 6c 69 74 65 33 46 74 73 35 42 75 66 66 65 72 47  lite3Fts5BufferG
9390: 72 6f 77 28 26 72 63 2c 20 26 62 75 66 2c 20 6e  row(&rc, &buf, n
93a0: 49 6e 73 74 20 2a 20 73 69 7a 65 6f 66 28 69 6e  Inst * sizeof(in
93b0: 74 29 20 2a 20 33 29 20 29 20 62 72 65 61 6b 3b  t) * 3) ) break;
93c0: 0a 0a 20 20 20 20 20 20 20 20 61 49 6e 73 74 20  ..        aInst 
93d0: 3d 20 26 28 28 69 6e 74 2a 29 62 75 66 2e 70 29  = &((int*)buf.p)
93e0: 5b 33 20 2a 20 28 6e 49 6e 73 74 2d 31 29 5d 3b  [3 * (nInst-1)];
93f0: 0a 20 20 20 20 20 20 20 20 61 49 6e 73 74 5b 30  .        aInst[0
9400: 5d 20 3d 20 69 42 65 73 74 3b 0a 20 20 20 20 20  ] = iBest;.     
9410: 20 20 20 61 49 6e 73 74 5b 31 5d 20 3d 20 46 54     aInst[1] = FT
9420: 53 35 5f 50 4f 53 32 43 4f 4c 55 4d 4e 28 61 49  S5_POS2COLUMN(aI
9430: 74 65 72 5b 69 42 65 73 74 5d 2e 69 50 6f 73 29  ter[iBest].iPos)
9440: 3b 0a 20 20 20 20 20 20 20 20 61 49 6e 73 74 5b  ;.        aInst[
9450: 32 5d 20 3d 20 46 54 53 35 5f 50 4f 53 32 4f 46  2] = FTS5_POS2OF
9460: 46 53 45 54 28 61 49 74 65 72 5b 69 42 65 73 74  FSET(aIter[iBest
9470: 5d 2e 69 50 6f 73 29 3b 0a 20 20 20 20 20 20 20  ].iPos);.       
9480: 20 73 71 6c 69 74 65 33 46 74 73 35 50 6f 73 6c   sqlite3Fts5Posl
9490: 69 73 74 52 65 61 64 65 72 4e 65 78 74 28 26 61  istReaderNext(&a
94a0: 49 74 65 72 5b 69 42 65 73 74 5d 29 3b 0a 20 20  Iter[iBest]);.  
94b0: 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 70 43 73      }..      pCs
94c0: 72 2d 3e 61 49 6e 73 74 20 3d 20 28 69 6e 74 2a  r->aInst = (int*
94d0: 29 62 75 66 2e 70 3b 0a 20 20 20 20 20 20 70 43  )buf.p;.      pC
94e0: 73 72 2d 3e 6e 49 6e 73 74 43 6f 75 6e 74 20 3d  sr->nInstCount =
94f0: 20 6e 49 6e 73 74 3b 0a 20 20 20 20 20 20 73 71   nInst;.      sq
9500: 6c 69 74 65 33 5f 66 72 65 65 28 61 49 74 65 72  lite3_free(aIter
9510: 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72  );.    }.  }.  r
9520: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61  eturn rc;.}..sta
9530: 74 69 63 20 69 6e 74 20 66 74 73 35 41 70 69 49  tic int fts5ApiI
9540: 6e 73 74 43 6f 75 6e 74 28 46 74 73 35 43 6f 6e  nstCount(Fts5Con
9550: 74 65 78 74 20 2a 70 43 74 78 2c 20 69 6e 74 20  text *pCtx, int 
9560: 2a 70 6e 49 6e 73 74 29 7b 0a 20 20 46 74 73 35  *pnInst){.  Fts5
9570: 43 75 72 73 6f 72 20 2a 70 43 73 72 20 3d 20 28  Cursor *pCsr = (
9580: 46 74 73 35 43 75 72 73 6f 72 2a 29 70 43 74 78  Fts5Cursor*)pCtx
9590: 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 69 66  ;.  int rc;.  if
95a0: 28 20 53 51 4c 49 54 45 5f 4f 4b 3d 3d 28 72 63  ( SQLITE_OK==(rc
95b0: 20 3d 20 66 74 73 35 43 61 63 68 65 49 6e 73 74   = fts5CacheInst
95c0: 41 72 72 61 79 28 70 43 73 72 29 29 20 29 7b 0a  Array(pCsr)) ){.
95d0: 20 20 20 20 2a 70 6e 49 6e 73 74 20 3d 20 70 43      *pnInst = pC
95e0: 73 72 2d 3e 6e 49 6e 73 74 43 6f 75 6e 74 3b 0a  sr->nInstCount;.
95f0: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b    }.  return rc;
9600: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 66  .}..static int f
9610: 74 73 35 41 70 69 49 6e 73 74 28 0a 20 20 46 74  ts5ApiInst(.  Ft
9620: 73 35 43 6f 6e 74 65 78 74 20 2a 70 43 74 78 2c  s5Context *pCtx,
9630: 20 0a 20 20 69 6e 74 20 69 49 64 78 2c 20 0a 20   .  int iIdx, . 
9640: 20 69 6e 74 20 2a 70 69 50 68 72 61 73 65 2c 20   int *piPhrase, 
9650: 0a 20 20 69 6e 74 20 2a 70 69 43 6f 6c 2c 20 0a  .  int *piCol, .
9660: 20 20 69 6e 74 20 2a 70 69 4f 66 66 0a 29 7b 0a    int *piOff.){.
9670: 20 20 46 74 73 35 43 75 72 73 6f 72 20 2a 70 43    Fts5Cursor *pC
9680: 73 72 20 3d 20 28 46 74 73 35 43 75 72 73 6f 72  sr = (Fts5Cursor
9690: 2a 29 70 43 74 78 3b 0a 20 20 69 6e 74 20 72 63  *)pCtx;.  int rc
96a0: 3b 0a 20 20 69 66 28 20 53 51 4c 49 54 45 5f 4f  ;.  if( SQLITE_O
96b0: 4b 3d 3d 28 72 63 20 3d 20 66 74 73 35 43 61 63  K==(rc = fts5Cac
96c0: 68 65 49 6e 73 74 41 72 72 61 79 28 70 43 73 72  heInstArray(pCsr
96d0: 29 29 20 29 7b 0a 20 20 20 20 69 66 28 20 69 49  )) ){.    if( iI
96e0: 64 78 3c 30 20 7c 7c 20 69 49 64 78 3e 3d 70 43  dx<0 || iIdx>=pC
96f0: 73 72 2d 3e 6e 49 6e 73 74 43 6f 75 6e 74 20 29  sr->nInstCount )
9700: 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c  {.      rc = SQL
9710: 49 54 45 5f 52 41 4e 47 45 3b 0a 20 20 20 20 7d  ITE_RANGE;.    }
9720: 65 6c 73 65 7b 0a 20 20 20 20 20 20 2a 70 69 50  else{.      *piP
9730: 68 72 61 73 65 20 3d 20 70 43 73 72 2d 3e 61 49  hrase = pCsr->aI
9740: 6e 73 74 5b 69 49 64 78 2a 33 5d 3b 0a 20 20 20  nst[iIdx*3];.   
9750: 20 20 20 2a 70 69 43 6f 6c 20 3d 20 70 43 73 72     *piCol = pCsr
9760: 2d 3e 61 49 6e 73 74 5b 69 49 64 78 2a 33 20 2b  ->aInst[iIdx*3 +
9770: 20 31 5d 3b 0a 20 20 20 20 20 20 2a 70 69 4f 66   1];.      *piOf
9780: 66 20 3d 20 70 43 73 72 2d 3e 61 49 6e 73 74 5b  f = pCsr->aInst[
9790: 69 49 64 78 2a 33 20 2b 20 32 5d 3b 0a 20 20 20  iIdx*3 + 2];.   
97a0: 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20   }.  }.  return 
97b0: 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 73 71  rc;.}..static sq
97c0: 6c 69 74 65 33 5f 69 6e 74 36 34 20 66 74 73 35  lite3_int64 fts5
97d0: 41 70 69 52 6f 77 69 64 28 46 74 73 35 43 6f 6e  ApiRowid(Fts5Con
97e0: 74 65 78 74 20 2a 70 43 74 78 29 7b 0a 20 20 72  text *pCtx){.  r
97f0: 65 74 75 72 6e 20 66 74 73 35 43 75 72 73 6f 72  eturn fts5Cursor
9800: 52 6f 77 69 64 28 28 46 74 73 35 43 75 72 73 6f  Rowid((Fts5Curso
9810: 72 2a 29 70 43 74 78 29 3b 0a 7d 0a 0a 73 74 61  r*)pCtx);.}..sta
9820: 74 69 63 20 69 6e 74 20 66 74 73 35 41 70 69 43  tic int fts5ApiC
9830: 6f 6c 75 6d 6e 54 65 78 74 28 0a 20 20 46 74 73  olumnText(.  Fts
9840: 35 43 6f 6e 74 65 78 74 20 2a 70 43 74 78 2c 20  5Context *pCtx, 
9850: 0a 20 20 69 6e 74 20 69 43 6f 6c 2c 20 0a 20 20  .  int iCol, .  
9860: 63 6f 6e 73 74 20 63 68 61 72 20 2a 2a 70 7a 2c  const char **pz,
9870: 20 0a 20 20 69 6e 74 20 2a 70 6e 0a 29 7b 0a 20   .  int *pn.){. 
9880: 20 46 74 73 35 43 75 72 73 6f 72 20 2a 70 43 73   Fts5Cursor *pCs
9890: 72 20 3d 20 28 46 74 73 35 43 75 72 73 6f 72 2a  r = (Fts5Cursor*
98a0: 29 70 43 74 78 3b 0a 20 20 69 6e 74 20 72 63 20  )pCtx;.  int rc 
98b0: 3d 20 66 74 73 35 53 65 65 6b 43 75 72 73 6f 72  = fts5SeekCursor
98c0: 28 70 43 73 72 29 3b 0a 20 20 69 66 28 20 72 63  (pCsr);.  if( rc
98d0: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
98e0: 20 20 20 2a 70 7a 20 3d 20 28 63 6f 6e 73 74 20     *pz = (const 
98f0: 63 68 61 72 2a 29 73 71 6c 69 74 65 33 5f 63 6f  char*)sqlite3_co
9900: 6c 75 6d 6e 5f 74 65 78 74 28 70 43 73 72 2d 3e  lumn_text(pCsr->
9910: 70 53 74 6d 74 2c 20 69 43 6f 6c 2b 31 29 3b 0a  pStmt, iCol+1);.
9920: 20 20 20 20 2a 70 6e 20 3d 20 73 71 6c 69 74 65      *pn = sqlite
9930: 33 5f 63 6f 6c 75 6d 6e 5f 62 79 74 65 73 28 70  3_column_bytes(p
9940: 43 73 72 2d 3e 70 53 74 6d 74 2c 20 69 43 6f 6c  Csr->pStmt, iCol
9950: 2b 31 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72  +1);.  }.  retur
9960: 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  n rc;.}..static 
9970: 69 6e 74 20 66 74 73 35 41 70 69 43 6f 6c 75 6d  int fts5ApiColum
9980: 6e 53 69 7a 65 28 46 74 73 35 43 6f 6e 74 65 78  nSize(Fts5Contex
9990: 74 20 2a 70 43 74 78 2c 20 69 6e 74 20 69 43 6f  t *pCtx, int iCo
99a0: 6c 2c 20 69 6e 74 20 2a 70 6e 54 6f 6b 65 6e 29  l, int *pnToken)
99b0: 7b 0a 20 20 46 74 73 35 43 75 72 73 6f 72 20 2a  {.  Fts5Cursor *
99c0: 70 43 73 72 20 3d 20 28 46 74 73 35 43 75 72 73  pCsr = (Fts5Curs
99d0: 6f 72 2a 29 70 43 74 78 3b 0a 20 20 46 74 73 35  or*)pCtx;.  Fts5
99e0: 54 61 62 6c 65 20 2a 70 54 61 62 20 3d 20 28 46  Table *pTab = (F
99f0: 74 73 35 54 61 62 6c 65 2a 29 28 70 43 73 72 2d  ts5Table*)(pCsr-
9a00: 3e 62 61 73 65 2e 70 56 74 61 62 29 3b 0a 20 20  >base.pVtab);.  
9a10: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
9a20: 4f 4b 3b 0a 0a 20 20 69 66 28 20 43 73 72 46 6c  OK;..  if( CsrFl
9a30: 61 67 54 65 73 74 28 70 43 73 72 2c 20 46 54 53  agTest(pCsr, FTS
9a40: 35 43 53 52 5f 52 45 51 55 49 52 45 5f 44 4f 43  5CSR_REQUIRE_DOC
9a50: 53 49 5a 45 29 20 29 7b 0a 20 20 20 20 69 36 34  SIZE) ){.    i64
9a60: 20 69 52 6f 77 69 64 20 3d 20 66 74 73 35 43 75   iRowid = fts5Cu
9a70: 72 73 6f 72 52 6f 77 69 64 28 70 43 73 72 29 3b  rsorRowid(pCsr);
9a80: 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65  .    rc = sqlite
9a90: 33 46 74 73 35 53 74 6f 72 61 67 65 44 6f 63 73  3Fts5StorageDocs
9aa0: 69 7a 65 28 70 54 61 62 2d 3e 70 53 74 6f 72 61  ize(pTab->pStora
9ab0: 67 65 2c 20 69 52 6f 77 69 64 2c 20 70 43 73 72  ge, iRowid, pCsr
9ac0: 2d 3e 61 43 6f 6c 75 6d 6e 53 69 7a 65 29 3b 0a  ->aColumnSize);.
9ad0: 20 20 7d 0a 20 20 69 66 28 20 69 43 6f 6c 3e 3d    }.  if( iCol>=
9ae0: 30 20 26 26 20 69 43 6f 6c 3c 70 54 61 62 2d 3e  0 && iCol<pTab->
9af0: 70 43 6f 6e 66 69 67 2d 3e 6e 43 6f 6c 20 29 7b  pConfig->nCol ){
9b00: 0a 20 20 20 20 2a 70 6e 54 6f 6b 65 6e 20 3d 20  .    *pnToken = 
9b10: 70 43 73 72 2d 3e 61 43 6f 6c 75 6d 6e 53 69 7a  pCsr->aColumnSiz
9b20: 65 5b 69 43 6f 6c 5d 3b 0a 20 20 7d 65 6c 73 65  e[iCol];.  }else
9b30: 7b 0a 20 20 20 20 2a 70 6e 54 6f 6b 65 6e 20 3d  {.    *pnToken =
9b40: 20 30 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e   0;.  }.  return
9b50: 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69   rc;.}..static i
9b60: 6e 74 20 66 74 73 35 41 70 69 50 6f 73 6c 69 73  nt fts5ApiPoslis
9b70: 74 28 0a 20 20 46 74 73 35 43 6f 6e 74 65 78 74  t(.  Fts5Context
9b80: 20 2a 70 43 74 78 2c 20 0a 20 20 69 6e 74 20 69   *pCtx, .  int i
9b90: 50 68 72 61 73 65 2c 20 0a 20 20 69 6e 74 20 2a  Phrase, .  int *
9ba0: 70 69 2c 20 0a 20 20 69 36 34 20 2a 70 69 50 6f  pi, .  i64 *piPo
9bb0: 73 20 0a 29 7b 0a 20 20 46 74 73 35 43 75 72 73  s .){.  Fts5Curs
9bc0: 6f 72 20 2a 70 43 73 72 20 3d 20 28 46 74 73 35  or *pCsr = (Fts5
9bd0: 43 75 72 73 6f 72 2a 29 70 43 74 78 3b 0a 20 20  Cursor*)pCtx;.  
9be0: 63 6f 6e 73 74 20 75 38 20 2a 61 3b 20 69 6e 74  const u8 *a; int
9bf0: 20 6e 3b 20 20 20 20 20 20 20 20 20 20 20 20 20   n;             
9c00: 2f 2a 20 50 6f 73 6c 69 73 74 20 66 6f 72 20 70  /* Poslist for p
9c10: 68 72 61 73 65 20 69 50 68 72 61 73 65 20 2a 2f  hrase iPhrase */
9c20: 0a 20 20 6e 20 3d 20 66 74 73 35 43 73 72 50 6f  .  n = fts5CsrPo
9c30: 73 6c 69 73 74 28 70 43 73 72 2c 20 69 50 68 72  slist(pCsr, iPhr
9c40: 61 73 65 2c 20 26 61 29 3b 0a 20 20 72 65 74 75  ase, &a);.  retu
9c50: 72 6e 20 73 71 6c 69 74 65 33 46 74 73 35 50 6f  rn sqlite3Fts5Po
9c60: 73 6c 69 73 74 4e 65 78 74 36 34 28 61 2c 20 6e  slistNext64(a, n
9c70: 2c 20 70 69 2c 20 70 69 50 6f 73 29 3b 0a 7d 0a  , pi, piPos);.}.
9c80: 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35  .static int fts5
9c90: 41 70 69 53 65 74 41 75 78 64 61 74 61 28 0a 20  ApiSetAuxdata(. 
9ca0: 20 46 74 73 35 43 6f 6e 74 65 78 74 20 2a 70 43   Fts5Context *pC
9cb0: 74 78 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  tx,             
9cc0: 20 2f 2a 20 46 74 73 35 20 63 6f 6e 74 65 78 74   /* Fts5 context
9cd0: 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 50 74 72   */.  void *pPtr
9ce0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
9cf0: 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72        /* Pointer
9d00: 20 74 6f 20 73 61 76 65 20 61 73 20 61 75 78 64   to save as auxd
9d10: 61 74 61 20 2a 2f 0a 20 20 76 6f 69 64 28 2a 78  ata */.  void(*x
9d20: 44 65 6c 65 74 65 29 28 76 6f 69 64 2a 29 20 20  Delete)(void*)  
9d30: 20 20 20 20 20 20 20 20 20 2f 2a 20 44 65 73 74           /* Dest
9d40: 72 75 63 74 6f 72 20 66 6f 72 20 70 50 74 72 20  ructor for pPtr 
9d50: 28 6f 72 20 4e 55 4c 4c 29 20 2a 2f 0a 29 7b 0a  (or NULL) */.){.
9d60: 20 20 46 74 73 35 43 75 72 73 6f 72 20 2a 70 43    Fts5Cursor *pC
9d70: 73 72 20 3d 20 28 46 74 73 35 43 75 72 73 6f 72  sr = (Fts5Cursor
9d80: 2a 29 70 43 74 78 3b 0a 20 20 46 74 73 35 41 75  *)pCtx;.  Fts5Au
9d90: 78 64 61 74 61 20 2a 70 44 61 74 61 3b 0a 0a 20  xdata *pData;.. 
9da0: 20 66 6f 72 28 70 44 61 74 61 3d 70 43 73 72 2d   for(pData=pCsr-
9db0: 3e 70 41 75 78 64 61 74 61 3b 20 70 44 61 74 61  >pAuxdata; pData
9dc0: 3b 20 70 44 61 74 61 3d 70 44 61 74 61 2d 3e 70  ; pData=pData->p
9dd0: 4e 65 78 74 29 7b 0a 20 20 20 20 69 66 28 20 70  Next){.    if( p
9de0: 44 61 74 61 2d 3e 70 41 75 78 3d 3d 70 43 73 72  Data->pAux==pCsr
9df0: 2d 3e 70 41 75 78 20 29 20 62 72 65 61 6b 3b 0a  ->pAux ) break;.
9e00: 20 20 7d 0a 0a 20 20 69 66 28 20 70 44 61 74 61    }..  if( pData
9e10: 20 29 7b 0a 20 20 20 20 69 66 28 20 70 44 61 74   ){.    if( pDat
9e20: 61 2d 3e 78 44 65 6c 65 74 65 20 29 7b 0a 20 20  a->xDelete ){.  
9e30: 20 20 20 20 70 44 61 74 61 2d 3e 78 44 65 6c 65      pData->xDele
9e40: 74 65 28 70 44 61 74 61 2d 3e 70 50 74 72 29 3b  te(pData->pPtr);
9e50: 0a 20 20 20 20 7d 0a 20 20 7d 65 6c 73 65 7b 0a  .    }.  }else{.
9e60: 20 20 20 20 70 44 61 74 61 20 3d 20 28 46 74 73      pData = (Fts
9e70: 35 41 75 78 64 61 74 61 2a 29 73 71 6c 69 74 65  5Auxdata*)sqlite
9e80: 33 5f 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28  3_malloc(sizeof(
9e90: 46 74 73 35 41 75 78 64 61 74 61 29 29 3b 0a 20  Fts5Auxdata));. 
9ea0: 20 20 20 69 66 28 20 70 44 61 74 61 3d 3d 30 20     if( pData==0 
9eb0: 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f  ) return SQLITE_
9ec0: 4e 4f 4d 45 4d 3b 0a 20 20 20 20 6d 65 6d 73 65  NOMEM;.    memse
9ed0: 74 28 70 44 61 74 61 2c 20 30 2c 20 73 69 7a 65  t(pData, 0, size
9ee0: 6f 66 28 46 74 73 35 41 75 78 64 61 74 61 29 29  of(Fts5Auxdata))
9ef0: 3b 0a 20 20 20 20 70 44 61 74 61 2d 3e 70 41 75  ;.    pData->pAu
9f00: 78 20 3d 20 70 43 73 72 2d 3e 70 41 75 78 3b 0a  x = pCsr->pAux;.
9f10: 20 20 20 20 70 44 61 74 61 2d 3e 70 4e 65 78 74      pData->pNext
9f20: 20 3d 20 70 43 73 72 2d 3e 70 41 75 78 64 61 74   = pCsr->pAuxdat
9f30: 61 3b 0a 20 20 20 20 70 43 73 72 2d 3e 70 41 75  a;.    pCsr->pAu
9f40: 78 64 61 74 61 20 3d 20 70 44 61 74 61 3b 0a 20  xdata = pData;. 
9f50: 20 7d 0a 0a 20 20 70 44 61 74 61 2d 3e 78 44 65   }..  pData->xDe
9f60: 6c 65 74 65 20 3d 20 78 44 65 6c 65 74 65 3b 0a  lete = xDelete;.
9f70: 20 20 70 44 61 74 61 2d 3e 70 50 74 72 20 3d 20    pData->pPtr = 
9f80: 70 50 74 72 3b 0a 20 20 72 65 74 75 72 6e 20 53  pPtr;.  return S
9f90: 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 73 74 61  QLITE_OK;.}..sta
9fa0: 74 69 63 20 76 6f 69 64 20 2a 66 74 73 35 41 70  tic void *fts5Ap
9fb0: 69 47 65 74 41 75 78 64 61 74 61 28 46 74 73 35  iGetAuxdata(Fts5
9fc0: 43 6f 6e 74 65 78 74 20 2a 70 43 74 78 2c 20 69  Context *pCtx, i
9fd0: 6e 74 20 62 43 6c 65 61 72 29 7b 0a 20 20 46 74  nt bClear){.  Ft
9fe0: 73 35 43 75 72 73 6f 72 20 2a 70 43 73 72 20 3d  s5Cursor *pCsr =
9ff0: 20 28 46 74 73 35 43 75 72 73 6f 72 2a 29 70 43   (Fts5Cursor*)pC
a000: 74 78 3b 0a 20 20 46 74 73 35 41 75 78 64 61 74  tx;.  Fts5Auxdat
a010: 61 20 2a 70 44 61 74 61 3b 0a 20 20 76 6f 69 64  a *pData;.  void
a020: 20 2a 70 52 65 74 20 3d 20 30 3b 0a 0a 20 20 66   *pRet = 0;..  f
a030: 6f 72 28 70 44 61 74 61 3d 70 43 73 72 2d 3e 70  or(pData=pCsr->p
a040: 41 75 78 64 61 74 61 3b 20 70 44 61 74 61 3b 20  Auxdata; pData; 
a050: 70 44 61 74 61 3d 70 44 61 74 61 2d 3e 70 4e 65  pData=pData->pNe
a060: 78 74 29 7b 0a 20 20 20 20 69 66 28 20 70 44 61  xt){.    if( pDa
a070: 74 61 2d 3e 70 41 75 78 3d 3d 70 43 73 72 2d 3e  ta->pAux==pCsr->
a080: 70 41 75 78 20 29 20 62 72 65 61 6b 3b 0a 20 20  pAux ) break;.  
a090: 7d 0a 0a 20 20 69 66 28 20 70 44 61 74 61 20 29  }..  if( pData )
a0a0: 7b 0a 20 20 20 20 70 52 65 74 20 3d 20 70 44 61  {.    pRet = pDa
a0b0: 74 61 2d 3e 70 50 74 72 3b 0a 20 20 20 20 69 66  ta->pPtr;.    if
a0c0: 28 20 62 43 6c 65 61 72 20 29 7b 0a 20 20 20 20  ( bClear ){.    
a0d0: 20 20 70 44 61 74 61 2d 3e 70 50 74 72 20 3d 20    pData->pPtr = 
a0e0: 30 3b 0a 20 20 20 20 20 20 70 44 61 74 61 2d 3e  0;.      pData->
a0f0: 78 44 65 6c 65 74 65 20 3d 20 30 3b 0a 20 20 20  xDelete = 0;.   
a100: 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e   }.  }..  return
a110: 20 70 52 65 74 3b 0a 7d 0a 0a 73 74 61 74 69 63   pRet;.}..static
a120: 20 69 6e 74 20 66 74 73 35 41 70 69 51 75 65 72   int fts5ApiQuer
a130: 79 50 68 72 61 73 65 28 46 74 73 35 43 6f 6e 74  yPhrase(Fts5Cont
a140: 65 78 74 2a 2c 20 69 6e 74 2c 20 76 6f 69 64 2a  ext*, int, void*
a150: 2c 20 0a 20 20 20 20 69 6e 74 28 2a 29 28 63 6f  , .    int(*)(co
a160: 6e 73 74 20 46 74 73 35 45 78 74 65 6e 73 69 6f  nst Fts5Extensio
a170: 6e 41 70 69 2a 2c 20 46 74 73 35 43 6f 6e 74 65  nApi*, Fts5Conte
a180: 78 74 2a 2c 20 76 6f 69 64 2a 29 0a 29 3b 0a 0a  xt*, void*).);..
a190: 73 74 61 74 69 63 20 63 6f 6e 73 74 20 46 74 73  static const Fts
a1a0: 35 45 78 74 65 6e 73 69 6f 6e 41 70 69 20 73 46  5ExtensionApi sF
a1b0: 74 73 35 41 70 69 20 3d 20 7b 0a 20 20 31 2c 20  ts5Api = {.  1, 
a1c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a1d0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 69 56             /* iV
a1e0: 65 72 73 69 6f 6e 20 2a 2f 0a 20 20 66 74 73 35  ersion */.  fts5
a1f0: 41 70 69 55 73 65 72 44 61 74 61 2c 0a 20 20 66  ApiUserData,.  f
a200: 74 73 35 41 70 69 43 6f 6c 75 6d 6e 43 6f 75 6e  ts5ApiColumnCoun
a210: 74 2c 0a 20 20 66 74 73 35 41 70 69 52 6f 77 43  t,.  fts5ApiRowC
a220: 6f 75 6e 74 2c 0a 20 20 66 74 73 35 41 70 69 43  ount,.  fts5ApiC
a230: 6f 6c 75 6d 6e 54 6f 74 61 6c 53 69 7a 65 2c 0a  olumnTotalSize,.
a240: 20 20 66 74 73 35 41 70 69 54 6f 6b 65 6e 69 7a    fts5ApiTokeniz
a250: 65 2c 0a 20 20 66 74 73 35 41 70 69 50 68 72 61  e,.  fts5ApiPhra
a260: 73 65 43 6f 75 6e 74 2c 0a 20 20 66 74 73 35 41  seCount,.  fts5A
a270: 70 69 50 68 72 61 73 65 53 69 7a 65 2c 0a 20 20  piPhraseSize,.  
a280: 66 74 73 35 41 70 69 49 6e 73 74 43 6f 75 6e 74  fts5ApiInstCount
a290: 2c 0a 20 20 66 74 73 35 41 70 69 49 6e 73 74 2c  ,.  fts5ApiInst,
a2a0: 0a 20 20 66 74 73 35 41 70 69 52 6f 77 69 64 2c  .  fts5ApiRowid,
a2b0: 0a 20 20 66 74 73 35 41 70 69 43 6f 6c 75 6d 6e  .  fts5ApiColumn
a2c0: 54 65 78 74 2c 0a 20 20 66 74 73 35 41 70 69 43  Text,.  fts5ApiC
a2d0: 6f 6c 75 6d 6e 53 69 7a 65 2c 0a 20 20 66 74 73  olumnSize,.  fts
a2e0: 35 41 70 69 50 6f 73 6c 69 73 74 2c 0a 20 20 66  5ApiPoslist,.  f
a2f0: 74 73 35 41 70 69 51 75 65 72 79 50 68 72 61 73  ts5ApiQueryPhras
a300: 65 2c 0a 20 20 66 74 73 35 41 70 69 53 65 74 41  e,.  fts5ApiSetA
a310: 75 78 64 61 74 61 2c 0a 20 20 66 74 73 35 41 70  uxdata,.  fts5Ap
a320: 69 47 65 74 41 75 78 64 61 74 61 2c 0a 7d 3b 0a  iGetAuxdata,.};.
a330: 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e  ../*.** Implemen
a340: 74 61 74 69 6f 6e 20 6f 66 20 41 50 49 20 66 75  tation of API fu
a350: 6e 63 74 69 6f 6e 20 78 51 75 65 72 79 50 68 72  nction xQueryPhr
a360: 61 73 65 28 29 2e 0a 2a 2f 0a 73 74 61 74 69 63  ase()..*/.static
a370: 20 69 6e 74 20 66 74 73 35 41 70 69 51 75 65 72   int fts5ApiQuer
a380: 79 50 68 72 61 73 65 28 0a 20 20 46 74 73 35 43  yPhrase(.  Fts5C
a390: 6f 6e 74 65 78 74 20 2a 70 43 74 78 2c 20 0a 20  ontext *pCtx, . 
a3a0: 20 69 6e 74 20 69 50 68 72 61 73 65 2c 20 0a 20   int iPhrase, . 
a3b0: 20 76 6f 69 64 20 2a 70 55 73 65 72 44 61 74 61   void *pUserData
a3c0: 2c 0a 20 20 69 6e 74 28 2a 78 43 61 6c 6c 62 61  ,.  int(*xCallba
a3d0: 63 6b 29 28 63 6f 6e 73 74 20 46 74 73 35 45 78  ck)(const Fts5Ex
a3e0: 74 65 6e 73 69 6f 6e 41 70 69 2a 2c 20 46 74 73  tensionApi*, Fts
a3f0: 35 43 6f 6e 74 65 78 74 2a 2c 20 76 6f 69 64 2a  5Context*, void*
a400: 29 0a 29 7b 0a 20 20 46 74 73 35 43 75 72 73 6f  ).){.  Fts5Curso
a410: 72 20 2a 70 43 73 72 20 3d 20 28 46 74 73 35 43  r *pCsr = (Fts5C
a420: 75 72 73 6f 72 2a 29 70 43 74 78 3b 0a 20 20 46  ursor*)pCtx;.  F
a430: 74 73 35 54 61 62 6c 65 20 2a 70 54 61 62 20 3d  ts5Table *pTab =
a440: 20 28 46 74 73 35 54 61 62 6c 65 2a 29 28 70 43   (Fts5Table*)(pC
a450: 73 72 2d 3e 62 61 73 65 2e 70 56 74 61 62 29 3b  sr->base.pVtab);
a460: 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 46 74 73  .  int rc;.  Fts
a470: 35 43 75 72 73 6f 72 20 2a 70 4e 65 77 20 3d 20  5Cursor *pNew = 
a480: 30 3b 0a 0a 20 20 72 63 20 3d 20 66 74 73 35 4f  0;..  rc = fts5O
a490: 70 65 6e 4d 65 74 68 6f 64 28 70 43 73 72 2d 3e  penMethod(pCsr->
a4a0: 62 61 73 65 2e 70 56 74 61 62 2c 20 28 73 71 6c  base.pVtab, (sql
a4b0: 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72  ite3_vtab_cursor
a4c0: 2a 2a 29 26 70 4e 65 77 29 3b 0a 20 20 69 66 28  **)&pNew);.  if(
a4d0: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
a4e0: 7b 0a 20 20 20 20 46 74 73 35 43 6f 6e 66 69 67  {.    Fts5Config
a4f0: 20 2a 70 43 6f 6e 66 20 3d 20 70 54 61 62 2d 3e   *pConf = pTab->
a500: 70 43 6f 6e 66 69 67 3b 0a 20 20 20 20 70 4e 65  pConfig;.    pNe
a510: 77 2d 3e 69 64 78 4e 75 6d 20 3d 20 46 54 53 35  w->idxNum = FTS5
a520: 5f 50 4c 41 4e 5f 4d 41 54 43 48 3b 0a 20 20 20  _PLAN_MATCH;.   
a530: 20 70 4e 65 77 2d 3e 62 61 73 65 2e 70 56 74 61   pNew->base.pVta
a540: 62 20 3d 20 28 73 71 6c 69 74 65 33 5f 76 74 61  b = (sqlite3_vta
a550: 62 2a 29 70 54 61 62 3b 0a 20 20 20 20 72 63 20  b*)pTab;.    rc 
a560: 3d 20 73 71 6c 69 74 65 33 46 74 73 35 45 78 70  = sqlite3Fts5Exp
a570: 72 50 68 72 61 73 65 45 78 70 72 28 70 43 6f 6e  rPhraseExpr(pCon
a580: 66 2c 20 70 43 73 72 2d 3e 70 45 78 70 72 2c 20  f, pCsr->pExpr, 
a590: 69 50 68 72 61 73 65 2c 20 26 70 4e 65 77 2d 3e  iPhrase, &pNew->
a5a0: 70 45 78 70 72 29 3b 0a 20 20 7d 0a 0a 20 20 69  pExpr);.  }..  i
a5b0: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
a5c0: 20 29 7b 0a 20 20 20 20 66 6f 72 28 72 63 20 3d   ){.    for(rc =
a5d0: 20 66 74 73 35 43 75 72 73 6f 72 46 69 72 73 74   fts5CursorFirst
a5e0: 28 70 54 61 62 2c 20 70 4e 65 77 2c 20 30 29 3b  (pTab, pNew, 0);
a5f0: 0a 20 20 20 20 20 20 20 20 72 63 3d 3d 53 51 4c  .        rc==SQL
a600: 49 54 45 5f 4f 4b 20 26 26 20 43 73 72 46 6c 61  ITE_OK && CsrFla
a610: 67 54 65 73 74 28 70 4e 65 77 2c 20 46 54 53 35  gTest(pNew, FTS5
a620: 43 53 52 5f 45 4f 46 29 3d 3d 30 3b 0a 20 20 20  CSR_EOF)==0;.   
a630: 20 20 20 20 20 72 63 20 3d 20 66 74 73 35 4e 65       rc = fts5Ne
a640: 78 74 4d 65 74 68 6f 64 28 28 73 71 6c 69 74 65  xtMethod((sqlite
a650: 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 2a 29 70  3_vtab_cursor*)p
a660: 4e 65 77 29 0a 20 20 20 20 29 7b 0a 20 20 20 20  New).    ){.    
a670: 20 20 72 63 20 3d 20 78 43 61 6c 6c 62 61 63 6b    rc = xCallback
a680: 28 26 73 46 74 73 35 41 70 69 2c 20 28 46 74 73  (&sFts5Api, (Fts
a690: 35 43 6f 6e 74 65 78 74 2a 29 70 4e 65 77 2c 20  5Context*)pNew, 
a6a0: 70 55 73 65 72 44 61 74 61 29 3b 0a 20 20 20 20  pUserData);.    
a6b0: 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
a6c0: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 69  _OK ){.        i
a6d0: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 44 4f  f( rc==SQLITE_DO
a6e0: 4e 45 20 29 20 72 63 20 3d 20 53 51 4c 49 54 45  NE ) rc = SQLITE
a6f0: 5f 4f 4b 3b 0a 20 20 20 20 20 20 20 20 62 72 65  _OK;.        bre
a700: 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  ak;.      }.    
a710: 7d 0a 20 20 7d 0a 0a 20 20 66 74 73 35 43 6c 6f  }.  }..  fts5Clo
a720: 73 65 4d 65 74 68 6f 64 28 28 73 71 6c 69 74 65  seMethod((sqlite
a730: 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 2a 29 70  3_vtab_cursor*)p
a740: 4e 65 77 29 3b 0a 20 20 72 65 74 75 72 6e 20 72  New);.  return r
a750: 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69  c;.}..static voi
a760: 64 20 66 74 73 35 41 70 69 49 6e 76 6f 6b 65 28  d fts5ApiInvoke(
a770: 0a 20 20 46 74 73 35 41 75 78 69 6c 69 61 72 79  .  Fts5Auxiliary
a780: 20 2a 70 41 75 78 2c 0a 20 20 46 74 73 35 43 75   *pAux,.  Fts5Cu
a790: 72 73 6f 72 20 2a 70 43 73 72 2c 0a 20 20 73 71  rsor *pCsr,.  sq
a7a0: 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74 20 2a 63  lite3_context *c
a7b0: 6f 6e 74 65 78 74 2c 0a 20 20 69 6e 74 20 61 72  ontext,.  int ar
a7c0: 67 63 2c 0a 20 20 73 71 6c 69 74 65 33 5f 76 61  gc,.  sqlite3_va
a7d0: 6c 75 65 20 2a 2a 61 72 67 76 0a 29 7b 0a 20 20  lue **argv.){.  
a7e0: 61 73 73 65 72 74 28 20 70 43 73 72 2d 3e 70 41  assert( pCsr->pA
a7f0: 75 78 3d 3d 30 20 29 3b 0a 20 20 70 43 73 72 2d  ux==0 );.  pCsr-
a800: 3e 70 41 75 78 20 3d 20 70 41 75 78 3b 0a 20 20  >pAux = pAux;.  
a810: 70 41 75 78 2d 3e 78 46 75 6e 63 28 26 73 46 74  pAux->xFunc(&sFt
a820: 73 35 41 70 69 2c 20 28 46 74 73 35 43 6f 6e 74  s5Api, (Fts5Cont
a830: 65 78 74 2a 29 70 43 73 72 2c 20 63 6f 6e 74 65  ext*)pCsr, conte
a840: 78 74 2c 20 61 72 67 63 2c 20 61 72 67 76 29 3b  xt, argc, argv);
a850: 0a 20 20 70 43 73 72 2d 3e 70 41 75 78 20 3d 20  .  pCsr->pAux = 
a860: 30 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69  0;.}..static voi
a870: 64 20 66 74 73 35 41 70 69 43 61 6c 6c 62 61 63  d fts5ApiCallbac
a880: 6b 28 0a 20 20 73 71 6c 69 74 65 33 5f 63 6f 6e  k(.  sqlite3_con
a890: 74 65 78 74 20 2a 63 6f 6e 74 65 78 74 2c 0a 20  text *context,. 
a8a0: 20 69 6e 74 20 61 72 67 63 2c 0a 20 20 73 71 6c   int argc,.  sql
a8b0: 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a 61 72 67  ite3_value **arg
a8c0: 76 0a 29 7b 0a 0a 20 20 46 74 73 35 41 75 78 69  v.){..  Fts5Auxi
a8d0: 6c 69 61 72 79 20 2a 70 41 75 78 3b 0a 20 20 46  liary *pAux;.  F
a8e0: 74 73 35 43 75 72 73 6f 72 20 2a 70 43 73 72 3b  ts5Cursor *pCsr;
a8f0: 0a 20 20 69 36 34 20 69 43 73 72 49 64 3b 0a 0a  .  i64 iCsrId;..
a900: 20 20 61 73 73 65 72 74 28 20 61 72 67 63 3e 3d    assert( argc>=
a910: 31 20 29 3b 0a 20 20 70 41 75 78 20 3d 20 28 46  1 );.  pAux = (F
a920: 74 73 35 41 75 78 69 6c 69 61 72 79 2a 29 73 71  ts5Auxiliary*)sq
a930: 6c 69 74 65 33 5f 75 73 65 72 5f 64 61 74 61 28  lite3_user_data(
a940: 63 6f 6e 74 65 78 74 29 3b 0a 20 20 69 43 73 72  context);.  iCsr
a950: 49 64 20 3d 20 73 71 6c 69 74 65 33 5f 76 61 6c  Id = sqlite3_val
a960: 75 65 5f 69 6e 74 36 34 28 61 72 67 76 5b 30 5d  ue_int64(argv[0]
a970: 29 3b 0a 0a 20 20 66 6f 72 28 70 43 73 72 3d 70  );..  for(pCsr=p
a980: 41 75 78 2d 3e 70 47 6c 6f 62 61 6c 2d 3e 70 43  Aux->pGlobal->pC
a990: 73 72 3b 20 70 43 73 72 3b 20 70 43 73 72 3d 70  sr; pCsr; pCsr=p
a9a0: 43 73 72 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20  Csr->pNext){.   
a9b0: 20 69 66 28 20 70 43 73 72 2d 3e 69 43 73 72 49   if( pCsr->iCsrI
a9c0: 64 3d 3d 69 43 73 72 49 64 20 29 20 62 72 65 61  d==iCsrId ) brea
a9d0: 6b 3b 0a 20 20 7d 0a 20 20 69 66 28 20 70 43 73  k;.  }.  if( pCs
a9e0: 72 3d 3d 30 20 29 7b 0a 20 20 20 20 63 68 61 72  r==0 ){.    char
a9f0: 20 2a 7a 45 72 72 20 3d 20 73 71 6c 69 74 65 33   *zErr = sqlite3
aa00: 5f 6d 70 72 69 6e 74 66 28 22 6e 6f 20 73 75 63  _mprintf("no suc
aa10: 68 20 63 75 72 73 6f 72 3a 20 25 6c 6c 64 22 2c  h cursor: %lld",
aa20: 20 69 43 73 72 49 64 29 3b 0a 20 20 20 20 73 71   iCsrId);.    sq
aa30: 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 65 72 72  lite3_result_err
aa40: 6f 72 28 63 6f 6e 74 65 78 74 2c 20 7a 45 72 72  or(context, zErr
aa50: 2c 20 2d 31 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a  , -1);.  }else{.
aa60: 20 20 20 20 66 74 73 35 41 70 69 49 6e 76 6f 6b      fts5ApiInvok
aa70: 65 28 70 41 75 78 2c 20 70 43 73 72 2c 20 63 6f  e(pAux, pCsr, co
aa80: 6e 74 65 78 74 2c 20 61 72 67 63 2d 31 2c 20 26  ntext, argc-1, &
aa90: 61 72 67 76 5b 31 5d 29 3b 0a 20 20 7d 0a 7d 0a  argv[1]);.  }.}.
aaa0: 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 61 20  ./*.** Return a 
aab0: 22 70 6f 73 69 74 69 6f 6e 2d 6c 69 73 74 20 62  "position-list b
aac0: 6c 6f 62 22 20 63 6f 72 72 65 73 70 6f 6e 64 69  lob" correspondi
aad0: 6e 67 20 74 6f 20 74 68 65 20 63 75 72 72 65 6e  ng to the curren
aae0: 74 20 70 6f 73 69 74 69 6f 6e 20 6f 66 0a 2a 2a  t position of.**
aaf0: 20 63 75 72 73 6f 72 20 70 43 73 72 20 76 69 61   cursor pCsr via
ab00: 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f   sqlite3_result_
ab10: 62 6c 6f 62 28 29 2e 20 41 20 70 6f 73 69 74 69  blob(). A positi
ab20: 6f 6e 2d 6c 69 73 74 20 62 6c 6f 62 20 63 6f 6e  on-list blob con
ab30: 74 61 69 6e 73 0a 2a 2a 20 74 68 65 20 63 75 72  tains.** the cur
ab40: 72 65 6e 74 20 70 6f 73 69 74 69 6f 6e 2d 6c 69  rent position-li
ab50: 73 74 20 66 6f 72 20 65 61 63 68 20 70 68 72 61  st for each phra
ab60: 73 65 20 69 6e 20 74 68 65 20 71 75 65 72 79 20  se in the query 
ab70: 61 73 73 6f 63 69 61 74 65 64 20 77 69 74 68 0a  associated with.
ab80: 2a 2a 20 63 75 72 73 6f 72 20 70 43 73 72 2e 0a  ** cursor pCsr..
ab90: 2a 2a 0a 2a 2a 20 41 20 70 6f 73 69 74 69 6f 6e  **.** A position
aba0: 2d 6c 69 73 74 20 62 6c 6f 62 20 62 65 67 69 6e  -list blob begin
abb0: 73 20 77 69 74 68 20 28 6e 50 68 72 61 73 65 2d  s with (nPhrase-
abc0: 31 29 20 76 61 72 69 6e 74 73 2c 20 77 68 65 72  1) varints, wher
abd0: 65 20 6e 50 68 72 61 73 65 20 69 73 0a 2a 2a 20  e nPhrase is.** 
abe0: 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 70 68  the number of ph
abf0: 72 61 73 65 73 20 69 6e 20 74 68 65 20 71 75 65  rases in the que
ac00: 72 79 2e 20 46 6f 6c 6c 6f 77 69 6e 67 20 74 68  ry. Following th
ac10: 65 20 76 61 72 69 6e 74 73 20 61 72 65 20 74 68  e varints are th
ac20: 65 0a 2a 2a 20 63 6f 6e 63 61 74 65 6e 61 74 65  e.** concatenate
ac30: 64 20 70 6f 73 69 74 69 6f 6e 20 6c 69 73 74 73  d position lists
ac40: 20 66 6f 72 20 65 61 63 68 20 70 68 72 61 73 65   for each phrase
ac50: 2c 20 69 6e 20 6f 72 64 65 72 2e 0a 2a 2a 0a 2a  , in order..**.*
ac60: 2a 20 54 68 65 20 66 69 72 73 74 20 76 61 72 69  * The first vari
ac70: 6e 74 20 28 69 66 20 69 74 20 65 78 69 73 74 73  nt (if it exists
ac80: 29 20 63 6f 6e 74 61 69 6e 73 20 74 68 65 20 73  ) contains the s
ac90: 69 7a 65 20 6f 66 20 74 68 65 20 70 6f 73 69 74  ize of the posit
aca0: 69 6f 6e 20 6c 69 73 74 0a 2a 2a 20 66 6f 72 20  ion list.** for 
acb0: 70 68 72 61 73 65 20 30 2e 20 54 68 65 20 73 65  phrase 0. The se
acc0: 63 6f 6e 64 20 28 73 61 6d 65 20 64 69 73 63 6c  cond (same discl
acd0: 61 69 6d 65 72 29 20 63 6f 6e 74 61 69 6e 73 20  aimer) contains 
ace0: 74 68 65 20 73 69 7a 65 20 6f 66 20 70 6f 73 69  the size of posi
acf0: 74 69 6f 6e 0a 2a 2a 20 6c 69 73 74 20 31 2e 20  tion.** list 1. 
ad00: 41 6e 64 20 73 6f 20 6f 6e 2e 20 54 68 65 72 65  And so on. There
ad10: 20 69 73 20 6e 6f 20 73 69 7a 65 20 66 69 65 6c   is no size fiel
ad20: 64 20 66 6f 72 20 74 68 65 20 66 69 6e 61 6c 20  d for the final 
ad30: 70 6f 73 69 74 69 6f 6e 20 6c 69 73 74 2c 0a 2a  position list,.*
ad40: 2a 20 61 73 20 69 74 20 63 61 6e 20 62 65 20 64  * as it can be d
ad50: 65 72 69 76 65 64 20 66 72 6f 6d 20 74 68 65 20  erived from the 
ad60: 74 6f 74 61 6c 20 73 69 7a 65 20 6f 66 20 74 68  total size of th
ad70: 65 20 62 6c 6f 62 2e 0a 2a 2f 0a 73 74 61 74 69  e blob..*/.stati
ad80: 63 20 69 6e 74 20 66 74 73 35 50 6f 73 6c 69 73  c int fts5Poslis
ad90: 74 42 6c 6f 62 28 73 71 6c 69 74 65 33 5f 63 6f  tBlob(sqlite3_co
ada0: 6e 74 65 78 74 20 2a 70 43 74 78 2c 20 46 74 73  ntext *pCtx, Fts
adb0: 35 43 75 72 73 6f 72 20 2a 70 43 73 72 29 7b 0a  5Cursor *pCsr){.
adc0: 20 20 69 6e 74 20 69 3b 0a 20 20 69 6e 74 20 72    int i;.  int r
add0: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  c = SQLITE_OK;. 
ade0: 20 69 6e 74 20 6e 50 68 72 61 73 65 20 3d 20 73   int nPhrase = s
adf0: 71 6c 69 74 65 33 46 74 73 35 45 78 70 72 50 68  qlite3Fts5ExprPh
ae00: 72 61 73 65 43 6f 75 6e 74 28 70 43 73 72 2d 3e  raseCount(pCsr->
ae10: 70 45 78 70 72 29 3b 0a 20 20 46 74 73 35 42 75  pExpr);.  Fts5Bu
ae20: 66 66 65 72 20 76 61 6c 3b 0a 0a 20 20 6d 65 6d  ffer val;..  mem
ae30: 73 65 74 28 26 76 61 6c 2c 20 30 2c 20 73 69 7a  set(&val, 0, siz
ae40: 65 6f 66 28 46 74 73 35 42 75 66 66 65 72 29 29  eof(Fts5Buffer))
ae50: 3b 0a 0a 20 20 2f 2a 20 41 70 70 65 6e 64 20 74  ;..  /* Append t
ae60: 68 65 20 76 61 72 69 6e 74 73 20 2a 2f 0a 20 20  he varints */.  
ae70: 66 6f 72 28 69 3d 30 3b 20 69 3c 28 6e 50 68 72  for(i=0; i<(nPhr
ae80: 61 73 65 2d 31 29 3b 20 69 2b 2b 29 7b 0a 20 20  ase-1); i++){.  
ae90: 20 20 63 6f 6e 73 74 20 75 38 20 2a 64 75 6d 6d    const u8 *dumm
aea0: 79 3b 0a 20 20 20 20 69 6e 74 20 6e 42 79 74 65  y;.    int nByte
aeb0: 20 3d 20 73 71 6c 69 74 65 33 46 74 73 35 45 78   = sqlite3Fts5Ex
aec0: 70 72 50 6f 73 6c 69 73 74 28 70 43 73 72 2d 3e  prPoslist(pCsr->
aed0: 70 45 78 70 72 2c 20 69 2c 20 26 64 75 6d 6d 79  pExpr, i, &dummy
aee0: 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 46 74  );.    sqlite3Ft
aef0: 73 35 42 75 66 66 65 72 41 70 70 65 6e 64 56 61  s5BufferAppendVa
af00: 72 69 6e 74 28 26 72 63 2c 20 26 76 61 6c 2c 20  rint(&rc, &val, 
af10: 6e 42 79 74 65 29 3b 0a 20 20 7d 0a 0a 20 20 2f  nByte);.  }..  /
af20: 2a 20 41 70 70 65 6e 64 20 74 68 65 20 70 6f 73  * Append the pos
af30: 69 74 69 6f 6e 20 6c 69 73 74 73 20 2a 2f 0a 20  ition lists */. 
af40: 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 50 68 72   for(i=0; i<nPhr
af50: 61 73 65 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 63  ase; i++){.    c
af60: 6f 6e 73 74 20 75 38 20 2a 70 50 6f 73 6c 69 73  onst u8 *pPoslis
af70: 74 3b 0a 20 20 20 20 69 6e 74 20 6e 50 6f 73 6c  t;.    int nPosl
af80: 69 73 74 3b 0a 20 20 20 20 6e 50 6f 73 6c 69 73  ist;.    nPoslis
af90: 74 20 3d 20 73 71 6c 69 74 65 33 46 74 73 35 45  t = sqlite3Fts5E
afa0: 78 70 72 50 6f 73 6c 69 73 74 28 70 43 73 72 2d  xprPoslist(pCsr-
afb0: 3e 70 45 78 70 72 2c 20 69 2c 20 26 70 50 6f 73  >pExpr, i, &pPos
afc0: 6c 69 73 74 29 3b 0a 20 20 20 20 73 71 6c 69 74  list);.    sqlit
afd0: 65 33 46 74 73 35 42 75 66 66 65 72 41 70 70 65  e3Fts5BufferAppe
afe0: 6e 64 42 6c 6f 62 28 26 72 63 2c 20 26 76 61 6c  ndBlob(&rc, &val
aff0: 2c 20 6e 50 6f 73 6c 69 73 74 2c 20 70 50 6f 73  , nPoslist, pPos
b000: 6c 69 73 74 29 3b 0a 20 20 7d 0a 0a 20 20 73 71  list);.  }..  sq
b010: 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 62 6c 6f  lite3_result_blo
b020: 62 28 70 43 74 78 2c 20 76 61 6c 2e 70 2c 20 76  b(pCtx, val.p, v
b030: 61 6c 2e 6e 2c 20 73 71 6c 69 74 65 33 5f 66 72  al.n, sqlite3_fr
b040: 65 65 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63  ee);.  return rc
b050: 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 54 68 69 73  ;.}../* .** This
b060: 20 69 73 20 74 68 65 20 78 43 6f 6c 75 6d 6e 20   is the xColumn 
b070: 6d 65 74 68 6f 64 2c 20 63 61 6c 6c 65 64 20 62  method, called b
b080: 79 20 53 51 4c 69 74 65 20 74 6f 20 72 65 71 75  y SQLite to requ
b090: 65 73 74 20 61 20 76 61 6c 75 65 20 66 72 6f 6d  est a value from
b0a0: 0a 2a 2a 20 74 68 65 20 72 6f 77 20 74 68 61 74  .** the row that
b0b0: 20 74 68 65 20 73 75 70 70 6c 69 65 64 20 63 75   the supplied cu
b0c0: 72 73 6f 72 20 63 75 72 72 65 6e 74 6c 79 20 70  rsor currently p
b0d0: 6f 69 6e 74 73 20 74 6f 2e 0a 2a 2f 0a 73 74 61  oints to..*/.sta
b0e0: 74 69 63 20 69 6e 74 20 66 74 73 35 43 6f 6c 75  tic int fts5Colu
b0f0: 6d 6e 4d 65 74 68 6f 64 28 0a 20 20 73 71 6c 69  mnMethod(.  sqli
b100: 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20  te3_vtab_cursor 
b110: 2a 70 43 75 72 73 6f 72 2c 20 20 20 2f 2a 20 43  *pCursor,   /* C
b120: 75 72 73 6f 72 20 74 6f 20 72 65 74 72 69 65 76  ursor to retriev
b130: 65 20 76 61 6c 75 65 20 66 72 6f 6d 20 2a 2f 0a  e value from */.
b140: 20 20 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78    sqlite3_contex
b150: 74 20 2a 70 43 74 78 2c 20 20 20 20 20 20 20 20  t *pCtx,        
b160: 20 20 2f 2a 20 43 6f 6e 74 65 78 74 20 66 6f 72    /* Context for
b170: 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f   sqlite3_result_
b180: 78 78 78 28 29 20 63 61 6c 6c 73 20 2a 2f 0a 20  xxx() calls */. 
b190: 20 69 6e 74 20 69 43 6f 6c 20 20 20 20 20 20 20   int iCol       
b1a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b1b0: 20 2f 2a 20 49 6e 64 65 78 20 6f 66 20 63 6f 6c   /* Index of col
b1c0: 75 6d 6e 20 74 6f 20 72 65 61 64 20 76 61 6c 75  umn to read valu
b1d0: 65 20 66 72 6f 6d 20 2a 2f 0a 29 7b 0a 20 20 46  e from */.){.  F
b1e0: 74 73 35 43 6f 6e 66 69 67 20 2a 70 43 6f 6e 66  ts5Config *pConf
b1f0: 69 67 20 3d 20 28 28 46 74 73 35 54 61 62 6c 65  ig = ((Fts5Table
b200: 2a 29 28 70 43 75 72 73 6f 72 2d 3e 70 56 74 61  *)(pCursor->pVta
b210: 62 29 29 2d 3e 70 43 6f 6e 66 69 67 3b 0a 20 20  b))->pConfig;.  
b220: 46 74 73 35 43 75 72 73 6f 72 20 2a 70 43 73 72  Fts5Cursor *pCsr
b230: 20 3d 20 28 46 74 73 35 43 75 72 73 6f 72 2a 29   = (Fts5Cursor*)
b240: 70 43 75 72 73 6f 72 3b 0a 20 20 69 6e 74 20 72  pCursor;.  int r
b250: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  c = SQLITE_OK;. 
b260: 20 0a 20 20 61 73 73 65 72 74 28 20 43 73 72 46   .  assert( CsrF
b270: 6c 61 67 54 65 73 74 28 70 43 73 72 2c 20 46 54  lagTest(pCsr, FT
b280: 53 35 43 53 52 5f 45 4f 46 29 3d 3d 30 20 29 3b  S5CSR_EOF)==0 );
b290: 0a 0a 20 20 69 66 28 20 70 43 73 72 2d 3e 69 64  ..  if( pCsr->id
b2a0: 78 4e 75 6d 3d 3d 46 54 53 35 5f 50 4c 41 4e 5f  xNum==FTS5_PLAN_
b2b0: 53 50 45 43 49 41 4c 20 29 7b 0a 20 20 20 20 69  SPECIAL ){.    i
b2c0: 66 28 20 69 43 6f 6c 3d 3d 70 43 6f 6e 66 69 67  f( iCol==pConfig
b2d0: 2d 3e 6e 43 6f 6c 20 29 7b 0a 20 20 20 20 20 20  ->nCol ){.      
b2e0: 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 74  sqlite3_result_t
b2f0: 65 78 74 28 70 43 74 78 2c 20 70 43 73 72 2d 3e  ext(pCtx, pCsr->
b300: 7a 53 70 65 63 69 61 6c 2c 20 2d 31 2c 20 53 51  zSpecial, -1, SQ
b310: 4c 49 54 45 5f 54 52 41 4e 53 49 45 4e 54 29 3b  LITE_TRANSIENT);
b320: 0a 20 20 20 20 7d 0a 20 20 7d 65 6c 73 65 0a 0a  .    }.  }else..
b330: 20 20 69 66 28 20 69 43 6f 6c 3d 3d 70 43 6f 6e    if( iCol==pCon
b340: 66 69 67 2d 3e 6e 43 6f 6c 20 29 7b 0a 20 20 20  fig->nCol ){.   
b350: 20 2f 2a 20 55 73 65 72 20 69 73 20 72 65 71 75   /* User is requ
b360: 65 73 74 69 6e 67 20 74 68 65 20 76 61 6c 75 65  esting the value
b370: 20 6f 66 20 74 68 65 20 73 70 65 63 69 61 6c 20   of the special 
b380: 63 6f 6c 75 6d 6e 20 77 69 74 68 20 74 68 65 20  column with the 
b390: 73 61 6d 65 20 6e 61 6d 65 0a 20 20 20 20 2a 2a  same name.    **
b3a0: 20 61 73 20 74 68 65 20 74 61 62 6c 65 2e 20 52   as the table. R
b3b0: 65 74 75 72 6e 20 74 68 65 20 63 75 72 73 6f 72  eturn the cursor
b3c0: 20 69 6e 74 65 67 65 72 20 69 64 20 6e 75 6d 62   integer id numb
b3d0: 65 72 2e 20 54 68 69 73 20 76 61 6c 75 65 20 69  er. This value i
b3e0: 73 20 6f 6e 6c 79 0a 20 20 20 20 2a 2a 20 75 73  s only.    ** us
b3f0: 65 66 75 6c 20 69 6e 20 74 68 61 74 20 69 74 20  eful in that it 
b400: 6d 61 79 20 62 65 20 70 61 73 73 65 64 20 61 73  may be passed as
b410: 20 74 68 65 20 66 69 72 73 74 20 61 72 67 75 6d   the first argum
b420: 65 6e 74 20 74 6f 20 61 6e 20 46 54 53 35 0a 20  ent to an FTS5. 
b430: 20 20 20 2a 2a 20 61 75 78 69 6c 69 61 72 79 20     ** auxiliary 
b440: 66 75 6e 63 74 69 6f 6e 2e 20 20 2a 2f 0a 20 20  function.  */.  
b450: 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74    sqlite3_result
b460: 5f 69 6e 74 36 34 28 70 43 74 78 2c 20 70 43 73  _int64(pCtx, pCs
b470: 72 2d 3e 69 43 73 72 49 64 29 3b 0a 20 20 7d 65  r->iCsrId);.  }e
b480: 6c 73 65 20 69 66 28 20 69 43 6f 6c 3d 3d 70 43  lse if( iCol==pC
b490: 6f 6e 66 69 67 2d 3e 6e 43 6f 6c 2b 31 20 29 7b  onfig->nCol+1 ){
b4a0: 0a 0a 20 20 20 20 2f 2a 20 54 68 65 20 76 61 6c  ..    /* The val
b4b0: 75 65 20 6f 66 20 74 68 65 20 22 72 61 6e 6b 22  ue of the "rank"
b4c0: 20 63 6f 6c 75 6d 6e 2e 20 2a 2f 0a 20 20 20 20   column. */.    
b4d0: 69 66 28 20 46 54 53 35 5f 50 4c 41 4e 28 70 43  if( FTS5_PLAN(pC
b4e0: 73 72 2d 3e 69 64 78 4e 75 6d 29 3d 3d 46 54 53  sr->idxNum)==FTS
b4f0: 35 5f 50 4c 41 4e 5f 53 4f 55 52 43 45 20 29 7b  5_PLAN_SOURCE ){
b500: 0a 20 20 20 20 20 20 66 74 73 35 50 6f 73 6c 69  .      fts5Posli
b510: 73 74 42 6c 6f 62 28 70 43 74 78 2c 20 70 43 73  stBlob(pCtx, pCs
b520: 72 29 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66  r);.    }else if
b530: 28 20 0a 20 20 20 20 20 20 20 20 46 54 53 35 5f  ( .        FTS5_
b540: 50 4c 41 4e 28 70 43 73 72 2d 3e 69 64 78 4e 75  PLAN(pCsr->idxNu
b550: 6d 29 3d 3d 46 54 53 35 5f 50 4c 41 4e 5f 4d 41  m)==FTS5_PLAN_MA
b560: 54 43 48 0a 20 20 20 20 20 7c 7c 20 46 54 53 35  TCH.     || FTS5
b570: 5f 50 4c 41 4e 28 70 43 73 72 2d 3e 69 64 78 4e  _PLAN(pCsr->idxN
b580: 75 6d 29 3d 3d 46 54 53 35 5f 50 4c 41 4e 5f 53  um)==FTS5_PLAN_S
b590: 4f 52 54 45 44 5f 4d 41 54 43 48 0a 20 20 20 20  ORTED_MATCH.    
b5a0: 29 7b 0a 20 20 20 20 20 20 69 66 28 20 70 43 73  ){.      if( pCs
b5b0: 72 2d 3e 70 52 61 6e 6b 20 7c 7c 20 53 51 4c 49  r->pRank || SQLI
b5c0: 54 45 5f 4f 4b 3d 3d 28 72 63 20 3d 20 66 74 73  TE_OK==(rc = fts
b5d0: 35 46 69 6e 64 52 61 6e 6b 46 75 6e 63 74 69 6f  5FindRankFunctio
b5e0: 6e 28 70 43 73 72 29 29 20 29 7b 0a 20 20 20 20  n(pCsr)) ){.    
b5f0: 20 20 20 20 66 74 73 35 41 70 69 49 6e 76 6f 6b      fts5ApiInvok
b600: 65 28 70 43 73 72 2d 3e 70 52 61 6e 6b 2c 20 70  e(pCsr->pRank, p
b610: 43 73 72 2c 20 70 43 74 78 2c 20 70 43 73 72 2d  Csr, pCtx, pCsr-
b620: 3e 6e 52 61 6e 6b 41 72 67 2c 20 70 43 73 72 2d  >nRankArg, pCsr-
b630: 3e 61 70 52 61 6e 6b 41 72 67 29 3b 0a 20 20 20  >apRankArg);.   
b640: 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 65 6c     }.    }.  }el
b650: 73 65 7b 0a 20 20 20 20 72 63 20 3d 20 66 74 73  se{.    rc = fts
b660: 35 53 65 65 6b 43 75 72 73 6f 72 28 70 43 73 72  5SeekCursor(pCsr
b670: 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53  );.    if( rc==S
b680: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
b690: 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74    sqlite3_result
b6a0: 5f 76 61 6c 75 65 28 70 43 74 78 2c 20 73 71 6c  _value(pCtx, sql
b6b0: 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 76 61 6c 75  ite3_column_valu
b6c0: 65 28 70 43 73 72 2d 3e 70 53 74 6d 74 2c 20 69  e(pCsr->pStmt, i
b6d0: 43 6f 6c 2b 31 29 29 3b 0a 20 20 20 20 7d 0a 20  Col+1));.    }. 
b6e0: 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a   }.  return rc;.
b6f0: 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 72  }.../*.** This r
b700: 6f 75 74 69 6e 65 20 69 6d 70 6c 65 6d 65 6e 74  outine implement
b710: 73 20 74 68 65 20 78 46 69 6e 64 46 75 6e 63 74  s the xFindFunct
b720: 69 6f 6e 20 6d 65 74 68 6f 64 20 66 6f 72 20 74  ion method for t
b730: 68 65 20 46 54 53 33 0a 2a 2a 20 76 69 72 74 75  he FTS3.** virtu
b740: 61 6c 20 74 61 62 6c 65 2e 0a 2a 2f 0a 73 74 61  al table..*/.sta
b750: 74 69 63 20 69 6e 74 20 66 74 73 35 46 69 6e 64  tic int fts5Find
b760: 46 75 6e 63 74 69 6f 6e 4d 65 74 68 6f 64 28 0a  FunctionMethod(.
b770: 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a    sqlite3_vtab *
b780: 70 56 74 61 62 2c 20 20 20 20 20 20 20 20 20 20  pVtab,          
b790: 20 20 2f 2a 20 56 69 72 74 75 61 6c 20 74 61 62    /* Virtual tab
b7a0: 6c 65 20 68 61 6e 64 6c 65 20 2a 2f 0a 20 20 69  le handle */.  i
b7b0: 6e 74 20 6e 41 72 67 2c 20 20 20 20 20 20 20 20  nt nArg,        
b7c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
b7d0: 2a 20 4e 75 6d 62 65 72 20 6f 66 20 53 51 4c 20  * Number of SQL 
b7e0: 66 75 6e 63 74 69 6f 6e 20 61 72 67 75 6d 65 6e  function argumen
b7f0: 74 73 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68  ts */.  const ch
b800: 61 72 20 2a 7a 4e 61 6d 65 2c 20 20 20 20 20 20  ar *zName,      
b810: 20 20 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65 20          /* Name 
b820: 6f 66 20 53 51 4c 20 66 75 6e 63 74 69 6f 6e 20  of SQL function 
b830: 2a 2f 0a 20 20 76 6f 69 64 20 28 2a 2a 70 78 46  */.  void (**pxF
b840: 75 6e 63 29 28 73 71 6c 69 74 65 33 5f 63 6f 6e  unc)(sqlite3_con
b850: 74 65 78 74 2a 2c 69 6e 74 2c 73 71 6c 69 74 65  text*,int,sqlite
b860: 33 5f 76 61 6c 75 65 2a 2a 29 2c 20 2f 2a 20 4f  3_value**), /* O
b870: 55 54 3a 20 52 65 73 75 6c 74 20 2a 2f 0a 20 20  UT: Result */.  
b880: 76 6f 69 64 20 2a 2a 70 70 41 72 67 20 20 20 20  void **ppArg    
b890: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b8a0: 2f 2a 20 4f 55 54 3a 20 55 73 65 72 20 64 61 74  /* OUT: User dat
b8b0: 61 20 66 6f 72 20 2a 70 78 46 75 6e 63 20 2a 2f  a for *pxFunc */
b8c0: 0a 29 7b 0a 20 20 46 74 73 35 54 61 62 6c 65 20  .){.  Fts5Table 
b8d0: 2a 70 54 61 62 20 3d 20 28 46 74 73 35 54 61 62  *pTab = (Fts5Tab
b8e0: 6c 65 2a 29 70 56 74 61 62 3b 0a 20 20 46 74 73  le*)pVtab;.  Fts
b8f0: 35 41 75 78 69 6c 69 61 72 79 20 2a 70 41 75 78  5Auxiliary *pAux
b900: 3b 0a 0a 20 20 70 41 75 78 20 3d 20 66 74 73 35  ;..  pAux = fts5
b910: 46 69 6e 64 41 75 78 69 6c 69 61 72 79 28 70 54  FindAuxiliary(pT
b920: 61 62 2c 20 7a 4e 61 6d 65 29 3b 0a 20 20 69 66  ab, zName);.  if
b930: 28 20 70 41 75 78 20 29 7b 0a 20 20 20 20 2a 70  ( pAux ){.    *p
b940: 78 46 75 6e 63 20 3d 20 66 74 73 35 41 70 69 43  xFunc = fts5ApiC
b950: 61 6c 6c 62 61 63 6b 3b 0a 20 20 20 20 2a 70 70  allback;.    *pp
b960: 41 72 67 20 3d 20 28 76 6f 69 64 2a 29 70 41 75  Arg = (void*)pAu
b970: 78 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 31 3b  x;.    return 1;
b980: 0a 20 20 7d 0a 0a 20 20 2f 2a 20 4e 6f 20 66 75  .  }..  /* No fu
b990: 6e 63 74 69 6f 6e 20 6f 66 20 74 68 65 20 73 70  nction of the sp
b9a0: 65 63 69 66 69 65 64 20 6e 61 6d 65 20 77 61 73  ecified name was
b9b0: 20 66 6f 75 6e 64 2e 20 52 65 74 75 72 6e 20 30   found. Return 0
b9c0: 2e 20 2a 2f 0a 20 20 72 65 74 75 72 6e 20 30 3b  . */.  return 0;
b9d0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d  .}../*.** Implem
b9e0: 65 6e 74 61 74 69 6f 6e 20 6f 66 20 46 54 53 33  entation of FTS3
b9f0: 20 78 52 65 6e 61 6d 65 20 6d 65 74 68 6f 64 2e   xRename method.
ba00: 20 52 65 6e 61 6d 65 20 61 6e 20 66 74 73 35 20   Rename an fts5 
ba10: 74 61 62 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63  table..*/.static
ba20: 20 69 6e 74 20 66 74 73 35 52 65 6e 61 6d 65 4d   int fts5RenameM
ba30: 65 74 68 6f 64 28 0a 20 20 73 71 6c 69 74 65 33  ethod(.  sqlite3
ba40: 5f 76 74 61 62 20 2a 70 56 74 61 62 2c 20 20 20  _vtab *pVtab,   
ba50: 20 20 20 20 20 20 20 20 20 2f 2a 20 56 69 72 74           /* Virt
ba60: 75 61 6c 20 74 61 62 6c 65 20 68 61 6e 64 6c 65  ual table handle
ba70: 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72   */.  const char
ba80: 20 2a 7a 4e 61 6d 65 20 20 20 20 20 20 20 20 20   *zName         
ba90: 20 20 20 20 20 20 2f 2a 20 4e 65 77 20 6e 61 6d        /* New nam
baa0: 65 20 6f 66 20 74 61 62 6c 65 20 2a 2f 0a 29 7b  e of table */.){
bab0: 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49  .  int rc = SQLI
bac0: 54 45 5f 4f 4b 3b 0a 20 20 72 65 74 75 72 6e 20  TE_OK;.  return 
bad0: 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65  rc;.}../*.** The
bae0: 20 78 53 61 76 65 70 6f 69 6e 74 28 29 20 6d 65   xSavepoint() me
baf0: 74 68 6f 64 2e 0a 2a 2a 0a 2a 2a 20 46 6c 75 73  thod..**.** Flus
bb00: 68 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f  h the contents o
bb10: 66 20 74 68 65 20 70 65 6e 64 69 6e 67 2d 74 65  f the pending-te
bb20: 72 6d 73 20 74 61 62 6c 65 20 74 6f 20 64 69 73  rms table to dis
bb30: 6b 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  k..*/.static int
bb40: 20 66 74 73 35 53 61 76 65 70 6f 69 6e 74 4d 65   fts5SavepointMe
bb50: 74 68 6f 64 28 73 71 6c 69 74 65 33 5f 76 74 61  thod(sqlite3_vta
bb60: 62 20 2a 70 56 74 61 62 2c 20 69 6e 74 20 69 53  b *pVtab, int iS
bb70: 61 76 65 70 6f 69 6e 74 29 7b 0a 20 20 46 74 73  avepoint){.  Fts
bb80: 35 54 61 62 6c 65 20 2a 70 54 61 62 20 3d 20 28  5Table *pTab = (
bb90: 46 74 73 35 54 61 62 6c 65 2a 29 70 56 74 61 62  Fts5Table*)pVtab
bba0: 3b 0a 20 20 66 74 73 35 43 68 65 63 6b 54 72 61  ;.  fts5CheckTra
bbb0: 6e 73 61 63 74 69 6f 6e 53 74 61 74 65 28 70 54  nsactionState(pT
bbc0: 61 62 2c 20 46 54 53 35 5f 53 41 56 45 50 4f 49  ab, FTS5_SAVEPOI
bbd0: 4e 54 2c 20 69 53 61 76 65 70 6f 69 6e 74 29 3b  NT, iSavepoint);
bbe0: 0a 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74 65  .  return sqlite
bbf0: 33 46 74 73 35 53 74 6f 72 61 67 65 53 79 6e 63  3Fts5StorageSync
bc00: 28 70 54 61 62 2d 3e 70 53 74 6f 72 61 67 65 2c  (pTab->pStorage,
bc10: 20 30 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68   0);.}../*.** Th
bc20: 65 20 78 52 65 6c 65 61 73 65 28 29 20 6d 65 74  e xRelease() met
bc30: 68 6f 64 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20  hod..**.** This 
bc40: 69 73 20 61 20 6e 6f 2d 6f 70 2e 0a 2a 2f 0a 73  is a no-op..*/.s
bc50: 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 52 65  tatic int fts5Re
bc60: 6c 65 61 73 65 4d 65 74 68 6f 64 28 73 71 6c 69  leaseMethod(sqli
bc70: 74 65 33 5f 76 74 61 62 20 2a 70 56 74 61 62 2c  te3_vtab *pVtab,
bc80: 20 69 6e 74 20 69 53 61 76 65 70 6f 69 6e 74 29   int iSavepoint)
bc90: 7b 0a 20 20 46 74 73 35 54 61 62 6c 65 20 2a 70  {.  Fts5Table *p
bca0: 54 61 62 20 3d 20 28 46 74 73 35 54 61 62 6c 65  Tab = (Fts5Table
bcb0: 2a 29 70 56 74 61 62 3b 0a 20 20 66 74 73 35 43  *)pVtab;.  fts5C
bcc0: 68 65 63 6b 54 72 61 6e 73 61 63 74 69 6f 6e 53  heckTransactionS
bcd0: 74 61 74 65 28 70 54 61 62 2c 20 46 54 53 35 5f  tate(pTab, FTS5_
bce0: 52 45 4c 45 41 53 45 2c 20 69 53 61 76 65 70 6f  RELEASE, iSavepo
bcf0: 69 6e 74 29 3b 0a 20 20 72 65 74 75 72 6e 20 73  int);.  return s
bd00: 71 6c 69 74 65 33 46 74 73 35 53 74 6f 72 61 67  qlite3Fts5Storag
bd10: 65 53 79 6e 63 28 70 54 61 62 2d 3e 70 53 74 6f  eSync(pTab->pSto
bd20: 72 61 67 65 2c 20 30 29 3b 0a 7d 0a 0a 2f 2a 0a  rage, 0);.}../*.
bd30: 2a 2a 20 54 68 65 20 78 52 6f 6c 6c 62 61 63 6b  ** The xRollback
bd40: 54 6f 28 29 20 6d 65 74 68 6f 64 2e 0a 2a 2a 0a  To() method..**.
bd50: 2a 2a 20 44 69 73 63 61 72 64 20 74 68 65 20 63  ** Discard the c
bd60: 6f 6e 74 65 6e 74 73 20 6f 66 20 74 68 65 20 70  ontents of the p
bd70: 65 6e 64 69 6e 67 20 74 65 72 6d 73 20 74 61 62  ending terms tab
bd80: 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  le..*/.static in
bd90: 74 20 66 74 73 35 52 6f 6c 6c 62 61 63 6b 54 6f  t fts5RollbackTo
bda0: 4d 65 74 68 6f 64 28 73 71 6c 69 74 65 33 5f 76  Method(sqlite3_v
bdb0: 74 61 62 20 2a 70 56 74 61 62 2c 20 69 6e 74 20  tab *pVtab, int 
bdc0: 69 53 61 76 65 70 6f 69 6e 74 29 7b 0a 20 20 46  iSavepoint){.  F
bdd0: 74 73 35 54 61 62 6c 65 20 2a 70 54 61 62 20 3d  ts5Table *pTab =
bde0: 20 28 46 74 73 35 54 61 62 6c 65 2a 29 70 56 74   (Fts5Table*)pVt
bdf0: 61 62 3b 0a 20 20 66 74 73 35 43 68 65 63 6b 54  ab;.  fts5CheckT
be00: 72 61 6e 73 61 63 74 69 6f 6e 53 74 61 74 65 28  ransactionState(
be10: 70 54 61 62 2c 20 46 54 53 35 5f 52 4f 4c 4c 42  pTab, FTS5_ROLLB
be20: 41 43 4b 54 4f 2c 20 69 53 61 76 65 70 6f 69 6e  ACKTO, iSavepoin
be30: 74 29 3b 0a 20 20 72 65 74 75 72 6e 20 73 71 6c  t);.  return sql
be40: 69 74 65 33 46 74 73 35 53 74 6f 72 61 67 65 52  ite3Fts5StorageR
be50: 6f 6c 6c 62 61 63 6b 28 70 54 61 62 2d 3e 70 53  ollback(pTab->pS
be60: 74 6f 72 61 67 65 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  torage);.}../*.*
be70: 2a 20 52 65 67 69 73 74 65 72 20 61 20 6e 65 77  * Register a new
be80: 20 61 75 78 69 6c 69 61 72 79 20 66 75 6e 63 74   auxiliary funct
be90: 69 6f 6e 20 77 69 74 68 20 67 6c 6f 62 61 6c 20  ion with global 
bea0: 63 6f 6e 74 65 78 74 20 70 47 6c 6f 62 61 6c 2e  context pGlobal.
beb0: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66  .*/.static int f
bec0: 74 73 35 43 72 65 61 74 65 41 75 78 28 0a 20 20  ts5CreateAux(.  
bed0: 66 74 73 35 5f 61 70 69 20 2a 70 41 70 69 2c 20  fts5_api *pApi, 
bee0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
bef0: 2f 2a 20 47 6c 6f 62 61 6c 20 63 6f 6e 74 65 78  /* Global contex
bf00: 74 20 28 6f 6e 65 20 70 65 72 20 64 62 20 68 61  t (one per db ha
bf10: 6e 64 6c 65 29 20 2a 2f 0a 20 20 63 6f 6e 73 74  ndle) */.  const
bf20: 20 63 68 61 72 20 2a 7a 4e 61 6d 65 2c 20 20 20   char *zName,   
bf30: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 61             /* Na
bf40: 6d 65 20 6f 66 20 6e 65 77 20 66 75 6e 63 74 69  me of new functi
bf50: 6f 6e 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 55  on */.  void *pU
bf60: 73 65 72 44 61 74 61 2c 20 20 20 20 20 20 20 20  serData,        
bf70: 20 20 20 20 20 20 20 20 2f 2a 20 55 73 65 72 20          /* User 
bf80: 64 61 74 61 20 66 6f 72 20 61 75 78 2e 20 66 75  data for aux. fu
bf90: 6e 63 74 69 6f 6e 20 2a 2f 0a 20 20 66 74 73 35  nction */.  fts5
bfa0: 5f 65 78 74 65 6e 73 69 6f 6e 5f 66 75 6e 63 74  _extension_funct
bfb0: 69 6f 6e 20 78 46 75 6e 63 2c 20 20 2f 2a 20 41  ion xFunc,  /* A
bfc0: 75 78 2e 20 66 75 6e 63 74 69 6f 6e 20 69 6d 70  ux. function imp
bfd0: 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 2a 2f 0a 20  lementation */. 
bfe0: 20 76 6f 69 64 28 2a 78 44 65 73 74 72 6f 79 29   void(*xDestroy)
bff0: 28 76 6f 69 64 2a 29 20 20 20 20 20 20 20 20 20  (void*)         
c000: 20 2f 2a 20 44 65 73 74 72 75 63 74 6f 72 20 66   /* Destructor f
c010: 6f 72 20 70 55 73 65 72 44 61 74 61 20 2a 2f 0a  or pUserData */.
c020: 29 7b 0a 20 20 46 74 73 35 47 6c 6f 62 61 6c 20  ){.  Fts5Global 
c030: 2a 70 47 6c 6f 62 61 6c 20 3d 20 28 46 74 73 35  *pGlobal = (Fts5
c040: 47 6c 6f 62 61 6c 2a 29 70 41 70 69 3b 0a 20 20  Global*)pApi;.  
c050: 69 6e 74 20 72 63 20 3d 20 73 71 6c 69 74 65 33  int rc = sqlite3
c060: 5f 6f 76 65 72 6c 6f 61 64 5f 66 75 6e 63 74 69  _overload_functi
c070: 6f 6e 28 70 47 6c 6f 62 61 6c 2d 3e 64 62 2c 20  on(pGlobal->db, 
c080: 7a 4e 61 6d 65 2c 20 2d 31 29 3b 0a 20 20 69 66  zName, -1);.  if
c090: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
c0a0: 29 7b 0a 20 20 20 20 46 74 73 35 41 75 78 69 6c  ){.    Fts5Auxil
c0b0: 69 61 72 79 20 2a 70 41 75 78 3b 0a 20 20 20 20  iary *pAux;.    
c0c0: 69 6e 74 20 6e 42 79 74 65 3b 20 20 20 20 20 20  int nByte;      
c0d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c0e0: 2f 2a 20 42 79 74 65 73 20 6f 66 20 73 70 61 63  /* Bytes of spac
c0f0: 65 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20 2a 2f  e to allocate */
c100: 0a 0a 20 20 20 20 6e 42 79 74 65 20 3d 20 73 69  ..    nByte = si
c110: 7a 65 6f 66 28 46 74 73 35 41 75 78 69 6c 69 61  zeof(Fts5Auxilia
c120: 72 79 29 20 2b 20 73 74 72 6c 65 6e 28 7a 4e 61  ry) + strlen(zNa
c130: 6d 65 29 20 2b 20 31 3b 0a 20 20 20 20 70 41 75  me) + 1;.    pAu
c140: 78 20 3d 20 28 46 74 73 35 41 75 78 69 6c 69 61  x = (Fts5Auxilia
c150: 72 79 2a 29 73 71 6c 69 74 65 33 5f 6d 61 6c 6c  ry*)sqlite3_mall
c160: 6f 63 28 6e 42 79 74 65 29 3b 0a 20 20 20 20 69  oc(nByte);.    i
c170: 66 28 20 70 41 75 78 20 29 7b 0a 20 20 20 20 20  f( pAux ){.     
c180: 20 6d 65 6d 73 65 74 28 70 41 75 78 2c 20 30 2c   memset(pAux, 0,
c190: 20 6e 42 79 74 65 29 3b 0a 20 20 20 20 20 20 70   nByte);.      p
c1a0: 41 75 78 2d 3e 7a 46 75 6e 63 20 3d 20 28 63 68  Aux->zFunc = (ch
c1b0: 61 72 2a 29 26 70 41 75 78 5b 31 5d 3b 0a 20 20  ar*)&pAux[1];.  
c1c0: 20 20 20 20 73 74 72 63 70 79 28 70 41 75 78 2d      strcpy(pAux-
c1d0: 3e 7a 46 75 6e 63 2c 20 7a 4e 61 6d 65 29 3b 0a  >zFunc, zName);.
c1e0: 20 20 20 20 20 20 70 41 75 78 2d 3e 70 47 6c 6f        pAux->pGlo
c1f0: 62 61 6c 20 3d 20 70 47 6c 6f 62 61 6c 3b 0a 20  bal = pGlobal;. 
c200: 20 20 20 20 20 70 41 75 78 2d 3e 70 55 73 65 72       pAux->pUser
c210: 44 61 74 61 20 3d 20 70 55 73 65 72 44 61 74 61  Data = pUserData
c220: 3b 0a 20 20 20 20 20 20 70 41 75 78 2d 3e 78 46  ;.      pAux->xF
c230: 75 6e 63 20 3d 20 78 46 75 6e 63 3b 0a 20 20 20  unc = xFunc;.   
c240: 20 20 20 70 41 75 78 2d 3e 78 44 65 73 74 72 6f     pAux->xDestro
c250: 79 20 3d 20 78 44 65 73 74 72 6f 79 3b 0a 20 20  y = xDestroy;.  
c260: 20 20 20 20 70 41 75 78 2d 3e 70 4e 65 78 74 20      pAux->pNext 
c270: 3d 20 70 47 6c 6f 62 61 6c 2d 3e 70 41 75 78 3b  = pGlobal->pAux;
c280: 0a 20 20 20 20 20 20 70 47 6c 6f 62 61 6c 2d 3e  .      pGlobal->
c290: 70 41 75 78 20 3d 20 70 41 75 78 3b 0a 20 20 20  pAux = pAux;.   
c2a0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 72 63   }else{.      rc
c2b0: 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b   = SQLITE_NOMEM;
c2c0: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65  .    }.  }..  re
c2d0: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
c2e0: 2a 20 52 65 67 69 73 74 65 72 20 61 20 6e 65 77  * Register a new
c2f0: 20 74 6f 6b 65 6e 69 7a 65 72 2e 20 54 68 69 73   tokenizer. This
c300: 20 69 73 20 74 68 65 20 69 6d 70 6c 65 6d 65 6e   is the implemen
c310: 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 0a 2a  tation of the .*
c320: 2a 20 66 74 73 35 5f 61 70 69 2e 78 43 72 65 61  * fts5_api.xCrea
c330: 74 65 54 6f 6b 65 6e 69 7a 65 72 28 29 20 6d 65  teTokenizer() me
c340: 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  thod..*/.static 
c350: 69 6e 74 20 66 74 73 35 43 72 65 61 74 65 54 6f  int fts5CreateTo
c360: 6b 65 6e 69 7a 65 72 28 0a 20 20 66 74 73 35 5f  kenizer(.  fts5_
c370: 61 70 69 20 2a 70 41 70 69 2c 20 20 20 20 20 20  api *pApi,      
c380: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 47 6c             /* Gl
c390: 6f 62 61 6c 20 63 6f 6e 74 65 78 74 20 28 6f 6e  obal context (on
c3a0: 65 20 70 65 72 20 64 62 20 68 61 6e 64 6c 65 29  e per db handle)
c3b0: 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72   */.  const char
c3c0: 20 2a 7a 4e 61 6d 65 2c 20 20 20 20 20 20 20 20   *zName,        
c3d0: 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66        /* Name of
c3e0: 20 6e 65 77 20 66 75 6e 63 74 69 6f 6e 20 2a 2f   new function */
c3f0: 0a 20 20 76 6f 69 64 20 2a 70 55 73 65 72 44 61  .  void *pUserDa
c400: 74 61 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ta,             
c410: 20 20 20 2f 2a 20 55 73 65 72 20 64 61 74 61 20     /* User data 
c420: 66 6f 72 20 61 75 78 2e 20 66 75 6e 63 74 69 6f  for aux. functio
c430: 6e 20 2a 2f 0a 20 20 66 74 73 35 5f 74 6f 6b 65  n */.  fts5_toke
c440: 6e 69 7a 65 72 20 2a 70 54 6f 6b 65 6e 69 7a 65  nizer *pTokenize
c450: 72 2c 20 20 20 20 20 2f 2a 20 54 6f 6b 65 6e 69  r,     /* Tokeni
c460: 7a 65 72 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69  zer implementati
c470: 6f 6e 20 2a 2f 0a 20 20 76 6f 69 64 28 2a 78 44  on */.  void(*xD
c480: 65 73 74 72 6f 79 29 28 76 6f 69 64 2a 29 20 20  estroy)(void*)  
c490: 20 20 20 20 20 20 20 20 2f 2a 20 44 65 73 74 72          /* Destr
c4a0: 75 63 74 6f 72 20 66 6f 72 20 70 55 73 65 72 44  uctor for pUserD
c4b0: 61 74 61 20 2a 2f 0a 29 7b 0a 20 20 46 74 73 35  ata */.){.  Fts5
c4c0: 47 6c 6f 62 61 6c 20 2a 70 47 6c 6f 62 61 6c 20  Global *pGlobal 
c4d0: 3d 20 28 46 74 73 35 47 6c 6f 62 61 6c 2a 29 70  = (Fts5Global*)p
c4e0: 41 70 69 3b 0a 20 20 46 74 73 35 54 6f 6b 65 6e  Api;.  Fts5Token
c4f0: 69 7a 65 72 4d 6f 64 75 6c 65 20 2a 70 4e 65 77  izerModule *pNew
c500: 3b 0a 20 20 69 6e 74 20 6e 42 79 74 65 3b 20 20  ;.  int nByte;  
c510: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c520: 20 20 20 20 2f 2a 20 42 79 74 65 73 20 6f 66 20      /* Bytes of 
c530: 73 70 61 63 65 20 74 6f 20 61 6c 6c 6f 63 61 74  space to allocat
c540: 65 20 2a 2f 0a 20 20 69 6e 74 20 72 63 20 3d 20  e */.  int rc = 
c550: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20 6e 42  SQLITE_OK;..  nB
c560: 79 74 65 20 3d 20 73 69 7a 65 6f 66 28 46 74 73  yte = sizeof(Fts
c570: 35 54 6f 6b 65 6e 69 7a 65 72 4d 6f 64 75 6c 65  5TokenizerModule
c580: 29 20 2b 20 73 74 72 6c 65 6e 28 7a 4e 61 6d 65  ) + strlen(zName
c590: 29 20 2b 20 31 3b 0a 20 20 70 4e 65 77 20 3d 20  ) + 1;.  pNew = 
c5a0: 28 46 74 73 35 54 6f 6b 65 6e 69 7a 65 72 4d 6f  (Fts5TokenizerMo
c5b0: 64 75 6c 65 2a 29 73 71 6c 69 74 65 33 5f 6d 61  dule*)sqlite3_ma
c5c0: 6c 6c 6f 63 28 6e 42 79 74 65 29 3b 0a 20 20 69  lloc(nByte);.  i
c5d0: 66 28 20 70 4e 65 77 20 29 7b 0a 20 20 20 20 6d  f( pNew ){.    m
c5e0: 65 6d 73 65 74 28 70 4e 65 77 2c 20 30 2c 20 6e  emset(pNew, 0, n
c5f0: 42 79 74 65 29 3b 0a 20 20 20 20 70 4e 65 77 2d  Byte);.    pNew-
c600: 3e 7a 4e 61 6d 65 20 3d 20 28 63 68 61 72 2a 29  >zName = (char*)
c610: 26 70 4e 65 77 5b 31 5d 3b 0a 20 20 20 20 73 74  &pNew[1];.    st
c620: 72 63 70 79 28 70 4e 65 77 2d 3e 7a 4e 61 6d 65  rcpy(pNew->zName
c630: 2c 20 7a 4e 61 6d 65 29 3b 0a 20 20 20 20 70 4e  , zName);.    pN
c640: 65 77 2d 3e 70 55 73 65 72 44 61 74 61 20 3d 20  ew->pUserData = 
c650: 70 55 73 65 72 44 61 74 61 3b 0a 20 20 20 20 70  pUserData;.    p
c660: 4e 65 77 2d 3e 78 20 3d 20 2a 70 54 6f 6b 65 6e  New->x = *pToken
c670: 69 7a 65 72 3b 0a 20 20 20 20 70 4e 65 77 2d 3e  izer;.    pNew->
c680: 78 44 65 73 74 72 6f 79 20 3d 20 78 44 65 73 74  xDestroy = xDest
c690: 72 6f 79 3b 0a 20 20 20 20 70 4e 65 77 2d 3e 70  roy;.    pNew->p
c6a0: 4e 65 78 74 20 3d 20 70 47 6c 6f 62 61 6c 2d 3e  Next = pGlobal->
c6b0: 70 54 6f 6b 3b 0a 20 20 20 20 70 47 6c 6f 62 61  pTok;.    pGloba
c6c0: 6c 2d 3e 70 54 6f 6b 20 3d 20 70 4e 65 77 3b 0a  l->pTok = pNew;.
c6d0: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 72 63 20    }else{.    rc 
c6e0: 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  = SQLITE_NOMEM;.
c6f0: 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63    }..  return rc
c700: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 69 6e 64 20  ;.}../*.** Find 
c710: 61 20 74 6f 6b 65 6e 69 7a 65 72 2e 20 54 68 69  a tokenizer. Thi
c720: 73 20 69 73 20 74 68 65 20 69 6d 70 6c 65 6d 65  s is the impleme
c730: 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 0a  ntation of the .
c740: 2a 2a 20 66 74 73 35 5f 61 70 69 2e 78 46 69 6e  ** fts5_api.xFin
c750: 64 54 6f 6b 65 6e 69 7a 65 72 28 29 20 6d 65 74  dTokenizer() met
c760: 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  hod..*/.static i
c770: 6e 74 20 66 74 73 35 46 69 6e 64 54 6f 6b 65 6e  nt fts5FindToken
c780: 69 7a 65 72 28 0a 20 20 66 74 73 35 5f 61 70 69  izer(.  fts5_api
c790: 20 2a 70 41 70 69 2c 20 20 20 20 20 20 20 20 20   *pApi,         
c7a0: 20 20 20 20 20 20 20 20 2f 2a 20 47 6c 6f 62 61          /* Globa
c7b0: 6c 20 63 6f 6e 74 65 78 74 20 28 6f 6e 65 20 70  l context (one p
c7c0: 65 72 20 64 62 20 68 61 6e 64 6c 65 29 20 2a 2f  er db handle) */
c7d0: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
c7e0: 4e 61 6d 65 2c 20 20 20 20 20 20 20 20 20 20 20  Name,           
c7f0: 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 6e 65     /* Name of ne
c800: 77 20 66 75 6e 63 74 69 6f 6e 20 2a 2f 0a 20 20  w function */.  
c810: 66 74 73 35 5f 74 6f 6b 65 6e 69 7a 65 72 20 2a  fts5_tokenizer *
c820: 70 54 6f 6b 65 6e 69 7a 65 72 20 20 20 20 20 20  pTokenizer      
c830: 2f 2a 20 50 6f 70 75 6c 61 74 65 20 74 68 69 73  /* Populate this
c840: 20 6f 62 6a 65 63 74 20 2a 2f 0a 29 7b 0a 20 20   object */.){.  
c850: 46 74 73 35 47 6c 6f 62 61 6c 20 2a 70 47 6c 6f  Fts5Global *pGlo
c860: 62 61 6c 20 3d 20 28 46 74 73 35 47 6c 6f 62 61  bal = (Fts5Globa
c870: 6c 2a 29 70 41 70 69 3b 0a 20 20 69 6e 74 20 72  l*)pApi;.  int r
c880: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  c = SQLITE_OK;. 
c890: 20 46 74 73 35 54 6f 6b 65 6e 69 7a 65 72 4d 6f   Fts5TokenizerMo
c8a0: 64 75 6c 65 20 2a 70 54 6f 6b 3b 0a 0a 20 20 66  dule *pTok;..  f
c8b0: 6f 72 28 70 54 6f 6b 3d 70 47 6c 6f 62 61 6c 2d  or(pTok=pGlobal-
c8c0: 3e 70 54 6f 6b 3b 20 70 54 6f 6b 3b 20 70 54 6f  >pTok; pTok; pTo
c8d0: 6b 3d 70 54 6f 6b 2d 3e 70 4e 65 78 74 29 7b 0a  k=pTok->pNext){.
c8e0: 20 20 20 20 69 66 28 20 73 71 6c 69 74 65 33 5f      if( sqlite3_
c8f0: 73 74 72 69 63 6d 70 28 7a 4e 61 6d 65 2c 20 70  stricmp(zName, p
c900: 54 6f 6b 2d 3e 7a 4e 61 6d 65 29 3d 3d 30 20 29  Tok->zName)==0 )
c910: 20 62 72 65 61 6b 3b 0a 20 20 7d 0a 0a 20 20 69   break;.  }..  i
c920: 66 28 20 70 54 6f 6b 20 29 7b 0a 20 20 20 20 2a  f( pTok ){.    *
c930: 70 54 6f 6b 65 6e 69 7a 65 72 20 3d 20 70 54 6f  pTokenizer = pTo
c940: 6b 2d 3e 78 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  k->x;.  }else{. 
c950: 20 20 20 6d 65 6d 73 65 74 28 70 54 6f 6b 65 6e     memset(pToken
c960: 69 7a 65 72 2c 20 30 2c 20 73 69 7a 65 6f 66 28  izer, 0, sizeof(
c970: 66 74 73 35 5f 74 6f 6b 65 6e 69 7a 65 72 29 29  fts5_tokenizer))
c980: 3b 0a 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54  ;.    rc = SQLIT
c990: 45 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20  E_ERROR;.  }..  
c9a0: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 69 6e  return rc;.}..in
c9b0: 74 20 73 71 6c 69 74 65 33 46 74 73 35 47 65 74  t sqlite3Fts5Get
c9c0: 54 6f 6b 65 6e 69 7a 65 72 28 0a 20 20 46 74 73  Tokenizer(.  Fts
c9d0: 35 47 6c 6f 62 61 6c 20 2a 70 47 6c 6f 62 61 6c  5Global *pGlobal
c9e0: 2c 20 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  , .  const char 
c9f0: 2a 2a 61 7a 41 72 67 2c 0a 20 20 69 6e 74 20 6e  **azArg,.  int n
ca00: 41 72 67 2c 0a 20 20 46 74 73 35 54 6f 6b 65 6e  Arg,.  Fts5Token
ca10: 69 7a 65 72 20 2a 2a 70 70 54 6f 6b 2c 0a 20 20  izer **ppTok,.  
ca20: 66 74 73 35 5f 74 6f 6b 65 6e 69 7a 65 72 20 2a  fts5_tokenizer *
ca30: 2a 70 70 54 6f 6b 41 70 69 0a 29 7b 0a 20 20 46  *ppTokApi.){.  F
ca40: 74 73 35 54 6f 6b 65 6e 69 7a 65 72 4d 6f 64 75  ts5TokenizerModu
ca50: 6c 65 20 2a 70 4d 6f 64 20 3d 20 30 3b 0a 20 20  le *pMod = 0;.  
ca60: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
ca70: 4f 4b 3b 0a 20 20 69 66 28 20 6e 41 72 67 3d 3d  OK;.  if( nArg==
ca80: 30 20 29 7b 0a 20 20 20 20 70 4d 6f 64 20 3d 20  0 ){.    pMod = 
ca90: 70 47 6c 6f 62 61 6c 2d 3e 70 54 6f 6b 3b 0a 20  pGlobal->pTok;. 
caa0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 66 6f 72 28   }else{.    for(
cab0: 70 4d 6f 64 3d 70 47 6c 6f 62 61 6c 2d 3e 70 54  pMod=pGlobal->pT
cac0: 6f 6b 3b 20 70 4d 6f 64 3b 20 70 4d 6f 64 3d 70  ok; pMod; pMod=p
cad0: 4d 6f 64 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20  Mod->pNext){.   
cae0: 20 20 20 69 66 28 20 73 71 6c 69 74 65 33 5f 73     if( sqlite3_s
caf0: 74 72 69 63 6d 70 28 61 7a 41 72 67 5b 30 5d 2c  tricmp(azArg[0],
cb00: 20 70 4d 6f 64 2d 3e 7a 4e 61 6d 65 29 3d 3d 30   pMod->zName)==0
cb10: 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a   ) break;.    }.
cb20: 20 20 7d 0a 0a 20 20 69 66 28 20 70 4d 6f 64 3d    }..  if( pMod=
cb30: 3d 30 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 53  =0 ){.    rc = S
cb40: 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 7d  QLITE_ERROR;.  }
cb50: 65 6c 73 65 7b 0a 20 20 20 20 72 63 20 3d 20 70  else{.    rc = p
cb60: 4d 6f 64 2d 3e 78 2e 78 43 72 65 61 74 65 28 70  Mod->x.xCreate(p
cb70: 4d 6f 64 2d 3e 70 55 73 65 72 44 61 74 61 2c 20  Mod->pUserData, 
cb80: 26 61 7a 41 72 67 5b 31 5d 2c 20 28 6e 41 72 67  &azArg[1], (nArg
cb90: 3f 6e 41 72 67 2d 31 3a 30 29 2c 20 70 70 54 6f  ?nArg-1:0), ppTo
cba0: 6b 29 3b 0a 20 20 20 20 2a 70 70 54 6f 6b 41 70  k);.    *ppTokAp
cbb0: 69 20 3d 20 26 70 4d 6f 64 2d 3e 78 3b 0a 20 20  i = &pMod->x;.  
cbc0: 7d 0a 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c  }..  if( rc!=SQL
cbd0: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 2a 70  ITE_OK ){.    *p
cbe0: 70 54 6f 6b 41 70 69 20 3d 20 30 3b 0a 20 20 20  pTokApi = 0;.   
cbf0: 20 2a 70 70 54 6f 6b 20 3d 20 30 3b 0a 20 20 7d   *ppTok = 0;.  }
cc00: 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ..  return rc;.}
cc10: 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 66 74  ..static void ft
cc20: 73 35 4d 6f 64 75 6c 65 44 65 73 74 72 6f 79 28  s5ModuleDestroy(
cc30: 76 6f 69 64 20 2a 70 43 74 78 29 7b 0a 20 20 46  void *pCtx){.  F
cc40: 74 73 35 54 6f 6b 65 6e 69 7a 65 72 4d 6f 64 75  ts5TokenizerModu
cc50: 6c 65 20 2a 70 54 6f 6b 2c 20 2a 70 4e 65 78 74  le *pTok, *pNext
cc60: 54 6f 6b 3b 0a 20 20 46 74 73 35 41 75 78 69 6c  Tok;.  Fts5Auxil
cc70: 69 61 72 79 20 2a 70 41 75 78 2c 20 2a 70 4e 65  iary *pAux, *pNe
cc80: 78 74 41 75 78 3b 0a 20 20 46 74 73 35 47 6c 6f  xtAux;.  Fts5Glo
cc90: 62 61 6c 20 2a 70 47 6c 6f 62 61 6c 20 3d 20 28  bal *pGlobal = (
cca0: 46 74 73 35 47 6c 6f 62 61 6c 2a 29 70 43 74 78  Fts5Global*)pCtx
ccb0: 3b 0a 0a 20 20 66 6f 72 28 70 41 75 78 3d 70 47  ;..  for(pAux=pG
ccc0: 6c 6f 62 61 6c 2d 3e 70 41 75 78 3b 20 70 41 75  lobal->pAux; pAu
ccd0: 78 3b 20 70 41 75 78 3d 70 4e 65 78 74 41 75 78  x; pAux=pNextAux
cce0: 29 7b 0a 20 20 20 20 70 4e 65 78 74 41 75 78 20  ){.    pNextAux 
ccf0: 3d 20 70 41 75 78 2d 3e 70 4e 65 78 74 3b 0a 20  = pAux->pNext;. 
cd00: 20 20 20 69 66 28 20 70 41 75 78 2d 3e 78 44 65     if( pAux->xDe
cd10: 73 74 72 6f 79 20 29 20 70 41 75 78 2d 3e 78 44  stroy ) pAux->xD
cd20: 65 73 74 72 6f 79 28 70 41 75 78 2d 3e 70 55 73  estroy(pAux->pUs
cd30: 65 72 44 61 74 61 29 3b 0a 20 20 20 20 73 71 6c  erData);.    sql
cd40: 69 74 65 33 5f 66 72 65 65 28 70 41 75 78 29 3b  ite3_free(pAux);
cd50: 0a 20 20 7d 0a 0a 20 20 66 6f 72 28 70 54 6f 6b  .  }..  for(pTok
cd60: 3d 70 47 6c 6f 62 61 6c 2d 3e 70 54 6f 6b 3b 20  =pGlobal->pTok; 
cd70: 70 54 6f 6b 3b 20 70 54 6f 6b 3d 70 4e 65 78 74  pTok; pTok=pNext
cd80: 54 6f 6b 29 7b 0a 20 20 20 20 70 4e 65 78 74 54  Tok){.    pNextT
cd90: 6f 6b 20 3d 20 70 54 6f 6b 2d 3e 70 4e 65 78 74  ok = pTok->pNext
cda0: 3b 0a 20 20 20 20 69 66 28 20 70 54 6f 6b 2d 3e  ;.    if( pTok->
cdb0: 78 44 65 73 74 72 6f 79 20 29 20 70 54 6f 6b 2d  xDestroy ) pTok-
cdc0: 3e 78 44 65 73 74 72 6f 79 28 70 54 6f 6b 2d 3e  >xDestroy(pTok->
cdd0: 70 55 73 65 72 44 61 74 61 29 3b 0a 20 20 20 20  pUserData);.    
cde0: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 54 6f  sqlite3_free(pTo
cdf0: 6b 29 3b 0a 20 20 7d 0a 0a 20 20 73 71 6c 69 74  k);.  }..  sqlit
ce00: 65 33 5f 66 72 65 65 28 70 47 6c 6f 62 61 6c 29  e3_free(pGlobal)
ce10: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64  ;.}..static void
ce20: 20 66 74 73 35 46 74 73 35 46 75 6e 63 28 0a 20   fts5Fts5Func(. 
ce30: 20 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74   sqlite3_context
ce40: 20 2a 70 43 74 78 2c 20 20 20 20 20 20 20 20 20   *pCtx,         
ce50: 20 2f 2a 20 46 75 6e 63 74 69 6f 6e 20 63 61 6c   /* Function cal
ce60: 6c 20 63 6f 6e 74 65 78 74 20 2a 2f 0a 20 20 69  l context */.  i
ce70: 6e 74 20 6e 41 72 67 2c 20 20 20 20 20 20 20 20  nt nArg,        
ce80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
ce90: 2a 20 4e 75 6d 62 65 72 20 6f 66 20 61 72 67 73  * Number of args
cea0: 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 76 61   */.  sqlite3_va
ceb0: 6c 75 65 20 2a 2a 61 70 56 61 6c 20 20 20 20 20  lue **apVal     
cec0: 20 20 20 20 20 20 2f 2a 20 46 75 6e 63 74 69 6f        /* Functio
ced0: 6e 20 61 72 67 75 6d 65 6e 74 73 20 2a 2f 0a 29  n arguments */.)
cee0: 7b 0a 20 20 46 74 73 35 47 6c 6f 62 61 6c 20 2a  {.  Fts5Global *
cef0: 70 47 6c 6f 62 61 6c 20 3d 20 28 46 74 73 35 47  pGlobal = (Fts5G
cf00: 6c 6f 62 61 6c 2a 29 73 71 6c 69 74 65 33 5f 75  lobal*)sqlite3_u
cf10: 73 65 72 5f 64 61 74 61 28 70 43 74 78 29 3b 0a  ser_data(pCtx);.
cf20: 20 20 63 68 61 72 20 62 75 66 5b 38 5d 3b 0a 20    char buf[8];. 
cf30: 20 61 73 73 65 72 74 28 20 6e 41 72 67 3d 3d 30   assert( nArg==0
cf40: 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 73 69   );.  assert( si
cf50: 7a 65 6f 66 28 62 75 66 29 3e 3d 73 69 7a 65 6f  zeof(buf)>=sizeo
cf60: 66 28 70 47 6c 6f 62 61 6c 29 20 29 3b 0a 20 20  f(pGlobal) );.  
cf70: 6d 65 6d 63 70 79 28 62 75 66 2c 20 28 76 6f 69  memcpy(buf, (voi
cf80: 64 2a 29 26 70 47 6c 6f 62 61 6c 2c 20 73 69 7a  d*)&pGlobal, siz
cf90: 65 6f 66 28 70 47 6c 6f 62 61 6c 29 29 3b 0a 20  eof(pGlobal));. 
cfa0: 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f   sqlite3_result_
cfb0: 62 6c 6f 62 28 70 43 74 78 2c 20 62 75 66 2c 20  blob(pCtx, buf, 
cfc0: 73 69 7a 65 6f 66 28 70 47 6c 6f 62 61 6c 29 2c  sizeof(pGlobal),
cfd0: 20 53 51 4c 49 54 45 5f 54 52 41 4e 53 49 45 4e   SQLITE_TRANSIEN
cfe0: 54 29 3b 0a 7d 0a 0a 69 6e 74 20 73 71 6c 69 74  T);.}..int sqlit
cff0: 65 33 46 74 73 35 49 6e 69 74 28 73 71 6c 69 74  e3Fts5Init(sqlit
d000: 65 33 20 2a 64 62 29 7b 0a 20 20 73 74 61 74 69  e3 *db){.  stati
d010: 63 20 63 6f 6e 73 74 20 73 71 6c 69 74 65 33 5f  c const sqlite3_
d020: 6d 6f 64 75 6c 65 20 66 74 73 35 4d 6f 64 20 3d  module fts5Mod =
d030: 20 7b 0a 20 20 20 20 2f 2a 20 69 56 65 72 73 69   {.    /* iVersi
d040: 6f 6e 20 20 20 20 20 20 2a 2f 20 32 2c 0a 20 20  on      */ 2,.  
d050: 20 20 2f 2a 20 78 43 72 65 61 74 65 20 20 20 20    /* xCreate    
d060: 20 20 20 2a 2f 20 66 74 73 35 43 72 65 61 74 65     */ fts5Create
d070: 4d 65 74 68 6f 64 2c 0a 20 20 20 20 2f 2a 20 78  Method,.    /* x
d080: 43 6f 6e 6e 65 63 74 20 20 20 20 20 20 2a 2f 20  Connect      */ 
d090: 66 74 73 35 43 6f 6e 6e 65 63 74 4d 65 74 68 6f  fts5ConnectMetho
d0a0: 64 2c 0a 20 20 20 20 2f 2a 20 78 42 65 73 74 49  d,.    /* xBestI
d0b0: 6e 64 65 78 20 20 20 20 2a 2f 20 66 74 73 35 42  ndex    */ fts5B
d0c0: 65 73 74 49 6e 64 65 78 4d 65 74 68 6f 64 2c 0a  estIndexMethod,.
d0d0: 20 20 20 20 2f 2a 20 78 44 69 73 63 6f 6e 6e 65      /* xDisconne
d0e0: 63 74 20 20 20 2a 2f 20 66 74 73 35 44 69 73 63  ct   */ fts5Disc
d0f0: 6f 6e 6e 65 63 74 4d 65 74 68 6f 64 2c 0a 20 20  onnectMethod,.  
d100: 20 20 2f 2a 20 78 44 65 73 74 72 6f 79 20 20 20    /* xDestroy   
d110: 20 20 20 2a 2f 20 66 74 73 35 44 65 73 74 72 6f     */ fts5Destro
d120: 79 4d 65 74 68 6f 64 2c 0a 20 20 20 20 2f 2a 20  yMethod,.    /* 
d130: 78 4f 70 65 6e 20 20 20 20 20 20 20 20 20 2a 2f  xOpen         */
d140: 20 66 74 73 35 4f 70 65 6e 4d 65 74 68 6f 64 2c   fts5OpenMethod,
d150: 0a 20 20 20 20 2f 2a 20 78 43 6c 6f 73 65 20 20  .    /* xClose  
d160: 20 20 20 20 20 20 2a 2f 20 66 74 73 35 43 6c 6f        */ fts5Clo
d170: 73 65 4d 65 74 68 6f 64 2c 0a 20 20 20 20 2f 2a  seMethod,.    /*
d180: 20 78 46 69 6c 74 65 72 20 20 20 20 20 20 20 2a   xFilter       *
d190: 2f 20 66 74 73 35 46 69 6c 74 65 72 4d 65 74 68  / fts5FilterMeth
d1a0: 6f 64 2c 0a 20 20 20 20 2f 2a 20 78 4e 65 78 74  od,.    /* xNext
d1b0: 20 20 20 20 20 20 20 20 20 2a 2f 20 66 74 73 35           */ fts5
d1c0: 4e 65 78 74 4d 65 74 68 6f 64 2c 0a 20 20 20 20  NextMethod,.    
d1d0: 2f 2a 20 78 45 6f 66 20 20 20 20 20 20 20 20 20  /* xEof         
d1e0: 20 2a 2f 20 66 74 73 35 45 6f 66 4d 65 74 68 6f   */ fts5EofMetho
d1f0: 64 2c 0a 20 20 20 20 2f 2a 20 78 43 6f 6c 75 6d  d,.    /* xColum
d200: 6e 20 20 20 20 20 20 20 2a 2f 20 66 74 73 35 43  n       */ fts5C
d210: 6f 6c 75 6d 6e 4d 65 74 68 6f 64 2c 0a 20 20 20  olumnMethod,.   
d220: 20 2f 2a 20 78 52 6f 77 69 64 20 20 20 20 20 20   /* xRowid      
d230: 20 20 2a 2f 20 66 74 73 35 52 6f 77 69 64 4d 65    */ fts5RowidMe
d240: 74 68 6f 64 2c 0a 20 20 20 20 2f 2a 20 78 55 70  thod,.    /* xUp
d250: 64 61 74 65 20 20 20 20 20 20 20 2a 2f 20 66 74  date       */ ft
d260: 73 35 55 70 64 61 74 65 4d 65 74 68 6f 64 2c 0a  s5UpdateMethod,.
d270: 20 20 20 20 2f 2a 20 78 42 65 67 69 6e 20 20 20      /* xBegin   
d280: 20 20 20 20 20 2a 2f 20 66 74 73 35 42 65 67 69       */ fts5Begi
d290: 6e 4d 65 74 68 6f 64 2c 0a 20 20 20 20 2f 2a 20  nMethod,.    /* 
d2a0: 78 53 79 6e 63 20 20 20 20 20 20 20 20 20 2a 2f  xSync         */
d2b0: 20 66 74 73 35 53 79 6e 63 4d 65 74 68 6f 64 2c   fts5SyncMethod,
d2c0: 0a 20 20 20 20 2f 2a 20 78 43 6f 6d 6d 69 74 20  .    /* xCommit 
d2d0: 20 20 20 20 20 20 2a 2f 20 66 74 73 35 43 6f 6d        */ fts5Com
d2e0: 6d 69 74 4d 65 74 68 6f 64 2c 0a 20 20 20 20 2f  mitMethod,.    /
d2f0: 2a 20 78 52 6f 6c 6c 62 61 63 6b 20 20 20 20 20  * xRollback     
d300: 2a 2f 20 66 74 73 35 52 6f 6c 6c 62 61 63 6b 4d  */ fts5RollbackM
d310: 65 74 68 6f 64 2c 0a 20 20 20 20 2f 2a 20 78 46  ethod,.    /* xF
d320: 69 6e 64 46 75 6e 63 74 69 6f 6e 20 2a 2f 20 66  indFunction */ f
d330: 74 73 35 46 69 6e 64 46 75 6e 63 74 69 6f 6e 4d  ts5FindFunctionM
d340: 65 74 68 6f 64 2c 0a 20 20 20 20 2f 2a 20 78 52  ethod,.    /* xR
d350: 65 6e 61 6d 65 20 20 20 20 20 20 20 2a 2f 20 66  ename       */ f
d360: 74 73 35 52 65 6e 61 6d 65 4d 65 74 68 6f 64 2c  ts5RenameMethod,
d370: 0a 20 20 20 20 2f 2a 20 78 53 61 76 65 70 6f 69  .    /* xSavepoi
d380: 6e 74 20 20 20 20 2a 2f 20 66 74 73 35 53 61 76  nt    */ fts5Sav
d390: 65 70 6f 69 6e 74 4d 65 74 68 6f 64 2c 0a 20 20  epointMethod,.  
d3a0: 20 20 2f 2a 20 78 52 65 6c 65 61 73 65 20 20 20    /* xRelease   
d3b0: 20 20 20 2a 2f 20 66 74 73 35 52 65 6c 65 61 73     */ fts5Releas
d3c0: 65 4d 65 74 68 6f 64 2c 0a 20 20 20 20 2f 2a 20  eMethod,.    /* 
d3d0: 78 52 6f 6c 6c 62 61 63 6b 54 6f 20 20 20 2a 2f  xRollbackTo   */
d3e0: 20 66 74 73 35 52 6f 6c 6c 62 61 63 6b 54 6f 4d   fts5RollbackToM
d3f0: 65 74 68 6f 64 2c 0a 20 20 7d 3b 0a 0a 20 20 69  ethod,.  };..  i
d400: 6e 74 20 72 63 3b 0a 20 20 46 74 73 35 47 6c 6f  nt rc;.  Fts5Glo
d410: 62 61 6c 20 2a 70 47 6c 6f 62 61 6c 20 3d 20 30  bal *pGlobal = 0
d420: 3b 0a 20 20 70 47 6c 6f 62 61 6c 20 3d 20 28 46  ;.  pGlobal = (F
d430: 74 73 35 47 6c 6f 62 61 6c 2a 29 73 71 6c 69 74  ts5Global*)sqlit
d440: 65 33 5f 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f 66  e3_malloc(sizeof
d450: 28 46 74 73 35 47 6c 6f 62 61 6c 29 29 3b 0a 0a  (Fts5Global));..
d460: 20 20 69 66 28 20 70 47 6c 6f 62 61 6c 3d 3d 30    if( pGlobal==0
d470: 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 53 51 4c   ){.    rc = SQL
d480: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 65 6c  ITE_NOMEM;.  }el
d490: 73 65 7b 0a 20 20 20 20 76 6f 69 64 20 2a 70 20  se{.    void *p 
d4a0: 3d 20 28 76 6f 69 64 2a 29 70 47 6c 6f 62 61 6c  = (void*)pGlobal
d4b0: 3b 0a 20 20 20 20 6d 65 6d 73 65 74 28 70 47 6c  ;.    memset(pGl
d4c0: 6f 62 61 6c 2c 20 30 2c 20 73 69 7a 65 6f 66 28  obal, 0, sizeof(
d4d0: 46 74 73 35 47 6c 6f 62 61 6c 29 29 3b 0a 20 20  Fts5Global));.  
d4e0: 20 20 70 47 6c 6f 62 61 6c 2d 3e 64 62 20 3d 20    pGlobal->db = 
d4f0: 64 62 3b 0a 20 20 20 20 70 47 6c 6f 62 61 6c 2d  db;.    pGlobal-
d500: 3e 61 70 69 2e 69 56 65 72 73 69 6f 6e 20 3d 20  >api.iVersion = 
d510: 31 3b 0a 20 20 20 20 70 47 6c 6f 62 61 6c 2d 3e  1;.    pGlobal->
d520: 61 70 69 2e 78 43 72 65 61 74 65 46 75 6e 63 74  api.xCreateFunct
d530: 69 6f 6e 20 3d 20 66 74 73 35 43 72 65 61 74 65  ion = fts5Create
d540: 41 75 78 3b 0a 20 20 20 20 70 47 6c 6f 62 61 6c  Aux;.    pGlobal
d550: 2d 3e 61 70 69 2e 78 43 72 65 61 74 65 54 6f 6b  ->api.xCreateTok
d560: 65 6e 69 7a 65 72 20 3d 20 66 74 73 35 43 72 65  enizer = fts5Cre
d570: 61 74 65 54 6f 6b 65 6e 69 7a 65 72 3b 0a 20 20  ateTokenizer;.  
d580: 20 20 70 47 6c 6f 62 61 6c 2d 3e 61 70 69 2e 78    pGlobal->api.x
d590: 46 69 6e 64 54 6f 6b 65 6e 69 7a 65 72 20 3d 20  FindTokenizer = 
d5a0: 66 74 73 35 46 69 6e 64 54 6f 6b 65 6e 69 7a 65  fts5FindTokenize
d5b0: 72 3b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69  r;.    rc = sqli
d5c0: 74 65 33 5f 63 72 65 61 74 65 5f 6d 6f 64 75 6c  te3_create_modul
d5d0: 65 5f 76 32 28 64 62 2c 20 22 66 74 73 35 22 2c  e_v2(db, "fts5",
d5e0: 20 26 66 74 73 35 4d 6f 64 2c 20 70 2c 20 66 74   &fts5Mod, p, ft
d5f0: 73 35 4d 6f 64 75 6c 65 44 65 73 74 72 6f 79 29  s5ModuleDestroy)
d600: 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51  ;.    if( rc==SQ
d610: 4c 49 54 45 5f 4f 4b 20 29 20 72 63 20 3d 20 73  LITE_OK ) rc = s
d620: 71 6c 69 74 65 33 46 74 73 35 49 6e 64 65 78 49  qlite3Fts5IndexI
d630: 6e 69 74 28 64 62 29 3b 0a 20 20 20 20 69 66 28  nit(db);.    if(
d640: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
d650: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 46 74 73   rc = sqlite3Fts
d660: 35 45 78 70 72 49 6e 69 74 28 70 47 6c 6f 62 61  5ExprInit(pGloba
d670: 6c 2c 20 64 62 29 3b 0a 20 20 20 20 69 66 28 20  l, db);.    if( 
d680: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20  rc==SQLITE_OK ) 
d690: 72 63 20 3d 20 73 71 6c 69 74 65 33 46 74 73 35  rc = sqlite3Fts5
d6a0: 41 75 78 49 6e 69 74 28 26 70 47 6c 6f 62 61 6c  AuxInit(&pGlobal
d6b0: 2d 3e 61 70 69 29 3b 0a 20 20 20 20 69 66 28 20  ->api);.    if( 
d6c0: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20  rc==SQLITE_OK ) 
d6d0: 72 63 20 3d 20 73 71 6c 69 74 65 33 46 74 73 35  rc = sqlite3Fts5
d6e0: 54 6f 6b 65 6e 69 7a 65 72 49 6e 69 74 28 26 70  TokenizerInit(&p
d6f0: 47 6c 6f 62 61 6c 2d 3e 61 70 69 29 3b 0a 20 20  Global->api);.  
d700: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
d710: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72 63 20  _OK ){.      rc 
d720: 3d 20 73 71 6c 69 74 65 33 5f 63 72 65 61 74 65  = sqlite3_create
d730: 5f 66 75 6e 63 74 69 6f 6e 28 0a 20 20 20 20 20  _function(.     
d740: 20 20 20 20 20 64 62 2c 20 22 66 74 73 35 22 2c       db, "fts5",
d750: 20 30 2c 20 53 51 4c 49 54 45 5f 55 54 46 38 2c   0, SQLITE_UTF8,
d760: 20 70 2c 20 66 74 73 35 46 74 73 35 46 75 6e 63   p, fts5Fts5Func
d770: 2c 20 30 2c 20 30 0a 20 20 20 20 20 20 29 3b 0a  , 0, 0.      );.
d780: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75      }.  }.  retu
d790: 72 6e 20 72 63 3b 0a 7d 0a 0a 0a                 rn rc;.}...