/ Hex Artifact Content
Login

Artifact c90004f4a91ce4f4dfad2fc980ade0d9314ebb10:


0000: 2f 2a 0a 2a 2a 20 32 30 31 34 20 4a 75 6e 20 30  /*.** 2014 Jun 0
0010: 39 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 75 74 68  9.**.** The auth
0020: 6f 72 20 64 69 73 63 6c 61 69 6d 73 20 63 6f 70  or disclaims cop
0030: 79 72 69 67 68 74 20 74 6f 20 74 68 69 73 20 73  yright to this s
0040: 6f 75 72 63 65 20 63 6f 64 65 2e 20 20 49 6e 20  ource code.  In 
0050: 70 6c 61 63 65 20 6f 66 0a 2a 2a 20 61 20 6c 65  place of.** a le
0060: 67 61 6c 20 6e 6f 74 69 63 65 2c 20 68 65 72 65  gal notice, here
0070: 20 69 73 20 61 20 62 6c 65 73 73 69 6e 67 3a 0a   is a blessing:.
0080: 2a 2a 0a 2a 2a 20 20 20 20 4d 61 79 20 79 6f 75  **.**    May you
0090: 20 64 6f 20 67 6f 6f 64 20 61 6e 64 20 6e 6f 74   do good and not
00a0: 20 65 76 69 6c 2e 0a 2a 2a 20 20 20 20 4d 61 79   evil..**    May
00b0: 20 79 6f 75 20 66 69 6e 64 20 66 6f 72 67 69 76   you find forgiv
00c0: 65 6e 65 73 73 20 66 6f 72 20 79 6f 75 72 73 65  eness for yourse
00d0: 6c 66 20 61 6e 64 20 66 6f 72 67 69 76 65 20 6f  lf and forgive o
00e0: 74 68 65 72 73 2e 0a 2a 2a 20 20 20 20 4d 61 79  thers..**    May
00f0: 20 79 6f 75 20 73 68 61 72 65 20 66 72 65 65 6c   you share freel
0100: 79 2c 20 6e 65 76 65 72 20 74 61 6b 69 6e 67 20  y, never taking 
0110: 6d 6f 72 65 20 74 68 61 6e 20 79 6f 75 20 67 69  more than you gi
0120: 76 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ve..**.*********
0130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0160: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0170: 2a 2a 2a 2a 2a 0a 2a 2a 0a 2a 2a 20 54 68 69 73  *****.**.** This
0180: 20 69 73 20 61 6e 20 53 51 4c 69 74 65 20 6d 6f   is an SQLite mo
0190: 64 75 6c 65 20 69 6d 70 6c 65 6d 65 6e 74 69 6e  dule implementin
01a0: 67 20 66 75 6c 6c 2d 74 65 78 74 20 73 65 61 72  g full-text sear
01b0: 63 68 2e 0a 2a 2f 0a 0a 0a 23 69 6e 63 6c 75 64  ch..*/...#includ
01c0: 65 20 22 66 74 73 35 49 6e 74 2e 68 22 0a 0a 0a  e "fts5Int.h"...
01d0: 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20 46  typedef struct F
01e0: 74 73 35 54 61 62 6c 65 20 46 74 73 35 54 61 62  ts5Table Fts5Tab
01f0: 6c 65 3b 0a 74 79 70 65 64 65 66 20 73 74 72 75  le;.typedef stru
0200: 63 74 20 46 74 73 35 43 75 72 73 6f 72 20 46 74  ct Fts5Cursor Ft
0210: 73 35 43 75 72 73 6f 72 3b 0a 74 79 70 65 64 65  s5Cursor;.typede
0220: 66 20 73 74 72 75 63 74 20 46 74 73 35 47 6c 6f  f struct Fts5Glo
0230: 62 61 6c 20 46 74 73 35 47 6c 6f 62 61 6c 3b 0a  bal Fts5Global;.
0240: 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20 46  typedef struct F
0250: 74 73 35 41 75 78 69 6c 69 61 72 79 20 46 74 73  ts5Auxiliary Fts
0260: 35 41 75 78 69 6c 69 61 72 79 3b 0a 74 79 70 65  5Auxiliary;.type
0270: 64 65 66 20 73 74 72 75 63 74 20 46 74 73 35 41  def struct Fts5A
0280: 75 78 64 61 74 61 20 46 74 73 35 41 75 78 64 61  uxdata Fts5Auxda
0290: 74 61 3b 0a 0a 74 79 70 65 64 65 66 20 73 74 72  ta;..typedef str
02a0: 75 63 74 20 46 74 73 35 54 6f 6b 65 6e 69 7a 65  uct Fts5Tokenize
02b0: 72 4d 6f 64 75 6c 65 20 46 74 73 35 54 6f 6b 65  rModule Fts5Toke
02c0: 6e 69 7a 65 72 4d 6f 64 75 6c 65 3b 0a 0a 2f 2a  nizerModule;../*
02d0: 0a 2a 2a 20 4e 4f 54 45 53 20 4f 4e 20 54 52 41  .** NOTES ON TRA
02e0: 4e 53 41 43 54 49 4f 4e 53 3a 20 0a 2a 2a 0a 2a  NSACTIONS: .**.*
02f0: 2a 20 53 51 4c 69 74 65 20 69 6e 76 6f 6b 65 73  * SQLite invokes
0300: 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 76   the following v
0310: 69 72 74 75 61 6c 20 74 61 62 6c 65 20 6d 65 74  irtual table met
0320: 68 6f 64 73 20 61 73 20 74 72 61 6e 73 61 63 74  hods as transact
0330: 69 6f 6e 73 20 61 72 65 20 0a 2a 2a 20 6f 70 65  ions are .** ope
0340: 6e 65 64 20 61 6e 64 20 63 6c 6f 73 65 64 20 62  ned and closed b
0350: 79 20 74 68 65 20 75 73 65 72 3a 0a 2a 2a 0a 2a  y the user:.**.*
0360: 2a 20 20 20 20 20 78 42 65 67 69 6e 28 29 3a 20  *     xBegin(): 
0370: 20 20 20 53 74 61 72 74 20 6f 66 20 61 20 6e 65     Start of a ne
0380: 77 20 74 72 61 6e 73 61 63 74 69 6f 6e 2e 0a 2a  w transaction..*
0390: 2a 20 20 20 20 20 78 53 79 6e 63 28 29 3a 20 20  *     xSync():  
03a0: 20 20 20 49 6e 69 74 69 61 6c 20 70 61 72 74 20     Initial part 
03b0: 6f 66 20 74 77 6f 2d 70 68 61 73 65 20 63 6f 6d  of two-phase com
03c0: 6d 69 74 2e 0a 2a 2a 20 20 20 20 20 78 43 6f 6d  mit..**     xCom
03d0: 6d 69 74 28 29 3a 20 20 20 46 69 6e 61 6c 20 70  mit():   Final p
03e0: 61 72 74 20 6f 66 20 74 77 6f 2d 70 68 61 73 65  art of two-phase
03f0: 20 63 6f 6d 6d 69 74 2e 0a 2a 2a 20 20 20 20 20   commit..**     
0400: 78 52 6f 6c 6c 62 61 63 6b 28 29 3a 20 52 6f 6c  xRollback(): Rol
0410: 6c 62 61 63 6b 20 74 68 65 20 74 72 61 6e 73 61  lback the transa
0420: 63 74 69 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 41 6e 79  ction..**.** Any
0430: 74 68 69 6e 67 20 74 68 61 74 20 69 73 20 72 65  thing that is re
0440: 71 75 69 72 65 64 20 61 73 20 70 61 72 74 20 6f  quired as part o
0450: 66 20 61 20 63 6f 6d 6d 69 74 20 74 68 61 74 20  f a commit that 
0460: 6d 61 79 20 66 61 69 6c 20 69 73 20 70 65 72 66  may fail is perf
0470: 6f 72 6d 65 64 0a 2a 2a 20 69 6e 20 74 68 65 20  ormed.** in the 
0480: 78 53 79 6e 63 28 29 20 63 61 6c 6c 62 61 63 6b  xSync() callback
0490: 2e 20 43 75 72 72 65 6e 74 20 76 65 72 73 69 6f  . Current versio
04a0: 6e 73 20 6f 66 20 53 51 4c 69 74 65 20 69 67 6e  ns of SQLite ign
04b0: 6f 72 65 20 61 6e 79 20 65 72 72 6f 72 73 20 0a  ore any errors .
04c0: 2a 2a 20 72 65 74 75 72 6e 65 64 20 62 79 20 78  ** returned by x
04d0: 43 6f 6d 6d 69 74 28 29 2e 0a 2a 2a 0a 2a 2a 20  Commit()..**.** 
04e0: 41 6e 64 20 61 73 20 73 75 62 2d 74 72 61 6e 73  And as sub-trans
04f0: 61 63 74 69 6f 6e 73 20 61 72 65 20 6f 70 65 6e  actions are open
0500: 65 64 2f 63 6c 6f 73 65 64 3a 0a 2a 2a 0a 2a 2a  ed/closed:.**.**
0510: 20 20 20 20 20 78 53 61 76 65 70 6f 69 6e 74 28       xSavepoint(
0520: 69 6e 74 20 53 29 3a 20 20 4f 70 65 6e 20 73 61  int S):  Open sa
0530: 76 65 70 6f 69 6e 74 20 53 2e 0a 2a 2a 20 20 20  vepoint S..**   
0540: 20 20 78 52 65 6c 65 61 73 65 28 69 6e 74 20 53    xRelease(int S
0550: 29 3a 20 20 20 20 43 6f 6d 6d 69 74 20 61 6e 64  ):    Commit and
0560: 20 63 6c 6f 73 65 20 73 61 76 65 70 6f 69 6e 74   close savepoint
0570: 20 53 2e 0a 2a 2a 20 20 20 20 20 78 52 6f 6c 6c   S..**     xRoll
0580: 62 61 63 6b 54 6f 28 69 6e 74 20 53 29 3a 20 52  backTo(int S): R
0590: 6f 6c 6c 62 61 63 6b 20 74 6f 20 73 74 61 72 74  ollback to start
05a0: 20 6f 66 20 73 61 76 65 70 6f 69 6e 74 20 53 2e   of savepoint S.
05b0: 0a 2a 2a 0a 2a 2a 20 44 75 72 69 6e 67 20 61 20  .**.** During a 
05c0: 77 72 69 74 65 2d 74 72 61 6e 73 61 63 74 69 6f  write-transactio
05d0: 6e 20 74 68 65 20 66 74 73 35 5f 69 6e 64 65 78  n the fts5_index
05e0: 2e 63 20 6d 6f 64 75 6c 65 20 6d 61 79 20 63 61  .c module may ca
05f0: 63 68 65 20 73 6f 6d 65 20 64 61 74 61 20 0a 2a  che some data .*
0600: 2a 20 69 6e 2d 6d 65 6d 6f 72 79 2e 20 49 74 20  * in-memory. It 
0610: 69 73 20 66 6c 75 73 68 65 64 20 74 6f 20 64 69  is flushed to di
0620: 73 6b 20 77 68 65 6e 65 76 65 72 20 78 53 79 6e  sk whenever xSyn
0630: 63 28 29 2c 20 78 52 65 6c 65 61 73 65 28 29 20  c(), xRelease() 
0640: 6f 72 0a 2a 2a 20 78 53 61 76 65 70 6f 69 6e 74  or.** xSavepoint
0650: 28 29 20 69 73 20 63 61 6c 6c 65 64 2e 20 41 6e  () is called. An
0660: 64 20 64 69 73 63 61 72 64 65 64 20 77 68 65 6e  d discarded when
0670: 65 76 65 72 20 78 52 6f 6c 6c 62 61 63 6b 28 29  ever xRollback()
0680: 20 6f 72 20 78 52 6f 6c 6c 62 61 63 6b 54 6f 28   or xRollbackTo(
0690: 29 20 0a 2a 2a 20 69 73 20 63 61 6c 6c 65 64 2e  ) .** is called.
06a0: 0a 2a 2a 0a 2a 2a 20 41 64 64 69 74 69 6f 6e 61  .**.** Additiona
06b0: 6c 6c 79 2c 20 69 66 20 53 51 4c 49 54 45 5f 44  lly, if SQLITE_D
06c0: 45 42 55 47 20 69 73 20 64 65 66 69 6e 65 64 2c  EBUG is defined,
06d0: 20 61 6e 20 69 6e 73 74 61 6e 63 65 20 6f 66 20   an instance of 
06e0: 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 0a 2a 2a  the following.**
06f0: 20 73 74 72 75 63 74 75 72 65 20 69 73 20 75 73   structure is us
0700: 65 64 20 74 6f 20 72 65 63 6f 72 64 20 74 68 65  ed to record the
0710: 20 63 75 72 72 65 6e 74 20 74 72 61 6e 73 61 63   current transac
0720: 74 69 6f 6e 20 73 74 61 74 65 2e 20 54 68 69 73  tion state. This
0730: 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 0a 2a 2a 20   information.** 
0740: 69 73 20 6e 6f 74 20 72 65 71 75 69 72 65 64 2c  is not required,
0750: 20 62 75 74 20 69 74 20 69 73 20 75 73 65 64 20   but it is used 
0760: 69 6e 20 74 68 65 20 61 73 73 65 72 74 28 29 20  in the assert() 
0770: 73 74 61 74 65 6d 65 6e 74 73 20 65 78 65 63 75  statements execu
0780: 74 65 64 20 62 79 0a 2a 2a 20 66 75 6e 63 74 69  ted by.** functi
0790: 6f 6e 20 66 74 73 35 43 68 65 63 6b 54 72 61 6e  on fts5CheckTran
07a0: 73 61 63 74 69 6f 6e 53 74 61 74 65 28 29 20 28  sactionState() (
07b0: 73 65 65 20 62 65 6c 6f 77 29 2e 0a 2a 2f 0a 73  see below)..*/.s
07c0: 74 72 75 63 74 20 46 74 73 35 54 72 61 6e 73 61  truct Fts5Transa
07d0: 63 74 69 6f 6e 53 74 61 74 65 20 7b 0a 20 20 69  ctionState {.  i
07e0: 6e 74 20 65 53 74 61 74 65 3b 20 20 20 20 20 20  nt eState;      
07f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
0800: 2a 20 30 3d 3d 63 6c 6f 73 65 64 2c 20 31 3d 3d  * 0==closed, 1==
0810: 6f 70 65 6e 2c 20 32 3d 3d 73 79 6e 63 65 64 20  open, 2==synced 
0820: 2a 2f 0a 20 20 69 6e 74 20 69 53 61 76 65 70 6f  */.  int iSavepo
0830: 69 6e 74 3b 20 20 20 20 20 20 20 20 20 20 20 20  int;            
0840: 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
0850: 66 20 6f 70 65 6e 20 73 61 76 65 70 6f 69 6e 74  f open savepoint
0860: 73 20 28 30 20 2d 3e 20 6e 6f 6e 65 29 20 2a 2f  s (0 -> none) */
0870: 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 41 20 73 69 6e  .};../*.** A sin
0880: 67 6c 65 20 6f 62 6a 65 63 74 20 6f 66 20 74 68  gle object of th
0890: 69 73 20 74 79 70 65 20 69 73 20 61 6c 6c 6f 63  is type is alloc
08a0: 61 74 65 64 20 77 68 65 6e 20 74 68 65 20 46 54  ated when the FT
08b0: 53 35 20 6d 6f 64 75 6c 65 20 69 73 20 0a 2a 2a  S5 module is .**
08c0: 20 72 65 67 69 73 74 65 72 65 64 20 77 69 74 68   registered with
08d0: 20 61 20 64 61 74 61 62 61 73 65 20 68 61 6e 64   a database hand
08e0: 6c 65 2e 20 49 74 20 69 73 20 75 73 65 64 20 74  le. It is used t
08f0: 6f 20 73 74 6f 72 65 20 70 6f 69 6e 74 65 72 73  o store pointers
0900: 20 74 6f 0a 2a 2a 20 61 6c 6c 20 72 65 67 69 73   to.** all regis
0910: 74 65 72 65 64 20 46 54 53 35 20 65 78 74 65 6e  tered FTS5 exten
0920: 73 69 6f 6e 73 20 2d 20 74 6f 6b 65 6e 69 7a 65  sions - tokenize
0930: 72 73 20 61 6e 64 20 61 75 78 69 6c 69 61 72 79  rs and auxiliary
0940: 20 66 75 6e 63 74 69 6f 6e 73 2e 0a 2a 2f 0a 73   functions..*/.s
0950: 74 72 75 63 74 20 46 74 73 35 47 6c 6f 62 61 6c  truct Fts5Global
0960: 20 7b 0a 20 20 66 74 73 35 5f 61 70 69 20 61 70   {.  fts5_api ap
0970: 69 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  i;              
0980: 20 20 20 20 20 2f 2a 20 55 73 65 72 20 76 69 73       /* User vis
0990: 69 62 6c 65 20 70 61 72 74 20 6f 66 20 6f 62 6a  ible part of obj
09a0: 65 63 74 20 28 73 65 65 20 66 74 73 35 2e 68 29  ect (see fts5.h)
09b0: 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 20 2a 64   */.  sqlite3 *d
09c0: 62 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  b;              
09d0: 20 20 20 20 20 20 2f 2a 20 41 73 73 6f 63 69 61        /* Associa
09e0: 74 65 64 20 64 61 74 61 62 61 73 65 20 63 6f 6e  ted database con
09f0: 6e 65 63 74 69 6f 6e 20 2a 2f 20 0a 20 20 69 36  nection */ .  i6
0a00: 34 20 69 4e 65 78 74 49 64 3b 20 20 20 20 20 20  4 iNextId;      
0a10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0a20: 20 55 73 65 64 20 74 6f 20 61 6c 6c 6f 63 61 74   Used to allocat
0a30: 65 20 75 6e 69 71 75 65 20 63 75 72 73 6f 72 20  e unique cursor 
0a40: 69 64 73 20 2a 2f 0a 20 20 46 74 73 35 41 75 78  ids */.  Fts5Aux
0a50: 69 6c 69 61 72 79 20 2a 70 41 75 78 3b 20 20 20  iliary *pAux;   
0a60: 20 20 20 20 20 20 20 20 20 2f 2a 20 46 69 72 73           /* Firs
0a70: 74 20 69 6e 20 6c 69 73 74 20 6f 66 20 61 6c 6c  t in list of all
0a80: 20 61 75 78 2e 20 66 75 6e 63 74 69 6f 6e 73 20   aux. functions 
0a90: 2a 2f 0a 20 20 46 74 73 35 54 6f 6b 65 6e 69 7a  */.  Fts5Tokeniz
0aa0: 65 72 4d 6f 64 75 6c 65 20 2a 70 54 6f 6b 3b 20  erModule *pTok; 
0ab0: 20 20 20 20 20 2f 2a 20 46 69 72 73 74 20 69 6e       /* First in
0ac0: 20 6c 69 73 74 20 6f 66 20 61 6c 6c 20 74 6f 6b   list of all tok
0ad0: 65 6e 69 7a 65 72 20 6d 6f 64 75 6c 65 73 20 2a  enizer modules *
0ae0: 2f 0a 20 20 46 74 73 35 43 75 72 73 6f 72 20 2a  /.  Fts5Cursor *
0af0: 70 43 73 72 3b 20 20 20 20 20 20 20 20 20 20 20  pCsr;           
0b00: 20 20 20 20 2f 2a 20 46 69 72 73 74 20 69 6e 20      /* First in 
0b10: 6c 69 73 74 20 6f 66 20 61 6c 6c 20 6f 70 65 6e  list of all open
0b20: 20 63 75 72 73 6f 72 73 20 2a 2f 0a 7d 3b 0a 0a   cursors */.};..
0b30: 2f 2a 0a 2a 2a 20 45 61 63 68 20 61 75 78 69 6c  /*.** Each auxil
0b40: 69 61 72 79 20 66 75 6e 63 74 69 6f 6e 20 72 65  iary function re
0b50: 67 69 73 74 65 72 65 64 20 77 69 74 68 20 74 68  gistered with th
0b60: 65 20 46 54 53 35 20 6d 6f 64 75 6c 65 20 69 73  e FTS5 module is
0b70: 20 72 65 70 72 65 73 65 6e 74 65 64 0a 2a 2a 20   represented.** 
0b80: 62 79 20 61 6e 20 6f 62 6a 65 63 74 20 6f 66 20  by an object of 
0b90: 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 74 79  the following ty
0ba0: 70 65 2e 20 41 6c 6c 20 73 75 63 68 20 6f 62 6a  pe. All such obj
0bb0: 65 63 74 73 20 61 72 65 20 73 74 6f 72 65 64 20  ects are stored 
0bc0: 61 73 20 70 61 72 74 0a 2a 2a 20 6f 66 20 74 68  as part.** of th
0bd0: 65 20 46 74 73 35 47 6c 6f 62 61 6c 2e 70 41 75  e Fts5Global.pAu
0be0: 78 20 6c 69 73 74 2e 0a 2a 2f 0a 73 74 72 75 63  x list..*/.struc
0bf0: 74 20 46 74 73 35 41 75 78 69 6c 69 61 72 79 20  t Fts5Auxiliary 
0c00: 7b 0a 20 20 46 74 73 35 47 6c 6f 62 61 6c 20 2a  {.  Fts5Global *
0c10: 70 47 6c 6f 62 61 6c 3b 20 20 20 20 20 20 20 20  pGlobal;        
0c20: 20 20 20 20 2f 2a 20 47 6c 6f 62 61 6c 20 63 6f      /* Global co
0c30: 6e 74 65 78 74 20 66 6f 72 20 74 68 69 73 20 66  ntext for this f
0c40: 75 6e 63 74 69 6f 6e 20 2a 2f 0a 20 20 63 68 61  unction */.  cha
0c50: 72 20 2a 7a 46 75 6e 63 3b 20 20 20 20 20 20 20  r *zFunc;       
0c60: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
0c70: 46 75 6e 63 74 69 6f 6e 20 6e 61 6d 65 20 28 6e  Function name (n
0c80: 75 6c 2d 74 65 72 6d 69 6e 61 74 65 64 29 20 2a  ul-terminated) *
0c90: 2f 0a 20 20 76 6f 69 64 20 2a 70 55 73 65 72 44  /.  void *pUserD
0ca0: 61 74 61 3b 20 20 20 20 20 20 20 20 20 20 20 20  ata;            
0cb0: 20 20 20 20 2f 2a 20 55 73 65 72 2d 64 61 74 61      /* User-data
0cc0: 20 70 6f 69 6e 74 65 72 20 2a 2f 0a 20 20 66 74   pointer */.  ft
0cd0: 73 35 5f 65 78 74 65 6e 73 69 6f 6e 5f 66 75 6e  s5_extension_fun
0ce0: 63 74 69 6f 6e 20 78 46 75 6e 63 3b 20 20 2f 2a  ction xFunc;  /*
0cf0: 20 43 61 6c 6c 62 61 63 6b 20 66 75 6e 63 74 69   Callback functi
0d00: 6f 6e 20 2a 2f 0a 20 20 76 6f 69 64 20 28 2a 78  on */.  void (*x
0d10: 44 65 73 74 72 6f 79 29 28 76 6f 69 64 2a 29 3b  Destroy)(void*);
0d20: 20 20 20 20 20 20 20 20 2f 2a 20 44 65 73 74 72          /* Destr
0d30: 75 63 74 6f 72 20 66 75 6e 63 74 69 6f 6e 20 2a  uctor function *
0d40: 2f 0a 20 20 46 74 73 35 41 75 78 69 6c 69 61 72  /.  Fts5Auxiliar
0d50: 79 20 2a 70 4e 65 78 74 3b 20 20 20 20 20 20 20  y *pNext;       
0d60: 20 20 20 20 2f 2a 20 4e 65 78 74 20 72 65 67 69      /* Next regi
0d70: 73 74 65 72 65 64 20 61 75 78 69 6c 69 61 72 79  stered auxiliary
0d80: 20 66 75 6e 63 74 69 6f 6e 20 2a 2f 0a 7d 3b 0a   function */.};.
0d90: 0a 2f 2a 0a 2a 2a 20 45 61 63 68 20 74 6f 6b 65  ./*.** Each toke
0da0: 6e 69 7a 65 72 20 6d 6f 64 75 6c 65 20 72 65 67  nizer module reg
0db0: 69 73 74 65 72 65 64 20 77 69 74 68 20 74 68 65  istered with the
0dc0: 20 46 54 53 35 20 6d 6f 64 75 6c 65 20 69 73 20   FTS5 module is 
0dd0: 72 65 70 72 65 73 65 6e 74 65 64 0a 2a 2a 20 62  represented.** b
0de0: 79 20 61 6e 20 6f 62 6a 65 63 74 20 6f 66 20 74  y an object of t
0df0: 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 74 79 70  he following typ
0e00: 65 2e 20 41 6c 6c 20 73 75 63 68 20 6f 62 6a 65  e. All such obje
0e10: 63 74 73 20 61 72 65 20 73 74 6f 72 65 64 20 61  cts are stored a
0e20: 73 20 70 61 72 74 0a 2a 2a 20 6f 66 20 74 68 65  s part.** of the
0e30: 20 46 74 73 35 47 6c 6f 62 61 6c 2e 70 54 6f 6b   Fts5Global.pTok
0e40: 20 6c 69 73 74 2e 0a 2a 2f 0a 73 74 72 75 63 74   list..*/.struct
0e50: 20 46 74 73 35 54 6f 6b 65 6e 69 7a 65 72 4d 6f   Fts5TokenizerMo
0e60: 64 75 6c 65 20 7b 0a 20 20 63 68 61 72 20 2a 7a  dule {.  char *z
0e70: 4e 61 6d 65 3b 20 20 20 20 20 20 20 20 20 20 20  Name;           
0e80: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65           /* Name
0e90: 20 6f 66 20 74 6f 6b 65 6e 69 7a 65 72 20 2a 2f   of tokenizer */
0ea0: 0a 20 20 76 6f 69 64 20 2a 70 55 73 65 72 44 61  .  void *pUserDa
0eb0: 74 61 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ta;             
0ec0: 20 20 20 2f 2a 20 55 73 65 72 20 70 6f 69 6e 74     /* User point
0ed0: 65 72 20 70 61 73 73 65 64 20 74 6f 20 78 43 72  er passed to xCr
0ee0: 65 61 74 65 28 29 20 2a 2f 0a 20 20 66 74 73 35  eate() */.  fts5
0ef0: 5f 74 6f 6b 65 6e 69 7a 65 72 20 78 3b 20 20 20  _tokenizer x;   
0f00: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
0f10: 6f 6b 65 6e 69 7a 65 72 20 66 75 6e 63 74 69 6f  okenizer functio
0f20: 6e 73 20 2a 2f 0a 20 20 76 6f 69 64 20 28 2a 78  ns */.  void (*x
0f30: 44 65 73 74 72 6f 79 29 28 76 6f 69 64 2a 29 3b  Destroy)(void*);
0f40: 20 20 20 20 20 20 20 20 2f 2a 20 44 65 73 74 72          /* Destr
0f50: 75 63 74 6f 72 20 66 75 6e 63 74 69 6f 6e 20 2a  uctor function *
0f60: 2f 0a 20 20 46 74 73 35 54 6f 6b 65 6e 69 7a 65  /.  Fts5Tokenize
0f70: 72 4d 6f 64 75 6c 65 20 2a 70 4e 65 78 74 3b 20  rModule *pNext; 
0f80: 20 20 20 20 2f 2a 20 4e 65 78 74 20 72 65 67 69      /* Next regi
0f90: 73 74 65 72 65 64 20 74 6f 6b 65 6e 69 7a 65 72  stered tokenizer
0fa0: 20 6d 6f 64 75 6c 65 20 2a 2f 0a 7d 3b 0a 0a 2f   module */.};../
0fb0: 2a 0a 2a 2a 20 56 69 72 74 75 61 6c 2d 74 61 62  *.** Virtual-tab
0fc0: 6c 65 20 6f 62 6a 65 63 74 2e 0a 2a 2f 0a 73 74  le object..*/.st
0fd0: 72 75 63 74 20 46 74 73 35 54 61 62 6c 65 20 7b  ruct Fts5Table {
0fe0: 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62 20  .  sqlite3_vtab 
0ff0: 62 61 73 65 3b 20 20 20 20 20 20 20 20 20 20 20  base;           
1000: 20 20 20 2f 2a 20 42 61 73 65 20 63 6c 61 73 73     /* Base class
1010: 20 75 73 65 64 20 62 79 20 53 51 4c 69 74 65 20   used by SQLite 
1020: 63 6f 72 65 20 2a 2f 0a 20 20 46 74 73 35 43 6f  core */.  Fts5Co
1030: 6e 66 69 67 20 2a 70 43 6f 6e 66 69 67 3b 20 20  nfig *pConfig;  
1040: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 56 69 72            /* Vir
1050: 74 75 61 6c 20 74 61 62 6c 65 20 63 6f 6e 66 69  tual table confi
1060: 67 75 72 61 74 69 6f 6e 20 2a 2f 0a 20 20 46 74  guration */.  Ft
1070: 73 35 49 6e 64 65 78 20 2a 70 49 6e 64 65 78 3b  s5Index *pIndex;
1080: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1090: 20 46 75 6c 6c 2d 74 65 78 74 20 69 6e 64 65 78   Full-text index
10a0: 20 2a 2f 0a 20 20 46 74 73 35 53 74 6f 72 61 67   */.  Fts5Storag
10b0: 65 20 2a 70 53 74 6f 72 61 67 65 3b 20 20 20 20  e *pStorage;    
10c0: 20 20 20 20 20 20 2f 2a 20 44 6f 63 75 6d 65 6e        /* Documen
10d0: 74 20 73 74 6f 72 65 20 2a 2f 0a 20 20 46 74 73  t store */.  Fts
10e0: 35 47 6c 6f 62 61 6c 20 2a 70 47 6c 6f 62 61 6c  5Global *pGlobal
10f0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ;            /* 
1100: 47 6c 6f 62 61 6c 20 28 63 6f 6e 6e 65 63 74 69  Global (connecti
1110: 6f 6e 20 77 69 64 65 29 20 64 61 74 61 20 2a 2f  on wide) data */
1120: 0a 20 20 46 74 73 35 43 75 72 73 6f 72 20 2a 70  .  Fts5Cursor *p
1130: 53 6f 72 74 43 73 72 3b 20 20 20 20 20 20 20 20  SortCsr;        
1140: 20 20 20 2f 2a 20 53 6f 72 74 20 64 61 74 61 20     /* Sort data 
1150: 66 72 6f 6d 20 74 68 69 73 20 63 75 72 73 6f 72  from this cursor
1160: 20 2a 2f 0a 23 69 66 64 65 66 20 53 51 4c 49 54   */.#ifdef SQLIT
1170: 45 5f 44 45 42 55 47 0a 20 20 73 74 72 75 63 74  E_DEBUG.  struct
1180: 20 46 74 73 35 54 72 61 6e 73 61 63 74 69 6f 6e   Fts5Transaction
1190: 53 74 61 74 65 20 74 73 3b 0a 23 65 6e 64 69 66  State ts;.#endif
11a0: 0a 7d 3b 0a 0a 73 74 72 75 63 74 20 46 74 73 35  .};..struct Fts5
11b0: 4d 61 74 63 68 50 68 72 61 73 65 20 7b 0a 20 20  MatchPhrase {.  
11c0: 46 74 73 35 42 75 66 66 65 72 20 2a 70 50 6f 73  Fts5Buffer *pPos
11d0: 6c 69 73 74 3b 20 20 20 20 20 20 20 20 20 20 20  list;           
11e0: 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 63 75  /* Pointer to cu
11f0: 72 72 65 6e 74 20 70 6f 73 6c 69 73 74 20 2a 2f  rrent poslist */
1200: 0a 20 20 69 6e 74 20 6e 54 65 72 6d 3b 20 20 20  .  int nTerm;   
1210: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1220: 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 70 68     /* Size of ph
1230: 72 61 73 65 20 69 6e 20 74 65 72 6d 73 20 2a 2f  rase in terms */
1240: 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 70 53 74 6d 74  .};../*.** pStmt
1250: 3a 0a 2a 2a 20 20 20 53 45 4c 45 43 54 20 72 6f  :.**   SELECT ro
1260: 77 69 64 2c 20 3c 66 74 73 3e 20 46 52 4f 4d 20  wid, <fts> FROM 
1270: 3c 66 74 73 3e 20 4f 52 44 45 52 20 42 59 20 2b  <fts> ORDER BY +
1280: 72 61 6e 6b 3b 0a 2a 2a 0a 2a 2a 20 61 49 64 78  rank;.**.** aIdx
1290: 5b 5d 3a 0a 2a 2a 20 20 20 54 68 65 72 65 20 69  []:.**   There i
12a0: 73 20 6f 6e 65 20 65 6e 74 72 79 20 69 6e 20 74  s one entry in t
12b0: 68 65 20 61 49 64 78 5b 5d 20 61 72 72 61 79 20  he aIdx[] array 
12c0: 66 6f 72 20 65 61 63 68 20 70 68 72 61 73 65 20  for each phrase 
12d0: 69 6e 20 74 68 65 20 71 75 65 72 79 2c 0a 2a 2a  in the query,.**
12e0: 20 20 20 74 68 65 20 76 61 6c 75 65 20 6f 66 20     the value of 
12f0: 77 68 69 63 68 20 69 73 20 74 68 65 20 6f 66 66  which is the off
1300: 73 65 74 20 77 69 74 68 69 6e 20 61 50 6f 73 6c  set within aPosl
1310: 69 73 74 5b 5d 20 66 6f 6c 6c 6f 77 69 6e 67 20  ist[] following 
1320: 74 68 65 20 6c 61 73 74 20 0a 2a 2a 20 20 20 62  the last .**   b
1330: 79 74 65 20 6f 66 20 74 68 65 20 70 6f 73 69 74  yte of the posit
1340: 69 6f 6e 20 6c 69 73 74 20 66 6f 72 20 74 68 65  ion list for the
1350: 20 63 6f 72 72 65 73 70 6f 6e 64 69 6e 67 20 70   corresponding p
1360: 68 72 61 73 65 2e 0a 2a 2f 0a 73 74 72 75 63 74  hrase..*/.struct
1370: 20 46 74 73 35 53 6f 72 74 65 72 20 7b 0a 20 20   Fts5Sorter {.  
1380: 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 53  sqlite3_stmt *pS
1390: 74 6d 74 3b 0a 20 20 69 36 34 20 69 52 6f 77 69  tmt;.  i64 iRowi
13a0: 64 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  d;              
13b0: 20 20 20 20 20 20 20 2f 2a 20 43 75 72 72 65 6e         /* Curren
13c0: 74 20 72 6f 77 69 64 20 2a 2f 0a 20 20 63 6f 6e  t rowid */.  con
13d0: 73 74 20 75 38 20 2a 61 50 6f 73 6c 69 73 74 3b  st u8 *aPoslist;
13e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
13f0: 50 6f 73 69 74 69 6f 6e 20 6c 69 73 74 73 20 66  Position lists f
1400: 6f 72 20 63 75 72 72 65 6e 74 20 72 6f 77 20 2a  or current row *
1410: 2f 0a 20 20 69 6e 74 20 6e 49 64 78 3b 20 20 20  /.  int nIdx;   
1420: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1430: 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66      /* Number of
1440: 20 65 6e 74 72 69 65 73 20 69 6e 20 61 49 64 78   entries in aIdx
1450: 5b 5d 20 2a 2f 0a 20 20 69 6e 74 20 61 49 64 78  [] */.  int aIdx
1460: 5b 30 5d 3b 20 20 20 20 20 20 20 20 20 20 20 20  [0];            
1470: 20 20 20 20 20 20 20 20 2f 2a 20 4f 66 66 73 65          /* Offse
1480: 74 73 20 69 6e 74 6f 20 61 50 6f 73 6c 69 73 74  ts into aPoslist
1490: 20 66 6f 72 20 63 75 72 72 65 6e 74 20 72 6f 77   for current row
14a0: 20 2a 2f 0a 7d 3b 0a 0a 0a 2f 2a 0a 2a 2a 20 56   */.};.../*.** V
14b0: 69 72 74 75 61 6c 2d 74 61 62 6c 65 20 63 75 72  irtual-table cur
14c0: 73 6f 72 20 6f 62 6a 65 63 74 2e 0a 2a 2a 0a 2a  sor object..**.*
14d0: 2a 20 7a 53 70 65 63 69 61 6c 3a 0a 2a 2a 20 20  * zSpecial:.**  
14e0: 20 49 66 20 74 68 69 73 20 69 73 20 61 20 27 73   If this is a 's
14f0: 70 65 63 69 61 6c 27 20 71 75 65 72 79 20 28 72  pecial' query (r
1500: 65 66 65 72 20 74 6f 20 66 75 6e 63 74 69 6f 6e  efer to function
1510: 20 66 74 73 35 53 70 65 63 69 61 6c 4d 61 74 63   fts5SpecialMatc
1520: 68 28 29 29 2c 20 0a 2a 2a 20 20 20 74 68 65 6e  h()), .**   then
1530: 20 74 68 69 73 20 76 61 72 69 61 62 6c 65 20 70   this variable p
1540: 6f 69 6e 74 73 20 74 6f 20 61 20 6e 75 6c 2d 74  oints to a nul-t
1550: 65 72 6d 69 6e 61 74 65 64 20 62 75 66 66 65 72  erminated buffer
1560: 20 63 6f 6e 74 61 69 6e 69 6e 67 20 74 68 65 0a   containing the.
1570: 2a 2a 20 20 20 72 65 73 75 6c 74 20 74 6f 20 72  **   result to r
1580: 65 74 75 72 6e 20 74 68 72 6f 75 67 68 20 74 68  eturn through th
1590: 65 20 74 61 62 6c 65 2d 6e 61 6d 65 20 63 6f 6c  e table-name col
15a0: 75 6d 6e 2e 20 49 74 20 69 73 20 6e 75 6c 2d 74  umn. It is nul-t
15b0: 65 72 6d 69 6e 61 74 65 64 0a 2a 2a 20 20 20 61  erminated.**   a
15c0: 6e 64 20 73 68 6f 75 6c 64 20 65 76 65 6e 74 75  nd should eventu
15d0: 61 6c 6c 79 20 62 65 20 66 72 65 65 64 20 75 73  ally be freed us
15e0: 69 6e 67 20 73 71 6c 69 74 65 33 5f 66 72 65 65  ing sqlite3_free
15f0: 28 29 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 46 74  ()..*/.struct Ft
1600: 73 35 43 75 72 73 6f 72 20 7b 0a 20 20 73 71 6c  s5Cursor {.  sql
1610: 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72  ite3_vtab_cursor
1620: 20 62 61 73 65 3b 20 20 20 20 20 20 20 2f 2a 20   base;       /* 
1630: 42 61 73 65 20 63 6c 61 73 73 20 75 73 65 64 20  Base class used 
1640: 62 79 20 53 51 4c 69 74 65 20 63 6f 72 65 20 2a  by SQLite core *
1650: 2f 0a 20 20 69 6e 74 20 69 64 78 4e 75 6d 3b 20  /.  int idxNum; 
1660: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1670: 20 20 20 20 2f 2a 20 69 64 78 4e 75 6d 20 70 61      /* idxNum pa
1680: 73 73 65 64 20 74 6f 20 78 46 69 6c 74 65 72 28  ssed to xFilter(
1690: 29 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 73  ) */.  sqlite3_s
16a0: 74 6d 74 20 2a 70 53 74 6d 74 3b 20 20 20 20 20  tmt *pStmt;     
16b0: 20 20 20 20 20 20 20 2f 2a 20 53 74 61 74 65 6d         /* Statem
16c0: 65 6e 74 20 75 73 65 64 20 74 6f 20 72 65 61 64  ent used to read
16d0: 20 25 5f 63 6f 6e 74 65 6e 74 20 2a 2f 0a 20 20   %_content */.  
16e0: 46 74 73 35 45 78 70 72 20 2a 70 45 78 70 72 3b  Fts5Expr *pExpr;
16f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1700: 2f 2a 20 45 78 70 72 65 73 73 69 6f 6e 20 66 6f  /* Expression fo
1710: 72 20 4d 41 54 43 48 20 71 75 65 72 69 65 73 20  r MATCH queries 
1720: 2a 2f 0a 20 20 46 74 73 35 53 6f 72 74 65 72 20  */.  Fts5Sorter 
1730: 2a 70 53 6f 72 74 65 72 3b 20 20 20 20 20 20 20  *pSorter;       
1740: 20 20 20 20 20 2f 2a 20 53 6f 72 74 65 72 20 66       /* Sorter f
1750: 6f 72 20 22 4f 52 44 45 52 20 42 59 20 72 61 6e  or "ORDER BY ran
1760: 6b 22 20 71 75 65 72 69 65 73 20 2a 2f 0a 20 20  k" queries */.  
1770: 69 6e 74 20 63 73 72 66 6c 61 67 73 3b 20 20 20  int csrflags;   
1780: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1790: 2f 2a 20 4d 61 73 6b 20 6f 66 20 63 75 72 73 6f  /* Mask of curso
17a0: 72 20 66 6c 61 67 73 20 28 73 65 65 20 62 65 6c  r flags (see bel
17b0: 6f 77 29 20 2a 2f 0a 20 20 46 74 73 35 43 75 72  ow) */.  Fts5Cur
17c0: 73 6f 72 20 2a 70 4e 65 78 74 3b 20 20 20 20 20  sor *pNext;     
17d0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 65 78 74           /* Next
17e0: 20 63 75 72 73 6f 72 20 69 6e 20 46 74 73 35 43   cursor in Fts5C
17f0: 75 72 73 6f 72 2e 70 43 73 72 20 6c 69 73 74 20  ursor.pCsr list 
1800: 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 53 70 65 63  */.  char *zSpec
1810: 69 61 6c 3b 20 20 20 20 20 20 20 20 20 20 20 20  ial;            
1820: 20 20 20 20 20 2f 2a 20 52 65 73 75 6c 74 20 6f       /* Result o
1830: 66 20 73 70 65 63 69 61 6c 20 71 75 65 72 79 20  f special query 
1840: 2a 2f 0a 0a 20 20 2f 2a 20 22 72 61 6e 6b 22 20  */..  /* "rank" 
1850: 66 75 6e 63 74 69 6f 6e 2e 20 50 6f 70 75 6c 61  function. Popula
1860: 74 65 64 20 6f 6e 20 64 65 6d 61 6e 64 20 66 72  ted on demand fr
1870: 6f 6d 20 76 74 61 62 2e 78 43 6f 6c 75 6d 6e 28  om vtab.xColumn(
1880: 29 2e 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 52  ). */.  char *zR
1890: 61 6e 6b 3b 20 20 20 20 20 20 20 20 20 20 20 20  ank;            
18a0: 20 20 20 20 20 20 20 20 2f 2a 20 43 75 73 74 6f          /* Custo
18b0: 6d 20 72 61 6e 6b 20 66 75 6e 63 74 69 6f 6e 20  m rank function 
18c0: 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 52 61 6e 6b  */.  char *zRank
18d0: 41 72 67 73 3b 20 20 20 20 20 20 20 20 20 20 20  Args;           
18e0: 20 20 20 20 20 2f 2a 20 43 75 73 74 6f 6d 20 72       /* Custom r
18f0: 61 6e 6b 20 66 75 6e 63 74 69 6f 6e 20 61 72 67  ank function arg
1900: 73 20 2a 2f 0a 20 20 46 74 73 35 41 75 78 69 6c  s */.  Fts5Auxil
1910: 69 61 72 79 20 2a 70 52 61 6e 6b 3b 20 20 20 20  iary *pRank;    
1920: 20 20 20 20 20 20 20 2f 2a 20 52 61 6e 6b 20 63         /* Rank c
1930: 61 6c 6c 62 61 63 6b 20 28 6f 72 20 4e 55 4c 4c  allback (or NULL
1940: 29 20 2a 2f 0a 20 20 69 6e 74 20 6e 52 61 6e 6b  ) */.  int nRank
1950: 41 72 67 3b 20 20 20 20 20 20 20 20 20 20 20 20  Arg;            
1960: 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
1970: 20 6f 66 20 74 72 61 69 6c 69 6e 67 20 61 72 67   of trailing arg
1980: 75 6d 65 6e 74 73 20 66 6f 72 20 72 61 6e 6b 28  uments for rank(
1990: 29 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 76  ) */.  sqlite3_v
19a0: 61 6c 75 65 20 2a 2a 61 70 52 61 6e 6b 41 72 67  alue **apRankArg
19b0: 3b 20 20 20 20 20 20 2f 2a 20 41 72 72 61 79 20  ;      /* Array 
19c0: 6f 66 20 74 72 61 69 6c 69 6e 67 20 61 72 67 75  of trailing argu
19d0: 6d 65 6e 74 73 20 2a 2f 0a 20 20 73 71 6c 69 74  ments */.  sqlit
19e0: 65 33 5f 73 74 6d 74 20 2a 70 52 61 6e 6b 41 72  e3_stmt *pRankAr
19f0: 67 53 74 6d 74 3b 20 20 20 20 20 2f 2a 20 4f 72  gStmt;     /* Or
1a00: 69 67 69 6e 20 6f 66 20 6f 62 6a 65 63 74 73 20  igin of objects 
1a10: 69 6e 20 61 70 52 61 6e 6b 41 72 67 5b 5d 20 2a  in apRankArg[] *
1a20: 2f 0a 0a 20 20 2f 2a 20 56 61 72 69 61 62 6c 65  /..  /* Variable
1a30: 73 20 75 73 65 64 20 62 79 20 61 75 78 69 6c 69  s used by auxili
1a40: 61 72 79 20 66 75 6e 63 74 69 6f 6e 73 20 2a 2f  ary functions */
1a50: 0a 20 20 69 36 34 20 69 43 73 72 49 64 3b 20 20  .  i64 iCsrId;  
1a60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1a70: 20 20 20 2f 2a 20 43 75 72 73 6f 72 20 69 64 20     /* Cursor id 
1a80: 2a 2f 0a 20 20 46 74 73 35 41 75 78 69 6c 69 61  */.  Fts5Auxilia
1a90: 72 79 20 2a 70 41 75 78 3b 20 20 20 20 20 20 20  ry *pAux;       
1aa0: 20 20 20 20 20 2f 2a 20 43 75 72 72 65 6e 74 6c       /* Currentl
1ab0: 79 20 65 78 65 63 75 74 69 6e 67 20 65 78 74 65  y executing exte
1ac0: 6e 73 69 6f 6e 20 66 75 6e 63 74 69 6f 6e 20 2a  nsion function *
1ad0: 2f 0a 20 20 46 74 73 35 41 75 78 64 61 74 61 20  /.  Fts5Auxdata 
1ae0: 2a 70 41 75 78 64 61 74 61 3b 20 20 20 20 20 20  *pAuxdata;      
1af0: 20 20 20 20 2f 2a 20 46 69 72 73 74 20 69 6e 20      /* First in 
1b00: 6c 69 6e 6b 65 64 20 6c 69 73 74 20 6f 66 20 73  linked list of s
1b10: 61 76 65 64 20 61 75 78 2d 64 61 74 61 20 2a 2f  aved aux-data */
1b20: 0a 20 20 69 6e 74 20 2a 61 43 6f 6c 75 6d 6e 53  .  int *aColumnS
1b30: 69 7a 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  ize;            
1b40: 20 20 20 2f 2a 20 56 61 6c 75 65 73 20 66 6f 72     /* Values for
1b50: 20 78 43 6f 6c 75 6d 6e 53 69 7a 65 28 29 20 2a   xColumnSize() *
1b60: 2f 0a 0a 20 20 69 6e 74 20 6e 49 6e 73 74 43 6f  /..  int nInstCo
1b70: 75 6e 74 3b 20 20 20 20 20 20 20 20 20 20 20 20  unt;            
1b80: 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
1b90: 66 20 70 68 72 61 73 65 20 69 6e 73 74 61 6e 63  f phrase instanc
1ba0: 65 73 20 2a 2f 0a 20 20 69 6e 74 20 2a 61 49 6e  es */.  int *aIn
1bb0: 73 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  st;             
1bc0: 20 20 20 20 20 20 20 20 2f 2a 20 33 20 69 6e 74          /* 3 int
1bd0: 65 67 65 72 73 20 70 65 72 20 70 68 72 61 73 65  egers per phrase
1be0: 20 69 6e 73 74 61 6e 63 65 20 2a 2f 0a 7d 3b 0a   instance */.};.
1bf0: 0a 2f 2a 0a 2a 2a 20 56 61 6c 75 65 73 20 66 6f  ./*.** Values fo
1c00: 72 20 46 74 73 35 43 75 72 73 6f 72 2e 63 73 72  r Fts5Cursor.csr
1c10: 66 6c 61 67 73 0a 2a 2f 0a 23 64 65 66 69 6e 65  flags.*/.#define
1c20: 20 46 54 53 35 43 53 52 5f 52 45 51 55 49 52 45   FTS5CSR_REQUIRE
1c30: 5f 43 4f 4e 54 45 4e 54 20 20 20 30 78 30 31 0a  _CONTENT   0x01.
1c40: 23 64 65 66 69 6e 65 20 46 54 53 35 43 53 52 5f  #define FTS5CSR_
1c50: 52 45 51 55 49 52 45 5f 44 4f 43 53 49 5a 45 20  REQUIRE_DOCSIZE 
1c60: 20 20 30 78 30 32 0a 23 64 65 66 69 6e 65 20 46    0x02.#define F
1c70: 54 53 35 43 53 52 5f 45 4f 46 20 20 20 20 20 20  TS5CSR_EOF      
1c80: 20 20 20 20 20 20 20 20 20 30 78 30 34 0a 23 64           0x04.#d
1c90: 65 66 69 6e 65 20 46 54 53 35 43 53 52 5f 46 52  efine FTS5CSR_FR
1ca0: 45 45 5f 5a 52 41 4e 4b 20 20 20 20 20 20 20 20  EE_ZRANK        
1cb0: 30 78 30 38 0a 0a 2f 2a 0a 2a 2a 20 4d 61 63 72  0x08../*.** Macr
1cc0: 6f 73 20 74 6f 20 53 65 74 28 29 2c 20 43 6c 65  os to Set(), Cle
1cd0: 61 72 28 29 20 61 6e 64 20 54 65 73 74 28 29 20  ar() and Test() 
1ce0: 63 75 72 73 6f 72 20 66 6c 61 67 73 2e 0a 2a 2f  cursor flags..*/
1cf0: 0a 23 64 65 66 69 6e 65 20 43 73 72 46 6c 61 67  .#define CsrFlag
1d00: 53 65 74 28 70 43 73 72 2c 20 66 6c 61 67 29 20  Set(pCsr, flag) 
1d10: 20 20 28 28 70 43 73 72 29 2d 3e 63 73 72 66 6c    ((pCsr)->csrfl
1d20: 61 67 73 20 7c 3d 20 28 66 6c 61 67 29 29 0a 23  ags |= (flag)).#
1d30: 64 65 66 69 6e 65 20 43 73 72 46 6c 61 67 43 6c  define CsrFlagCl
1d40: 65 61 72 28 70 43 73 72 2c 20 66 6c 61 67 29 20  ear(pCsr, flag) 
1d50: 28 28 70 43 73 72 29 2d 3e 63 73 72 66 6c 61 67  ((pCsr)->csrflag
1d60: 73 20 26 3d 20 7e 28 66 6c 61 67 29 29 0a 23 64  s &= ~(flag)).#d
1d70: 65 66 69 6e 65 20 43 73 72 46 6c 61 67 54 65 73  efine CsrFlagTes
1d80: 74 28 70 43 73 72 2c 20 66 6c 61 67 29 20 20 28  t(pCsr, flag)  (
1d90: 28 70 43 73 72 29 2d 3e 63 73 72 66 6c 61 67 73  (pCsr)->csrflags
1da0: 20 26 20 28 66 6c 61 67 29 29 0a 0a 73 74 72 75   & (flag))..stru
1db0: 63 74 20 46 74 73 35 41 75 78 64 61 74 61 20 7b  ct Fts5Auxdata {
1dc0: 0a 20 20 46 74 73 35 41 75 78 69 6c 69 61 72 79  .  Fts5Auxiliary
1dd0: 20 2a 70 41 75 78 3b 20 20 20 20 20 20 20 20 20   *pAux;         
1de0: 20 20 20 2f 2a 20 45 78 74 65 6e 73 69 6f 6e 20     /* Extension 
1df0: 74 6f 20 77 68 69 63 68 20 74 68 69 73 20 62 65  to which this be
1e00: 6c 6f 6e 67 73 20 2a 2f 0a 20 20 76 6f 69 64 20  longs */.  void 
1e10: 2a 70 50 74 72 3b 20 20 20 20 20 20 20 20 20 20  *pPtr;          
1e20: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 6f             /* Po
1e30: 69 6e 74 65 72 20 76 61 6c 75 65 20 2a 2f 0a 20  inter value */. 
1e40: 20 76 6f 69 64 28 2a 78 44 65 6c 65 74 65 29 28   void(*xDelete)(
1e50: 76 6f 69 64 2a 29 3b 20 20 20 20 20 20 20 20 20  void*);         
1e60: 20 2f 2a 20 44 65 73 74 72 75 63 74 6f 72 20 2a   /* Destructor *
1e70: 2f 0a 20 20 46 74 73 35 41 75 78 64 61 74 61 20  /.  Fts5Auxdata 
1e80: 2a 70 4e 65 78 74 3b 20 20 20 20 20 20 20 20 20  *pNext;         
1e90: 20 20 20 20 2f 2a 20 4e 65 78 74 20 6f 62 6a 65      /* Next obje
1ea0: 63 74 20 69 6e 20 6c 69 6e 6b 65 64 20 6c 69 73  ct in linked lis
1eb0: 74 20 2a 2f 0a 7d 3b 0a 0a 23 69 66 64 65 66 20  t */.};..#ifdef 
1ec0: 53 51 4c 49 54 45 5f 44 45 42 55 47 0a 23 64 65  SQLITE_DEBUG.#de
1ed0: 66 69 6e 65 20 46 54 53 35 5f 42 45 47 49 4e 20  fine FTS5_BEGIN 
1ee0: 20 20 20 20 20 31 0a 23 64 65 66 69 6e 65 20 46       1.#define F
1ef0: 54 53 35 5f 53 59 4e 43 20 20 20 20 20 20 20 32  TS5_SYNC       2
1f00: 0a 23 64 65 66 69 6e 65 20 46 54 53 35 5f 43 4f  .#define FTS5_CO
1f10: 4d 4d 49 54 20 20 20 20 20 33 0a 23 64 65 66 69  MMIT     3.#defi
1f20: 6e 65 20 46 54 53 35 5f 52 4f 4c 4c 42 41 43 4b  ne FTS5_ROLLBACK
1f30: 20 20 20 34 0a 23 64 65 66 69 6e 65 20 46 54 53     4.#define FTS
1f40: 35 5f 53 41 56 45 50 4f 49 4e 54 20 20 35 0a 23  5_SAVEPOINT  5.#
1f50: 64 65 66 69 6e 65 20 46 54 53 35 5f 52 45 4c 45  define FTS5_RELE
1f60: 41 53 45 20 20 20 20 36 0a 23 64 65 66 69 6e 65  ASE    6.#define
1f70: 20 46 54 53 35 5f 52 4f 4c 4c 42 41 43 4b 54 4f   FTS5_ROLLBACKTO
1f80: 20 37 0a 73 74 61 74 69 63 20 76 6f 69 64 20 66   7.static void f
1f90: 74 73 35 43 68 65 63 6b 54 72 61 6e 73 61 63 74  ts5CheckTransact
1fa0: 69 6f 6e 53 74 61 74 65 28 46 74 73 35 54 61 62  ionState(Fts5Tab
1fb0: 6c 65 20 2a 70 2c 20 69 6e 74 20 6f 70 2c 20 69  le *p, int op, i
1fc0: 6e 74 20 69 53 61 76 65 70 6f 69 6e 74 29 7b 0a  nt iSavepoint){.
1fd0: 20 20 73 77 69 74 63 68 28 20 6f 70 20 29 7b 0a    switch( op ){.
1fe0: 20 20 20 20 63 61 73 65 20 46 54 53 35 5f 42 45      case FTS5_BE
1ff0: 47 49 4e 3a 0a 20 20 20 20 20 20 61 73 73 65 72  GIN:.      asser
2000: 74 28 20 70 2d 3e 74 73 2e 65 53 74 61 74 65 3d  t( p->ts.eState=
2010: 3d 30 20 29 3b 0a 20 20 20 20 20 20 70 2d 3e 74  =0 );.      p->t
2020: 73 2e 65 53 74 61 74 65 20 3d 20 31 3b 0a 20 20  s.eState = 1;.  
2030: 20 20 20 20 70 2d 3e 74 73 2e 69 53 61 76 65 70      p->ts.iSavep
2040: 6f 69 6e 74 20 3d 20 2d 31 3b 0a 20 20 20 20 20  oint = -1;.     
2050: 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20 63 61 73   break;..    cas
2060: 65 20 46 54 53 35 5f 53 59 4e 43 3a 0a 20 20 20  e FTS5_SYNC:.   
2070: 20 20 20 61 73 73 65 72 74 28 20 70 2d 3e 74 73     assert( p->ts
2080: 2e 65 53 74 61 74 65 3d 3d 31 20 29 3b 0a 20 20  .eState==1 );.  
2090: 20 20 20 20 70 2d 3e 74 73 2e 65 53 74 61 74 65      p->ts.eState
20a0: 20 3d 20 32 3b 0a 20 20 20 20 20 20 62 72 65 61   = 2;.      brea
20b0: 6b 3b 0a 0a 20 20 20 20 63 61 73 65 20 46 54 53  k;..    case FTS
20c0: 35 5f 43 4f 4d 4d 49 54 3a 0a 20 20 20 20 20 20  5_COMMIT:.      
20d0: 61 73 73 65 72 74 28 20 70 2d 3e 74 73 2e 65 53  assert( p->ts.eS
20e0: 74 61 74 65 3d 3d 32 20 29 3b 0a 20 20 20 20 20  tate==2 );.     
20f0: 20 70 2d 3e 74 73 2e 65 53 74 61 74 65 20 3d 20   p->ts.eState = 
2100: 30 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a  0;.      break;.
2110: 0a 20 20 20 20 63 61 73 65 20 46 54 53 35 5f 52  .    case FTS5_R
2120: 4f 4c 4c 42 41 43 4b 3a 0a 20 20 20 20 20 20 61  OLLBACK:.      a
2130: 73 73 65 72 74 28 20 70 2d 3e 74 73 2e 65 53 74  ssert( p->ts.eSt
2140: 61 74 65 3d 3d 31 20 7c 7c 20 70 2d 3e 74 73 2e  ate==1 || p->ts.
2150: 65 53 74 61 74 65 3d 3d 32 20 7c 7c 20 70 2d 3e  eState==2 || p->
2160: 74 73 2e 65 53 74 61 74 65 3d 3d 30 20 29 3b 0a  ts.eState==0 );.
2170: 20 20 20 20 20 20 70 2d 3e 74 73 2e 65 53 74 61        p->ts.eSta
2180: 74 65 20 3d 20 30 3b 0a 20 20 20 20 20 20 62 72  te = 0;.      br
2190: 65 61 6b 3b 0a 0a 20 20 20 20 63 61 73 65 20 46  eak;..    case F
21a0: 54 53 35 5f 53 41 56 45 50 4f 49 4e 54 3a 0a 20  TS5_SAVEPOINT:. 
21b0: 20 20 20 20 20 61 73 73 65 72 74 28 20 70 2d 3e       assert( p->
21c0: 74 73 2e 65 53 74 61 74 65 3d 3d 31 20 29 3b 0a  ts.eState==1 );.
21d0: 20 20 20 20 20 20 61 73 73 65 72 74 28 20 69 53        assert( iS
21e0: 61 76 65 70 6f 69 6e 74 3e 3d 30 20 29 3b 0a 20  avepoint>=0 );. 
21f0: 20 20 20 20 20 61 73 73 65 72 74 28 20 69 53 61       assert( iSa
2200: 76 65 70 6f 69 6e 74 3e 70 2d 3e 74 73 2e 69 53  vepoint>p->ts.iS
2210: 61 76 65 70 6f 69 6e 74 20 29 3b 0a 20 20 20 20  avepoint );.    
2220: 20 20 70 2d 3e 74 73 2e 69 53 61 76 65 70 6f 69    p->ts.iSavepoi
2230: 6e 74 20 3d 20 69 53 61 76 65 70 6f 69 6e 74 3b  nt = iSavepoint;
2240: 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20  .      break;.  
2250: 20 20 20 20 0a 20 20 20 20 63 61 73 65 20 46 54      .    case FT
2260: 53 35 5f 52 45 4c 45 41 53 45 3a 0a 20 20 20 20  S5_RELEASE:.    
2270: 20 20 61 73 73 65 72 74 28 20 70 2d 3e 74 73 2e    assert( p->ts.
2280: 65 53 74 61 74 65 3d 3d 31 20 29 3b 0a 20 20 20  eState==1 );.   
2290: 20 20 20 61 73 73 65 72 74 28 20 69 53 61 76 65     assert( iSave
22a0: 70 6f 69 6e 74 3e 3d 30 20 29 3b 0a 20 20 20 20  point>=0 );.    
22b0: 20 20 61 73 73 65 72 74 28 20 69 53 61 76 65 70    assert( iSavep
22c0: 6f 69 6e 74 3c 3d 70 2d 3e 74 73 2e 69 53 61 76  oint<=p->ts.iSav
22d0: 65 70 6f 69 6e 74 20 29 3b 0a 20 20 20 20 20 20  epoint );.      
22e0: 70 2d 3e 74 73 2e 69 53 61 76 65 70 6f 69 6e 74  p->ts.iSavepoint
22f0: 20 3d 20 69 53 61 76 65 70 6f 69 6e 74 2d 31 3b   = iSavepoint-1;
2300: 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 0a 20  .      break;.. 
2310: 20 20 20 63 61 73 65 20 46 54 53 35 5f 52 4f 4c     case FTS5_ROL
2320: 4c 42 41 43 4b 54 4f 3a 0a 20 20 20 20 20 20 61  LBACKTO:.      a
2330: 73 73 65 72 74 28 20 70 2d 3e 74 73 2e 65 53 74  ssert( p->ts.eSt
2340: 61 74 65 3d 3d 31 20 29 3b 0a 20 20 20 20 20 20  ate==1 );.      
2350: 61 73 73 65 72 74 28 20 69 53 61 76 65 70 6f 69  assert( iSavepoi
2360: 6e 74 3e 3d 30 20 29 3b 0a 20 20 20 20 20 20 61  nt>=0 );.      a
2370: 73 73 65 72 74 28 20 69 53 61 76 65 70 6f 69 6e  ssert( iSavepoin
2380: 74 3c 3d 70 2d 3e 74 73 2e 69 53 61 76 65 70 6f  t<=p->ts.iSavepo
2390: 69 6e 74 20 29 3b 0a 20 20 20 20 20 20 70 2d 3e  int );.      p->
23a0: 74 73 2e 69 53 61 76 65 70 6f 69 6e 74 20 3d 20  ts.iSavepoint = 
23b0: 69 53 61 76 65 70 6f 69 6e 74 3b 0a 20 20 20 20  iSavepoint;.    
23c0: 20 20 62 72 65 61 6b 3b 0a 20 20 7d 0a 7d 0a 23    break;.  }.}.#
23d0: 65 6c 73 65 0a 23 20 64 65 66 69 6e 65 20 66 74  else.# define ft
23e0: 73 35 43 68 65 63 6b 54 72 61 6e 73 61 63 74 69  s5CheckTransacti
23f0: 6f 6e 53 74 61 74 65 28 78 2c 79 2c 7a 29 0a 23  onState(x,y,z).#
2400: 65 6e 64 69 66 0a 0a 2f 2a 0a 2a 2a 20 52 65 74  endif../*.** Ret
2410: 75 72 6e 20 74 72 75 65 20 69 66 20 70 54 61 62  urn true if pTab
2420: 20 69 73 20 61 20 63 6f 6e 74 65 6e 74 6c 65 73   is a contentles
2430: 73 20 74 61 62 6c 65 2e 0a 2a 2f 0a 73 74 61 74  s table..*/.stat
2440: 69 63 20 69 6e 74 20 66 74 73 35 49 73 43 6f 6e  ic int fts5IsCon
2450: 74 65 6e 74 6c 65 73 73 28 46 74 73 35 54 61 62  tentless(Fts5Tab
2460: 6c 65 20 2a 70 54 61 62 29 7b 0a 20 20 72 65 74  le *pTab){.  ret
2470: 75 72 6e 20 70 54 61 62 2d 3e 70 43 6f 6e 66 69  urn pTab->pConfi
2480: 67 2d 3e 65 43 6f 6e 74 65 6e 74 3d 3d 46 54 53  g->eContent==FTS
2490: 35 5f 43 4f 4e 54 45 4e 54 5f 4e 4f 4e 45 3b 0a  5_CONTENT_NONE;.
24a0: 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6c 6f 73 65 20 61  }../*.** Close a
24b0: 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20 68   virtual table h
24c0: 61 6e 64 6c 65 20 6f 70 65 6e 65 64 20 62 79 20  andle opened by 
24d0: 66 74 73 35 49 6e 69 74 56 74 61 62 28 29 2e 20  fts5InitVtab(). 
24e0: 49 66 20 74 68 65 20 62 44 65 73 74 72 6f 79 0a  If the bDestroy.
24f0: 2a 2a 20 61 72 67 75 6d 65 6e 74 20 69 73 20 6e  ** argument is n
2500: 6f 6e 2d 7a 65 72 6f 2c 20 61 74 74 65 6d 70 74  on-zero, attempt
2510: 20 64 65 6c 65 74 65 20 74 68 65 20 73 68 61 64   delete the shad
2520: 6f 77 20 74 61 62 6c 65 73 20 66 72 6f 6d 20 74  ow tables from t
2530: 65 68 20 64 61 74 61 62 61 73 65 0a 2a 2f 0a 73  eh database.*/.s
2540: 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 46 72  tatic int fts5Fr
2550: 65 65 56 74 61 62 28 46 74 73 35 54 61 62 6c 65  eeVtab(Fts5Table
2560: 20 2a 70 54 61 62 2c 20 69 6e 74 20 62 44 65 73   *pTab, int bDes
2570: 74 72 6f 79 29 7b 0a 20 20 69 6e 74 20 72 63 20  troy){.  int rc 
2580: 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69  = SQLITE_OK;.  i
2590: 66 28 20 70 54 61 62 20 29 7b 0a 20 20 20 20 69  f( pTab ){.    i
25a0: 6e 74 20 72 63 32 3b 0a 20 20 20 20 72 63 32 20  nt rc2;.    rc2 
25b0: 3d 20 73 71 6c 69 74 65 33 46 74 73 35 49 6e 64  = sqlite3Fts5Ind
25c0: 65 78 43 6c 6f 73 65 28 70 54 61 62 2d 3e 70 49  exClose(pTab->pI
25d0: 6e 64 65 78 2c 20 62 44 65 73 74 72 6f 79 29 3b  ndex, bDestroy);
25e0: 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  .    if( rc==SQL
25f0: 49 54 45 5f 4f 4b 20 29 20 72 63 20 3d 20 72 63  ITE_OK ) rc = rc
2600: 32 3b 0a 20 20 20 20 72 63 32 20 3d 20 73 71 6c  2;.    rc2 = sql
2610: 69 74 65 33 46 74 73 35 53 74 6f 72 61 67 65 43  ite3Fts5StorageC
2620: 6c 6f 73 65 28 70 54 61 62 2d 3e 70 53 74 6f 72  lose(pTab->pStor
2630: 61 67 65 2c 20 62 44 65 73 74 72 6f 79 29 3b 0a  age, bDestroy);.
2640: 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49      if( rc==SQLI
2650: 54 45 5f 4f 4b 20 29 20 72 63 20 3d 20 72 63 32  TE_OK ) rc = rc2
2660: 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 46 74 73  ;.    sqlite3Fts
2670: 35 43 6f 6e 66 69 67 46 72 65 65 28 70 54 61 62  5ConfigFree(pTab
2680: 2d 3e 70 43 6f 6e 66 69 67 29 3b 0a 20 20 20 20  ->pConfig);.    
2690: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 54 61  sqlite3_free(pTa
26a0: 62 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  b);.  }.  return
26b0: 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68   rc;.}../*.** Th
26c0: 65 20 78 44 69 73 63 6f 6e 6e 65 63 74 28 29 20  e xDisconnect() 
26d0: 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20 6d 65  virtual table me
26e0: 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  thod..*/.static 
26f0: 69 6e 74 20 66 74 73 35 44 69 73 63 6f 6e 6e 65  int fts5Disconne
2700: 63 74 4d 65 74 68 6f 64 28 73 71 6c 69 74 65 33  ctMethod(sqlite3
2710: 5f 76 74 61 62 20 2a 70 56 74 61 62 29 7b 0a 20  _vtab *pVtab){. 
2720: 20 72 65 74 75 72 6e 20 66 74 73 35 46 72 65 65   return fts5Free
2730: 56 74 61 62 28 28 46 74 73 35 54 61 62 6c 65 2a  Vtab((Fts5Table*
2740: 29 70 56 74 61 62 2c 20 30 29 3b 0a 7d 0a 0a 2f  )pVtab, 0);.}../
2750: 2a 0a 2a 2a 20 54 68 65 20 78 44 65 73 74 72 6f  *.** The xDestro
2760: 79 28 29 20 76 69 72 74 75 61 6c 20 74 61 62 6c  y() virtual tabl
2770: 65 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61  e method..*/.sta
2780: 74 69 63 20 69 6e 74 20 66 74 73 35 44 65 73 74  tic int fts5Dest
2790: 72 6f 79 4d 65 74 68 6f 64 28 73 71 6c 69 74 65  royMethod(sqlite
27a0: 33 5f 76 74 61 62 20 2a 70 56 74 61 62 29 7b 0a  3_vtab *pVtab){.
27b0: 20 20 72 65 74 75 72 6e 20 66 74 73 35 46 72 65    return fts5Fre
27c0: 65 56 74 61 62 28 28 46 74 73 35 54 61 62 6c 65  eVtab((Fts5Table
27d0: 2a 29 70 56 74 61 62 2c 20 31 29 3b 0a 7d 0a 0a  *)pVtab, 1);.}..
27e0: 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74  /*.** This funct
27f0: 69 6f 6e 20 69 73 20 74 68 65 20 69 6d 70 6c 65  ion is the imple
2800: 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 62 6f 74  mentation of bot
2810: 68 20 74 68 65 20 78 43 6f 6e 6e 65 63 74 20 61  h the xConnect a
2820: 6e 64 20 78 43 72 65 61 74 65 0a 2a 2a 20 6d 65  nd xCreate.** me
2830: 74 68 6f 64 73 20 6f 66 20 74 68 65 20 46 54 53  thods of the FTS
2840: 33 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 2e  3 virtual table.
2850: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 72 67 76 5b  .**.** The argv[
2860: 5d 20 61 72 72 61 79 20 63 6f 6e 74 61 69 6e 73  ] array contains
2870: 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 3a 0a   the following:.
2880: 2a 2a 0a 2a 2a 20 20 20 61 72 67 76 5b 30 5d 20  **.**   argv[0] 
2890: 20 20 2d 3e 20 6d 6f 64 75 6c 65 20 6e 61 6d 65    -> module name
28a0: 20 20 28 22 66 74 73 35 22 29 0a 2a 2a 20 20 20    ("fts5").**   
28b0: 61 72 67 76 5b 31 5d 20 20 20 2d 3e 20 64 61 74  argv[1]   -> dat
28c0: 61 62 61 73 65 20 6e 61 6d 65 0a 2a 2a 20 20 20  abase name.**   
28d0: 61 72 67 76 5b 32 5d 20 20 20 2d 3e 20 74 61 62  argv[2]   -> tab
28e0: 6c 65 20 6e 61 6d 65 0a 2a 2a 20 20 20 61 72 67  le name.**   arg
28f0: 76 5b 2e 2e 2e 5d 20 2d 3e 20 22 63 6f 6c 75 6d  v[...] -> "colum
2900: 6e 20 6e 61 6d 65 22 20 61 6e 64 20 6f 74 68 65  n name" and othe
2910: 72 20 6d 6f 64 75 6c 65 20 61 72 67 75 6d 65 6e  r module argumen
2920: 74 20 66 69 65 6c 64 73 2e 0a 2a 2f 0a 73 74 61  t fields..*/.sta
2930: 74 69 63 20 69 6e 74 20 66 74 73 35 49 6e 69 74  tic int fts5Init
2940: 56 74 61 62 28 0a 20 20 69 6e 74 20 62 43 72 65  Vtab(.  int bCre
2950: 61 74 65 2c 20 20 20 20 20 20 20 20 20 20 20 20  ate,            
2960: 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20          /* True 
2970: 66 6f 72 20 78 43 72 65 61 74 65 2c 20 66 61 6c  for xCreate, fal
2980: 73 65 20 66 6f 72 20 78 43 6f 6e 6e 65 63 74 20  se for xConnect 
2990: 2a 2f 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62  */.  sqlite3 *db
29a0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
29b0: 20 20 20 20 20 2f 2a 20 54 68 65 20 53 51 4c 69       /* The SQLi
29c0: 74 65 20 64 61 74 61 62 61 73 65 20 63 6f 6e 6e  te database conn
29d0: 65 63 74 69 6f 6e 20 2a 2f 0a 20 20 76 6f 69 64  ection */.  void
29e0: 20 2a 70 41 75 78 2c 20 20 20 20 20 20 20 20 20   *pAux,         
29f0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 48              /* H
2a00: 61 73 68 20 74 61 62 6c 65 20 63 6f 6e 74 61 69  ash table contai
2a10: 6e 69 6e 67 20 74 6f 6b 65 6e 69 7a 65 72 73 20  ning tokenizers 
2a20: 2a 2f 0a 20 20 69 6e 74 20 61 72 67 63 2c 20 20  */.  int argc,  
2a30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2a40: 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
2a50: 66 20 65 6c 65 6d 65 6e 74 73 20 69 6e 20 61 72  f elements in ar
2a60: 67 76 20 61 72 72 61 79 20 2a 2f 0a 20 20 63 6f  gv array */.  co
2a70: 6e 73 74 20 63 68 61 72 20 2a 20 63 6f 6e 73 74  nst char * const
2a80: 20 2a 61 72 67 76 2c 20 20 20 20 20 20 20 2f 2a   *argv,       /*
2a90: 20 78 43 72 65 61 74 65 2f 78 43 6f 6e 6e 65 63   xCreate/xConnec
2aa0: 74 20 61 72 67 75 6d 65 6e 74 20 61 72 72 61 79  t argument array
2ab0: 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 76 74   */.  sqlite3_vt
2ac0: 61 62 20 2a 2a 70 70 56 54 61 62 2c 20 20 20 20  ab **ppVTab,    
2ad0: 20 20 20 20 20 20 2f 2a 20 57 72 69 74 65 20 74        /* Write t
2ae0: 68 65 20 72 65 73 75 6c 74 69 6e 67 20 76 74 61  he resulting vta
2af0: 62 20 73 74 72 75 63 74 75 72 65 20 68 65 72 65  b structure here
2b00: 20 2a 2f 0a 20 20 63 68 61 72 20 2a 2a 70 7a 45   */.  char **pzE
2b10: 72 72 20 20 20 20 20 20 20 20 20 20 20 20 20 20  rr              
2b20: 20 20 20 20 20 20 2f 2a 20 57 72 69 74 65 20 61        /* Write a
2b30: 6e 79 20 65 72 72 6f 72 20 6d 65 73 73 61 67 65  ny error message
2b40: 20 68 65 72 65 20 2a 2f 0a 29 7b 0a 20 20 46 74   here */.){.  Ft
2b50: 73 35 47 6c 6f 62 61 6c 20 2a 70 47 6c 6f 62 61  s5Global *pGloba
2b60: 6c 20 3d 20 28 46 74 73 35 47 6c 6f 62 61 6c 2a  l = (Fts5Global*
2b70: 29 70 41 75 78 3b 0a 20 20 63 6f 6e 73 74 20 63  )pAux;.  const c
2b80: 68 61 72 20 2a 2a 61 7a 43 6f 6e 66 69 67 20 3d  har **azConfig =
2b90: 20 28 63 6f 6e 73 74 20 63 68 61 72 2a 2a 29 61   (const char**)a
2ba0: 72 67 76 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20  rgv;.  int rc = 
2bb0: 53 51 4c 49 54 45 5f 4f 4b 3b 20 20 20 20 20 20  SQLITE_OK;      
2bc0: 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e         /* Return
2bd0: 20 63 6f 64 65 20 2a 2f 0a 20 20 46 74 73 35 43   code */.  Fts5C
2be0: 6f 6e 66 69 67 20 2a 70 43 6f 6e 66 69 67 3b 20  onfig *pConfig; 
2bf0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65             /* Re
2c00: 73 75 6c 74 73 20 6f 66 20 70 61 72 73 69 6e 67  sults of parsing
2c10: 20 61 72 67 63 2f 61 72 67 76 20 2a 2f 0a 20 20   argc/argv */.  
2c20: 46 74 73 35 54 61 62 6c 65 20 2a 70 54 61 62 20  Fts5Table *pTab 
2c30: 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20  = 0;            
2c40: 2f 2a 20 4e 65 77 20 76 69 72 74 75 61 6c 20 74  /* New virtual t
2c50: 61 62 6c 65 20 6f 62 6a 65 63 74 20 2a 2f 0a 0a  able object */..
2c60: 20 20 2f 2a 20 41 6c 6c 6f 63 61 74 65 20 74 68    /* Allocate th
2c70: 65 20 6e 65 77 20 76 74 61 62 20 6f 62 6a 65 63  e new vtab objec
2c80: 74 20 61 6e 64 20 70 61 72 73 65 20 74 68 65 20  t and parse the 
2c90: 63 6f 6e 66 69 67 75 72 61 74 69 6f 6e 20 2a 2f  configuration */
2ca0: 0a 20 20 70 54 61 62 20 3d 20 28 46 74 73 35 54  .  pTab = (Fts5T
2cb0: 61 62 6c 65 2a 29 73 71 6c 69 74 65 33 46 74 73  able*)sqlite3Fts
2cc0: 35 4d 61 6c 6c 6f 63 5a 65 72 6f 28 26 72 63 2c  5MallocZero(&rc,
2cd0: 20 73 69 7a 65 6f 66 28 46 74 73 35 54 61 62 6c   sizeof(Fts5Tabl
2ce0: 65 29 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53  e));.  if( rc==S
2cf0: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
2d00: 72 63 20 3d 20 73 71 6c 69 74 65 33 46 74 73 35  rc = sqlite3Fts5
2d10: 43 6f 6e 66 69 67 50 61 72 73 65 28 70 47 6c 6f  ConfigParse(pGlo
2d20: 62 61 6c 2c 20 64 62 2c 20 61 72 67 63 2c 20 61  bal, db, argc, a
2d30: 7a 43 6f 6e 66 69 67 2c 20 26 70 43 6f 6e 66 69  zConfig, &pConfi
2d40: 67 2c 20 70 7a 45 72 72 29 3b 0a 20 20 20 20 61  g, pzErr);.    a
2d50: 73 73 65 72 74 28 20 28 72 63 3d 3d 53 51 4c 49  ssert( (rc==SQLI
2d60: 54 45 5f 4f 4b 20 26 26 20 2a 70 7a 45 72 72 3d  TE_OK && *pzErr=
2d70: 3d 30 29 20 7c 7c 20 70 43 6f 6e 66 69 67 3d 3d  =0) || pConfig==
2d80: 30 20 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20 72  0 );.  }.  if( r
2d90: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
2da0: 20 20 20 20 70 54 61 62 2d 3e 70 43 6f 6e 66 69      pTab->pConfi
2db0: 67 20 3d 20 70 43 6f 6e 66 69 67 3b 0a 20 20 20  g = pConfig;.   
2dc0: 20 70 54 61 62 2d 3e 70 47 6c 6f 62 61 6c 20 3d   pTab->pGlobal =
2dd0: 20 70 47 6c 6f 62 61 6c 3b 0a 20 20 7d 0a 0a 20   pGlobal;.  }.. 
2de0: 20 2f 2a 20 4f 70 65 6e 20 74 68 65 20 69 6e 64   /* Open the ind
2df0: 65 78 20 73 75 62 2d 73 79 73 74 65 6d 20 2a 2f  ex sub-system */
2e00: 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
2e10: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d  E_OK ){.    rc =
2e20: 20 73 71 6c 69 74 65 33 46 74 73 35 49 6e 64 65   sqlite3Fts5Inde
2e30: 78 4f 70 65 6e 28 70 43 6f 6e 66 69 67 2c 20 62  xOpen(pConfig, b
2e40: 43 72 65 61 74 65 2c 20 26 70 54 61 62 2d 3e 70  Create, &pTab->p
2e50: 49 6e 64 65 78 2c 20 70 7a 45 72 72 29 3b 0a 20  Index, pzErr);. 
2e60: 20 7d 0a 0a 20 20 2f 2a 20 4f 70 65 6e 20 74 68   }..  /* Open th
2e70: 65 20 73 74 6f 72 61 67 65 20 73 75 62 2d 73 79  e storage sub-sy
2e80: 73 74 65 6d 20 2a 2f 0a 20 20 69 66 28 20 72 63  stem */.  if( rc
2e90: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
2ea0: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 46     rc = sqlite3F
2eb0: 74 73 35 53 74 6f 72 61 67 65 4f 70 65 6e 28 0a  ts5StorageOpen(.
2ec0: 20 20 20 20 20 20 20 20 70 43 6f 6e 66 69 67 2c          pConfig,
2ed0: 20 70 54 61 62 2d 3e 70 49 6e 64 65 78 2c 20 62   pTab->pIndex, b
2ee0: 43 72 65 61 74 65 2c 20 26 70 54 61 62 2d 3e 70  Create, &pTab->p
2ef0: 53 74 6f 72 61 67 65 2c 20 70 7a 45 72 72 0a 20  Storage, pzErr. 
2f00: 20 20 20 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20     );.  }..  /* 
2f10: 43 61 6c 6c 20 73 71 6c 69 74 65 33 5f 64 65 63  Call sqlite3_dec
2f20: 6c 61 72 65 5f 76 74 61 62 28 29 20 2a 2f 0a 20  lare_vtab() */. 
2f30: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
2f40: 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 73  OK ){.    rc = s
2f50: 71 6c 69 74 65 33 46 74 73 35 43 6f 6e 66 69 67  qlite3Fts5Config
2f60: 44 65 63 6c 61 72 65 56 74 61 62 28 70 43 6f 6e  DeclareVtab(pCon
2f70: 66 69 67 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28  fig);.  }..  if(
2f80: 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
2f90: 7b 0a 20 20 20 20 66 74 73 35 46 72 65 65 56 74  {.    fts5FreeVt
2fa0: 61 62 28 70 54 61 62 2c 20 30 29 3b 0a 20 20 20  ab(pTab, 0);.   
2fb0: 20 70 54 61 62 20 3d 20 30 3b 0a 20 20 7d 65 6c   pTab = 0;.  }el
2fc0: 73 65 20 69 66 28 20 62 43 72 65 61 74 65 20 29  se if( bCreate )
2fd0: 7b 0a 20 20 20 20 66 74 73 35 43 68 65 63 6b 54  {.    fts5CheckT
2fe0: 72 61 6e 73 61 63 74 69 6f 6e 53 74 61 74 65 28  ransactionState(
2ff0: 70 54 61 62 2c 20 46 54 53 35 5f 42 45 47 49 4e  pTab, FTS5_BEGIN
3000: 2c 20 30 29 3b 0a 20 20 7d 0a 20 20 2a 70 70 56  , 0);.  }.  *ppV
3010: 54 61 62 20 3d 20 28 73 71 6c 69 74 65 33 5f 76  Tab = (sqlite3_v
3020: 74 61 62 2a 29 70 54 61 62 3b 0a 20 20 72 65 74  tab*)pTab;.  ret
3030: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
3040: 20 54 68 65 20 78 43 6f 6e 6e 65 63 74 28 29 20   The xConnect() 
3050: 61 6e 64 20 78 43 72 65 61 74 65 28 29 20 6d 65  and xCreate() me
3060: 74 68 6f 64 73 20 66 6f 72 20 74 68 65 20 76 69  thods for the vi
3070: 72 74 75 61 6c 20 74 61 62 6c 65 2e 20 41 6c 6c  rtual table. All
3080: 20 74 68 65 0a 2a 2a 20 77 6f 72 6b 20 69 73 20   the.** work is 
3090: 64 6f 6e 65 20 69 6e 20 66 75 6e 63 74 69 6f 6e  done in function
30a0: 20 66 74 73 35 49 6e 69 74 56 74 61 62 28 29 2e   fts5InitVtab().
30b0: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66  .*/.static int f
30c0: 74 73 35 43 6f 6e 6e 65 63 74 4d 65 74 68 6f 64  ts5ConnectMethod
30d0: 28 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 2c  (.  sqlite3 *db,
30e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
30f0: 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65 20      /* Database 
3100: 63 6f 6e 6e 65 63 74 69 6f 6e 20 2a 2f 0a 20 20  connection */.  
3110: 76 6f 69 64 20 2a 70 41 75 78 2c 20 20 20 20 20  void *pAux,     
3120: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3130: 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 74 6f  /* Pointer to to
3140: 6b 65 6e 69 7a 65 72 20 68 61 73 68 20 74 61 62  kenizer hash tab
3150: 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 61 72 67 63  le */.  int argc
3160: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
3170: 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65          /* Numbe
3180: 72 20 6f 66 20 65 6c 65 6d 65 6e 74 73 20 69 6e  r of elements in
3190: 20 61 72 67 76 20 61 72 72 61 79 20 2a 2f 0a 20   argv array */. 
31a0: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 20 63 6f   const char * co
31b0: 6e 73 74 20 2a 61 72 67 76 2c 20 20 20 20 20 20  nst *argv,      
31c0: 20 2f 2a 20 78 43 72 65 61 74 65 2f 78 43 6f 6e   /* xCreate/xCon
31d0: 6e 65 63 74 20 61 72 67 75 6d 65 6e 74 20 61 72  nect argument ar
31e0: 72 61 79 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33  ray */.  sqlite3
31f0: 5f 76 74 61 62 20 2a 2a 70 70 56 74 61 62 2c 20  _vtab **ppVtab, 
3200: 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a           /* OUT:
3210: 20 4e 65 77 20 73 71 6c 69 74 65 33 5f 76 74 61   New sqlite3_vta
3220: 62 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 63 68  b object */.  ch
3230: 61 72 20 2a 2a 70 7a 45 72 72 20 20 20 20 20 20  ar **pzErr      
3240: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
3250: 20 4f 55 54 3a 20 73 71 6c 69 74 65 33 5f 6d 61   OUT: sqlite3_ma
3260: 6c 6c 6f 63 27 64 20 65 72 72 6f 72 20 6d 65 73  lloc'd error mes
3270: 73 61 67 65 20 2a 2f 0a 29 7b 0a 20 20 72 65 74  sage */.){.  ret
3280: 75 72 6e 20 66 74 73 35 49 6e 69 74 56 74 61 62  urn fts5InitVtab
3290: 28 30 2c 20 64 62 2c 20 70 41 75 78 2c 20 61 72  (0, db, pAux, ar
32a0: 67 63 2c 20 61 72 67 76 2c 20 70 70 56 74 61 62  gc, argv, ppVtab
32b0: 2c 20 70 7a 45 72 72 29 3b 0a 7d 0a 73 74 61 74  , pzErr);.}.stat
32c0: 69 63 20 69 6e 74 20 66 74 73 35 43 72 65 61 74  ic int fts5Creat
32d0: 65 4d 65 74 68 6f 64 28 0a 20 20 73 71 6c 69 74  eMethod(.  sqlit
32e0: 65 33 20 2a 64 62 2c 20 20 20 20 20 20 20 20 20  e3 *db,         
32f0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61             /* Da
3300: 74 61 62 61 73 65 20 63 6f 6e 6e 65 63 74 69 6f  tabase connectio
3310: 6e 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 41 75  n */.  void *pAu
3320: 78 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  x,              
3330: 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65         /* Pointe
3340: 72 20 74 6f 20 74 6f 6b 65 6e 69 7a 65 72 20 68  r to tokenizer h
3350: 61 73 68 20 74 61 62 6c 65 20 2a 2f 0a 20 20 69  ash table */.  i
3360: 6e 74 20 61 72 67 63 2c 20 20 20 20 20 20 20 20  nt argc,        
3370: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
3380: 2a 20 4e 75 6d 62 65 72 20 6f 66 20 65 6c 65 6d  * Number of elem
3390: 65 6e 74 73 20 69 6e 20 61 72 67 76 20 61 72 72  ents in argv arr
33a0: 61 79 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68  ay */.  const ch
33b0: 61 72 20 2a 20 63 6f 6e 73 74 20 2a 61 72 67 76  ar * const *argv
33c0: 2c 20 20 20 20 20 20 20 2f 2a 20 78 43 72 65 61  ,       /* xCrea
33d0: 74 65 2f 78 43 6f 6e 6e 65 63 74 20 61 72 67 75  te/xConnect argu
33e0: 6d 65 6e 74 20 61 72 72 61 79 20 2a 2f 0a 20 20  ment array */.  
33f0: 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 2a 70  sqlite3_vtab **p
3400: 70 56 74 61 62 2c 20 20 20 20 20 20 20 20 20 20  pVtab,          
3410: 2f 2a 20 4f 55 54 3a 20 4e 65 77 20 73 71 6c 69  /* OUT: New sqli
3420: 74 65 33 5f 76 74 61 62 20 6f 62 6a 65 63 74 20  te3_vtab object 
3430: 2a 2f 0a 20 20 63 68 61 72 20 2a 2a 70 7a 45 72  */.  char **pzEr
3440: 72 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  r               
3450: 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 73 71 6c       /* OUT: sql
3460: 69 74 65 33 5f 6d 61 6c 6c 6f 63 27 64 20 65 72  ite3_malloc'd er
3470: 72 6f 72 20 6d 65 73 73 61 67 65 20 2a 2f 0a 29  ror message */.)
3480: 7b 0a 20 20 72 65 74 75 72 6e 20 66 74 73 35 49  {.  return fts5I
3490: 6e 69 74 56 74 61 62 28 31 2c 20 64 62 2c 20 70  nitVtab(1, db, p
34a0: 41 75 78 2c 20 61 72 67 63 2c 20 61 72 67 76 2c  Aux, argc, argv,
34b0: 20 70 70 56 74 61 62 2c 20 70 7a 45 72 72 29 3b   ppVtab, pzErr);
34c0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 74 68  .}../*.** The th
34d0: 72 65 65 20 71 75 65 72 79 20 70 6c 61 6e 73 20  ree query plans 
34e0: 78 42 65 73 74 49 6e 64 65 78 20 6d 61 79 20 63  xBestIndex may c
34f0: 68 6f 6f 73 65 20 62 65 74 77 65 65 6e 2e 0a 2a  hoose between..*
3500: 2f 0a 23 64 65 66 69 6e 65 20 46 54 53 35 5f 50  /.#define FTS5_P
3510: 4c 41 4e 5f 53 43 41 4e 20 20 20 20 20 20 20 20  LAN_SCAN        
3520: 20 20 20 31 20 20 20 20 20 20 20 2f 2a 20 4e 6f     1       /* No
3530: 20 75 73 61 62 6c 65 20 63 6f 6e 73 74 72 61 69   usable constrai
3540: 6e 74 20 2a 2f 0a 23 64 65 66 69 6e 65 20 46 54  nt */.#define FT
3550: 53 35 5f 50 4c 41 4e 5f 4d 41 54 43 48 20 20 20  S5_PLAN_MATCH   
3560: 20 20 20 20 20 20 20 32 20 20 20 20 20 20 20 2f         2       /
3570: 2a 20 28 3c 74 62 6c 3e 20 4d 41 54 43 48 20 3f  * (<tbl> MATCH ?
3580: 29 20 2a 2f 0a 23 64 65 66 69 6e 65 20 46 54 53  ) */.#define FTS
3590: 35 5f 50 4c 41 4e 5f 53 4f 52 54 45 44 5f 4d 41  5_PLAN_SORTED_MA
35a0: 54 43 48 20 20 20 33 20 20 20 20 20 20 20 2f 2a  TCH   3       /*
35b0: 20 28 3c 74 62 6c 3e 20 4d 41 54 43 48 20 3f 20   (<tbl> MATCH ? 
35c0: 4f 52 44 45 52 20 42 59 20 72 61 6e 6b 29 20 2a  ORDER BY rank) *
35d0: 2f 0a 23 64 65 66 69 6e 65 20 46 54 53 35 5f 50  /.#define FTS5_P
35e0: 4c 41 4e 5f 52 4f 57 49 44 20 20 20 20 20 20 20  LAN_ROWID       
35f0: 20 20 20 34 20 20 20 20 20 20 20 2f 2a 20 28 72     4       /* (r
3600: 6f 77 69 64 20 3d 20 3f 29 20 2a 2f 0a 23 64 65  owid = ?) */.#de
3610: 66 69 6e 65 20 46 54 53 35 5f 50 4c 41 4e 5f 53  fine FTS5_PLAN_S
3620: 4f 55 52 43 45 20 20 20 20 20 20 20 20 20 35 20  OURCE         5 
3630: 20 20 20 20 20 20 2f 2a 20 41 20 73 6f 75 72 63        /* A sourc
3640: 65 20 63 75 72 73 6f 72 20 66 6f 72 20 53 4f 52  e cursor for SOR
3650: 54 45 44 5f 4d 41 54 43 48 20 2a 2f 0a 23 64 65  TED_MATCH */.#de
3660: 66 69 6e 65 20 46 54 53 35 5f 50 4c 41 4e 5f 53  fine FTS5_PLAN_S
3670: 50 45 43 49 41 4c 20 20 20 20 20 20 20 20 36 20  PECIAL        6 
3680: 20 20 20 20 20 20 2f 2a 20 41 6e 20 69 6e 74 65        /* An inte
3690: 72 6e 61 6c 20 71 75 65 72 79 20 2a 2f 0a 0a 23  rnal query */..#
36a0: 64 65 66 69 6e 65 20 46 54 53 35 5f 50 4c 41 4e  define FTS5_PLAN
36b0: 28 69 64 78 4e 75 6d 29 20 28 28 69 64 78 4e 75  (idxNum) ((idxNu
36c0: 6d 29 20 26 20 30 78 37 29 0a 0a 23 64 65 66 69  m) & 0x7)..#defi
36d0: 6e 65 20 46 54 53 35 5f 4f 52 44 45 52 5f 44 45  ne FTS5_ORDER_DE
36e0: 53 43 20 20 20 38 20 20 20 20 20 20 20 2f 2a 20  SC   8       /* 
36f0: 4f 52 44 45 52 20 42 59 20 72 6f 77 69 64 20 44  ORDER BY rowid D
3700: 45 53 43 20 2a 2f 0a 23 64 65 66 69 6e 65 20 46  ESC */.#define F
3710: 54 53 35 5f 4f 52 44 45 52 5f 41 53 43 20 20 20  TS5_ORDER_ASC   
3720: 31 36 20 20 20 20 20 20 20 2f 2a 20 4f 52 44 45  16       /* ORDE
3730: 52 20 42 59 20 72 6f 77 69 64 20 41 53 43 20 2a  R BY rowid ASC *
3740: 2f 0a 0a 2f 2a 0a 2a 2a 20 53 65 61 72 63 68 20  /../*.** Search 
3750: 74 68 65 20 6f 62 6a 65 63 74 20 70 61 73 73 65  the object passe
3760: 64 20 61 73 20 74 68 65 20 66 69 72 73 74 20 61  d as the first a
3770: 72 67 75 6d 65 6e 74 20 66 6f 72 20 61 20 75 73  rgument for a us
3780: 61 62 6c 65 20 63 6f 6e 73 74 72 61 69 6e 74 0a  able constraint.
3790: 2a 2a 20 6f 6e 20 63 6f 6c 75 6d 6e 20 69 43 6f  ** on column iCo
37a0: 6c 20 75 73 69 6e 67 20 6f 70 65 72 61 74 6f 72  l using operator
37b0: 20 65 4f 70 2e 20 49 66 20 6f 6e 65 20 69 73 20   eOp. If one is 
37c0: 66 6f 75 6e 64 2c 20 72 65 74 75 72 6e 20 69 74  found, return it
37d0: 73 20 69 6e 64 65 78 20 69 6e 0a 2a 2a 20 74 68  s index in.** th
37e0: 65 20 70 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74 72  e pInfo->aConstr
37f0: 61 69 6e 74 5b 5d 20 61 72 72 61 79 2e 20 49 66  aint[] array. If
3800: 20 6e 6f 20 73 75 63 68 20 63 6f 6e 73 74 72 61   no such constra
3810: 69 6e 74 20 69 73 20 66 6f 75 6e 64 2c 20 72 65  int is found, re
3820: 74 75 72 6e 0a 2a 2a 20 61 20 6e 65 67 61 74 69  turn.** a negati
3830: 76 65 20 76 61 6c 75 65 2e 0a 2a 2f 0a 73 74 61  ve value..*/.sta
3840: 74 69 63 20 69 6e 74 20 66 74 73 35 46 69 6e 64  tic int fts5Find
3850: 43 6f 6e 73 74 72 61 69 6e 74 28 73 71 6c 69 74  Constraint(sqlit
3860: 65 33 5f 69 6e 64 65 78 5f 69 6e 66 6f 20 2a 70  e3_index_info *p
3870: 49 6e 66 6f 2c 20 69 6e 74 20 65 4f 70 2c 20 69  Info, int eOp, i
3880: 6e 74 20 69 43 6f 6c 29 7b 0a 20 20 69 6e 74 20  nt iCol){.  int 
3890: 69 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c  i;.  for(i=0; i<
38a0: 70 49 6e 66 6f 2d 3e 6e 43 6f 6e 73 74 72 61 69  pInfo->nConstrai
38b0: 6e 74 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 73 74  nt; i++){.    st
38c0: 72 75 63 74 20 73 71 6c 69 74 65 33 5f 69 6e 64  ruct sqlite3_ind
38d0: 65 78 5f 63 6f 6e 73 74 72 61 69 6e 74 20 2a 70  ex_constraint *p
38e0: 20 3d 20 26 70 49 6e 66 6f 2d 3e 61 43 6f 6e 73   = &pInfo->aCons
38f0: 74 72 61 69 6e 74 5b 69 5d 3b 0a 20 20 20 20 69  traint[i];.    i
3900: 66 28 20 70 2d 3e 75 73 61 62 6c 65 20 26 26 20  f( p->usable && 
3910: 70 2d 3e 69 43 6f 6c 75 6d 6e 3d 3d 69 43 6f 6c  p->iColumn==iCol
3920: 20 26 26 20 70 2d 3e 6f 70 3d 3d 65 4f 70 20 29   && p->op==eOp )
3930: 20 72 65 74 75 72 6e 20 69 3b 0a 20 20 7d 0a 20   return i;.  }. 
3940: 20 72 65 74 75 72 6e 20 2d 31 3b 0a 7d 0a 0a 2f   return -1;.}../
3950: 2a 20 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61  * .** Implementa
3960: 74 69 6f 6e 20 6f 66 20 74 68 65 20 78 42 65 73  tion of the xBes
3970: 74 49 6e 64 65 78 20 6d 65 74 68 6f 64 20 66 6f  tIndex method fo
3980: 72 20 46 54 53 35 20 74 61 62 6c 65 73 2e 20 54  r FTS5 tables. T
3990: 68 65 72 65 0a 2a 2a 20 61 72 65 20 74 68 72 65  here.** are thre
39a0: 65 20 70 6f 73 73 69 62 6c 65 20 73 74 72 61 74  e possible strat
39b0: 65 67 69 65 73 2c 20 69 6e 20 6f 72 64 65 72 20  egies, in order 
39c0: 6f 66 20 70 72 65 66 65 72 65 6e 63 65 3a 0a 2a  of preference:.*
39d0: 2a 0a 2a 2a 20 20 20 31 2e 20 46 75 6c 6c 2d 74  *.**   1. Full-t
39e0: 65 78 74 20 73 65 61 72 63 68 20 75 73 69 6e 67  ext search using
39f0: 20 61 20 4d 41 54 43 48 20 6f 70 65 72 61 74 6f   a MATCH operato
3a00: 72 2e 0a 2a 2a 20 20 20 32 2e 20 41 20 62 79 2d  r..**   2. A by-
3a10: 72 6f 77 69 64 20 6c 6f 6f 6b 75 70 2e 0a 2a 2a  rowid lookup..**
3a20: 20 20 20 33 2e 20 41 20 66 75 6c 6c 2d 74 61 62     3. A full-tab
3a30: 6c 65 20 73 63 61 6e 2e 0a 2a 2f 0a 73 74 61 74  le scan..*/.stat
3a40: 69 63 20 69 6e 74 20 66 74 73 35 42 65 73 74 49  ic int fts5BestI
3a50: 6e 64 65 78 4d 65 74 68 6f 64 28 73 71 6c 69 74  ndexMethod(sqlit
3a60: 65 33 5f 76 74 61 62 20 2a 70 56 54 61 62 2c 20  e3_vtab *pVTab, 
3a70: 73 71 6c 69 74 65 33 5f 69 6e 64 65 78 5f 69 6e  sqlite3_index_in
3a80: 66 6f 20 2a 70 49 6e 66 6f 29 7b 0a 20 20 46 74  fo *pInfo){.  Ft
3a90: 73 35 54 61 62 6c 65 20 2a 70 54 61 62 20 3d 20  s5Table *pTab = 
3aa0: 28 46 74 73 35 54 61 62 6c 65 2a 29 70 56 54 61  (Fts5Table*)pVTa
3ab0: 62 3b 0a 20 20 46 74 73 35 43 6f 6e 66 69 67 20  b;.  Fts5Config 
3ac0: 2a 70 43 6f 6e 66 69 67 20 3d 20 70 54 61 62 2d  *pConfig = pTab-
3ad0: 3e 70 43 6f 6e 66 69 67 3b 0a 20 20 69 6e 74 20  >pConfig;.  int 
3ae0: 69 43 6f 6e 73 3b 0a 20 20 69 6e 74 20 65 50 6c  iCons;.  int ePl
3af0: 61 6e 20 3d 20 46 54 53 35 5f 50 4c 41 4e 5f 53  an = FTS5_PLAN_S
3b00: 43 41 4e 3b 0a 20 20 69 6e 74 20 69 52 61 6e 6b  CAN;.  int iRank
3b10: 4d 61 74 63 68 3b 0a 0a 20 20 69 43 6f 6e 73 20  Match;..  iCons 
3b20: 3d 20 66 74 73 35 46 69 6e 64 43 6f 6e 73 74 72  = fts5FindConstr
3b30: 61 69 6e 74 28 70 49 6e 66 6f 2c 53 51 4c 49 54  aint(pInfo,SQLIT
3b40: 45 5f 49 4e 44 45 58 5f 43 4f 4e 53 54 52 41 49  E_INDEX_CONSTRAI
3b50: 4e 54 5f 4d 41 54 43 48 2c 70 43 6f 6e 66 69 67  NT_MATCH,pConfig
3b60: 2d 3e 6e 43 6f 6c 29 3b 0a 20 20 69 66 28 20 69  ->nCol);.  if( i
3b70: 43 6f 6e 73 3e 3d 30 20 29 7b 0a 20 20 20 20 65  Cons>=0 ){.    e
3b80: 50 6c 61 6e 20 3d 20 46 54 53 35 5f 50 4c 41 4e  Plan = FTS5_PLAN
3b90: 5f 4d 41 54 43 48 3b 0a 20 20 20 20 70 49 6e 66  _MATCH;.    pInf
3ba0: 6f 2d 3e 65 73 74 69 6d 61 74 65 64 43 6f 73 74  o->estimatedCost
3bb0: 20 3d 20 31 2e 30 3b 0a 20 20 7d 65 6c 73 65 7b   = 1.0;.  }else{
3bc0: 0a 20 20 20 20 69 43 6f 6e 73 20 3d 20 66 74 73  .    iCons = fts
3bd0: 35 46 69 6e 64 43 6f 6e 73 74 72 61 69 6e 74 28  5FindConstraint(
3be0: 70 49 6e 66 6f 2c 20 53 51 4c 49 54 45 5f 49 4e  pInfo, SQLITE_IN
3bf0: 44 45 58 5f 43 4f 4e 53 54 52 41 49 4e 54 5f 45  DEX_CONSTRAINT_E
3c00: 51 2c 20 2d 31 29 3b 0a 20 20 20 20 69 66 28 20  Q, -1);.    if( 
3c10: 69 43 6f 6e 73 3e 3d 30 20 29 7b 0a 20 20 20 20  iCons>=0 ){.    
3c20: 20 20 65 50 6c 61 6e 20 3d 20 46 54 53 35 5f 50    ePlan = FTS5_P
3c30: 4c 41 4e 5f 52 4f 57 49 44 3b 0a 20 20 20 20 20  LAN_ROWID;.     
3c40: 20 70 49 6e 66 6f 2d 3e 65 73 74 69 6d 61 74 65   pInfo->estimate
3c50: 64 43 6f 73 74 20 3d 20 32 2e 30 3b 0a 20 20 20  dCost = 2.0;.   
3c60: 20 7d 0a 20 20 7d 0a 0a 20 20 69 66 28 20 69 43   }.  }..  if( iC
3c70: 6f 6e 73 3e 3d 30 20 29 7b 0a 20 20 20 20 70 49  ons>=0 ){.    pI
3c80: 6e 66 6f 2d 3e 61 43 6f 6e 73 74 72 61 69 6e 74  nfo->aConstraint
3c90: 55 73 61 67 65 5b 69 43 6f 6e 73 5d 2e 61 72 67  Usage[iCons].arg
3ca0: 76 49 6e 64 65 78 20 3d 20 31 3b 0a 20 20 20 20  vIndex = 1;.    
3cb0: 70 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74 72 61 69  pInfo->aConstrai
3cc0: 6e 74 55 73 61 67 65 5b 69 43 6f 6e 73 5d 2e 6f  ntUsage[iCons].o
3cd0: 6d 69 74 20 3d 20 31 3b 0a 20 20 7d 65 6c 73 65  mit = 1;.  }else
3ce0: 7b 0a 20 20 20 20 70 49 6e 66 6f 2d 3e 65 73 74  {.    pInfo->est
3cf0: 69 6d 61 74 65 64 43 6f 73 74 20 3d 20 31 30 30  imatedCost = 100
3d00: 30 30 30 30 30 2e 30 3b 0a 20 20 7d 0a 0a 20 20  00000.0;.  }..  
3d10: 69 66 28 20 70 49 6e 66 6f 2d 3e 6e 4f 72 64 65  if( pInfo->nOrde
3d20: 72 42 79 3d 3d 31 20 29 7b 0a 20 20 20 20 69 6e  rBy==1 ){.    in
3d30: 74 20 69 53 6f 72 74 20 3d 20 70 49 6e 66 6f 2d  t iSort = pInfo-
3d40: 3e 61 4f 72 64 65 72 42 79 5b 30 5d 2e 69 43 6f  >aOrderBy[0].iCo
3d50: 6c 75 6d 6e 3b 0a 20 20 20 20 69 66 28 20 69 53  lumn;.    if( iS
3d60: 6f 72 74 3c 30 20 29 7b 0a 20 20 20 20 20 20 2f  ort<0 ){.      /
3d70: 2a 20 4f 52 44 45 52 20 42 59 20 72 6f 77 69 64  * ORDER BY rowid
3d80: 20 5b 41 53 43 7c 44 45 53 43 5d 20 2a 2f 0a 20   [ASC|DESC] */. 
3d90: 20 20 20 20 20 70 49 6e 66 6f 2d 3e 6f 72 64 65       pInfo->orde
3da0: 72 42 79 43 6f 6e 73 75 6d 65 64 20 3d 20 31 3b  rByConsumed = 1;
3db0: 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 69  .    }else if( i
3dc0: 53 6f 72 74 3d 3d 28 70 43 6f 6e 66 69 67 2d 3e  Sort==(pConfig->
3dd0: 6e 43 6f 6c 2b 31 29 20 26 26 20 65 50 6c 61 6e  nCol+1) && ePlan
3de0: 3d 3d 46 54 53 35 5f 50 4c 41 4e 5f 4d 41 54 43  ==FTS5_PLAN_MATC
3df0: 48 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20 4f 52  H ){.      /* OR
3e00: 44 45 52 20 42 59 20 72 61 6e 6b 20 5b 41 53 43  DER BY rank [ASC
3e10: 7c 44 45 53 43 5d 20 2a 2f 0a 20 20 20 20 20 20  |DESC] */.      
3e20: 70 49 6e 66 6f 2d 3e 6f 72 64 65 72 42 79 43 6f  pInfo->orderByCo
3e30: 6e 73 75 6d 65 64 20 3d 20 31 3b 0a 20 20 20 20  nsumed = 1;.    
3e40: 20 20 65 50 6c 61 6e 20 3d 20 46 54 53 35 5f 50    ePlan = FTS5_P
3e50: 4c 41 4e 5f 53 4f 52 54 45 44 5f 4d 41 54 43 48  LAN_SORTED_MATCH
3e60: 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 28  ;.    }..    if(
3e70: 20 70 49 6e 66 6f 2d 3e 6f 72 64 65 72 42 79 43   pInfo->orderByC
3e80: 6f 6e 73 75 6d 65 64 20 29 7b 0a 20 20 20 20 20  onsumed ){.     
3e90: 20 65 50 6c 61 6e 20 7c 3d 20 70 49 6e 66 6f 2d   ePlan |= pInfo-
3ea0: 3e 61 4f 72 64 65 72 42 79 5b 30 5d 2e 64 65 73  >aOrderBy[0].des
3eb0: 63 20 3f 20 46 54 53 35 5f 4f 52 44 45 52 5f 44  c ? FTS5_ORDER_D
3ec0: 45 53 43 20 3a 20 46 54 53 35 5f 4f 52 44 45 52  ESC : FTS5_ORDER
3ed0: 5f 41 53 43 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  _ASC;.    }.  }.
3ee0: 0a 20 20 69 52 61 6e 6b 4d 61 74 63 68 20 3d 20  .  iRankMatch = 
3ef0: 66 74 73 35 46 69 6e 64 43 6f 6e 73 74 72 61 69  fts5FindConstrai
3f00: 6e 74 28 0a 20 20 20 20 20 20 70 49 6e 66 6f 2c  nt(.      pInfo,
3f10: 20 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f 43 4f   SQLITE_INDEX_CO
3f20: 4e 53 54 52 41 49 4e 54 5f 4d 41 54 43 48 2c 20  NSTRAINT_MATCH, 
3f30: 70 43 6f 6e 66 69 67 2d 3e 6e 43 6f 6c 2b 31 0a  pConfig->nCol+1.
3f40: 20 20 29 3b 0a 20 20 69 66 28 20 69 52 61 6e 6b    );.  if( iRank
3f50: 4d 61 74 63 68 3e 3d 30 20 29 7b 0a 20 20 20 20  Match>=0 ){.    
3f60: 70 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74 72 61 69  pInfo->aConstrai
3f70: 6e 74 55 73 61 67 65 5b 69 52 61 6e 6b 4d 61 74  ntUsage[iRankMat
3f80: 63 68 5d 2e 61 72 67 76 49 6e 64 65 78 20 3d 20  ch].argvIndex = 
3f90: 31 20 2b 20 28 69 43 6f 6e 73 3e 3d 30 29 3b 0a  1 + (iCons>=0);.
3fa0: 20 20 20 20 70 49 6e 66 6f 2d 3e 61 43 6f 6e 73      pInfo->aCons
3fb0: 74 72 61 69 6e 74 55 73 61 67 65 5b 69 52 61 6e  traintUsage[iRan
3fc0: 6b 4d 61 74 63 68 5d 2e 6f 6d 69 74 20 3d 20 31  kMatch].omit = 1
3fd0: 3b 0a 20 20 7d 0a 20 20 20 0a 20 20 70 49 6e 66  ;.  }.   .  pInf
3fe0: 6f 2d 3e 69 64 78 4e 75 6d 20 3d 20 65 50 6c 61  o->idxNum = ePla
3ff0: 6e 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49  n;.  return SQLI
4000: 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  TE_OK;.}../*.** 
4010: 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f  Implementation o
4020: 66 20 78 4f 70 65 6e 20 6d 65 74 68 6f 64 2e 0a  f xOpen method..
4030: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74  */.static int ft
4040: 73 35 4f 70 65 6e 4d 65 74 68 6f 64 28 73 71 6c  s5OpenMethod(sql
4050: 69 74 65 33 5f 76 74 61 62 20 2a 70 56 54 61 62  ite3_vtab *pVTab
4060: 2c 20 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63  , sqlite3_vtab_c
4070: 75 72 73 6f 72 20 2a 2a 70 70 43 73 72 29 7b 0a  ursor **ppCsr){.
4080: 20 20 46 74 73 35 54 61 62 6c 65 20 2a 70 54 61    Fts5Table *pTa
4090: 62 20 3d 20 28 46 74 73 35 54 61 62 6c 65 2a 29  b = (Fts5Table*)
40a0: 70 56 54 61 62 3b 0a 20 20 46 74 73 35 43 6f 6e  pVTab;.  Fts5Con
40b0: 66 69 67 20 2a 70 43 6f 6e 66 69 67 20 3d 20 70  fig *pConfig = p
40c0: 54 61 62 2d 3e 70 43 6f 6e 66 69 67 3b 0a 20 20  Tab->pConfig;.  
40d0: 46 74 73 35 43 75 72 73 6f 72 20 2a 70 43 73 72  Fts5Cursor *pCsr
40e0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
40f0: 2f 2a 20 4e 65 77 20 63 75 72 73 6f 72 20 6f 62  /* New cursor ob
4100: 6a 65 63 74 20 2a 2f 0a 20 20 69 6e 74 20 6e 42  ject */.  int nB
4110: 79 74 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  yte;            
4120: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42 79 74            /* Byt
4130: 65 73 20 6f 66 20 73 70 61 63 65 20 74 6f 20 61  es of space to a
4140: 6c 6c 6f 63 61 74 65 20 2a 2f 0a 20 20 69 6e 74  llocate */.  int
4150: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
4160: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
4170: 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 0a  Return code */..
4180: 20 20 6e 42 79 74 65 20 3d 20 73 69 7a 65 6f 66    nByte = sizeof
4190: 28 46 74 73 35 43 75 72 73 6f 72 29 20 2b 20 70  (Fts5Cursor) + p
41a0: 43 6f 6e 66 69 67 2d 3e 6e 43 6f 6c 20 2a 20 73  Config->nCol * s
41b0: 69 7a 65 6f 66 28 69 6e 74 29 3b 0a 20 20 70 43  izeof(int);.  pC
41c0: 73 72 20 3d 20 28 46 74 73 35 43 75 72 73 6f 72  sr = (Fts5Cursor
41d0: 2a 29 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63  *)sqlite3_malloc
41e0: 28 6e 42 79 74 65 29 3b 0a 20 20 69 66 28 20 70  (nByte);.  if( p
41f0: 43 73 72 20 29 7b 0a 20 20 20 20 46 74 73 35 47  Csr ){.    Fts5G
4200: 6c 6f 62 61 6c 20 2a 70 47 6c 6f 62 61 6c 20 3d  lobal *pGlobal =
4210: 20 70 54 61 62 2d 3e 70 47 6c 6f 62 61 6c 3b 0a   pTab->pGlobal;.
4220: 20 20 20 20 6d 65 6d 73 65 74 28 70 43 73 72 2c      memset(pCsr,
4230: 20 30 2c 20 6e 42 79 74 65 29 3b 0a 20 20 20 20   0, nByte);.    
4240: 70 43 73 72 2d 3e 61 43 6f 6c 75 6d 6e 53 69 7a  pCsr->aColumnSiz
4250: 65 20 3d 20 28 69 6e 74 2a 29 26 70 43 73 72 5b  e = (int*)&pCsr[
4260: 31 5d 3b 0a 20 20 20 20 70 43 73 72 2d 3e 70 4e  1];.    pCsr->pN
4270: 65 78 74 20 3d 20 70 47 6c 6f 62 61 6c 2d 3e 70  ext = pGlobal->p
4280: 43 73 72 3b 0a 20 20 20 20 70 47 6c 6f 62 61 6c  Csr;.    pGlobal
4290: 2d 3e 70 43 73 72 20 3d 20 70 43 73 72 3b 0a 20  ->pCsr = pCsr;. 
42a0: 20 20 20 70 43 73 72 2d 3e 69 43 73 72 49 64 20     pCsr->iCsrId 
42b0: 3d 20 2b 2b 70 47 6c 6f 62 61 6c 2d 3e 69 4e 65  = ++pGlobal->iNe
42c0: 78 74 49 64 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  xtId;.  }else{. 
42d0: 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e     rc = SQLITE_N
42e0: 4f 4d 45 4d 3b 0a 20 20 7d 0a 20 20 2a 70 70 43  OMEM;.  }.  *ppC
42f0: 73 72 20 3d 20 28 73 71 6c 69 74 65 33 5f 76 74  sr = (sqlite3_vt
4300: 61 62 5f 63 75 72 73 6f 72 2a 29 70 43 73 72 3b  ab_cursor*)pCsr;
4310: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
4320: 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35  .static int fts5
4330: 53 74 6d 74 54 79 70 65 28 69 6e 74 20 69 64 78  StmtType(int idx
4340: 4e 75 6d 29 7b 0a 20 20 69 66 28 20 46 54 53 35  Num){.  if( FTS5
4350: 5f 50 4c 41 4e 28 69 64 78 4e 75 6d 29 3d 3d 46  _PLAN(idxNum)==F
4360: 54 53 35 5f 50 4c 41 4e 5f 53 43 41 4e 20 29 7b  TS5_PLAN_SCAN ){
4370: 0a 20 20 20 20 72 65 74 75 72 6e 20 28 69 64 78  .    return (idx
4380: 4e 75 6d 26 46 54 53 35 5f 4f 52 44 45 52 5f 41  Num&FTS5_ORDER_A
4390: 53 43 29 20 3f 20 46 54 53 35 5f 53 54 4d 54 5f  SC) ? FTS5_STMT_
43a0: 53 43 41 4e 5f 41 53 43 20 3a 20 46 54 53 35 5f  SCAN_ASC : FTS5_
43b0: 53 54 4d 54 5f 53 43 41 4e 5f 44 45 53 43 3b 0a  STMT_SCAN_DESC;.
43c0: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 46 54 53    }.  return FTS
43d0: 35 5f 53 54 4d 54 5f 4c 4f 4f 4b 55 50 3b 0a 7d  5_STMT_LOOKUP;.}
43e0: 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e  ../*.** This fun
43f0: 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20  ction is called 
4400: 61 66 74 65 72 20 74 68 65 20 63 75 72 73 6f 72  after the cursor
4410: 20 70 61 73 73 65 64 20 61 73 20 74 68 65 20 6f   passed as the o
4420: 6e 6c 79 20 61 72 67 75 6d 65 6e 74 0a 2a 2a 20  nly argument.** 
4430: 69 73 20 6d 6f 76 65 64 20 74 6f 20 70 6f 69 6e  is moved to poin
4440: 74 20 61 74 20 61 20 64 69 66 66 65 72 65 6e 74  t at a different
4450: 20 72 6f 77 2e 20 49 74 20 63 6c 65 61 72 73 20   row. It clears 
4460: 61 6c 6c 20 63 61 63 68 65 64 20 64 61 74 61 20  all cached data 
4470: 0a 2a 2a 20 73 70 65 63 69 66 69 63 20 74 6f 20  .** specific to 
4480: 74 68 65 20 70 72 65 76 69 6f 75 73 20 72 6f 77  the previous row
4490: 20 73 74 6f 72 65 64 20 62 79 20 74 68 65 20 63   stored by the c
44a0: 75 72 73 6f 72 20 6f 62 6a 65 63 74 2e 0a 2a 2f  ursor object..*/
44b0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 66 74 73  .static void fts
44c0: 35 43 73 72 4e 65 77 72 6f 77 28 46 74 73 35 43  5CsrNewrow(Fts5C
44d0: 75 72 73 6f 72 20 2a 70 43 73 72 29 7b 0a 20 20  ursor *pCsr){.  
44e0: 43 73 72 46 6c 61 67 53 65 74 28 70 43 73 72 2c  CsrFlagSet(pCsr,
44f0: 20 46 54 53 35 43 53 52 5f 52 45 51 55 49 52 45   FTS5CSR_REQUIRE
4500: 5f 43 4f 4e 54 45 4e 54 20 7c 20 46 54 53 35 43  _CONTENT | FTS5C
4510: 53 52 5f 52 45 51 55 49 52 45 5f 44 4f 43 53 49  SR_REQUIRE_DOCSI
4520: 5a 45 20 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f  ZE );.  sqlite3_
4530: 66 72 65 65 28 70 43 73 72 2d 3e 61 49 6e 73 74  free(pCsr->aInst
4540: 29 3b 0a 20 20 70 43 73 72 2d 3e 61 49 6e 73 74  );.  pCsr->aInst
4550: 20 3d 20 30 3b 0a 20 20 70 43 73 72 2d 3e 6e 49   = 0;.  pCsr->nI
4560: 6e 73 74 43 6f 75 6e 74 20 3d 20 30 3b 0a 7d 0a  nstCount = 0;.}.
4570: 0a 2f 2a 0a 2a 2a 20 43 6c 6f 73 65 20 74 68 65  ./*.** Close the
4580: 20 63 75 72 73 6f 72 2e 20 20 46 6f 72 20 61 64   cursor.  For ad
4590: 64 69 74 69 6f 6e 61 6c 20 69 6e 66 6f 72 6d 61  ditional informa
45a0: 74 69 6f 6e 20 73 65 65 20 74 68 65 20 64 6f 63  tion see the doc
45b0: 75 6d 65 6e 74 61 74 69 6f 6e 0a 2a 2a 20 6f 6e  umentation.** on
45c0: 20 74 68 65 20 78 43 6c 6f 73 65 20 6d 65 74 68   the xClose meth
45d0: 6f 64 20 6f 66 20 74 68 65 20 76 69 72 74 75 61  od of the virtua
45e0: 6c 20 74 61 62 6c 65 20 69 6e 74 65 72 66 61 63  l table interfac
45f0: 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  e..*/.static int
4600: 20 66 74 73 35 43 6c 6f 73 65 4d 65 74 68 6f 64   fts5CloseMethod
4610: 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75  (sqlite3_vtab_cu
4620: 72 73 6f 72 20 2a 70 43 75 72 73 6f 72 29 7b 0a  rsor *pCursor){.
4630: 20 20 46 74 73 35 54 61 62 6c 65 20 2a 70 54 61    Fts5Table *pTa
4640: 62 20 3d 20 28 46 74 73 35 54 61 62 6c 65 2a 29  b = (Fts5Table*)
4650: 28 70 43 75 72 73 6f 72 2d 3e 70 56 74 61 62 29  (pCursor->pVtab)
4660: 3b 0a 20 20 46 74 73 35 43 75 72 73 6f 72 20 2a  ;.  Fts5Cursor *
4670: 70 43 73 72 20 3d 20 28 46 74 73 35 43 75 72 73  pCsr = (Fts5Curs
4680: 6f 72 2a 29 70 43 75 72 73 6f 72 3b 0a 20 20 46  or*)pCursor;.  F
4690: 74 73 35 43 75 72 73 6f 72 20 2a 2a 70 70 3b 0a  ts5Cursor **pp;.
46a0: 20 20 46 74 73 35 41 75 78 64 61 74 61 20 2a 70    Fts5Auxdata *p
46b0: 44 61 74 61 3b 0a 20 20 46 74 73 35 41 75 78 64  Data;.  Fts5Auxd
46c0: 61 74 61 20 2a 70 4e 65 78 74 3b 0a 0a 20 20 66  ata *pNext;..  f
46d0: 74 73 35 43 73 72 4e 65 77 72 6f 77 28 70 43 73  ts5CsrNewrow(pCs
46e0: 72 29 3b 0a 20 20 69 66 28 20 70 43 73 72 2d 3e  r);.  if( pCsr->
46f0: 70 53 74 6d 74 20 29 7b 0a 20 20 20 20 69 6e 74  pStmt ){.    int
4700: 20 65 53 74 6d 74 20 3d 20 66 74 73 35 53 74 6d   eStmt = fts5Stm
4710: 74 54 79 70 65 28 70 43 73 72 2d 3e 69 64 78 4e  tType(pCsr->idxN
4720: 75 6d 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33  um);.    sqlite3
4730: 46 74 73 35 53 74 6f 72 61 67 65 53 74 6d 74 52  Fts5StorageStmtR
4740: 65 6c 65 61 73 65 28 70 54 61 62 2d 3e 70 53 74  elease(pTab->pSt
4750: 6f 72 61 67 65 2c 20 65 53 74 6d 74 2c 20 70 43  orage, eStmt, pC
4760: 73 72 2d 3e 70 53 74 6d 74 29 3b 0a 20 20 7d 0a  sr->pStmt);.  }.
4770: 20 20 69 66 28 20 70 43 73 72 2d 3e 70 53 6f 72    if( pCsr->pSor
4780: 74 65 72 20 29 7b 0a 20 20 20 20 46 74 73 35 53  ter ){.    Fts5S
4790: 6f 72 74 65 72 20 2a 70 53 6f 72 74 65 72 20 3d  orter *pSorter =
47a0: 20 70 43 73 72 2d 3e 70 53 6f 72 74 65 72 3b 0a   pCsr->pSorter;.
47b0: 20 20 20 20 73 71 6c 69 74 65 33 5f 66 69 6e 61      sqlite3_fina
47c0: 6c 69 7a 65 28 70 53 6f 72 74 65 72 2d 3e 70 53  lize(pSorter->pS
47d0: 74 6d 74 29 3b 0a 20 20 20 20 73 71 6c 69 74 65  tmt);.    sqlite
47e0: 33 5f 66 72 65 65 28 70 53 6f 72 74 65 72 29 3b  3_free(pSorter);
47f0: 0a 20 20 7d 0a 20 20 0a 20 20 69 66 28 20 70 43  .  }.  .  if( pC
4800: 73 72 2d 3e 69 64 78 4e 75 6d 21 3d 46 54 53 35  sr->idxNum!=FTS5
4810: 5f 50 4c 41 4e 5f 53 4f 55 52 43 45 20 29 7b 0a  _PLAN_SOURCE ){.
4820: 20 20 20 20 73 71 6c 69 74 65 33 46 74 73 35 45      sqlite3Fts5E
4830: 78 70 72 46 72 65 65 28 70 43 73 72 2d 3e 70 45  xprFree(pCsr->pE
4840: 78 70 72 29 3b 0a 20 20 7d 0a 0a 20 20 66 6f 72  xpr);.  }..  for
4850: 28 70 44 61 74 61 3d 70 43 73 72 2d 3e 70 41 75  (pData=pCsr->pAu
4860: 78 64 61 74 61 3b 20 70 44 61 74 61 3b 20 70 44  xdata; pData; pD
4870: 61 74 61 3d 70 4e 65 78 74 29 7b 0a 20 20 20 20  ata=pNext){.    
4880: 70 4e 65 78 74 20 3d 20 70 44 61 74 61 2d 3e 70  pNext = pData->p
4890: 4e 65 78 74 3b 0a 20 20 20 20 69 66 28 20 70 44  Next;.    if( pD
48a0: 61 74 61 2d 3e 78 44 65 6c 65 74 65 20 29 20 70  ata->xDelete ) p
48b0: 44 61 74 61 2d 3e 78 44 65 6c 65 74 65 28 70 44  Data->xDelete(pD
48c0: 61 74 61 2d 3e 70 50 74 72 29 3b 0a 20 20 20 20  ata->pPtr);.    
48d0: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 44 61  sqlite3_free(pDa
48e0: 74 61 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 52  ta);.  }..  /* R
48f0: 65 6d 6f 76 65 20 74 68 65 20 63 75 72 73 6f 72  emove the cursor
4900: 20 66 72 6f 6d 20 74 68 65 20 46 74 73 35 47 6c   from the Fts5Gl
4910: 6f 62 61 6c 2e 70 43 73 72 20 6c 69 73 74 20 2a  obal.pCsr list *
4920: 2f 0a 20 20 66 6f 72 28 70 70 3d 26 70 54 61 62  /.  for(pp=&pTab
4930: 2d 3e 70 47 6c 6f 62 61 6c 2d 3e 70 43 73 72 3b  ->pGlobal->pCsr;
4940: 20 28 2a 70 70 29 21 3d 70 43 73 72 3b 20 70 70   (*pp)!=pCsr; pp
4950: 3d 26 28 2a 70 70 29 2d 3e 70 4e 65 78 74 29 3b  =&(*pp)->pNext);
4960: 0a 20 20 2a 70 70 20 3d 20 70 43 73 72 2d 3e 70  .  *pp = pCsr->p
4970: 4e 65 78 74 3b 0a 0a 20 20 73 71 6c 69 74 65 33  Next;..  sqlite3
4980: 5f 66 69 6e 61 6c 69 7a 65 28 70 43 73 72 2d 3e  _finalize(pCsr->
4990: 70 52 61 6e 6b 41 72 67 53 74 6d 74 29 3b 0a 20  pRankArgStmt);. 
49a0: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 43   sqlite3_free(pC
49b0: 73 72 2d 3e 61 70 52 61 6e 6b 41 72 67 29 3b 0a  sr->apRankArg);.
49c0: 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28  .  sqlite3_free(
49d0: 70 43 73 72 2d 3e 7a 53 70 65 63 69 61 6c 29 3b  pCsr->zSpecial);
49e0: 0a 20 20 69 66 28 20 43 73 72 46 6c 61 67 54 65  .  if( CsrFlagTe
49f0: 73 74 28 70 43 73 72 2c 20 46 54 53 35 43 53 52  st(pCsr, FTS5CSR
4a00: 5f 46 52 45 45 5f 5a 52 41 4e 4b 29 20 29 7b 0a  _FREE_ZRANK) ){.
4a10: 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65      sqlite3_free
4a20: 28 70 43 73 72 2d 3e 7a 52 61 6e 6b 29 3b 0a 20  (pCsr->zRank);. 
4a30: 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28     sqlite3_free(
4a40: 70 43 73 72 2d 3e 7a 52 61 6e 6b 41 72 67 73 29  pCsr->zRankArgs)
4a50: 3b 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65 33 5f  ;.  }.  sqlite3_
4a60: 66 72 65 65 28 70 43 73 72 29 3b 0a 20 20 72 65  free(pCsr);.  re
4a70: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
4a80: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74  }..static int ft
4a90: 73 35 53 6f 72 74 65 72 4e 65 78 74 28 46 74 73  s5SorterNext(Fts
4aa0: 35 43 75 72 73 6f 72 20 2a 70 43 73 72 29 7b 0a  5Cursor *pCsr){.
4ab0: 20 20 46 74 73 35 53 6f 72 74 65 72 20 2a 70 53    Fts5Sorter *pS
4ac0: 6f 72 74 65 72 20 3d 20 70 43 73 72 2d 3e 70 53  orter = pCsr->pS
4ad0: 6f 72 74 65 72 3b 0a 20 20 69 6e 74 20 72 63 3b  orter;.  int rc;
4ae0: 0a 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33  ..  rc = sqlite3
4af0: 5f 73 74 65 70 28 70 53 6f 72 74 65 72 2d 3e 70  _step(pSorter->p
4b00: 53 74 6d 74 29 3b 0a 20 20 69 66 28 20 72 63 3d  Stmt);.  if( rc=
4b10: 3d 53 51 4c 49 54 45 5f 44 4f 4e 45 20 29 7b 0a  =SQLITE_DONE ){.
4b20: 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
4b30: 4f 4b 3b 0a 20 20 20 20 43 73 72 46 6c 61 67 53  OK;.    CsrFlagS
4b40: 65 74 28 70 43 73 72 2c 20 46 54 53 35 43 53 52  et(pCsr, FTS5CSR
4b50: 5f 45 4f 46 29 3b 0a 20 20 7d 65 6c 73 65 20 69  _EOF);.  }else i
4b60: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 52 4f  f( rc==SQLITE_RO
4b70: 57 20 29 7b 0a 20 20 20 20 63 6f 6e 73 74 20 75  W ){.    const u
4b80: 38 20 2a 61 3b 0a 20 20 20 20 63 6f 6e 73 74 20  8 *a;.    const 
4b90: 75 38 20 2a 61 42 6c 6f 62 3b 0a 20 20 20 20 69  u8 *aBlob;.    i
4ba0: 6e 74 20 6e 42 6c 6f 62 3b 0a 20 20 20 20 69 6e  nt nBlob;.    in
4bb0: 74 20 69 3b 0a 20 20 20 20 69 6e 74 20 69 4f 66  t i;.    int iOf
4bc0: 66 20 3d 20 30 3b 0a 20 20 20 20 72 63 20 3d 20  f = 0;.    rc = 
4bd0: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20 20 20  SQLITE_OK;..    
4be0: 70 53 6f 72 74 65 72 2d 3e 69 52 6f 77 69 64 20  pSorter->iRowid 
4bf0: 3d 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e  = sqlite3_column
4c00: 5f 69 6e 74 36 34 28 70 53 6f 72 74 65 72 2d 3e  _int64(pSorter->
4c10: 70 53 74 6d 74 2c 20 30 29 3b 0a 20 20 20 20 6e  pStmt, 0);.    n
4c20: 42 6c 6f 62 20 3d 20 73 71 6c 69 74 65 33 5f 63  Blob = sqlite3_c
4c30: 6f 6c 75 6d 6e 5f 62 79 74 65 73 28 70 53 6f 72  olumn_bytes(pSor
4c40: 74 65 72 2d 3e 70 53 74 6d 74 2c 20 31 29 3b 0a  ter->pStmt, 1);.
4c50: 20 20 20 20 61 42 6c 6f 62 20 3d 20 61 20 3d 20      aBlob = a = 
4c60: 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 62  sqlite3_column_b
4c70: 6c 6f 62 28 70 53 6f 72 74 65 72 2d 3e 70 53 74  lob(pSorter->pSt
4c80: 6d 74 2c 20 31 29 3b 0a 0a 20 20 20 20 66 6f 72  mt, 1);..    for
4c90: 28 69 3d 30 3b 20 69 3c 28 70 53 6f 72 74 65 72  (i=0; i<(pSorter
4ca0: 2d 3e 6e 49 64 78 2d 31 29 3b 20 69 2b 2b 29 7b  ->nIdx-1); i++){
4cb0: 0a 20 20 20 20 20 20 69 6e 74 20 69 56 61 6c 3b  .      int iVal;
4cc0: 0a 20 20 20 20 20 20 61 20 2b 3d 20 67 65 74 56  .      a += getV
4cd0: 61 72 69 6e 74 33 32 28 61 2c 20 69 56 61 6c 29  arint32(a, iVal)
4ce0: 3b 0a 20 20 20 20 20 20 69 4f 66 66 20 2b 3d 20  ;.      iOff += 
4cf0: 69 56 61 6c 3b 0a 20 20 20 20 20 20 70 53 6f 72  iVal;.      pSor
4d00: 74 65 72 2d 3e 61 49 64 78 5b 69 5d 20 3d 20 69  ter->aIdx[i] = i
4d10: 4f 66 66 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70  Off;.    }.    p
4d20: 53 6f 72 74 65 72 2d 3e 61 49 64 78 5b 69 5d 20  Sorter->aIdx[i] 
4d30: 3d 20 26 61 42 6c 6f 62 5b 6e 42 6c 6f 62 5d 20  = &aBlob[nBlob] 
4d40: 2d 20 61 3b 0a 0a 20 20 20 20 70 53 6f 72 74 65  - a;..    pSorte
4d50: 72 2d 3e 61 50 6f 73 6c 69 73 74 20 3d 20 61 3b  r->aPoslist = a;
4d60: 0a 20 20 20 20 66 74 73 35 43 73 72 4e 65 77 72  .    fts5CsrNewr
4d70: 6f 77 28 70 43 73 72 29 3b 0a 20 20 7d 0a 0a 20  ow(pCsr);.  }.. 
4d80: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
4d90: 2a 0a 2a 2a 20 41 64 76 61 6e 63 65 20 74 68 65  *.** Advance the
4da0: 20 63 75 72 73 6f 72 20 74 6f 20 74 68 65 20 6e   cursor to the n
4db0: 65 78 74 20 72 6f 77 20 69 6e 20 74 68 65 20 74  ext row in the t
4dc0: 61 62 6c 65 20 74 68 61 74 20 6d 61 74 63 68 65  able that matche
4dd0: 73 20 74 68 65 20 0a 2a 2a 20 73 65 61 72 63 68  s the .** search
4de0: 20 63 72 69 74 65 72 69 61 2e 0a 2a 2a 0a 2a 2a   criteria..**.**
4df0: 20 52 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   Return SQLITE_O
4e00: 4b 20 69 66 20 6e 6f 74 68 69 6e 67 20 67 6f 65  K if nothing goe
4e10: 73 20 77 72 6f 6e 67 2e 20 20 53 51 4c 49 54 45  s wrong.  SQLITE
4e20: 5f 4f 4b 20 69 73 20 72 65 74 75 72 6e 65 64 0a  _OK is returned.
4e30: 2a 2a 20 65 76 65 6e 20 69 66 20 77 65 20 72 65  ** even if we re
4e40: 61 63 68 20 65 6e 64 2d 6f 66 2d 66 69 6c 65 2e  ach end-of-file.
4e50: 20 20 54 68 65 20 66 74 73 35 45 6f 66 4d 65 74    The fts5EofMet
4e60: 68 6f 64 28 29 20 77 69 6c 6c 20 62 65 20 63 61  hod() will be ca
4e70: 6c 6c 65 64 0a 2a 2a 20 73 75 62 73 65 71 75 65  lled.** subseque
4e80: 6e 74 6c 79 20 74 6f 20 64 65 74 65 72 6d 69 6e  ntly to determin
4e90: 65 20 77 68 65 74 68 65 72 20 6f 72 20 6e 6f 74  e whether or not
4ea0: 20 61 6e 20 45 4f 46 20 77 61 73 20 68 69 74 2e   an EOF was hit.
4eb0: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66  .*/.static int f
4ec0: 74 73 35 4e 65 78 74 4d 65 74 68 6f 64 28 73 71  ts5NextMethod(sq
4ed0: 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f  lite3_vtab_curso
4ee0: 72 20 2a 70 43 75 72 73 6f 72 29 7b 0a 20 20 46  r *pCursor){.  F
4ef0: 74 73 35 43 75 72 73 6f 72 20 2a 70 43 73 72 20  ts5Cursor *pCsr 
4f00: 3d 20 28 46 74 73 35 43 75 72 73 6f 72 2a 29 70  = (Fts5Cursor*)p
4f10: 43 75 72 73 6f 72 3b 0a 20 20 69 6e 74 20 65 50  Cursor;.  int eP
4f20: 6c 61 6e 20 3d 20 46 54 53 35 5f 50 4c 41 4e 28  lan = FTS5_PLAN(
4f30: 70 43 73 72 2d 3e 69 64 78 4e 75 6d 29 3b 0a 20  pCsr->idxNum);. 
4f40: 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
4f50: 5f 4f 4b 3b 0a 0a 20 20 73 77 69 74 63 68 28 20  _OK;..  switch( 
4f60: 65 50 6c 61 6e 20 29 7b 0a 20 20 20 20 63 61 73  ePlan ){.    cas
4f70: 65 20 46 54 53 35 5f 50 4c 41 4e 5f 4d 41 54 43  e FTS5_PLAN_MATC
4f80: 48 3a 0a 20 20 20 20 63 61 73 65 20 46 54 53 35  H:.    case FTS5
4f90: 5f 50 4c 41 4e 5f 53 4f 55 52 43 45 3a 0a 20 20  _PLAN_SOURCE:.  
4fa0: 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
4fb0: 46 74 73 35 45 78 70 72 4e 65 78 74 28 70 43 73  Fts5ExprNext(pCs
4fc0: 72 2d 3e 70 45 78 70 72 29 3b 0a 20 20 20 20 20  r->pExpr);.     
4fd0: 20 69 66 28 20 73 71 6c 69 74 65 33 46 74 73 35   if( sqlite3Fts5
4fe0: 45 78 70 72 45 6f 66 28 70 43 73 72 2d 3e 70 45  ExprEof(pCsr->pE
4ff0: 78 70 72 29 20 29 7b 0a 20 20 20 20 20 20 20 20  xpr) ){.        
5000: 43 73 72 46 6c 61 67 53 65 74 28 70 43 73 72 2c  CsrFlagSet(pCsr,
5010: 20 46 54 53 35 43 53 52 5f 45 4f 46 29 3b 0a 20   FTS5CSR_EOF);. 
5020: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 66 74 73       }.      fts
5030: 35 43 73 72 4e 65 77 72 6f 77 28 70 43 73 72 29  5CsrNewrow(pCsr)
5040: 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 0a  ;.      break;..
5050: 20 20 20 20 63 61 73 65 20 46 54 53 35 5f 50 4c      case FTS5_PL
5060: 41 4e 5f 53 50 45 43 49 41 4c 3a 20 7b 0a 20 20  AN_SPECIAL: {.  
5070: 20 20 20 20 43 73 72 46 6c 61 67 53 65 74 28 70      CsrFlagSet(p
5080: 43 73 72 2c 20 46 54 53 35 43 53 52 5f 45 4f 46  Csr, FTS5CSR_EOF
5090: 29 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a  );.      break;.
50a0: 20 20 20 20 7d 0a 0a 20 20 20 20 63 61 73 65 20      }..    case 
50b0: 46 54 53 35 5f 50 4c 41 4e 5f 53 4f 52 54 45 44  FTS5_PLAN_SORTED
50c0: 5f 4d 41 54 43 48 3a 20 7b 0a 20 20 20 20 20 20  _MATCH: {.      
50d0: 72 63 20 3d 20 66 74 73 35 53 6f 72 74 65 72 4e  rc = fts5SorterN
50e0: 65 78 74 28 70 43 73 72 29 3b 0a 20 20 20 20 20  ext(pCsr);.     
50f0: 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20   break;.    }.. 
5100: 20 20 20 64 65 66 61 75 6c 74 3a 0a 20 20 20 20     default:.    
5110: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 73    rc = sqlite3_s
5120: 74 65 70 28 70 43 73 72 2d 3e 70 53 74 6d 74 29  tep(pCsr->pStmt)
5130: 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 21 3d  ;.      if( rc!=
5140: 53 51 4c 49 54 45 5f 52 4f 57 20 29 7b 0a 20 20  SQLITE_ROW ){.  
5150: 20 20 20 20 20 20 43 73 72 46 6c 61 67 53 65 74        CsrFlagSet
5160: 28 70 43 73 72 2c 20 46 54 53 35 43 53 52 5f 45  (pCsr, FTS5CSR_E
5170: 4f 46 29 3b 0a 20 20 20 20 20 20 20 20 72 63 20  OF);.        rc 
5180: 3d 20 73 71 6c 69 74 65 33 5f 72 65 73 65 74 28  = sqlite3_reset(
5190: 70 43 73 72 2d 3e 70 53 74 6d 74 29 3b 0a 20 20  pCsr->pStmt);.  
51a0: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
51b0: 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f     rc = SQLITE_O
51c0: 4b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  K;.      }.     
51d0: 20 62 72 65 61 6b 3b 0a 20 20 7d 0a 20 20 0a 20   break;.  }.  . 
51e0: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73   return rc;.}..s
51f0: 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 43 75  tatic int fts5Cu
5200: 72 73 6f 72 46 69 72 73 74 53 6f 72 74 65 64 28  rsorFirstSorted(
5210: 46 74 73 35 54 61 62 6c 65 20 2a 70 54 61 62 2c  Fts5Table *pTab,
5220: 20 46 74 73 35 43 75 72 73 6f 72 20 2a 70 43 73   Fts5Cursor *pCs
5230: 72 2c 20 69 6e 74 20 62 41 73 63 29 7b 0a 20 20  r, int bAsc){.  
5240: 46 74 73 35 43 6f 6e 66 69 67 20 2a 70 43 6f 6e  Fts5Config *pCon
5250: 66 69 67 20 3d 20 70 54 61 62 2d 3e 70 43 6f 6e  fig = pTab->pCon
5260: 66 69 67 3b 0a 20 20 46 74 73 35 53 6f 72 74 65  fig;.  Fts5Sorte
5270: 72 20 2a 70 53 6f 72 74 65 72 3b 0a 20 20 69 6e  r *pSorter;.  in
5280: 74 20 6e 50 68 72 61 73 65 3b 0a 20 20 69 6e 74  t nPhrase;.  int
5290: 20 6e 42 79 74 65 3b 0a 20 20 69 6e 74 20 72 63   nByte;.  int rc
52a0: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20   = SQLITE_OK;.  
52b0: 63 68 61 72 20 2a 7a 53 71 6c 3b 0a 20 20 63 6f  char *zSql;.  co
52c0: 6e 73 74 20 63 68 61 72 20 2a 7a 52 61 6e 6b 20  nst char *zRank 
52d0: 3d 20 70 43 73 72 2d 3e 7a 52 61 6e 6b 3b 0a 20  = pCsr->zRank;. 
52e0: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 52 61   const char *zRa
52f0: 6e 6b 41 72 67 73 20 3d 20 70 43 73 72 2d 3e 7a  nkArgs = pCsr->z
5300: 52 61 6e 6b 41 72 67 73 3b 0a 20 20 0a 20 20 6e  RankArgs;.  .  n
5310: 50 68 72 61 73 65 20 3d 20 73 71 6c 69 74 65 33  Phrase = sqlite3
5320: 46 74 73 35 45 78 70 72 50 68 72 61 73 65 43 6f  Fts5ExprPhraseCo
5330: 75 6e 74 28 70 43 73 72 2d 3e 70 45 78 70 72 29  unt(pCsr->pExpr)
5340: 3b 0a 20 20 6e 42 79 74 65 20 3d 20 73 69 7a 65  ;.  nByte = size
5350: 6f 66 28 46 74 73 35 53 6f 72 74 65 72 29 20 2b  of(Fts5Sorter) +
5360: 20 73 69 7a 65 6f 66 28 69 6e 74 29 20 2a 20 6e   sizeof(int) * n
5370: 50 68 72 61 73 65 3b 0a 20 20 70 53 6f 72 74 65  Phrase;.  pSorte
5380: 72 20 3d 20 28 46 74 73 35 53 6f 72 74 65 72 2a  r = (Fts5Sorter*
5390: 29 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28  )sqlite3_malloc(
53a0: 6e 42 79 74 65 29 3b 0a 20 20 69 66 28 20 70 53  nByte);.  if( pS
53b0: 6f 72 74 65 72 3d 3d 30 20 29 20 72 65 74 75 72  orter==0 ) retur
53c0: 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  n SQLITE_NOMEM;.
53d0: 20 20 6d 65 6d 73 65 74 28 70 53 6f 72 74 65 72    memset(pSorter
53e0: 2c 20 30 2c 20 6e 42 79 74 65 29 3b 0a 20 20 70  , 0, nByte);.  p
53f0: 53 6f 72 74 65 72 2d 3e 6e 49 64 78 20 3d 20 6e  Sorter->nIdx = n
5400: 50 68 72 61 73 65 3b 0a 0a 20 20 2f 2a 20 54 4f  Phrase;..  /* TO
5410: 44 4f 3a 20 49 74 20 77 6f 75 6c 64 20 62 65 20  DO: It would be 
5420: 62 65 74 74 65 72 20 74 6f 20 68 61 76 65 20 73  better to have s
5430: 6f 6d 65 20 73 79 73 74 65 6d 20 66 6f 72 20 72  ome system for r
5440: 65 75 73 69 6e 67 20 73 74 61 74 65 6d 65 6e 74  eusing statement
5450: 0a 20 20 2a 2a 20 68 61 6e 64 6c 65 73 20 68 65  .  ** handles he
5460: 72 65 2c 20 72 61 74 68 65 72 20 74 68 61 6e 20  re, rather than 
5470: 70 72 65 70 61 72 69 6e 67 20 61 20 6e 65 77 20  preparing a new 
5480: 6f 6e 65 20 66 6f 72 20 65 61 63 68 20 71 75 65  one for each que
5490: 72 79 2e 20 42 75 74 20 74 68 61 74 0a 20 20 2a  ry. But that.  *
54a0: 2a 20 69 73 20 6e 6f 74 20 70 6f 73 73 69 62 6c  * is not possibl
54b0: 65 20 61 73 20 53 51 4c 69 74 65 20 72 65 66 65  e as SQLite refe
54c0: 72 65 6e 63 65 20 63 6f 75 6e 74 73 20 74 68 65  rence counts the
54d0: 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20 6f   virtual table o
54e0: 62 6a 65 63 74 73 2e 0a 20 20 2a 2a 20 41 6e 64  bjects..  ** And
54f0: 20 73 69 6e 63 65 20 74 68 65 20 73 74 61 74 65   since the state
5500: 6d 65 6e 74 20 72 65 71 75 69 72 65 64 20 68 65  ment required he
5510: 72 65 20 72 65 61 64 73 20 66 72 6f 6d 20 74 68  re reads from th
5520: 69 73 20 76 65 72 79 20 76 69 72 74 75 61 6c 20  is very virtual 
5530: 0a 20 20 2a 2a 20 74 61 62 6c 65 2c 20 73 61 76  .  ** table, sav
5540: 69 6e 67 20 69 74 20 63 72 65 61 74 65 73 20 61  ing it creates a
5550: 20 63 69 72 63 75 6c 61 72 20 72 65 66 65 72 65   circular refere
5560: 6e 63 65 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20 49  nce..  **.  ** I
5570: 66 20 53 51 4c 69 74 65 20 61 20 62 75 69 6c 74  f SQLite a built
5580: 2d 69 6e 20 73 74 61 74 65 6d 65 6e 74 20 63 61  -in statement ca
5590: 63 68 65 2c 20 74 68 69 73 20 77 6f 75 6c 64 6e  che, this wouldn
55a0: 27 74 20 62 65 20 61 20 70 72 6f 62 6c 65 6d 2e  't be a problem.
55b0: 20 2a 2f 0a 20 20 7a 53 71 6c 20 3d 20 73 71 6c   */.  zSql = sql
55c0: 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 53 45  ite3_mprintf("SE
55d0: 4c 45 43 54 20 72 6f 77 69 64 2c 20 72 61 6e 6b  LECT rowid, rank
55e0: 20 46 52 4f 4d 20 25 51 2e 25 51 20 4f 52 44 45   FROM %Q.%Q ORDE
55f0: 52 20 42 59 20 25 73 28 25 73 25 73 25 73 29 20  R BY %s(%s%s%s) 
5600: 25 73 22 2c 0a 20 20 20 20 20 20 70 43 6f 6e 66  %s",.      pConf
5610: 69 67 2d 3e 7a 44 62 2c 20 70 43 6f 6e 66 69 67  ig->zDb, pConfig
5620: 2d 3e 7a 4e 61 6d 65 2c 20 7a 52 61 6e 6b 2c 20  ->zName, zRank, 
5630: 70 43 6f 6e 66 69 67 2d 3e 7a 4e 61 6d 65 2c 0a  pConfig->zName,.
5640: 20 20 20 20 20 20 28 7a 52 61 6e 6b 41 72 67 73        (zRankArgs
5650: 20 3f 20 22 2c 20 22 20 3a 20 22 22 29 2c 0a 20   ? ", " : ""),. 
5660: 20 20 20 20 20 28 7a 52 61 6e 6b 41 72 67 73 20       (zRankArgs 
5670: 3f 20 7a 52 61 6e 6b 41 72 67 73 20 3a 20 22 22  ? zRankArgs : ""
5680: 29 2c 0a 20 20 20 20 20 20 62 41 73 63 20 3f 20  ),.      bAsc ? 
5690: 22 41 53 43 22 20 3a 20 22 44 45 53 43 22 0a 20  "ASC" : "DESC". 
56a0: 20 29 3b 0a 20 20 69 66 28 20 7a 53 71 6c 3d 3d   );.  if( zSql==
56b0: 30 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 53 51  0 ){.    rc = SQ
56c0: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 65  LITE_NOMEM;.  }e
56d0: 6c 73 65 7b 0a 20 20 20 20 72 63 20 3d 20 73 71  lse{.    rc = sq
56e0: 6c 69 74 65 33 5f 70 72 65 70 61 72 65 5f 76 32  lite3_prepare_v2
56f0: 28 70 43 6f 6e 66 69 67 2d 3e 64 62 2c 20 7a 53  (pConfig->db, zS
5700: 71 6c 2c 20 2d 31 2c 20 26 70 53 6f 72 74 65 72  ql, -1, &pSorter
5710: 2d 3e 70 53 74 6d 74 2c 20 30 29 3b 0a 20 20 20  ->pStmt, 0);.   
5720: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a 53   sqlite3_free(zS
5730: 71 6c 29 3b 0a 20 20 7d 0a 0a 20 20 70 43 73 72  ql);.  }..  pCsr
5740: 2d 3e 70 53 6f 72 74 65 72 20 3d 20 70 53 6f 72  ->pSorter = pSor
5750: 74 65 72 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53  ter;.  if( rc==S
5760: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
5770: 61 73 73 65 72 74 28 20 70 54 61 62 2d 3e 70 53  assert( pTab->pS
5780: 6f 72 74 43 73 72 3d 3d 30 20 29 3b 0a 20 20 20  ortCsr==0 );.   
5790: 20 70 54 61 62 2d 3e 70 53 6f 72 74 43 73 72 20   pTab->pSortCsr 
57a0: 3d 20 70 43 73 72 3b 0a 20 20 20 20 72 63 20 3d  = pCsr;.    rc =
57b0: 20 66 74 73 35 53 6f 72 74 65 72 4e 65 78 74 28   fts5SorterNext(
57c0: 70 43 73 72 29 3b 0a 20 20 20 20 70 54 61 62 2d  pCsr);.    pTab-
57d0: 3e 70 53 6f 72 74 43 73 72 20 3d 20 30 3b 0a 20  >pSortCsr = 0;. 
57e0: 20 7d 0a 0a 20 20 69 66 28 20 72 63 21 3d 53 51   }..  if( rc!=SQ
57f0: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 73  LITE_OK ){.    s
5800: 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28  qlite3_finalize(
5810: 70 53 6f 72 74 65 72 2d 3e 70 53 74 6d 74 29 3b  pSorter->pStmt);
5820: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65  .    sqlite3_fre
5830: 65 28 70 53 6f 72 74 65 72 29 3b 0a 20 20 20 20  e(pSorter);.    
5840: 70 43 73 72 2d 3e 70 53 6f 72 74 65 72 20 3d 20  pCsr->pSorter = 
5850: 30 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e  0;.  }..  return
5860: 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69   rc;.}..static i
5870: 6e 74 20 66 74 73 35 43 75 72 73 6f 72 46 69 72  nt fts5CursorFir
5880: 73 74 28 46 74 73 35 54 61 62 6c 65 20 2a 70 54  st(Fts5Table *pT
5890: 61 62 2c 20 46 74 73 35 43 75 72 73 6f 72 20 2a  ab, Fts5Cursor *
58a0: 70 43 73 72 2c 20 69 6e 74 20 62 41 73 63 29 7b  pCsr, int bAsc){
58b0: 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 72 63 20  .  int rc;.  rc 
58c0: 3d 20 73 71 6c 69 74 65 33 46 74 73 35 45 78 70  = sqlite3Fts5Exp
58d0: 72 46 69 72 73 74 28 70 43 73 72 2d 3e 70 45 78  rFirst(pCsr->pEx
58e0: 70 72 2c 20 70 54 61 62 2d 3e 70 49 6e 64 65 78  pr, pTab->pIndex
58f0: 2c 20 62 41 73 63 29 3b 0a 20 20 69 66 28 20 73  , bAsc);.  if( s
5900: 71 6c 69 74 65 33 46 74 73 35 45 78 70 72 45 6f  qlite3Fts5ExprEo
5910: 66 28 70 43 73 72 2d 3e 70 45 78 70 72 29 20 29  f(pCsr->pExpr) )
5920: 7b 0a 20 20 20 20 43 73 72 46 6c 61 67 53 65 74  {.    CsrFlagSet
5930: 28 70 43 73 72 2c 20 46 54 53 35 43 53 52 5f 45  (pCsr, FTS5CSR_E
5940: 4f 46 29 3b 0a 20 20 7d 0a 20 20 66 74 73 35 43  OF);.  }.  fts5C
5950: 73 72 4e 65 77 72 6f 77 28 70 43 73 72 29 3b 0a  srNewrow(pCsr);.
5960: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
5970: 2f 2a 0a 2a 2a 20 50 72 6f 63 65 73 73 20 61 20  /*.** Process a 
5980: 22 73 70 65 63 69 61 6c 22 20 71 75 65 72 79 2e  "special" query.
5990: 20 41 20 73 70 65 63 69 61 6c 20 71 75 65 72 79   A special query
59a0: 20 69 73 20 69 64 65 6e 74 69 66 69 65 64 20 61   is identified a
59b0: 73 20 6f 6e 65 20 77 69 74 68 20 61 0a 2a 2a 20  s one with a.** 
59c0: 4d 41 54 43 48 20 65 78 70 72 65 73 73 69 6f 6e  MATCH expression
59d0: 20 74 68 61 74 20 62 65 67 69 6e 73 20 77 69 74   that begins wit
59e0: 68 20 61 20 27 2a 27 20 63 68 61 72 61 63 74 65  h a '*' characte
59f0: 72 2e 20 54 68 65 20 72 65 6d 61 69 6e 64 65 72  r. The remainder
5a00: 20 6f 66 0a 2a 2a 20 74 68 65 20 74 65 78 74 20   of.** the text 
5a10: 70 61 73 73 65 64 20 74 6f 20 74 68 65 20 4d 41  passed to the MA
5a20: 54 43 48 20 6f 70 65 72 61 74 6f 72 20 61 72 65  TCH operator are
5a30: 20 75 73 65 64 20 61 73 20 20 74 68 65 20 73 70   used as  the sp
5a40: 65 63 69 61 6c 20 71 75 65 72 79 0a 2a 2a 20 70  ecial query.** p
5a50: 61 72 61 6d 65 74 65 72 73 2e 0a 2a 2f 0a 73 74  arameters..*/.st
5a60: 61 74 69 63 20 69 6e 74 20 66 74 73 35 53 70 65  atic int fts5Spe
5a70: 63 69 61 6c 4d 61 74 63 68 28 0a 20 20 46 74 73  cialMatch(.  Fts
5a80: 35 54 61 62 6c 65 20 2a 70 54 61 62 2c 20 0a 20  5Table *pTab, . 
5a90: 20 46 74 73 35 43 75 72 73 6f 72 20 2a 70 43 73   Fts5Cursor *pCs
5aa0: 72 2c 20 0a 20 20 63 6f 6e 73 74 20 63 68 61 72  r, .  const char
5ab0: 20 2a 7a 51 75 65 72 79 0a 29 7b 0a 20 20 69 6e   *zQuery.){.  in
5ac0: 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b  t rc = SQLITE_OK
5ad0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ;             /*
5ae0: 20 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a   Return code */.
5af0: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 20    const char *z 
5b00: 3d 20 7a 51 75 65 72 79 3b 20 20 20 20 20 20 20  = zQuery;       
5b10: 20 20 2f 2a 20 53 70 65 63 69 61 6c 20 71 75 65    /* Special que
5b20: 72 79 20 74 65 78 74 20 2a 2f 0a 20 20 69 6e 74  ry text */.  int
5b30: 20 6e 3b 20 20 20 20 20 20 20 20 20 20 20 20 20   n;             
5b40: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
5b50: 4e 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20  Number of bytes 
5b60: 69 6e 20 74 65 78 74 20 61 74 20 7a 20 2a 2f 0a  in text at z */.
5b70: 0a 20 20 77 68 69 6c 65 28 20 7a 5b 30 5d 3d 3d  .  while( z[0]==
5b80: 27 20 27 20 29 20 7a 2b 2b 3b 0a 20 20 66 6f 72  ' ' ) z++;.  for
5b90: 28 6e 3d 30 3b 20 7a 5b 6e 5d 20 26 26 20 7a 5b  (n=0; z[n] && z[
5ba0: 6e 5d 21 3d 27 20 27 3b 20 6e 2b 2b 29 3b 0a 0a  n]!=' '; n++);..
5bb0: 20 20 61 73 73 65 72 74 28 20 70 54 61 62 2d 3e    assert( pTab->
5bc0: 62 61 73 65 2e 7a 45 72 72 4d 73 67 3d 3d 30 20  base.zErrMsg==0 
5bd0: 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 43 73  );.  assert( pCs
5be0: 72 2d 3e 7a 53 70 65 63 69 61 6c 3d 3d 30 20 29  r->zSpecial==0 )
5bf0: 3b 0a 0a 20 20 69 66 28 20 30 3d 3d 73 71 6c 69  ;..  if( 0==sqli
5c00: 74 65 33 5f 73 74 72 6e 69 63 6d 70 28 22 72 65  te3_strnicmp("re
5c10: 61 64 73 22 2c 20 7a 2c 20 6e 29 20 29 7b 0a 20  ads", z, n) ){. 
5c20: 20 20 20 70 43 73 72 2d 3e 7a 53 70 65 63 69 61     pCsr->zSpecia
5c30: 6c 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69  l = sqlite3_mpri
5c40: 6e 74 66 28 22 25 64 22 2c 20 73 71 6c 69 74 65  ntf("%d", sqlite
5c50: 33 46 74 73 35 49 6e 64 65 78 52 65 61 64 73 28  3Fts5IndexReads(
5c60: 70 54 61 62 2d 3e 70 49 6e 64 65 78 29 29 3b 0a  pTab->pIndex));.
5c70: 20 20 20 20 70 43 73 72 2d 3e 69 64 78 4e 75 6d      pCsr->idxNum
5c80: 20 3d 20 46 54 53 35 5f 50 4c 41 4e 5f 53 50 45   = FTS5_PLAN_SPE
5c90: 43 49 41 4c 3b 0a 20 20 20 20 69 66 28 20 70 43  CIAL;.    if( pC
5ca0: 73 72 2d 3e 7a 53 70 65 63 69 61 6c 3d 3d 30 20  sr->zSpecial==0 
5cb0: 29 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f  ) rc = SQLITE_NO
5cc0: 4d 45 4d 3b 0a 20 20 7d 0a 20 20 65 6c 73 65 7b  MEM;.  }.  else{
5cd0: 0a 20 20 20 20 2f 2a 20 41 6e 20 75 6e 72 65 63  .    /* An unrec
5ce0: 6f 67 6e 69 7a 65 64 20 64 69 72 65 63 74 69 76  ognized directiv
5cf0: 65 2e 20 52 65 74 75 72 6e 20 61 6e 20 65 72 72  e. Return an err
5d00: 6f 72 20 6d 65 73 73 61 67 65 2e 20 2a 2f 0a 20  or message. */. 
5d10: 20 20 20 70 54 61 62 2d 3e 62 61 73 65 2e 7a 45     pTab->base.zE
5d20: 72 72 4d 73 67 20 3d 20 73 71 6c 69 74 65 33 5f  rrMsg = sqlite3_
5d30: 6d 70 72 69 6e 74 66 28 22 75 6e 6b 6e 6f 77 6e  mprintf("unknown
5d40: 20 73 70 65 63 69 61 6c 20 71 75 65 72 79 3a 20   special query: 
5d50: 25 2e 2a 73 22 2c 20 6e 2c 20 7a 29 3b 0a 20 20  %.*s", n, z);.  
5d60: 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 45 52    rc = SQLITE_ER
5d70: 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75  ROR;.  }..  retu
5d80: 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  rn rc;.}../*.** 
5d90: 53 65 61 72 63 68 20 66 6f 72 20 61 6e 20 61 75  Search for an au
5da0: 78 69 6c 69 61 72 79 20 66 75 6e 63 74 69 6f 6e  xiliary function
5db0: 20 6e 61 6d 65 64 20 7a 4e 61 6d 65 20 74 68 61   named zName tha
5dc0: 74 20 63 61 6e 20 62 65 20 75 73 65 64 20 77 69  t can be used wi
5dd0: 74 68 20 74 61 62 6c 65 0a 2a 2a 20 70 54 61 62  th table.** pTab
5de0: 2e 20 49 66 20 6f 6e 65 20 69 73 20 66 6f 75 6e  . If one is foun
5df0: 64 2c 20 72 65 74 75 72 6e 20 61 20 70 6f 69 6e  d, return a poin
5e00: 74 65 72 20 74 6f 20 74 68 65 20 63 6f 72 72 65  ter to the corre
5e10: 73 70 6f 6e 64 69 6e 67 20 46 74 73 35 41 75 78  sponding Fts5Aux
5e20: 69 6c 69 61 72 79 0a 2a 2a 20 73 74 72 75 63 74  iliary.** struct
5e30: 75 72 65 2e 20 4f 74 68 65 72 77 69 73 65 2c 20  ure. Otherwise, 
5e40: 69 66 20 6e 6f 20 73 75 63 68 20 66 75 6e 63 74  if no such funct
5e50: 69 6f 6e 20 65 78 69 73 74 73 2c 20 72 65 74 75  ion exists, retu
5e60: 72 6e 20 4e 55 4c 4c 2e 0a 2a 2f 0a 73 74 61 74  rn NULL..*/.stat
5e70: 69 63 20 46 74 73 35 41 75 78 69 6c 69 61 72 79  ic Fts5Auxiliary
5e80: 20 2a 66 74 73 35 46 69 6e 64 41 75 78 69 6c 69   *fts5FindAuxili
5e90: 61 72 79 28 46 74 73 35 54 61 62 6c 65 20 2a 70  ary(Fts5Table *p
5ea0: 54 61 62 2c 20 63 6f 6e 73 74 20 63 68 61 72 20  Tab, const char 
5eb0: 2a 7a 4e 61 6d 65 29 7b 0a 20 20 46 74 73 35 41  *zName){.  Fts5A
5ec0: 75 78 69 6c 69 61 72 79 20 2a 70 41 75 78 3b 0a  uxiliary *pAux;.
5ed0: 0a 20 20 66 6f 72 28 70 41 75 78 3d 70 54 61 62  .  for(pAux=pTab
5ee0: 2d 3e 70 47 6c 6f 62 61 6c 2d 3e 70 41 75 78 3b  ->pGlobal->pAux;
5ef0: 20 70 41 75 78 3b 20 70 41 75 78 3d 70 41 75 78   pAux; pAux=pAux
5f00: 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20 69 66  ->pNext){.    if
5f10: 28 20 73 71 6c 69 74 65 33 5f 73 74 72 69 63 6d  ( sqlite3_stricm
5f20: 70 28 7a 4e 61 6d 65 2c 20 70 41 75 78 2d 3e 7a  p(zName, pAux->z
5f30: 46 75 6e 63 29 3d 3d 30 20 29 20 72 65 74 75 72  Func)==0 ) retur
5f40: 6e 20 70 41 75 78 3b 0a 20 20 7d 0a 0a 20 20 2f  n pAux;.  }..  /
5f50: 2a 20 4e 6f 20 66 75 6e 63 74 69 6f 6e 20 6f 66  * No function of
5f60: 20 74 68 65 20 73 70 65 63 69 66 69 65 64 20 6e   the specified n
5f70: 61 6d 65 20 77 61 73 20 66 6f 75 6e 64 2e 20 52  ame was found. R
5f80: 65 74 75 72 6e 20 30 2e 20 2a 2f 0a 20 20 72 65  eturn 0. */.  re
5f90: 74 75 72 6e 20 30 3b 0a 7d 0a 0a 0a 73 74 61 74  turn 0;.}...stat
5fa0: 69 63 20 69 6e 74 20 66 74 73 35 46 69 6e 64 52  ic int fts5FindR
5fb0: 61 6e 6b 46 75 6e 63 74 69 6f 6e 28 46 74 73 35  ankFunction(Fts5
5fc0: 43 75 72 73 6f 72 20 2a 70 43 73 72 29 7b 0a 20  Cursor *pCsr){. 
5fd0: 20 46 74 73 35 54 61 62 6c 65 20 2a 70 54 61 62   Fts5Table *pTab
5fe0: 20 3d 20 28 46 74 73 35 54 61 62 6c 65 2a 29 28   = (Fts5Table*)(
5ff0: 70 43 73 72 2d 3e 62 61 73 65 2e 70 56 74 61 62  pCsr->base.pVtab
6000: 29 3b 0a 20 20 46 74 73 35 43 6f 6e 66 69 67 20  );.  Fts5Config 
6010: 2a 70 43 6f 6e 66 69 67 20 3d 20 70 54 61 62 2d  *pConfig = pTab-
6020: 3e 70 43 6f 6e 66 69 67 3b 0a 20 20 69 6e 74 20  >pConfig;.  int 
6030: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  rc = SQLITE_OK;.
6040: 20 20 46 74 73 35 41 75 78 69 6c 69 61 72 79 20    Fts5Auxiliary 
6050: 2a 70 41 75 78 3b 0a 20 20 63 6f 6e 73 74 20 63  *pAux;.  const c
6060: 68 61 72 20 2a 7a 52 61 6e 6b 20 3d 20 70 43 73  har *zRank = pCs
6070: 72 2d 3e 7a 52 61 6e 6b 3b 0a 20 20 63 6f 6e 73  r->zRank;.  cons
6080: 74 20 63 68 61 72 20 2a 7a 52 61 6e 6b 41 72 67  t char *zRankArg
6090: 73 20 3d 20 70 43 73 72 2d 3e 7a 52 61 6e 6b 41  s = pCsr->zRankA
60a0: 72 67 73 3b 0a 0a 20 20 69 66 28 20 7a 52 61 6e  rgs;..  if( zRan
60b0: 6b 41 72 67 73 20 29 7b 0a 20 20 20 20 63 68 61  kArgs ){.    cha
60c0: 72 20 2a 7a 53 71 6c 20 3d 20 73 71 6c 69 74 65  r *zSql = sqlite
60d0: 33 5f 6d 70 72 69 6e 74 66 28 22 53 45 4c 45 43  3_mprintf("SELEC
60e0: 54 20 25 73 22 2c 20 7a 52 61 6e 6b 41 72 67 73  T %s", zRankArgs
60f0: 29 3b 0a 20 20 20 20 69 66 28 20 7a 53 71 6c 3d  );.    if( zSql=
6100: 3d 30 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d  =0 ){.      rc =
6110: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
6120: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
6130: 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 53  sqlite3_stmt *pS
6140: 74 6d 74 20 3d 20 30 3b 0a 20 20 20 20 20 20 72  tmt = 0;.      r
6150: 63 20 3d 20 73 71 6c 69 74 65 33 5f 70 72 65 70  c = sqlite3_prep
6160: 61 72 65 5f 76 32 28 70 43 6f 6e 66 69 67 2d 3e  are_v2(pConfig->
6170: 64 62 2c 20 7a 53 71 6c 2c 20 2d 31 2c 20 26 70  db, zSql, -1, &p
6180: 53 74 6d 74 2c 20 30 29 3b 0a 20 20 20 20 20 20  Stmt, 0);.      
6190: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a 53 71  sqlite3_free(zSq
61a0: 6c 29 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74  l);.      assert
61b0: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
61c0: 7c 7c 20 70 43 73 72 2d 3e 70 52 61 6e 6b 41 72  || pCsr->pRankAr
61d0: 67 53 74 6d 74 3d 3d 30 20 29 3b 0a 20 20 20 20  gStmt==0 );.    
61e0: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
61f0: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 69  _OK ){.        i
6200: 66 28 20 53 51 4c 49 54 45 5f 52 4f 57 3d 3d 73  f( SQLITE_ROW==s
6210: 71 6c 69 74 65 33 5f 73 74 65 70 28 70 53 74 6d  qlite3_step(pStm
6220: 74 29 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  t) ){.          
6230: 69 6e 74 20 6e 42 79 74 65 3b 0a 20 20 20 20 20  int nByte;.     
6240: 20 20 20 20 20 70 43 73 72 2d 3e 6e 52 61 6e 6b       pCsr->nRank
6250: 41 72 67 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f  Arg = sqlite3_co
6260: 6c 75 6d 6e 5f 63 6f 75 6e 74 28 70 53 74 6d 74  lumn_count(pStmt
6270: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 6e 42 79  );.          nBy
6280: 74 65 20 3d 20 73 69 7a 65 6f 66 28 73 71 6c 69  te = sizeof(sqli
6290: 74 65 33 5f 76 61 6c 75 65 2a 29 2a 70 43 73 72  te3_value*)*pCsr
62a0: 2d 3e 6e 52 61 6e 6b 41 72 67 3b 0a 20 20 20 20  ->nRankArg;.    
62b0: 20 20 20 20 20 20 70 43 73 72 2d 3e 61 70 52 61        pCsr->apRa
62c0: 6e 6b 41 72 67 20 3d 20 28 73 71 6c 69 74 65 33  nkArg = (sqlite3
62d0: 5f 76 61 6c 75 65 2a 2a 29 73 71 6c 69 74 65 33  _value**)sqlite3
62e0: 46 74 73 35 4d 61 6c 6c 6f 63 5a 65 72 6f 28 26  Fts5MallocZero(&
62f0: 72 63 2c 20 6e 42 79 74 65 29 3b 0a 20 20 20 20  rc, nByte);.    
6300: 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51        if( rc==SQ
6310: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
6320: 20 20 20 20 20 20 20 69 6e 74 20 69 3b 0a 20 20         int i;.  
6330: 20 20 20 20 20 20 20 20 20 20 66 6f 72 28 69 3d            for(i=
6340: 30 3b 20 69 3c 70 43 73 72 2d 3e 6e 52 61 6e 6b  0; i<pCsr->nRank
6350: 41 72 67 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20  Arg; i++){.     
6360: 20 20 20 20 20 20 20 20 20 70 43 73 72 2d 3e 61           pCsr->a
6370: 70 52 61 6e 6b 41 72 67 5b 69 5d 20 3d 20 73 71  pRankArg[i] = sq
6380: 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 76 61 6c  lite3_column_val
6390: 75 65 28 70 53 74 6d 74 2c 20 69 29 3b 0a 20 20  ue(pStmt, i);.  
63a0: 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20            }.    
63b0: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20        }.        
63c0: 20 20 70 43 73 72 2d 3e 70 52 61 6e 6b 41 72 67    pCsr->pRankArg
63d0: 53 74 6d 74 20 3d 20 70 53 74 6d 74 3b 0a 20 20  Stmt = pStmt;.  
63e0: 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20        }else{.   
63f0: 20 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69         rc = sqli
6400: 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70 53 74  te3_finalize(pSt
6410: 6d 74 29 3b 0a 20 20 20 20 20 20 20 20 20 20 61  mt);.          a
6420: 73 73 65 72 74 28 20 72 63 21 3d 53 51 4c 49 54  ssert( rc!=SQLIT
6430: 45 5f 4f 4b 20 29 3b 0a 20 20 20 20 20 20 20 20  E_OK );.        
6440: 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  }.      }.    }.
6450: 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53    }..  if( rc==S
6460: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
6470: 70 41 75 78 20 3d 20 66 74 73 35 46 69 6e 64 41  pAux = fts5FindA
6480: 75 78 69 6c 69 61 72 79 28 70 54 61 62 2c 20 7a  uxiliary(pTab, z
6490: 52 61 6e 6b 29 3b 0a 20 20 20 20 69 66 28 20 70  Rank);.    if( p
64a0: 41 75 78 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  Aux==0 ){.      
64b0: 61 73 73 65 72 74 28 20 70 54 61 62 2d 3e 62 61  assert( pTab->ba
64c0: 73 65 2e 7a 45 72 72 4d 73 67 3d 3d 30 20 29 3b  se.zErrMsg==0 );
64d0: 0a 20 20 20 20 20 20 70 54 61 62 2d 3e 62 61 73  .      pTab->bas
64e0: 65 2e 7a 45 72 72 4d 73 67 20 3d 20 73 71 6c 69  e.zErrMsg = sqli
64f0: 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 6e 6f 20  te3_mprintf("no 
6500: 73 75 63 68 20 66 75 6e 63 74 69 6f 6e 3a 20 25  such function: %
6510: 73 22 2c 20 7a 52 61 6e 6b 29 3b 0a 20 20 20 20  s", zRank);.    
6520: 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 45 52    rc = SQLITE_ER
6530: 52 4f 52 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  ROR;.    }.  }..
6540: 20 20 70 43 73 72 2d 3e 70 52 61 6e 6b 20 3d 20    pCsr->pRank = 
6550: 70 41 75 78 3b 0a 20 20 72 65 74 75 72 6e 20 72  pAux;.  return r
6560: 63 3b 0a 7d 0a 0a 0a 73 74 61 74 69 63 20 69 6e  c;.}...static in
6570: 74 20 66 74 73 35 43 75 72 73 6f 72 50 61 72 73  t fts5CursorPars
6580: 65 52 61 6e 6b 28 0a 20 20 46 74 73 35 43 6f 6e  eRank(.  Fts5Con
6590: 66 69 67 20 2a 70 43 6f 6e 66 69 67 2c 0a 20 20  fig *pConfig,.  
65a0: 46 74 73 35 43 75 72 73 6f 72 20 2a 70 43 73 72  Fts5Cursor *pCsr
65b0: 2c 20 0a 20 20 73 71 6c 69 74 65 33 5f 76 61 6c  , .  sqlite3_val
65c0: 75 65 20 2a 70 52 61 6e 6b 0a 29 7b 0a 20 20 69  ue *pRank.){.  i
65d0: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
65e0: 4b 3b 0a 20 20 69 66 28 20 70 52 61 6e 6b 20 29  K;.  if( pRank )
65f0: 7b 0a 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72  {.    const char
6600: 20 2a 7a 20 3d 20 28 63 6f 6e 73 74 20 63 68 61   *z = (const cha
6610: 72 2a 29 73 71 6c 69 74 65 33 5f 76 61 6c 75 65  r*)sqlite3_value
6620: 5f 74 65 78 74 28 70 52 61 6e 6b 29 3b 0a 20 20  _text(pRank);.  
6630: 20 20 63 68 61 72 20 2a 7a 52 61 6e 6b 20 3d 20    char *zRank = 
6640: 30 3b 0a 20 20 20 20 63 68 61 72 20 2a 7a 52 61  0;.    char *zRa
6650: 6e 6b 41 72 67 73 20 3d 20 30 3b 0a 0a 20 20 20  nkArgs = 0;..   
6660: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 46 74 73   rc = sqlite3Fts
6670: 35 43 6f 6e 66 69 67 50 61 72 73 65 52 61 6e 6b  5ConfigParseRank
6680: 28 7a 2c 20 26 7a 52 61 6e 6b 2c 20 26 7a 52 61  (z, &zRank, &zRa
6690: 6e 6b 41 72 67 73 29 3b 0a 20 20 20 20 69 66 28  nkArgs);.    if(
66a0: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
66b0: 7b 0a 20 20 20 20 20 20 70 43 73 72 2d 3e 7a 52  {.      pCsr->zR
66c0: 61 6e 6b 20 3d 20 7a 52 61 6e 6b 3b 0a 20 20 20  ank = zRank;.   
66d0: 20 20 20 70 43 73 72 2d 3e 7a 52 61 6e 6b 41 72     pCsr->zRankAr
66e0: 67 73 20 3d 20 7a 52 61 6e 6b 41 72 67 73 3b 0a  gs = zRankArgs;.
66f0: 20 20 20 20 20 20 43 73 72 46 6c 61 67 53 65 74        CsrFlagSet
6700: 28 70 43 73 72 2c 20 46 54 53 35 43 53 52 5f 46  (pCsr, FTS5CSR_F
6710: 52 45 45 5f 5a 52 41 4e 4b 29 3b 0a 20 20 20 20  REE_ZRANK);.    
6720: 7d 65 6c 73 65 20 69 66 28 20 72 63 3d 3d 53 51  }else if( rc==SQ
6730: 4c 49 54 45 5f 45 52 52 4f 52 20 29 7b 0a 20 20  LITE_ERROR ){.  
6740: 20 20 20 20 70 43 73 72 2d 3e 62 61 73 65 2e 70      pCsr->base.p
6750: 56 74 61 62 2d 3e 7a 45 72 72 4d 73 67 20 3d 20  Vtab->zErrMsg = 
6760: 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28  sqlite3_mprintf(
6770: 0a 20 20 20 20 20 20 20 20 20 20 22 70 61 72 73  .          "pars
6780: 65 20 65 72 72 6f 72 20 69 6e 20 72 61 6e 6b 20  e error in rank 
6790: 66 75 6e 63 74 69 6f 6e 3a 20 25 73 22 2c 20 7a  function: %s", z
67a0: 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20 7d 0a  .      );.    }.
67b0: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69 66 28    }else{.    if(
67c0: 20 70 43 6f 6e 66 69 67 2d 3e 7a 52 61 6e 6b 20   pConfig->zRank 
67d0: 29 7b 0a 20 20 20 20 20 20 70 43 73 72 2d 3e 7a  ){.      pCsr->z
67e0: 52 61 6e 6b 20 3d 20 28 63 68 61 72 2a 29 70 43  Rank = (char*)pC
67f0: 6f 6e 66 69 67 2d 3e 7a 52 61 6e 6b 3b 0a 20 20  onfig->zRank;.  
6800: 20 20 20 20 70 43 73 72 2d 3e 7a 52 61 6e 6b 41      pCsr->zRankA
6810: 72 67 73 20 3d 20 28 63 68 61 72 2a 29 70 43 6f  rgs = (char*)pCo
6820: 6e 66 69 67 2d 3e 7a 52 61 6e 6b 41 72 67 73 3b  nfig->zRankArgs;
6830: 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
6840: 20 20 70 43 73 72 2d 3e 7a 52 61 6e 6b 20 3d 20    pCsr->zRank = 
6850: 28 63 68 61 72 2a 29 46 54 53 35 5f 44 45 46 41  (char*)FTS5_DEFA
6860: 55 4c 54 5f 52 41 4e 4b 3b 0a 20 20 20 20 20 20  ULT_RANK;.      
6870: 70 43 73 72 2d 3e 7a 52 61 6e 6b 41 72 67 73 20  pCsr->zRankArgs 
6880: 3d 20 30 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20  = 0;.    }.  }. 
6890: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
68a0: 2a 0a 2a 2a 20 54 68 69 73 20 69 73 20 74 68 65  *.** This is the
68b0: 20 78 46 69 6c 74 65 72 20 69 6e 74 65 72 66 61   xFilter interfa
68c0: 63 65 20 66 6f 72 20 74 68 65 20 76 69 72 74 75  ce for the virtu
68d0: 61 6c 20 74 61 62 6c 65 2e 20 20 53 65 65 0a 2a  al table.  See.*
68e0: 2a 20 74 68 65 20 76 69 72 74 75 61 6c 20 74 61  * the virtual ta
68f0: 62 6c 65 20 78 46 69 6c 74 65 72 20 6d 65 74 68  ble xFilter meth
6900: 6f 64 20 64 6f 63 75 6d 65 6e 74 61 74 69 6f 6e  od documentation
6910: 20 66 6f 72 20 61 64 64 69 74 69 6f 6e 61 6c 0a   for additional.
6920: 2a 2a 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 2e 0a  ** information..
6930: 2a 2a 20 0a 2a 2a 20 54 68 65 72 65 20 61 72 65  ** .** There are
6940: 20 74 68 72 65 65 20 70 6f 73 73 69 62 6c 65 20   three possible 
6950: 71 75 65 72 79 20 73 74 72 61 74 65 67 69 65 73  query strategies
6960: 3a 0a 2a 2a 0a 2a 2a 20 20 20 31 2e 20 46 75 6c  :.**.**   1. Ful
6970: 6c 2d 74 65 78 74 20 73 65 61 72 63 68 20 75 73  l-text search us
6980: 69 6e 67 20 61 20 4d 41 54 43 48 20 6f 70 65 72  ing a MATCH oper
6990: 61 74 6f 72 2e 0a 2a 2a 20 20 20 32 2e 20 41 20  ator..**   2. A 
69a0: 62 79 2d 72 6f 77 69 64 20 6c 6f 6f 6b 75 70 2e  by-rowid lookup.
69b0: 0a 2a 2a 20 20 20 33 2e 20 41 20 66 75 6c 6c 2d  .**   3. A full-
69c0: 74 61 62 6c 65 20 73 63 61 6e 2e 0a 2a 2f 0a 73  table scan..*/.s
69d0: 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 46 69  tatic int fts5Fi
69e0: 6c 74 65 72 4d 65 74 68 6f 64 28 0a 20 20 73 71  lterMethod(.  sq
69f0: 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f  lite3_vtab_curso
6a00: 72 20 2a 70 43 75 72 73 6f 72 2c 20 20 20 2f 2a  r *pCursor,   /*
6a10: 20 54 68 65 20 63 75 72 73 6f 72 20 75 73 65 64   The cursor used
6a20: 20 66 6f 72 20 74 68 69 73 20 71 75 65 72 79 20   for this query 
6a30: 2a 2f 0a 20 20 69 6e 74 20 69 64 78 4e 75 6d 2c  */.  int idxNum,
6a40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6a50: 20 20 20 20 20 2f 2a 20 53 74 72 61 74 65 67 79       /* Strategy
6a60: 20 69 6e 64 65 78 20 2a 2f 0a 20 20 63 6f 6e 73   index */.  cons
6a70: 74 20 63 68 61 72 20 2a 69 64 78 53 74 72 2c 20  t char *idxStr, 
6a80: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 55              /* U
6a90: 6e 75 73 65 64 20 2a 2f 0a 20 20 69 6e 74 20 6e  nused */.  int n
6aa0: 56 61 6c 2c 20 20 20 20 20 20 20 20 20 20 20 20  Val,            
6ab0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75             /* Nu
6ac0: 6d 62 65 72 20 6f 66 20 65 6c 65 6d 65 6e 74 73  mber of elements
6ad0: 20 69 6e 20 61 70 56 61 6c 20 2a 2f 0a 20 20 73   in apVal */.  s
6ae0: 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a 61  qlite3_value **a
6af0: 70 56 61 6c 20 20 20 20 20 20 20 20 20 20 20 2f  pVal           /
6b00: 2a 20 41 72 67 75 6d 65 6e 74 73 20 66 6f 72 20  * Arguments for 
6b10: 74 68 65 20 69 6e 64 65 78 69 6e 67 20 73 63 68  the indexing sch
6b20: 65 6d 65 20 2a 2f 0a 29 7b 0a 20 20 46 74 73 35  eme */.){.  Fts5
6b30: 54 61 62 6c 65 20 2a 70 54 61 62 20 3d 20 28 46  Table *pTab = (F
6b40: 74 73 35 54 61 62 6c 65 2a 29 28 70 43 75 72 73  ts5Table*)(pCurs
6b50: 6f 72 2d 3e 70 56 74 61 62 29 3b 0a 20 20 46 74  or->pVtab);.  Ft
6b60: 73 35 43 75 72 73 6f 72 20 2a 70 43 73 72 20 3d  s5Cursor *pCsr =
6b70: 20 28 46 74 73 35 43 75 72 73 6f 72 2a 29 70 43   (Fts5Cursor*)pC
6b80: 75 72 73 6f 72 3b 0a 20 20 69 6e 74 20 62 41 73  ursor;.  int bAs
6b90: 63 20 3d 20 28 28 69 64 78 4e 75 6d 20 26 20 46  c = ((idxNum & F
6ba0: 54 53 35 5f 4f 52 44 45 52 5f 41 53 43 29 20 3f  TS5_ORDER_ASC) ?
6bb0: 20 31 20 3a 20 30 29 3b 0a 20 20 69 6e 74 20 72   1 : 0);.  int r
6bc0: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 0a  c = SQLITE_OK;..
6bd0: 20 20 61 73 73 65 72 74 28 20 6e 56 61 6c 3c 3d    assert( nVal<=
6be0: 32 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70  2 );.  assert( p
6bf0: 43 73 72 2d 3e 70 53 74 6d 74 3d 3d 30 20 29 3b  Csr->pStmt==0 );
6c00: 0a 20 20 61 73 73 65 72 74 28 20 70 43 73 72 2d  .  assert( pCsr-
6c10: 3e 70 45 78 70 72 3d 3d 30 20 29 3b 0a 20 20 61  >pExpr==0 );.  a
6c20: 73 73 65 72 74 28 20 70 43 73 72 2d 3e 63 73 72  ssert( pCsr->csr
6c30: 66 6c 61 67 73 3d 3d 30 20 29 3b 0a 20 20 61 73  flags==0 );.  as
6c40: 73 65 72 74 28 20 70 43 73 72 2d 3e 70 52 61 6e  sert( pCsr->pRan
6c50: 6b 3d 3d 30 20 29 3b 0a 20 20 61 73 73 65 72 74  k==0 );.  assert
6c60: 28 20 70 43 73 72 2d 3e 7a 52 61 6e 6b 3d 3d 30  ( pCsr->zRank==0
6c70: 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 43   );.  assert( pC
6c80: 73 72 2d 3e 7a 52 61 6e 6b 41 72 67 73 3d 3d 30  sr->zRankArgs==0
6c90: 20 29 3b 0a 0a 20 20 69 66 28 20 70 54 61 62 2d   );..  if( pTab-
6ca0: 3e 70 53 6f 72 74 43 73 72 20 29 7b 0a 20 20 20  >pSortCsr ){.   
6cb0: 20 2f 2a 20 49 66 20 70 53 6f 72 74 43 73 72 20   /* If pSortCsr 
6cc0: 69 73 20 6e 6f 6e 2d 4e 55 4c 4c 2c 20 74 68 65  is non-NULL, the
6cd0: 6e 20 74 68 69 73 20 63 61 6c 6c 20 69 73 20 62  n this call is b
6ce0: 65 69 6e 67 20 6d 61 64 65 20 61 73 20 70 61 72  eing made as par
6cf0: 74 20 6f 66 20 0a 20 20 20 20 2a 2a 20 70 72 6f  t of .    ** pro
6d00: 63 65 73 73 69 6e 67 20 66 6f 72 20 61 20 22 2e  cessing for a ".
6d10: 2e 2e 20 4d 41 54 43 48 20 3c 65 78 70 72 3e 20  .. MATCH <expr> 
6d20: 4f 52 44 45 52 20 42 59 20 72 61 6e 6b 22 20 71  ORDER BY rank" q
6d30: 75 65 72 79 20 28 65 50 6c 61 6e 20 69 73 0a 20  uery (ePlan is. 
6d40: 20 20 20 2a 2a 20 73 65 74 20 74 6f 20 46 54 53     ** set to FTS
6d50: 35 5f 50 4c 41 4e 5f 53 4f 52 54 45 44 5f 4d 41  5_PLAN_SORTED_MA
6d60: 54 43 48 29 2e 20 70 53 6f 72 74 43 73 72 20 69  TCH). pSortCsr i
6d70: 73 20 74 68 65 20 63 75 72 73 6f 72 20 74 68 61  s the cursor tha
6d80: 74 20 77 69 6c 6c 0a 20 20 20 20 2a 2a 20 72 65  t will.    ** re
6d90: 74 75 72 6e 20 72 65 73 75 6c 74 73 20 74 6f 20  turn results to 
6da0: 74 68 65 20 75 73 65 72 20 66 6f 72 20 74 68 69  the user for thi
6db0: 73 20 71 75 65 72 79 2e 20 54 68 65 20 63 75 72  s query. The cur
6dc0: 72 65 6e 74 20 63 75 72 73 6f 72 20 0a 20 20 20  rent cursor .   
6dd0: 20 2a 2a 20 28 70 43 75 72 73 6f 72 29 20 69 73   ** (pCursor) is
6de0: 20 75 73 65 64 20 74 6f 20 65 78 65 63 75 74 65   used to execute
6df0: 20 74 68 65 20 71 75 65 72 79 20 69 73 73 75 65   the query issue
6e00: 64 20 62 79 20 66 75 6e 63 74 69 6f 6e 20 0a 20  d by function . 
6e10: 20 20 20 2a 2a 20 66 74 73 35 43 75 72 73 6f 72     ** fts5Cursor
6e20: 46 69 72 73 74 53 6f 72 74 65 64 28 29 20 61 62  FirstSorted() ab
6e30: 6f 76 65 2e 20 20 2a 2f 0a 20 20 20 20 61 73 73  ove.  */.    ass
6e40: 65 72 74 28 20 46 54 53 35 5f 50 4c 41 4e 28 69  ert( FTS5_PLAN(i
6e50: 64 78 4e 75 6d 29 3d 3d 46 54 53 35 5f 50 4c 41  dxNum)==FTS5_PLA
6e60: 4e 5f 53 43 41 4e 20 29 3b 0a 20 20 20 20 70 43  N_SCAN );.    pC
6e70: 73 72 2d 3e 69 64 78 4e 75 6d 20 3d 20 46 54 53  sr->idxNum = FTS
6e80: 35 5f 50 4c 41 4e 5f 53 4f 55 52 43 45 3b 0a 20  5_PLAN_SOURCE;. 
6e90: 20 20 20 70 43 73 72 2d 3e 70 45 78 70 72 20 3d     pCsr->pExpr =
6ea0: 20 70 54 61 62 2d 3e 70 53 6f 72 74 43 73 72 2d   pTab->pSortCsr-
6eb0: 3e 70 45 78 70 72 3b 0a 20 20 20 20 72 63 20 3d  >pExpr;.    rc =
6ec0: 20 66 74 73 35 43 75 72 73 6f 72 46 69 72 73 74   fts5CursorFirst
6ed0: 28 70 54 61 62 2c 20 70 43 73 72 2c 20 62 41 73  (pTab, pCsr, bAs
6ee0: 63 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  c);.  }else{.   
6ef0: 20 69 6e 74 20 65 50 6c 61 6e 20 3d 20 46 54 53   int ePlan = FTS
6f00: 35 5f 50 4c 41 4e 28 69 64 78 4e 75 6d 29 3b 0a  5_PLAN(idxNum);.
6f10: 20 20 20 20 70 43 73 72 2d 3e 69 64 78 4e 75 6d      pCsr->idxNum
6f20: 20 3d 20 69 64 78 4e 75 6d 3b 0a 20 20 20 20 69   = idxNum;.    i
6f30: 66 28 20 65 50 6c 61 6e 3d 3d 46 54 53 35 5f 50  f( ePlan==FTS5_P
6f40: 4c 41 4e 5f 4d 41 54 43 48 20 7c 7c 20 65 50 6c  LAN_MATCH || ePl
6f50: 61 6e 3d 3d 46 54 53 35 5f 50 4c 41 4e 5f 53 4f  an==FTS5_PLAN_SO
6f60: 52 54 45 44 5f 4d 41 54 43 48 20 29 7b 0a 20 20  RTED_MATCH ){.  
6f70: 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a      const char *
6f80: 7a 45 78 70 72 20 3d 20 28 63 6f 6e 73 74 20 63  zExpr = (const c
6f90: 68 61 72 2a 29 73 71 6c 69 74 65 33 5f 76 61 6c  har*)sqlite3_val
6fa0: 75 65 5f 74 65 78 74 28 61 70 56 61 6c 5b 30 5d  ue_text(apVal[0]
6fb0: 29 3b 0a 0a 20 20 20 20 20 20 72 63 20 3d 20 66  );..      rc = f
6fc0: 74 73 35 43 75 72 73 6f 72 50 61 72 73 65 52 61  ts5CursorParseRa
6fd0: 6e 6b 28 70 54 61 62 2d 3e 70 43 6f 6e 66 69 67  nk(pTab->pConfig
6fe0: 2c 20 70 43 73 72 2c 20 28 6e 56 61 6c 3d 3d 32  , pCsr, (nVal==2
6ff0: 20 3f 20 61 70 56 61 6c 5b 31 5d 20 3a 20 30 29   ? apVal[1] : 0)
7000: 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d  );.      if( rc=
7010: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
7020: 20 20 20 20 20 20 69 66 28 20 7a 45 78 70 72 5b        if( zExpr[
7030: 30 5d 3d 3d 27 2a 27 20 29 7b 0a 20 20 20 20 20  0]=='*' ){.     
7040: 20 20 20 20 20 2f 2a 20 54 68 65 20 75 73 65 72       /* The user
7050: 20 68 61 73 20 69 73 73 75 65 64 20 61 20 71 75   has issued a qu
7060: 65 72 79 20 6f 66 20 74 68 65 20 66 6f 72 6d 20  ery of the form 
7070: 22 4d 41 54 43 48 20 27 2a 2e 2e 2e 27 22 2e 20  "MATCH '*...'". 
7080: 54 68 69 73 0a 20 20 20 20 20 20 20 20 20 20 2a  This.          *
7090: 2a 20 69 6e 64 69 63 61 74 65 73 20 74 68 61 74  * indicates that
70a0: 20 74 68 65 20 4d 41 54 43 48 20 65 78 70 72 65   the MATCH expre
70b0: 73 73 69 6f 6e 20 69 73 20 6e 6f 74 20 61 20 66  ssion is not a f
70c0: 75 6c 6c 20 74 65 78 74 20 71 75 65 72 79 2c 0a  ull text query,.
70d0: 20 20 20 20 20 20 20 20 20 20 2a 2a 20 62 75 74            ** but
70e0: 20 61 20 72 65 71 75 65 73 74 20 66 6f 72 20 61   a request for a
70f0: 6e 20 69 6e 74 65 72 6e 61 6c 20 70 61 72 61 6d  n internal param
7100: 65 74 65 72 2e 20 20 2a 2f 0a 20 20 20 20 20 20  eter.  */.      
7110: 20 20 20 20 72 63 20 3d 20 66 74 73 35 53 70 65      rc = fts5Spe
7120: 63 69 61 6c 4d 61 74 63 68 28 70 54 61 62 2c 20  cialMatch(pTab, 
7130: 70 43 73 72 2c 20 26 7a 45 78 70 72 5b 31 5d 29  pCsr, &zExpr[1])
7140: 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c 73 65 7b  ;.        }else{
7150: 0a 20 20 20 20 20 20 20 20 20 20 63 68 61 72 20  .          char 
7160: 2a 2a 70 7a 45 72 72 20 3d 20 26 70 54 61 62 2d  **pzErr = &pTab-
7170: 3e 62 61 73 65 2e 7a 45 72 72 4d 73 67 3b 0a 20  >base.zErrMsg;. 
7180: 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 73 71           rc = sq
7190: 6c 69 74 65 33 46 74 73 35 45 78 70 72 4e 65 77  lite3Fts5ExprNew
71a0: 28 70 54 61 62 2d 3e 70 43 6f 6e 66 69 67 2c 20  (pTab->pConfig, 
71b0: 7a 45 78 70 72 2c 20 26 70 43 73 72 2d 3e 70 45  zExpr, &pCsr->pE
71c0: 78 70 72 2c 20 70 7a 45 72 72 29 3b 0a 20 20 20  xpr, pzErr);.   
71d0: 20 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53         if( rc==S
71e0: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
71f0: 20 20 20 20 20 20 20 20 69 66 28 20 65 50 6c 61          if( ePla
7200: 6e 3d 3d 46 54 53 35 5f 50 4c 41 4e 5f 4d 41 54  n==FTS5_PLAN_MAT
7210: 43 48 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  CH ){.          
7220: 20 20 20 20 72 63 20 3d 20 66 74 73 35 43 75 72      rc = fts5Cur
7230: 73 6f 72 46 69 72 73 74 28 70 54 61 62 2c 20 70  sorFirst(pTab, p
7240: 43 73 72 2c 20 62 41 73 63 29 3b 0a 20 20 20 20  Csr, bAsc);.    
7250: 20 20 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20          }else{. 
7260: 20 20 20 20 20 20 20 20 20 20 20 20 20 72 63 20               rc 
7270: 3d 20 66 74 73 35 43 75 72 73 6f 72 46 69 72 73  = fts5CursorFirs
7280: 74 53 6f 72 74 65 64 28 70 54 61 62 2c 20 70 43  tSorted(pTab, pC
7290: 73 72 2c 20 62 41 73 63 29 3b 0a 20 20 20 20 20  sr, bAsc);.     
72a0: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20         }.       
72b0: 20 20 20 7d 0a 20 20 20 20 20 20 20 20 7d 0a 20     }.        }. 
72c0: 20 20 20 20 20 7d 0a 20 20 20 20 7d 65 6c 73 65       }.    }else
72d0: 7b 0a 20 20 20 20 20 20 2f 2a 20 54 68 69 73 20  {.      /* This 
72e0: 69 73 20 65 69 74 68 65 72 20 61 20 66 75 6c 6c  is either a full
72f0: 2d 74 61 62 6c 65 20 73 63 61 6e 20 28 65 50 6c  -table scan (ePl
7300: 61 6e 3d 3d 46 54 53 35 5f 50 4c 41 4e 5f 53 43  an==FTS5_PLAN_SC
7310: 41 4e 29 20 6f 72 20 61 20 6c 6f 6f 6b 75 70 0a  AN) or a lookup.
7320: 20 20 20 20 20 20 2a 2a 20 62 79 20 72 6f 77 69        ** by rowi
7330: 64 20 28 65 50 6c 61 6e 3d 3d 46 54 53 35 5f 50  d (ePlan==FTS5_P
7340: 4c 41 4e 5f 52 4f 57 49 44 29 2e 20 20 2a 2f 0a  LAN_ROWID).  */.
7350: 20 20 20 20 20 20 69 6e 74 20 65 53 74 6d 74 20        int eStmt 
7360: 3d 20 66 74 73 35 53 74 6d 74 54 79 70 65 28 69  = fts5StmtType(i
7370: 64 78 4e 75 6d 29 3b 0a 20 20 20 20 20 20 72 63  dxNum);.      rc
7380: 20 3d 20 73 71 6c 69 74 65 33 46 74 73 35 53 74   = sqlite3Fts5St
7390: 6f 72 61 67 65 53 74 6d 74 28 0a 20 20 20 20 20  orageStmt(.     
73a0: 20 20 20 20 20 70 54 61 62 2d 3e 70 53 74 6f 72       pTab->pStor
73b0: 61 67 65 2c 20 65 53 74 6d 74 2c 20 26 70 43 73  age, eStmt, &pCs
73c0: 72 2d 3e 70 53 74 6d 74 2c 20 26 70 54 61 62 2d  r->pStmt, &pTab-
73d0: 3e 62 61 73 65 2e 7a 45 72 72 4d 73 67 0a 20 20  >base.zErrMsg.  
73e0: 20 20 20 20 29 3b 0a 20 20 20 20 20 20 69 66 28      );.      if(
73f0: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
7400: 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20 65 50  {.        if( eP
7410: 6c 61 6e 3d 3d 46 54 53 35 5f 50 4c 41 4e 5f 52  lan==FTS5_PLAN_R
7420: 4f 57 49 44 20 29 7b 0a 20 20 20 20 20 20 20 20  OWID ){.        
7430: 20 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f 76    sqlite3_bind_v
7440: 61 6c 75 65 28 70 43 73 72 2d 3e 70 53 74 6d 74  alue(pCsr->pStmt
7450: 2c 20 31 2c 20 61 70 56 61 6c 5b 30 5d 29 3b 0a  , 1, apVal[0]);.
7460: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
7470: 20 20 72 63 20 3d 20 66 74 73 35 4e 65 78 74 4d    rc = fts5NextM
7480: 65 74 68 6f 64 28 70 43 75 72 73 6f 72 29 3b 0a  ethod(pCursor);.
7490: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20        }.    }.  
74a0: 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  }..  return rc;.
74b0: 7d 0a 0a 2f 2a 20 0a 2a 2a 20 54 68 69 73 20 69  }../* .** This i
74c0: 73 20 74 68 65 20 78 45 6f 66 20 6d 65 74 68 6f  s the xEof metho
74d0: 64 20 6f 66 20 74 68 65 20 76 69 72 74 75 61 6c  d of the virtual
74e0: 20 74 61 62 6c 65 2e 20 53 51 4c 69 74 65 20 63   table. SQLite c
74f0: 61 6c 6c 73 20 74 68 69 73 20 0a 2a 2a 20 72 6f  alls this .** ro
7500: 75 74 69 6e 65 20 74 6f 20 66 69 6e 64 20 6f 75  utine to find ou
7510: 74 20 69 66 20 69 74 20 68 61 73 20 72 65 61 63  t if it has reac
7520: 68 65 64 20 74 68 65 20 65 6e 64 20 6f 66 20 61  hed the end of a
7530: 20 72 65 73 75 6c 74 20 73 65 74 2e 0a 2a 2f 0a   result set..*/.
7540: 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 45  static int fts5E
7550: 6f 66 4d 65 74 68 6f 64 28 73 71 6c 69 74 65 33  ofMethod(sqlite3
7560: 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 70 43  _vtab_cursor *pC
7570: 75 72 73 6f 72 29 7b 0a 20 20 46 74 73 35 43 75  ursor){.  Fts5Cu
7580: 72 73 6f 72 20 2a 70 43 73 72 20 3d 20 28 46 74  rsor *pCsr = (Ft
7590: 73 35 43 75 72 73 6f 72 2a 29 70 43 75 72 73 6f  s5Cursor*)pCurso
75a0: 72 3b 0a 20 20 72 65 74 75 72 6e 20 28 43 73 72  r;.  return (Csr
75b0: 46 6c 61 67 54 65 73 74 28 70 43 73 72 2c 20 46  FlagTest(pCsr, F
75c0: 54 53 35 43 53 52 5f 45 4f 46 29 20 3f 20 31 20  TS5CSR_EOF) ? 1 
75d0: 3a 20 30 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52  : 0);.}../*.** R
75e0: 65 74 75 72 6e 20 74 68 65 20 72 6f 77 69 64 20  eturn the rowid 
75f0: 74 68 61 74 20 74 68 65 20 63 75 72 73 6f 72 20  that the cursor 
7600: 63 75 72 72 65 6e 74 6c 79 20 70 6f 69 6e 74 73  currently points
7610: 20 74 6f 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69   to..*/.static i
7620: 36 34 20 66 74 73 35 43 75 72 73 6f 72 52 6f 77  64 fts5CursorRow
7630: 69 64 28 46 74 73 35 43 75 72 73 6f 72 20 2a 70  id(Fts5Cursor *p
7640: 43 73 72 29 7b 0a 20 20 61 73 73 65 72 74 28 20  Csr){.  assert( 
7650: 46 54 53 35 5f 50 4c 41 4e 28 70 43 73 72 2d 3e  FTS5_PLAN(pCsr->
7660: 69 64 78 4e 75 6d 29 3d 3d 46 54 53 35 5f 50 4c  idxNum)==FTS5_PL
7670: 41 4e 5f 4d 41 54 43 48 20 0a 20 20 20 20 20 20  AN_MATCH .      
7680: 20 7c 7c 20 46 54 53 35 5f 50 4c 41 4e 28 70 43   || FTS5_PLAN(pC
7690: 73 72 2d 3e 69 64 78 4e 75 6d 29 3d 3d 46 54 53  sr->idxNum)==FTS
76a0: 35 5f 50 4c 41 4e 5f 53 4f 52 54 45 44 5f 4d 41  5_PLAN_SORTED_MA
76b0: 54 43 48 20 0a 20 20 20 20 20 20 20 7c 7c 20 46  TCH .       || F
76c0: 54 53 35 5f 50 4c 41 4e 28 70 43 73 72 2d 3e 69  TS5_PLAN(pCsr->i
76d0: 64 78 4e 75 6d 29 3d 3d 46 54 53 35 5f 50 4c 41  dxNum)==FTS5_PLA
76e0: 4e 5f 53 4f 55 52 43 45 20 0a 20 20 29 3b 0a 20  N_SOURCE .  );. 
76f0: 20 69 66 28 20 70 43 73 72 2d 3e 70 53 6f 72 74   if( pCsr->pSort
7700: 65 72 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e  er ){.    return
7710: 20 70 43 73 72 2d 3e 70 53 6f 72 74 65 72 2d 3e   pCsr->pSorter->
7720: 69 52 6f 77 69 64 3b 0a 20 20 7d 65 6c 73 65 7b  iRowid;.  }else{
7730: 0a 20 20 20 20 72 65 74 75 72 6e 20 73 71 6c 69  .    return sqli
7740: 74 65 33 46 74 73 35 45 78 70 72 52 6f 77 69 64  te3Fts5ExprRowid
7750: 28 70 43 73 72 2d 3e 70 45 78 70 72 29 3b 0a 20  (pCsr->pExpr);. 
7760: 20 7d 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 54 68 69   }.}../* .** Thi
7770: 73 20 69 73 20 74 68 65 20 78 52 6f 77 69 64 20  s is the xRowid 
7780: 6d 65 74 68 6f 64 2e 20 54 68 65 20 53 51 4c 69  method. The SQLi
7790: 74 65 20 63 6f 72 65 20 63 61 6c 6c 73 20 74 68  te core calls th
77a0: 69 73 20 72 6f 75 74 69 6e 65 20 74 6f 0a 2a 2a  is routine to.**
77b0: 20 72 65 74 72 69 65 76 65 20 74 68 65 20 72 6f   retrieve the ro
77c0: 77 69 64 20 66 6f 72 20 74 68 65 20 63 75 72 72  wid for the curr
77d0: 65 6e 74 20 72 6f 77 20 6f 66 20 74 68 65 20 72  ent row of the r
77e0: 65 73 75 6c 74 20 73 65 74 2e 20 66 74 73 35 0a  esult set. fts5.
77f0: 2a 2a 20 65 78 70 6f 73 65 73 20 25 5f 63 6f 6e  ** exposes %_con
7800: 74 65 6e 74 2e 64 6f 63 69 64 20 61 73 20 74 68  tent.docid as th
7810: 65 20 72 6f 77 69 64 20 66 6f 72 20 74 68 65 20  e rowid for the 
7820: 76 69 72 74 75 61 6c 20 74 61 62 6c 65 2e 20 54  virtual table. T
7830: 68 65 0a 2a 2a 20 72 6f 77 69 64 20 73 68 6f 75  he.** rowid shou
7840: 6c 64 20 62 65 20 77 72 69 74 74 65 6e 20 74 6f  ld be written to
7850: 20 2a 70 52 6f 77 69 64 2e 0a 2a 2f 0a 73 74 61   *pRowid..*/.sta
7860: 74 69 63 20 69 6e 74 20 66 74 73 35 52 6f 77 69  tic int fts5Rowi
7870: 64 4d 65 74 68 6f 64 28 73 71 6c 69 74 65 33 5f  dMethod(sqlite3_
7880: 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 70 43 75  vtab_cursor *pCu
7890: 72 73 6f 72 2c 20 73 71 6c 69 74 65 5f 69 6e 74  rsor, sqlite_int
78a0: 36 34 20 2a 70 52 6f 77 69 64 29 7b 0a 20 20 46  64 *pRowid){.  F
78b0: 74 73 35 43 75 72 73 6f 72 20 2a 70 43 73 72 20  ts5Cursor *pCsr 
78c0: 3d 20 28 46 74 73 35 43 75 72 73 6f 72 2a 29 70  = (Fts5Cursor*)p
78d0: 43 75 72 73 6f 72 3b 0a 20 20 69 6e 74 20 65 50  Cursor;.  int eP
78e0: 6c 61 6e 20 3d 20 46 54 53 35 5f 50 4c 41 4e 28  lan = FTS5_PLAN(
78f0: 70 43 73 72 2d 3e 69 64 78 4e 75 6d 29 3b 0a 20  pCsr->idxNum);. 
7900: 20 0a 20 20 61 73 73 65 72 74 28 20 43 73 72 46   .  assert( CsrF
7910: 6c 61 67 54 65 73 74 28 70 43 73 72 2c 20 46 54  lagTest(pCsr, FT
7920: 53 35 43 53 52 5f 45 4f 46 29 3d 3d 30 20 29 3b  S5CSR_EOF)==0 );
7930: 0a 20 20 73 77 69 74 63 68 28 20 65 50 6c 61 6e  .  switch( ePlan
7940: 20 29 7b 0a 20 20 20 20 63 61 73 65 20 46 54 53   ){.    case FTS
7950: 35 5f 50 4c 41 4e 5f 53 50 45 43 49 41 4c 3a 0a  5_PLAN_SPECIAL:.
7960: 20 20 20 20 20 20 2a 70 52 6f 77 69 64 20 3d 20        *pRowid = 
7970: 30 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a  0;.      break;.
7980: 0a 20 20 20 20 63 61 73 65 20 46 54 53 35 5f 50  .    case FTS5_P
7990: 4c 41 4e 5f 53 4f 55 52 43 45 3a 0a 20 20 20 20  LAN_SOURCE:.    
79a0: 63 61 73 65 20 46 54 53 35 5f 50 4c 41 4e 5f 4d  case FTS5_PLAN_M
79b0: 41 54 43 48 3a 0a 20 20 20 20 63 61 73 65 20 46  ATCH:.    case F
79c0: 54 53 35 5f 50 4c 41 4e 5f 53 4f 52 54 45 44 5f  TS5_PLAN_SORTED_
79d0: 4d 41 54 43 48 3a 0a 20 20 20 20 20 20 2a 70 52  MATCH:.      *pR
79e0: 6f 77 69 64 20 3d 20 66 74 73 35 43 75 72 73 6f  owid = fts5Curso
79f0: 72 52 6f 77 69 64 28 70 43 73 72 29 3b 0a 20 20  rRowid(pCsr);.  
7a00: 20 20 20 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20      break;..    
7a10: 64 65 66 61 75 6c 74 3a 0a 20 20 20 20 20 20 2a  default:.      *
7a20: 70 52 6f 77 69 64 20 3d 20 73 71 6c 69 74 65 33  pRowid = sqlite3
7a30: 5f 63 6f 6c 75 6d 6e 5f 69 6e 74 36 34 28 70 43  _column_int64(pC
7a40: 73 72 2d 3e 70 53 74 6d 74 2c 20 30 29 3b 0a 20  sr->pStmt, 0);. 
7a50: 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 7d 0a       break;.  }.
7a60: 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  .  return SQLITE
7a70: 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 66  _OK;.}../*.** If
7a80: 20 74 68 65 20 63 75 72 73 6f 72 20 72 65 71 75   the cursor requ
7a90: 69 72 65 73 20 73 65 65 6b 69 6e 67 20 28 62 53  ires seeking (bS
7aa0: 65 65 6b 52 65 71 75 69 72 65 64 20 66 6c 61 67  eekRequired flag
7ab0: 20 69 73 20 73 65 74 29 2c 20 73 65 65 6b 20 69   is set), seek i
7ac0: 74 2e 0a 2a 2a 20 52 65 74 75 72 6e 20 53 51 4c  t..** Return SQL
7ad0: 49 54 45 5f 4f 4b 20 69 66 20 6e 6f 20 65 72 72  ITE_OK if no err
7ae0: 6f 72 20 6f 63 63 75 72 73 2c 20 6f 72 20 61 6e  or occurs, or an
7af0: 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f   SQLite error co
7b00: 64 65 20 6f 74 68 65 72 77 69 73 65 2e 0a 2a 2f  de otherwise..*/
7b10: 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35  .static int fts5
7b20: 53 65 65 6b 43 75 72 73 6f 72 28 46 74 73 35 43  SeekCursor(Fts5C
7b30: 75 72 73 6f 72 20 2a 70 43 73 72 29 7b 0a 20 20  ursor *pCsr){.  
7b40: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
7b50: 4f 4b 3b 0a 0a 20 20 2f 2a 20 49 66 20 74 68 65  OK;..  /* If the
7b60: 20 63 75 72 73 6f 72 20 64 6f 65 73 20 6e 6f 74   cursor does not
7b70: 20 79 65 74 20 68 61 76 65 20 61 20 73 74 61 74   yet have a stat
7b80: 65 6d 65 6e 74 20 68 61 6e 64 6c 65 2c 20 6f 62  ement handle, ob
7b90: 74 61 69 6e 20 6f 6e 65 20 6e 6f 77 2e 20 2a 2f  tain one now. */
7ba0: 20 0a 20 20 69 66 28 20 70 43 73 72 2d 3e 70 53   .  if( pCsr->pS
7bb0: 74 6d 74 3d 3d 30 20 29 7b 0a 20 20 20 20 46 74  tmt==0 ){.    Ft
7bc0: 73 35 54 61 62 6c 65 20 2a 70 54 61 62 20 3d 20  s5Table *pTab = 
7bd0: 28 46 74 73 35 54 61 62 6c 65 2a 29 28 70 43 73  (Fts5Table*)(pCs
7be0: 72 2d 3e 62 61 73 65 2e 70 56 74 61 62 29 3b 0a  r->base.pVtab);.
7bf0: 20 20 20 20 69 6e 74 20 65 53 74 6d 74 20 3d 20      int eStmt = 
7c00: 66 74 73 35 53 74 6d 74 54 79 70 65 28 70 43 73  fts5StmtType(pCs
7c10: 72 2d 3e 69 64 78 4e 75 6d 29 3b 0a 20 20 20 20  r->idxNum);.    
7c20: 72 63 20 3d 20 73 71 6c 69 74 65 33 46 74 73 35  rc = sqlite3Fts5
7c30: 53 74 6f 72 61 67 65 53 74 6d 74 28 0a 20 20 20  StorageStmt(.   
7c40: 20 20 20 20 20 70 54 61 62 2d 3e 70 53 74 6f 72       pTab->pStor
7c50: 61 67 65 2c 20 65 53 74 6d 74 2c 20 26 70 43 73  age, eStmt, &pCs
7c60: 72 2d 3e 70 53 74 6d 74 2c 20 26 70 54 61 62 2d  r->pStmt, &pTab-
7c70: 3e 62 61 73 65 2e 7a 45 72 72 4d 73 67 0a 20 20  >base.zErrMsg.  
7c80: 20 20 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28    );.    assert(
7c90: 20 43 73 72 46 6c 61 67 54 65 73 74 28 70 43 73   CsrFlagTest(pCs
7ca0: 72 2c 20 46 54 53 35 43 53 52 5f 52 45 51 55 49  r, FTS5CSR_REQUI
7cb0: 52 45 5f 43 4f 4e 54 45 4e 54 29 20 29 3b 0a 20  RE_CONTENT) );. 
7cc0: 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51   }..  if( rc==SQ
7cd0: 4c 49 54 45 5f 4f 4b 20 26 26 20 43 73 72 46 6c  LITE_OK && CsrFl
7ce0: 61 67 54 65 73 74 28 70 43 73 72 2c 20 46 54 53  agTest(pCsr, FTS
7cf0: 35 43 53 52 5f 52 45 51 55 49 52 45 5f 43 4f 4e  5CSR_REQUIRE_CON
7d00: 54 45 4e 54 29 20 29 7b 0a 20 20 20 20 61 73 73  TENT) ){.    ass
7d10: 65 72 74 28 20 70 43 73 72 2d 3e 70 45 78 70 72  ert( pCsr->pExpr
7d20: 20 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f   );.    sqlite3_
7d30: 72 65 73 65 74 28 70 43 73 72 2d 3e 70 53 74 6d  reset(pCsr->pStm
7d40: 74 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f  t);.    sqlite3_
7d50: 62 69 6e 64 5f 69 6e 74 36 34 28 70 43 73 72 2d  bind_int64(pCsr-
7d60: 3e 70 53 74 6d 74 2c 20 31 2c 20 66 74 73 35 43  >pStmt, 1, fts5C
7d70: 75 72 73 6f 72 52 6f 77 69 64 28 70 43 73 72 29  ursorRowid(pCsr)
7d80: 29 3b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69  );.    rc = sqli
7d90: 74 65 33 5f 73 74 65 70 28 70 43 73 72 2d 3e 70  te3_step(pCsr->p
7da0: 53 74 6d 74 29 3b 0a 20 20 20 20 69 66 28 20 72  Stmt);.    if( r
7db0: 63 3d 3d 53 51 4c 49 54 45 5f 52 4f 57 20 29 7b  c==SQLITE_ROW ){
7dc0: 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49  .      rc = SQLI
7dd0: 54 45 5f 4f 4b 3b 0a 20 20 20 20 20 20 43 73 72  TE_OK;.      Csr
7de0: 46 6c 61 67 43 6c 65 61 72 28 70 43 73 72 2c 20  FlagClear(pCsr, 
7df0: 46 54 53 35 43 53 52 5f 52 45 51 55 49 52 45 5f  FTS5CSR_REQUIRE_
7e00: 43 4f 4e 54 45 4e 54 29 3b 0a 20 20 20 20 7d 65  CONTENT);.    }e
7e10: 6c 73 65 7b 0a 20 20 20 20 20 20 72 63 20 3d 20  lse{.      rc = 
7e20: 73 71 6c 69 74 65 33 5f 72 65 73 65 74 28 70 43  sqlite3_reset(pC
7e30: 73 72 2d 3e 70 53 74 6d 74 29 3b 0a 20 20 20 20  sr->pStmt);.    
7e40: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
7e50: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 72  _OK ){.        r
7e60: 63 20 3d 20 53 51 4c 49 54 45 5f 43 4f 52 52 55  c = SQLITE_CORRU
7e70: 50 54 5f 56 54 41 42 3b 0a 20 20 20 20 20 20 7d  PT_VTAB;.      }
7e80: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74  .    }.  }.  ret
7e90: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69  urn rc;.}..stati
7ea0: 63 20 76 6f 69 64 20 66 74 73 35 53 65 74 56 74  c void fts5SetVt
7eb0: 61 62 45 72 72 6f 72 28 46 74 73 35 54 61 62 6c  abError(Fts5Tabl
7ec0: 65 20 2a 70 2c 20 63 6f 6e 73 74 20 63 68 61 72  e *p, const char
7ed0: 20 2a 7a 46 6f 72 6d 61 74 2c 20 2e 2e 2e 29 7b   *zFormat, ...){
7ee0: 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 76 61 5f  .  int rc;.  va_
7ef0: 6c 69 73 74 20 61 70 3b 20 20 20 20 20 20 20 20  list ap;        
7f00: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
7f10: 2e 2e 2e 20 70 72 69 6e 74 66 20 61 72 67 75 6d  ... printf argum
7f20: 65 6e 74 73 20 2a 2f 0a 20 20 76 61 5f 73 74 61  ents */.  va_sta
7f30: 72 74 28 61 70 2c 20 7a 46 6f 72 6d 61 74 29 3b  rt(ap, zFormat);
7f40: 0a 20 20 61 73 73 65 72 74 28 20 70 2d 3e 62 61  .  assert( p->ba
7f50: 73 65 2e 7a 45 72 72 4d 73 67 3d 3d 30 20 29 3b  se.zErrMsg==0 );
7f60: 0a 20 20 70 2d 3e 62 61 73 65 2e 7a 45 72 72 4d  .  p->base.zErrM
7f70: 73 67 20 3d 20 73 71 6c 69 74 65 33 5f 76 6d 70  sg = sqlite3_vmp
7f80: 72 69 6e 74 66 28 7a 46 6f 72 6d 61 74 2c 20 61  rintf(zFormat, a
7f90: 70 29 3b 0a 20 20 76 61 5f 65 6e 64 28 61 70 29  p);.  va_end(ap)
7fa0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20  ;.}../*.** This 
7fb0: 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c  function is call
7fc0: 65 64 20 74 6f 20 68 61 6e 64 6c 65 20 61 6e 20  ed to handle an 
7fd0: 46 54 53 20 49 4e 53 45 52 54 20 63 6f 6d 6d 61  FTS INSERT comma
7fe0: 6e 64 2e 20 49 6e 20 6f 74 68 65 72 20 77 6f 72  nd. In other wor
7ff0: 64 73 2c 0a 2a 2a 20 61 6e 20 49 4e 53 45 52 54  ds,.** an INSERT
8000: 20 73 74 61 74 65 6d 65 6e 74 20 6f 66 20 74 68   statement of th
8010: 65 20 66 6f 72 6d 3a 0a 2a 2a 0a 2a 2a 20 20 20  e form:.**.**   
8020: 20 20 49 4e 53 45 52 54 20 49 4e 54 4f 20 66 74    INSERT INTO ft
8030: 73 28 66 74 73 29 20 56 41 4c 55 45 53 28 24 70  s(fts) VALUES($p
8040: 43 6d 64 29 0a 2a 2a 20 20 20 20 20 49 4e 53 45  Cmd).**     INSE
8050: 52 54 20 49 4e 54 4f 20 66 74 73 28 66 74 73 2c  RT INTO fts(fts,
8060: 20 72 61 6e 6b 29 20 56 41 4c 55 45 53 28 24 70   rank) VALUES($p
8070: 43 6d 64 2c 20 24 70 56 61 6c 29 0a 2a 2a 0a 2a  Cmd, $pVal).**.*
8080: 2a 20 41 72 67 75 6d 65 6e 74 20 70 56 61 6c 20  * Argument pVal 
8090: 69 73 20 74 68 65 20 76 61 6c 75 65 20 61 73 73  is the value ass
80a0: 69 67 6e 65 64 20 74 6f 20 63 6f 6c 75 6d 6e 20  igned to column 
80b0: 22 66 74 73 22 20 62 79 20 74 68 65 20 49 4e 53  "fts" by the INS
80c0: 45 52 54 20 0a 2a 2a 20 73 74 61 74 65 6d 65 6e  ERT .** statemen
80d0: 74 2e 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e  t. This function
80e0: 20 72 65 74 75 72 6e 73 20 53 51 4c 49 54 45 5f   returns SQLITE_
80f0: 4f 4b 20 69 66 20 73 75 63 63 65 73 73 66 75 6c  OK if successful
8100: 2c 20 6f 72 20 61 6e 20 53 51 4c 69 74 65 0a 2a  , or an SQLite.*
8110: 2a 20 65 72 72 6f 72 20 63 6f 64 65 20 69 66 20  * error code if 
8120: 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2e  an error occurs.
8130: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 6f 6d 6d 61  .**.** The comma
8140: 6e 64 73 20 69 6d 70 6c 65 6d 65 6e 74 65 64 20  nds implemented 
8150: 62 79 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e  by this function
8160: 20 61 72 65 20 64 6f 63 75 6d 65 6e 74 65 64 20   are documented 
8170: 69 6e 20 74 68 65 20 22 53 70 65 63 69 61 6c 0a  in the "Special.
8180: 2a 2a 20 49 4e 53 45 52 54 20 44 69 72 65 63 74  ** INSERT Direct
8190: 69 76 65 73 22 20 73 65 63 74 69 6f 6e 20 6f 66  ives" section of
81a0: 20 74 68 65 20 64 6f 63 75 6d 65 6e 74 61 74 69   the documentati
81b0: 6f 6e 2e 20 49 74 20 73 68 6f 75 6c 64 20 62 65  on. It should be
81c0: 20 75 70 64 61 74 65 64 20 69 66 0a 2a 2a 20 6d   updated if.** m
81d0: 6f 72 65 20 63 6f 6d 6d 61 6e 64 73 20 61 72 65  ore commands are
81e0: 20 61 64 64 65 64 20 74 6f 20 74 68 69 73 20 66   added to this f
81f0: 75 6e 63 74 69 6f 6e 2e 0a 2a 2f 0a 73 74 61 74  unction..*/.stat
8200: 69 63 20 69 6e 74 20 66 74 73 35 53 70 65 63 69  ic int fts5Speci
8210: 61 6c 49 6e 73 65 72 74 28 0a 20 20 46 74 73 35  alInsert(.  Fts5
8220: 54 61 62 6c 65 20 2a 70 54 61 62 2c 20 20 20 20  Table *pTab,    
8230: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46              /* F
8240: 74 73 35 20 74 61 62 6c 65 20 6f 62 6a 65 63 74  ts5 table object
8250: 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 76 61   */.  sqlite3_va
8260: 6c 75 65 20 2a 70 43 6d 64 2c 20 20 20 20 20 20  lue *pCmd,      
8270: 20 20 20 20 20 20 2f 2a 20 56 61 6c 75 65 20 69        /* Value i
8280: 6e 73 65 72 74 65 64 20 69 6e 74 6f 20 73 70 65  nserted into spe
8290: 63 69 61 6c 20 63 6f 6c 75 6d 6e 20 2a 2f 0a 20  cial column */. 
82a0: 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a   sqlite3_value *
82b0: 70 56 61 6c 20 20 20 20 20 20 20 20 20 20 20 20  pVal            
82c0: 20 2f 2a 20 56 61 6c 75 65 20 69 6e 73 65 72 74   /* Value insert
82d0: 65 64 20 69 6e 74 6f 20 72 6f 77 69 64 20 63 6f  ed into rowid co
82e0: 6c 75 6d 6e 20 2a 2f 0a 29 7b 0a 20 20 46 74 73  lumn */.){.  Fts
82f0: 35 43 6f 6e 66 69 67 20 2a 70 43 6f 6e 66 69 67  5Config *pConfig
8300: 20 3d 20 70 54 61 62 2d 3e 70 43 6f 6e 66 69 67   = pTab->pConfig
8310: 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  ;.  const char *
8320: 7a 20 3d 20 28 63 6f 6e 73 74 20 63 68 61 72 2a  z = (const char*
8330: 29 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74  )sqlite3_value_t
8340: 65 78 74 28 70 43 6d 64 29 3b 0a 20 20 69 6e 74  ext(pCmd);.  int
8350: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
8360: 0a 20 20 69 6e 74 20 62 45 72 72 6f 72 20 3d 20  .  int bError = 
8370: 30 3b 0a 0a 20 20 69 66 28 20 30 3d 3d 73 71 6c  0;..  if( 0==sql
8380: 69 74 65 33 5f 73 74 72 69 63 6d 70 28 22 64 65  ite3_stricmp("de
8390: 6c 65 74 65 2d 61 6c 6c 22 2c 20 7a 29 20 29 7b  lete-all", z) ){
83a0: 0a 20 20 20 20 69 66 28 20 70 43 6f 6e 66 69 67  .    if( pConfig
83b0: 2d 3e 65 43 6f 6e 74 65 6e 74 3d 3d 46 54 53 35  ->eContent==FTS5
83c0: 5f 43 4f 4e 54 45 4e 54 5f 4e 4f 52 4d 41 4c 20  _CONTENT_NORMAL 
83d0: 29 7b 0a 20 20 20 20 20 20 66 74 73 35 53 65 74  ){.      fts5Set
83e0: 56 74 61 62 45 72 72 6f 72 28 70 54 61 62 2c 20  VtabError(pTab, 
83f0: 0a 20 20 20 20 20 20 20 20 20 20 22 27 64 65 6c  .          "'del
8400: 65 74 65 2d 61 6c 6c 27 20 6d 61 79 20 6f 6e 6c  ete-all' may onl
8410: 79 20 62 65 20 75 73 65 64 20 77 69 74 68 20 61  y be used with a
8420: 20 22 0a 20 20 20 20 20 20 20 20 20 20 22 63 6f   ".          "co
8430: 6e 74 65 6e 74 6c 65 73 73 20 6f 72 20 65 78 74  ntentless or ext
8440: 65 72 6e 61 6c 20 63 6f 6e 74 65 6e 74 20 66 74  ernal content ft
8450: 73 35 20 74 61 62 6c 65 22 0a 20 20 20 20 20 20  s5 table".      
8460: 29 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51  );.      rc = SQ
8470: 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 20 20  LITE_ERROR;.    
8480: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 72 63 20  }else{.      rc 
8490: 3d 20 73 71 6c 69 74 65 33 46 74 73 35 53 74 6f  = sqlite3Fts5Sto
84a0: 72 61 67 65 44 65 6c 65 74 65 41 6c 6c 28 70 54  rageDeleteAll(pT
84b0: 61 62 2d 3e 70 53 74 6f 72 61 67 65 29 3b 0a 20  ab->pStorage);. 
84c0: 20 20 20 7d 0a 20 20 7d 65 6c 73 65 20 69 66 28     }.  }else if(
84d0: 20 30 3d 3d 73 71 6c 69 74 65 33 5f 73 74 72 69   0==sqlite3_stri
84e0: 63 6d 70 28 22 72 65 62 75 69 6c 64 22 2c 20 7a  cmp("rebuild", z
84f0: 29 20 29 7b 0a 20 20 20 20 69 66 28 20 70 43 6f  ) ){.    if( pCo
8500: 6e 66 69 67 2d 3e 65 43 6f 6e 74 65 6e 74 3d 3d  nfig->eContent==
8510: 46 54 53 35 5f 43 4f 4e 54 45 4e 54 5f 4e 4f 4e  FTS5_CONTENT_NON
8520: 45 20 29 7b 0a 20 20 20 20 20 20 66 74 73 35 53  E ){.      fts5S
8530: 65 74 56 74 61 62 45 72 72 6f 72 28 70 54 61 62  etVtabError(pTab
8540: 2c 20 0a 20 20 20 20 20 20 20 20 20 20 22 27 72  , .          "'r
8550: 65 62 75 69 6c 64 27 20 6d 61 79 20 6e 6f 74 20  ebuild' may not 
8560: 62 65 20 75 73 65 64 20 77 69 74 68 20 61 20 63  be used with a c
8570: 6f 6e 74 65 6e 74 6c 65 73 73 20 66 74 73 35 20  ontentless fts5 
8580: 74 61 62 6c 65 22 0a 20 20 20 20 20 20 29 3b 0a  table".      );.
8590: 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54        rc = SQLIT
85a0: 45 5f 45 52 52 4f 52 3b 0a 20 20 20 20 7d 65 6c  E_ERROR;.    }el
85b0: 73 65 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 73  se{.      rc = s
85c0: 71 6c 69 74 65 33 46 74 73 35 53 74 6f 72 61 67  qlite3Fts5Storag
85d0: 65 52 65 62 75 69 6c 64 28 70 54 61 62 2d 3e 70  eRebuild(pTab->p
85e0: 53 74 6f 72 61 67 65 29 3b 0a 20 20 20 20 7d 0a  Storage);.    }.
85f0: 20 20 7d 65 6c 73 65 20 69 66 28 20 30 3d 3d 73    }else if( 0==s
8600: 71 6c 69 74 65 33 5f 73 74 72 69 63 6d 70 28 22  qlite3_stricmp("
8610: 6f 70 74 69 6d 69 7a 65 22 2c 20 7a 29 20 29 7b  optimize", z) ){
8620: 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65  .    rc = sqlite
8630: 33 46 74 73 35 53 74 6f 72 61 67 65 4f 70 74 69  3Fts5StorageOpti
8640: 6d 69 7a 65 28 70 54 61 62 2d 3e 70 53 74 6f 72  mize(pTab->pStor
8650: 61 67 65 29 3b 0a 20 20 7d 65 6c 73 65 20 69 66  age);.  }else if
8660: 28 20 30 3d 3d 73 71 6c 69 74 65 33 5f 73 74 72  ( 0==sqlite3_str
8670: 69 63 6d 70 28 22 69 6e 74 65 67 72 69 74 79 2d  icmp("integrity-
8680: 63 68 65 63 6b 22 2c 20 7a 29 20 29 7b 0a 20 20  check", z) ){.  
8690: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 46 74    rc = sqlite3Ft
86a0: 73 35 53 74 6f 72 61 67 65 49 6e 74 65 67 72 69  s5StorageIntegri
86b0: 74 79 28 70 54 61 62 2d 3e 70 53 74 6f 72 61 67  ty(pTab->pStorag
86c0: 65 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  e);.  }else{.   
86d0: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 46 74 73   rc = sqlite3Fts
86e0: 35 43 6f 6e 66 69 67 53 65 74 56 61 6c 75 65 28  5ConfigSetValue(
86f0: 70 54 61 62 2d 3e 70 43 6f 6e 66 69 67 2c 20 7a  pTab->pConfig, z
8700: 2c 20 70 56 61 6c 2c 20 26 62 45 72 72 6f 72 29  , pVal, &bError)
8710: 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51  ;.    if( rc==SQ
8720: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
8730: 20 69 66 28 20 62 45 72 72 6f 72 20 29 7b 0a 20   if( bError ){. 
8740: 20 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49         rc = SQLI
8750: 54 45 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20 20  TE_ERROR;.      
8760: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 72  }else{.        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 43 6f 6e 66 69 67 56 61 6c 75  torageConfigValu
8790: 65 28 70 54 61 62 2d 3e 70 53 74 6f 72 61 67 65  e(pTab->pStorage
87a0: 2c 20 7a 2c 20 70 56 61 6c 29 3b 0a 20 20 20 20  , z, pVal);.    
87b0: 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20    }.    }.  }.  
87c0: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74  return rc;.}..st
87d0: 61 74 69 63 20 69 6e 74 20 66 74 73 35 53 70 65  atic int fts5Spe
87e0: 63 69 61 6c 44 65 6c 65 74 65 28 0a 20 20 46 74  cialDelete(.  Ft
87f0: 73 35 54 61 62 6c 65 20 2a 70 54 61 62 2c 20 0a  s5Table *pTab, .
8800: 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20    sqlite3_value 
8810: 2a 2a 61 70 56 61 6c 2c 20 0a 20 20 73 71 6c 69  **apVal, .  sqli
8820: 74 65 33 5f 69 6e 74 36 34 20 2a 70 69 52 6f 77  te3_int64 *piRow
8830: 69 64 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d  id.){.  int rc =
8840: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 6e   SQLITE_OK;.  in
8850: 74 20 65 54 79 70 65 31 20 3d 20 73 71 6c 69 74  t eType1 = sqlit
8860: 65 33 5f 76 61 6c 75 65 5f 74 79 70 65 28 61 70  e3_value_type(ap
8870: 56 61 6c 5b 31 5d 29 3b 0a 20 20 69 66 28 20 65  Val[1]);.  if( e
8880: 54 79 70 65 31 3d 3d 53 51 4c 49 54 45 5f 49 4e  Type1==SQLITE_IN
8890: 54 45 47 45 52 20 29 7b 0a 20 20 20 20 73 71 6c  TEGER ){.    sql
88a0: 69 74 65 33 5f 69 6e 74 36 34 20 69 44 65 6c 20  ite3_int64 iDel 
88b0: 3d 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f  = sqlite3_value_
88c0: 69 6e 74 36 34 28 61 70 56 61 6c 5b 31 5d 29 3b  int64(apVal[1]);
88d0: 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65  .    rc = sqlite
88e0: 33 46 74 73 35 53 74 6f 72 61 67 65 53 70 65 63  3Fts5StorageSpec
88f0: 69 61 6c 44 65 6c 65 74 65 28 70 54 61 62 2d 3e  ialDelete(pTab->
8900: 70 53 74 6f 72 61 67 65 2c 20 69 44 65 6c 2c 20  pStorage, iDel, 
8910: 26 61 70 56 61 6c 5b 32 5d 29 3b 0a 20 20 7d 0a  &apVal[2]);.  }.
8920: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
8930: 2f 2a 20 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63  /* .** This func
8940: 74 69 6f 6e 20 69 73 20 74 68 65 20 69 6d 70 6c  tion is the impl
8950: 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68  ementation of th
8960: 65 20 78 55 70 64 61 74 65 20 63 61 6c 6c 62 61  e xUpdate callba
8970: 63 6b 20 75 73 65 64 20 62 79 20 0a 2a 2a 20 46  ck used by .** F
8980: 54 53 33 20 76 69 72 74 75 61 6c 20 74 61 62 6c  TS3 virtual tabl
8990: 65 73 2e 20 49 74 20 69 73 20 69 6e 76 6f 6b 65  es. It is invoke
89a0: 64 20 62 79 20 53 51 4c 69 74 65 20 65 61 63 68  d by SQLite each
89b0: 20 74 69 6d 65 20 61 20 72 6f 77 20 69 73 20 74   time a row is t
89c0: 6f 20 62 65 0a 2a 2a 20 69 6e 73 65 72 74 65 64  o be.** inserted
89d0: 2c 20 75 70 64 61 74 65 64 20 6f 72 20 64 65 6c  , updated or del
89e0: 65 74 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  eted..*/.static 
89f0: 69 6e 74 20 66 74 73 35 55 70 64 61 74 65 4d 65  int fts5UpdateMe
8a00: 74 68 6f 64 28 0a 20 20 73 71 6c 69 74 65 33 5f  thod(.  sqlite3_
8a10: 76 74 61 62 20 2a 70 56 74 61 62 2c 20 20 20 20  vtab *pVtab,    
8a20: 20 20 20 20 20 20 20 20 2f 2a 20 56 69 72 74 75          /* Virtu
8a30: 61 6c 20 74 61 62 6c 65 20 68 61 6e 64 6c 65 20  al table handle 
8a40: 2a 2f 0a 20 20 69 6e 74 20 6e 41 72 67 2c 20 20  */.  int nArg,  
8a50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8a60: 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20       /* Size of 
8a70: 61 72 67 75 6d 65 6e 74 20 61 72 72 61 79 20 2a  argument array *
8a80: 2f 0a 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75  /.  sqlite3_valu
8a90: 65 20 2a 2a 61 70 56 61 6c 2c 20 20 20 20 20 20  e **apVal,      
8aa0: 20 20 20 20 2f 2a 20 41 72 72 61 79 20 6f 66 20      /* Array of 
8ab0: 61 72 67 75 6d 65 6e 74 73 20 2a 2f 0a 20 20 73  arguments */.  s
8ac0: 71 6c 69 74 65 5f 69 6e 74 36 34 20 2a 70 52 6f  qlite_int64 *pRo
8ad0: 77 69 64 20 20 20 20 20 20 20 20 20 20 20 20 2f  wid            /
8ae0: 2a 20 4f 55 54 3a 20 54 68 65 20 61 66 66 65 63  * OUT: The affec
8af0: 74 65 64 20 28 6f 72 20 65 66 66 65 63 74 65 64  ted (or effected
8b00: 29 20 72 6f 77 69 64 20 2a 2f 0a 29 7b 0a 20 20  ) rowid */.){.  
8b10: 46 74 73 35 54 61 62 6c 65 20 2a 70 54 61 62 20  Fts5Table *pTab 
8b20: 3d 20 28 46 74 73 35 54 61 62 6c 65 2a 29 70 56  = (Fts5Table*)pV
8b30: 74 61 62 3b 0a 20 20 46 74 73 35 43 6f 6e 66 69  tab;.  Fts5Confi
8b40: 67 20 2a 70 43 6f 6e 66 69 67 20 3d 20 70 54 61  g *pConfig = pTa
8b50: 62 2d 3e 70 43 6f 6e 66 69 67 3b 0a 20 20 69 6e  b->pConfig;.  in
8b60: 74 20 65 54 79 70 65 30 3b 20 20 20 20 20 20 20  t eType0;       
8b70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
8b80: 20 76 61 6c 75 65 5f 74 79 70 65 28 29 20 6f 66   value_type() of
8b90: 20 61 70 56 61 6c 5b 30 5d 20 2a 2f 0a 20 20 69   apVal[0] */.  i
8ba0: 6e 74 20 65 43 6f 6e 66 6c 69 63 74 3b 20 20 20  nt eConflict;   
8bb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
8bc0: 2a 20 4f 4e 20 43 4f 4e 46 4c 49 43 54 20 66 6f  * ON CONFLICT fo
8bd0: 72 20 74 68 69 73 20 44 4d 4c 20 2a 2f 0a 20 20  r this DML */.  
8be0: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
8bf0: 4f 4b 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  OK;             
8c00: 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20 2a  /* Return code *
8c10: 2f 0a 0a 20 20 2f 2a 20 41 20 74 72 61 6e 73 61  /..  /* A transa
8c20: 63 74 69 6f 6e 20 6d 75 73 74 20 62 65 20 6f 70  ction must be op
8c30: 65 6e 20 77 68 65 6e 20 74 68 69 73 20 69 73 20  en when this is 
8c40: 63 61 6c 6c 65 64 2e 20 2a 2f 0a 20 20 61 73 73  called. */.  ass
8c50: 65 72 74 28 20 70 54 61 62 2d 3e 74 73 2e 65 53  ert( pTab->ts.eS
8c60: 74 61 74 65 3d 3d 31 20 29 3b 0a 0a 20 20 2f 2a  tate==1 );..  /*
8c70: 20 41 20 64 65 6c 65 74 65 20 73 70 65 63 69 66   A delete specif
8c80: 69 65 73 20 61 20 73 69 6e 67 6c 65 20 61 72 67  ies a single arg
8c90: 75 6d 65 6e 74 20 2d 20 74 68 65 20 72 6f 77 69  ument - the rowi
8ca0: 64 20 6f 66 20 74 68 65 20 72 6f 77 20 74 6f 20  d of the row to 
8cb0: 72 65 6d 6f 76 65 2e 0a 20 20 2a 2a 20 55 70 64  remove..  ** Upd
8cc0: 61 74 65 20 61 6e 64 20 69 6e 73 65 72 74 20 6f  ate and insert o
8cd0: 70 65 72 61 74 69 6f 6e 73 20 70 61 73 73 3a 0a  perations pass:.
8ce0: 20 20 2a 2a 0a 20 20 2a 2a 20 20 20 31 2e 20 54    **.  **   1. T
8cf0: 68 65 20 22 6f 6c 64 22 20 72 6f 77 69 64 2c 20  he "old" rowid, 
8d00: 6f 72 20 4e 55 4c 4c 2e 0a 20 20 2a 2a 20 20 20  or NULL..  **   
8d10: 32 2e 20 54 68 65 20 22 6e 65 77 22 20 72 6f 77  2. The "new" row
8d20: 69 64 2e 0a 20 20 2a 2a 20 20 20 33 2e 20 56 61  id..  **   3. Va
8d30: 6c 75 65 73 20 66 6f 72 20 65 61 63 68 20 6f 66  lues for each of
8d40: 20 74 68 65 20 6e 43 6f 6c 20 6d 61 74 63 68 61   the nCol matcha
8d50: 62 6c 65 20 63 6f 6c 75 6d 6e 73 2e 0a 20 20 2a  ble columns..  *
8d60: 2a 20 20 20 34 2e 20 56 61 6c 75 65 73 20 66 6f  *   4. Values fo
8d70: 72 20 74 68 65 20 74 77 6f 20 68 69 64 64 65 6e  r the two hidden
8d80: 20 63 6f 6c 75 6d 6e 73 20 28 3c 74 61 62 6c 65   columns (<table
8d90: 6e 61 6d 65 3e 20 61 6e 64 20 22 72 61 6e 6b 22  name> and "rank"
8da0: 29 2e 0a 20 20 2a 2f 0a 20 20 61 73 73 65 72 74  )..  */.  assert
8db0: 28 20 6e 41 72 67 3d 3d 31 20 7c 7c 20 6e 41 72  ( nArg==1 || nAr
8dc0: 67 3d 3d 28 32 20 2b 20 70 43 6f 6e 66 69 67 2d  g==(2 + pConfig-
8dd0: 3e 6e 43 6f 6c 20 2b 20 32 29 20 29 3b 0a 0a 20  >nCol + 2) );.. 
8de0: 20 65 54 79 70 65 30 20 3d 20 73 71 6c 69 74 65   eType0 = sqlite
8df0: 33 5f 76 61 6c 75 65 5f 74 79 70 65 28 61 70 56  3_value_type(apV
8e00: 61 6c 5b 30 5d 29 3b 0a 20 20 65 43 6f 6e 66 6c  al[0]);.  eConfl
8e10: 69 63 74 20 3d 20 73 71 6c 69 74 65 33 5f 76 74  ict = sqlite3_vt
8e20: 61 62 5f 6f 6e 5f 63 6f 6e 66 6c 69 63 74 28 70  ab_on_conflict(p
8e30: 43 6f 6e 66 69 67 2d 3e 64 62 29 3b 0a 0a 20 20  Config->db);..  
8e40: 61 73 73 65 72 74 28 20 65 54 79 70 65 30 3d 3d  assert( eType0==
8e50: 53 51 4c 49 54 45 5f 49 4e 54 45 47 45 52 20 7c  SQLITE_INTEGER |
8e60: 7c 20 65 54 79 70 65 30 3d 3d 53 51 4c 49 54 45  | eType0==SQLITE
8e70: 5f 4e 55 4c 4c 20 29 3b 0a 20 20 61 73 73 65 72  _NULL );.  asser
8e80: 74 28 20 70 56 74 61 62 2d 3e 7a 45 72 72 4d 73  t( pVtab->zErrMs
8e90: 67 3d 3d 30 20 29 3b 0a 0a 20 20 69 66 28 20 72  g==0 );..  if( r
8ea0: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20  c==SQLITE_OK && 
8eb0: 65 54 79 70 65 30 3d 3d 53 51 4c 49 54 45 5f 49  eType0==SQLITE_I
8ec0: 4e 54 45 47 45 52 20 29 7b 0a 20 20 20 20 69 66  NTEGER ){.    if
8ed0: 28 20 66 74 73 35 49 73 43 6f 6e 74 65 6e 74 6c  ( fts5IsContentl
8ee0: 65 73 73 28 70 54 61 62 29 20 29 7b 0a 20 20 20  ess(pTab) ){.   
8ef0: 20 20 20 70 54 61 62 2d 3e 62 61 73 65 2e 7a 45     pTab->base.zE
8f00: 72 72 4d 73 67 20 3d 20 73 71 6c 69 74 65 33 5f  rrMsg = sqlite3_
8f10: 6d 70 72 69 6e 74 66 28 0a 20 20 20 20 20 20 20  mprintf(.       
8f20: 20 20 20 22 63 61 6e 6e 6f 74 20 25 73 20 63 6f     "cannot %s co
8f30: 6e 74 65 6e 74 6c 65 73 73 20 66 74 73 35 20 74  ntentless fts5 t
8f40: 61 62 6c 65 3a 20 25 73 22 2c 20 0a 20 20 20 20  able: %s", .    
8f50: 20 20 20 20 20 20 28 6e 41 72 67 3e 31 20 3f 20        (nArg>1 ? 
8f60: 22 55 50 44 41 54 45 22 20 3a 20 22 44 45 4c 45  "UPDATE" : "DELE
8f70: 54 45 20 66 72 6f 6d 22 29 2c 20 70 43 6f 6e 66  TE from"), pConf
8f80: 69 67 2d 3e 7a 4e 61 6d 65 0a 20 20 20 20 20 20  ig->zName.      
8f90: 29 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51  );.      rc = SQ
8fa0: 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 20 20  LITE_ERROR;.    
8fb0: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 69 36 34  }else{.      i64
8fc0: 20 69 44 65 6c 20 3d 20 73 71 6c 69 74 65 33 5f   iDel = sqlite3_
8fd0: 76 61 6c 75 65 5f 69 6e 74 36 34 28 61 70 56 61  value_int64(apVa
8fe0: 6c 5b 30 5d 29 3b 20 20 2f 2a 20 52 6f 77 69 64  l[0]);  /* Rowid
8ff0: 20 74 6f 20 64 65 6c 65 74 65 20 2a 2f 0a 20 20   to delete */.  
9000: 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
9010: 46 74 73 35 53 74 6f 72 61 67 65 44 65 6c 65 74  Fts5StorageDelet
9020: 65 28 70 54 61 62 2d 3e 70 53 74 6f 72 61 67 65  e(pTab->pStorage
9030: 2c 20 69 44 65 6c 29 3b 0a 20 20 20 20 7d 0a 20  , iDel);.    }. 
9040: 20 7d 65 6c 73 65 20 69 66 28 20 6e 41 72 67 3e   }else if( nArg>
9050: 31 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33  1 ){.    sqlite3
9060: 5f 76 61 6c 75 65 20 2a 70 43 6d 64 20 3d 20 61  _value *pCmd = a
9070: 70 56 61 6c 5b 32 20 2b 20 70 43 6f 6e 66 69 67  pVal[2 + pConfig
9080: 2d 3e 6e 43 6f 6c 5d 3b 0a 20 20 20 20 69 66 28  ->nCol];.    if(
9090: 20 53 51 4c 49 54 45 5f 4e 55 4c 4c 21 3d 73 71   SQLITE_NULL!=sq
90a0: 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 79 70 65  lite3_value_type
90b0: 28 70 43 6d 64 29 20 29 7b 0a 20 20 20 20 20 20  (pCmd) ){.      
90c0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 20 3d 20  const char *z = 
90d0: 28 63 6f 6e 73 74 20 63 68 61 72 2a 29 73 71 6c  (const char*)sql
90e0: 69 74 65 33 5f 76 61 6c 75 65 5f 74 65 78 74 28  ite3_value_text(
90f0: 70 43 6d 64 29 3b 0a 20 20 20 20 20 20 69 66 28  pCmd);.      if(
9100: 20 70 43 6f 6e 66 69 67 2d 3e 65 43 6f 6e 74 65   pConfig->eConte
9110: 6e 74 21 3d 46 54 53 35 5f 43 4f 4e 54 45 4e 54  nt!=FTS5_CONTENT
9120: 5f 4e 4f 52 4d 41 4c 20 0a 20 20 20 20 20 20 20  _NORMAL .       
9130: 26 26 20 30 3d 3d 73 71 6c 69 74 65 33 5f 73 74  && 0==sqlite3_st
9140: 72 69 63 6d 70 28 22 64 65 6c 65 74 65 22 2c 20  ricmp("delete", 
9150: 7a 29 20 0a 20 20 20 20 20 20 29 7b 0a 20 20 20  z) .      ){.   
9160: 20 20 20 20 20 72 65 74 75 72 6e 20 66 74 73 35       return fts5
9170: 53 70 65 63 69 61 6c 44 65 6c 65 74 65 28 70 54  SpecialDelete(pT
9180: 61 62 2c 20 61 70 56 61 6c 2c 20 70 52 6f 77 69  ab, apVal, pRowi
9190: 64 29 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b  d);.      }else{
91a0: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
91b0: 66 74 73 35 53 70 65 63 69 61 6c 49 6e 73 65 72  fts5SpecialInser
91c0: 74 28 70 54 61 62 2c 20 70 43 6d 64 2c 20 61 70  t(pTab, pCmd, ap
91d0: 56 61 6c 5b 32 20 2b 20 70 43 6f 6e 66 69 67 2d  Val[2 + pConfig-
91e0: 3e 6e 43 6f 6c 20 2b 20 31 5d 29 3b 0a 20 20 20  >nCol + 1]);.   
91f0: 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a     }.    }.  }..
9200: 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
9210: 45 5f 4f 4b 20 26 26 20 6e 41 72 67 3e 31 20 29  E_OK && nArg>1 )
9220: 7b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74  {.    rc = sqlit
9230: 65 33 46 74 73 35 53 74 6f 72 61 67 65 49 6e 73  e3Fts5StorageIns
9240: 65 72 74 28 70 54 61 62 2d 3e 70 53 74 6f 72 61  ert(pTab->pStora
9250: 67 65 2c 20 61 70 56 61 6c 2c 20 65 43 6f 6e 66  ge, apVal, eConf
9260: 6c 69 63 74 2c 20 70 52 6f 77 69 64 29 3b 0a 20  lict, pRowid);. 
9270: 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b   }..  return rc;
9280: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d  .}../*.** Implem
9290: 65 6e 74 61 74 69 6f 6e 20 6f 66 20 78 53 79 6e  entation of xSyn
92a0: 63 28 29 20 6d 65 74 68 6f 64 2e 20 0a 2a 2f 0a  c() method. .*/.
92b0: 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 53  static int fts5S
92c0: 79 6e 63 4d 65 74 68 6f 64 28 73 71 6c 69 74 65  yncMethod(sqlite
92d0: 33 5f 76 74 61 62 20 2a 70 56 74 61 62 29 7b 0a  3_vtab *pVtab){.
92e0: 20 20 69 6e 74 20 72 63 3b 0a 20 20 46 74 73 35    int rc;.  Fts5
92f0: 54 61 62 6c 65 20 2a 70 54 61 62 20 3d 20 28 46  Table *pTab = (F
9300: 74 73 35 54 61 62 6c 65 2a 29 70 56 74 61 62 3b  ts5Table*)pVtab;
9310: 0a 20 20 66 74 73 35 43 68 65 63 6b 54 72 61 6e  .  fts5CheckTran
9320: 73 61 63 74 69 6f 6e 53 74 61 74 65 28 70 54 61  sactionState(pTa
9330: 62 2c 20 46 54 53 35 5f 53 59 4e 43 2c 20 30 29  b, FTS5_SYNC, 0)
9340: 3b 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33  ;.  rc = sqlite3
9350: 46 74 73 35 53 74 6f 72 61 67 65 53 79 6e 63 28  Fts5StorageSync(
9360: 70 54 61 62 2d 3e 70 53 74 6f 72 61 67 65 2c 20  pTab->pStorage, 
9370: 31 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b  1);.  return rc;
9380: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d  .}../*.** Implem
9390: 65 6e 74 61 74 69 6f 6e 20 6f 66 20 78 42 65 67  entation of xBeg
93a0: 69 6e 28 29 20 6d 65 74 68 6f 64 2e 20 0a 2a 2f  in() method. .*/
93b0: 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35  .static int fts5
93c0: 42 65 67 69 6e 4d 65 74 68 6f 64 28 73 71 6c 69  BeginMethod(sqli
93d0: 74 65 33 5f 76 74 61 62 20 2a 70 56 74 61 62 29  te3_vtab *pVtab)
93e0: 7b 0a 20 20 66 74 73 35 43 68 65 63 6b 54 72 61  {.  fts5CheckTra
93f0: 6e 73 61 63 74 69 6f 6e 53 74 61 74 65 28 28 46  nsactionState((F
9400: 74 73 35 54 61 62 6c 65 2a 29 70 56 74 61 62 2c  ts5Table*)pVtab,
9410: 20 46 54 53 35 5f 42 45 47 49 4e 2c 20 30 29 3b   FTS5_BEGIN, 0);
9420: 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  .  return SQLITE
9430: 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d  _OK;.}../*.** Im
9440: 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20  plementation of 
9450: 78 43 6f 6d 6d 69 74 28 29 20 6d 65 74 68 6f 64  xCommit() method
9460: 2e 20 54 68 69 73 20 69 73 20 61 20 6e 6f 2d 6f  . This is a no-o
9470: 70 2e 20 54 68 65 20 63 6f 6e 74 65 6e 74 73 20  p. The contents 
9480: 6f 66 0a 2a 2a 20 74 68 65 20 70 65 6e 64 69 6e  of.** the pendin
9490: 67 2d 74 65 72 6d 73 20 68 61 73 68 2d 74 61 62  g-terms hash-tab
94a0: 6c 65 20 68 61 76 65 20 61 6c 72 65 61 64 79 20  le have already 
94b0: 62 65 65 6e 20 66 6c 75 73 68 65 64 20 69 6e 74  been flushed int
94c0: 6f 20 74 68 65 20 64 61 74 61 62 61 73 65 0a 2a  o the database.*
94d0: 2a 20 62 79 20 66 74 73 35 53 79 6e 63 4d 65 74  * by fts5SyncMet
94e0: 68 6f 64 28 29 2e 0a 2a 2f 0a 73 74 61 74 69 63  hod()..*/.static
94f0: 20 69 6e 74 20 66 74 73 35 43 6f 6d 6d 69 74 4d   int fts5CommitM
9500: 65 74 68 6f 64 28 73 71 6c 69 74 65 33 5f 76 74  ethod(sqlite3_vt
9510: 61 62 20 2a 70 56 74 61 62 29 7b 0a 20 20 66 74  ab *pVtab){.  ft
9520: 73 35 43 68 65 63 6b 54 72 61 6e 73 61 63 74 69  s5CheckTransacti
9530: 6f 6e 53 74 61 74 65 28 28 46 74 73 35 54 61 62  onState((Fts5Tab
9540: 6c 65 2a 29 70 56 74 61 62 2c 20 46 54 53 35 5f  le*)pVtab, FTS5_
9550: 43 4f 4d 4d 49 54 2c 20 30 29 3b 0a 20 20 72 65  COMMIT, 0);.  re
9560: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
9570: 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65  }../*.** Impleme
9580: 6e 74 61 74 69 6f 6e 20 6f 66 20 78 52 6f 6c 6c  ntation of xRoll
9590: 62 61 63 6b 28 29 2e 20 44 69 73 63 61 72 64 20  back(). Discard 
95a0: 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20  the contents of 
95b0: 74 68 65 20 70 65 6e 64 69 6e 67 2d 74 65 72 6d  the pending-term
95c0: 73 0a 2a 2a 20 68 61 73 68 2d 74 61 62 6c 65 2e  s.** hash-table.
95d0: 20 41 6e 79 20 63 68 61 6e 67 65 73 20 6d 61 64   Any changes mad
95e0: 65 20 74 6f 20 74 68 65 20 64 61 74 61 62 61 73  e to the databas
95f0: 65 20 61 72 65 20 72 65 76 65 72 74 65 64 20 62  e are reverted b
9600: 79 20 53 51 4c 69 74 65 2e 0a 2a 2f 0a 73 74 61  y SQLite..*/.sta
9610: 74 69 63 20 69 6e 74 20 66 74 73 35 52 6f 6c 6c  tic int fts5Roll
9620: 62 61 63 6b 4d 65 74 68 6f 64 28 73 71 6c 69 74  backMethod(sqlit
9630: 65 33 5f 76 74 61 62 20 2a 70 56 74 61 62 29 7b  e3_vtab *pVtab){
9640: 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 46 74 73  .  int rc;.  Fts
9650: 35 54 61 62 6c 65 20 2a 70 54 61 62 20 3d 20 28  5Table *pTab = (
9660: 46 74 73 35 54 61 62 6c 65 2a 29 70 56 74 61 62  Fts5Table*)pVtab
9670: 3b 0a 20 20 66 74 73 35 43 68 65 63 6b 54 72 61  ;.  fts5CheckTra
9680: 6e 73 61 63 74 69 6f 6e 53 74 61 74 65 28 70 54  nsactionState(pT
9690: 61 62 2c 20 46 54 53 35 5f 52 4f 4c 4c 42 41 43  ab, FTS5_ROLLBAC
96a0: 4b 2c 20 30 29 3b 0a 20 20 72 63 20 3d 20 73 71  K, 0);.  rc = sq
96b0: 6c 69 74 65 33 46 74 73 35 53 74 6f 72 61 67 65  lite3Fts5Storage
96c0: 52 6f 6c 6c 62 61 63 6b 28 70 54 61 62 2d 3e 70  Rollback(pTab->p
96d0: 53 74 6f 72 61 67 65 29 3b 0a 20 20 72 65 74 75  Storage);.  retu
96e0: 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63  rn rc;.}..static
96f0: 20 76 6f 69 64 20 2a 66 74 73 35 41 70 69 55 73   void *fts5ApiUs
9700: 65 72 44 61 74 61 28 46 74 73 35 43 6f 6e 74 65  erData(Fts5Conte
9710: 78 74 20 2a 70 43 74 78 29 7b 0a 20 20 46 74 73  xt *pCtx){.  Fts
9720: 35 43 75 72 73 6f 72 20 2a 70 43 73 72 20 3d 20  5Cursor *pCsr = 
9730: 28 46 74 73 35 43 75 72 73 6f 72 2a 29 70 43 74  (Fts5Cursor*)pCt
9740: 78 3b 0a 20 20 72 65 74 75 72 6e 20 70 43 73 72  x;.  return pCsr
9750: 2d 3e 70 41 75 78 2d 3e 70 55 73 65 72 44 61 74  ->pAux->pUserDat
9760: 61 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  a;.}..static int
9770: 20 66 74 73 35 41 70 69 43 6f 6c 75 6d 6e 43 6f   fts5ApiColumnCo
9780: 75 6e 74 28 46 74 73 35 43 6f 6e 74 65 78 74 20  unt(Fts5Context 
9790: 2a 70 43 74 78 29 7b 0a 20 20 46 74 73 35 43 75  *pCtx){.  Fts5Cu
97a0: 72 73 6f 72 20 2a 70 43 73 72 20 3d 20 28 46 74  rsor *pCsr = (Ft
97b0: 73 35 43 75 72 73 6f 72 2a 29 70 43 74 78 3b 0a  s5Cursor*)pCtx;.
97c0: 20 20 72 65 74 75 72 6e 20 28 28 46 74 73 35 54    return ((Fts5T
97d0: 61 62 6c 65 2a 29 28 70 43 73 72 2d 3e 62 61 73  able*)(pCsr->bas
97e0: 65 2e 70 56 74 61 62 29 29 2d 3e 70 43 6f 6e 66  e.pVtab))->pConf
97f0: 69 67 2d 3e 6e 43 6f 6c 3b 0a 7d 0a 0a 73 74 61  ig->nCol;.}..sta
9800: 74 69 63 20 69 6e 74 20 66 74 73 35 41 70 69 43  tic int fts5ApiC
9810: 6f 6c 75 6d 6e 54 6f 74 61 6c 53 69 7a 65 28 0a  olumnTotalSize(.
9820: 20 20 46 74 73 35 43 6f 6e 74 65 78 74 20 2a 70    Fts5Context *p
9830: 43 74 78 2c 20 0a 20 20 69 6e 74 20 69 43 6f 6c  Ctx, .  int iCol
9840: 2c 20 0a 20 20 73 71 6c 69 74 65 33 5f 69 6e 74  , .  sqlite3_int
9850: 36 34 20 2a 70 6e 54 6f 6b 65 6e 0a 29 7b 0a 20  64 *pnToken.){. 
9860: 20 46 74 73 35 43 75 72 73 6f 72 20 2a 70 43 73   Fts5Cursor *pCs
9870: 72 20 3d 20 28 46 74 73 35 43 75 72 73 6f 72 2a  r = (Fts5Cursor*
9880: 29 70 43 74 78 3b 0a 20 20 46 74 73 35 54 61 62  )pCtx;.  Fts5Tab
9890: 6c 65 20 2a 70 54 61 62 20 3d 20 28 46 74 73 35  le *pTab = (Fts5
98a0: 54 61 62 6c 65 2a 29 28 70 43 73 72 2d 3e 62 61  Table*)(pCsr->ba
98b0: 73 65 2e 70 56 74 61 62 29 3b 0a 20 20 72 65 74  se.pVtab);.  ret
98c0: 75 72 6e 20 73 71 6c 69 74 65 33 46 74 73 35 53  urn sqlite3Fts5S
98d0: 74 6f 72 61 67 65 53 69 7a 65 28 70 54 61 62 2d  torageSize(pTab-
98e0: 3e 70 53 74 6f 72 61 67 65 2c 20 69 43 6f 6c 2c  >pStorage, iCol,
98f0: 20 70 6e 54 6f 6b 65 6e 29 3b 0a 7d 0a 0a 73 74   pnToken);.}..st
9900: 61 74 69 63 20 69 6e 74 20 66 74 73 35 41 70 69  atic int fts5Api
9910: 52 6f 77 43 6f 75 6e 74 28 46 74 73 35 43 6f 6e  RowCount(Fts5Con
9920: 74 65 78 74 20 2a 70 43 74 78 2c 20 69 36 34 20  text *pCtx, i64 
9930: 2a 70 6e 52 6f 77 29 7b 0a 20 20 46 74 73 35 43  *pnRow){.  Fts5C
9940: 75 72 73 6f 72 20 2a 70 43 73 72 20 3d 20 28 46  ursor *pCsr = (F
9950: 74 73 35 43 75 72 73 6f 72 2a 29 70 43 74 78 3b  ts5Cursor*)pCtx;
9960: 0a 20 20 46 74 73 35 54 61 62 6c 65 20 2a 70 54  .  Fts5Table *pT
9970: 61 62 20 3d 20 28 46 74 73 35 54 61 62 6c 65 2a  ab = (Fts5Table*
9980: 29 28 70 43 73 72 2d 3e 62 61 73 65 2e 70 56 74  )(pCsr->base.pVt
9990: 61 62 29 3b 0a 20 20 72 65 74 75 72 6e 20 73 71  ab);.  return sq
99a0: 6c 69 74 65 33 46 74 73 35 53 74 6f 72 61 67 65  lite3Fts5Storage
99b0: 52 6f 77 43 6f 75 6e 74 28 70 54 61 62 2d 3e 70  RowCount(pTab->p
99c0: 53 74 6f 72 61 67 65 2c 20 70 6e 52 6f 77 29 3b  Storage, pnRow);
99d0: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 66  .}..static int f
99e0: 74 73 35 41 70 69 54 6f 6b 65 6e 69 7a 65 28 0a  ts5ApiTokenize(.
99f0: 20 20 46 74 73 35 43 6f 6e 74 65 78 74 20 2a 70    Fts5Context *p
9a00: 43 74 78 2c 20 0a 20 20 63 6f 6e 73 74 20 63 68  Ctx, .  const ch
9a10: 61 72 20 2a 70 54 65 78 74 2c 20 69 6e 74 20 6e  ar *pText, int n
9a20: 54 65 78 74 2c 20 0a 20 20 76 6f 69 64 20 2a 70  Text, .  void *p
9a30: 55 73 65 72 44 61 74 61 2c 0a 20 20 69 6e 74 20  UserData,.  int 
9a40: 28 2a 78 54 6f 6b 65 6e 29 28 76 6f 69 64 2a 2c  (*xToken)(void*,
9a50: 20 63 6f 6e 73 74 20 63 68 61 72 2a 2c 20 69 6e   const char*, in
9a60: 74 2c 20 69 6e 74 2c 20 69 6e 74 29 0a 29 7b 0a  t, int, int).){.
9a70: 20 20 46 74 73 35 43 75 72 73 6f 72 20 2a 70 43    Fts5Cursor *pC
9a80: 73 72 20 3d 20 28 46 74 73 35 43 75 72 73 6f 72  sr = (Fts5Cursor
9a90: 2a 29 70 43 74 78 3b 0a 20 20 46 74 73 35 54 61  *)pCtx;.  Fts5Ta
9aa0: 62 6c 65 20 2a 70 54 61 62 20 3d 20 28 46 74 73  ble *pTab = (Fts
9ab0: 35 54 61 62 6c 65 2a 29 28 70 43 73 72 2d 3e 62  5Table*)(pCsr->b
9ac0: 61 73 65 2e 70 56 74 61 62 29 3b 0a 20 20 72 65  ase.pVtab);.  re
9ad0: 74 75 72 6e 20 73 71 6c 69 74 65 33 46 74 73 35  turn sqlite3Fts5
9ae0: 54 6f 6b 65 6e 69 7a 65 28 70 54 61 62 2d 3e 70  Tokenize(pTab->p
9af0: 43 6f 6e 66 69 67 2c 20 70 54 65 78 74 2c 20 6e  Config, pText, n
9b00: 54 65 78 74 2c 20 70 55 73 65 72 44 61 74 61 2c  Text, pUserData,
9b10: 20 78 54 6f 6b 65 6e 29 3b 0a 7d 0a 0a 73 74 61   xToken);.}..sta
9b20: 74 69 63 20 69 6e 74 20 66 74 73 35 41 70 69 50  tic int fts5ApiP
9b30: 68 72 61 73 65 43 6f 75 6e 74 28 46 74 73 35 43  hraseCount(Fts5C
9b40: 6f 6e 74 65 78 74 20 2a 70 43 74 78 29 7b 0a 20  ontext *pCtx){. 
9b50: 20 46 74 73 35 43 75 72 73 6f 72 20 2a 70 43 73   Fts5Cursor *pCs
9b60: 72 20 3d 20 28 46 74 73 35 43 75 72 73 6f 72 2a  r = (Fts5Cursor*
9b70: 29 70 43 74 78 3b 0a 20 20 72 65 74 75 72 6e 20  )pCtx;.  return 
9b80: 73 71 6c 69 74 65 33 46 74 73 35 45 78 70 72 50  sqlite3Fts5ExprP
9b90: 68 72 61 73 65 43 6f 75 6e 74 28 70 43 73 72 2d  hraseCount(pCsr-
9ba0: 3e 70 45 78 70 72 29 3b 0a 7d 0a 0a 73 74 61 74  >pExpr);.}..stat
9bb0: 69 63 20 69 6e 74 20 66 74 73 35 41 70 69 50 68  ic int fts5ApiPh
9bc0: 72 61 73 65 53 69 7a 65 28 46 74 73 35 43 6f 6e  raseSize(Fts5Con
9bd0: 74 65 78 74 20 2a 70 43 74 78 2c 20 69 6e 74 20  text *pCtx, int 
9be0: 69 50 68 72 61 73 65 29 7b 0a 20 20 46 74 73 35  iPhrase){.  Fts5
9bf0: 43 75 72 73 6f 72 20 2a 70 43 73 72 20 3d 20 28  Cursor *pCsr = (
9c00: 46 74 73 35 43 75 72 73 6f 72 2a 29 70 43 74 78  Fts5Cursor*)pCtx
9c10: 3b 0a 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74  ;.  return sqlit
9c20: 65 33 46 74 73 35 45 78 70 72 50 68 72 61 73 65  e3Fts5ExprPhrase
9c30: 53 69 7a 65 28 70 43 73 72 2d 3e 70 45 78 70 72  Size(pCsr->pExpr
9c40: 2c 20 69 50 68 72 61 73 65 29 3b 0a 7d 0a 0a 73  , iPhrase);.}..s
9c50: 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 43 73  tatic int fts5Cs
9c60: 72 50 6f 73 6c 69 73 74 28 46 74 73 35 43 75 72  rPoslist(Fts5Cur
9c70: 73 6f 72 20 2a 70 43 73 72 2c 20 69 6e 74 20 69  sor *pCsr, int i
9c80: 50 68 72 61 73 65 2c 20 63 6f 6e 73 74 20 75 38  Phrase, const u8
9c90: 20 2a 2a 70 61 29 7b 0a 20 20 69 6e 74 20 6e 3b   **pa){.  int n;
9ca0: 0a 20 20 69 66 28 20 70 43 73 72 2d 3e 70 53 6f  .  if( pCsr->pSo
9cb0: 72 74 65 72 20 29 7b 0a 20 20 20 20 46 74 73 35  rter ){.    Fts5
9cc0: 53 6f 72 74 65 72 20 2a 70 53 6f 72 74 65 72 20  Sorter *pSorter 
9cd0: 3d 20 70 43 73 72 2d 3e 70 53 6f 72 74 65 72 3b  = pCsr->pSorter;
9ce0: 0a 20 20 20 20 69 6e 74 20 69 31 20 3d 20 28 69  .    int i1 = (i
9cf0: 50 68 72 61 73 65 3d 3d 30 20 3f 20 30 20 3a 20  Phrase==0 ? 0 : 
9d00: 70 53 6f 72 74 65 72 2d 3e 61 49 64 78 5b 69 50  pSorter->aIdx[iP
9d10: 68 72 61 73 65 2d 31 5d 29 3b 0a 20 20 20 20 6e  hrase-1]);.    n
9d20: 20 3d 20 70 53 6f 72 74 65 72 2d 3e 61 49 64 78   = pSorter->aIdx
9d30: 5b 69 50 68 72 61 73 65 5d 20 2d 20 69 31 3b 0a  [iPhrase] - i1;.
9d40: 20 20 20 20 2a 70 61 20 3d 20 26 70 53 6f 72 74      *pa = &pSort
9d50: 65 72 2d 3e 61 50 6f 73 6c 69 73 74 5b 69 31 5d  er->aPoslist[i1]
9d60: 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 6e  ;.  }else{.    n
9d70: 20 3d 20 73 71 6c 69 74 65 33 46 74 73 35 45 78   = sqlite3Fts5Ex
9d80: 70 72 50 6f 73 6c 69 73 74 28 70 43 73 72 2d 3e  prPoslist(pCsr->
9d90: 70 45 78 70 72 2c 20 69 50 68 72 61 73 65 2c 20  pExpr, iPhrase, 
9da0: 70 61 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72  pa);.  }.  retur
9db0: 6e 20 6e 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 45 6e  n n;.}../*.** En
9dc0: 73 75 72 65 20 74 68 61 74 20 74 68 65 20 46 74  sure that the Ft
9dd0: 73 35 43 75 72 73 6f 72 2e 6e 49 6e 73 74 43 6f  s5Cursor.nInstCo
9de0: 75 6e 74 20 61 6e 64 20 61 49 6e 73 74 5b 5d 20  unt and aInst[] 
9df0: 76 61 72 69 61 62 6c 65 73 20 61 72 65 20 70 6f  variables are po
9e00: 70 75 6c 61 74 65 64 0a 2a 2a 20 63 6f 72 72 65  pulated.** corre
9e10: 63 74 6c 79 20 66 6f 72 20 74 68 65 20 63 75 72  ctly for the cur
9e20: 72 65 6e 74 20 76 69 65 77 2e 20 52 65 74 75 72  rent view. Retur
9e30: 6e 20 53 51 4c 49 54 45 5f 4f 4b 20 69 66 20 73  n SQLITE_OK if s
9e40: 75 63 63 65 73 73 66 75 6c 2c 20 6f 72 20 61 6e  uccessful, or an
9e50: 0a 2a 2a 20 53 51 4c 69 74 65 20 65 72 72 6f 72  .** SQLite error
9e60: 20 63 6f 64 65 20 6f 74 68 65 72 77 69 73 65 2e   code otherwise.
9e70: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66  .*/.static int f
9e80: 74 73 35 43 61 63 68 65 49 6e 73 74 41 72 72 61  ts5CacheInstArra
9e90: 79 28 46 74 73 35 43 75 72 73 6f 72 20 2a 70 43  y(Fts5Cursor *pC
9ea0: 73 72 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20  sr){.  int rc = 
9eb0: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 66 28  SQLITE_OK;.  if(
9ec0: 20 70 43 73 72 2d 3e 61 49 6e 73 74 3d 3d 30 20   pCsr->aInst==0 
9ed0: 29 7b 0a 20 20 20 20 46 74 73 35 50 6f 73 6c 69  ){.    Fts5Posli
9ee0: 73 74 52 65 61 64 65 72 20 2a 61 49 74 65 72 3b  stReader *aIter;
9ef0: 20 20 20 20 20 2f 2a 20 4f 6e 65 20 69 74 65 72       /* One iter
9f00: 61 74 6f 72 20 66 6f 72 20 65 61 63 68 20 70 68  ator for each ph
9f10: 72 61 73 65 20 2a 2f 0a 20 20 20 20 69 6e 74 20  rase */.    int 
9f20: 6e 49 74 65 72 3b 20 20 20 20 20 20 20 20 20 20  nIter;          
9f30: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d            /* Num
9f40: 62 65 72 20 6f 66 20 69 74 65 72 61 74 6f 72 73  ber of iterators
9f50: 2f 70 68 72 61 73 65 73 20 2a 2f 0a 20 20 20 20  /phrases */.    
9f60: 69 6e 74 20 6e 42 79 74 65 3b 0a 20 20 20 20 0a  int nByte;.    .
9f70: 20 20 20 20 6e 49 74 65 72 20 3d 20 73 71 6c 69      nIter = sqli
9f80: 74 65 33 46 74 73 35 45 78 70 72 50 68 72 61 73  te3Fts5ExprPhras
9f90: 65 43 6f 75 6e 74 28 70 43 73 72 2d 3e 70 45 78  eCount(pCsr->pEx
9fa0: 70 72 29 3b 0a 20 20 20 20 6e 42 79 74 65 20 3d  pr);.    nByte =
9fb0: 20 73 69 7a 65 6f 66 28 46 74 73 35 50 6f 73 6c   sizeof(Fts5Posl
9fc0: 69 73 74 52 65 61 64 65 72 29 20 2a 20 6e 49 74  istReader) * nIt
9fd0: 65 72 3b 0a 20 20 20 20 61 49 74 65 72 20 3d 20  er;.    aIter = 
9fe0: 28 46 74 73 35 50 6f 73 6c 69 73 74 52 65 61 64  (Fts5PoslistRead
9ff0: 65 72 2a 29 73 71 6c 69 74 65 33 46 74 73 35 4d  er*)sqlite3Fts5M
a000: 61 6c 6c 6f 63 5a 65 72 6f 28 26 72 63 2c 20 6e  allocZero(&rc, n
a010: 42 79 74 65 29 3b 0a 20 20 20 20 69 66 28 20 61  Byte);.    if( a
a020: 49 74 65 72 20 29 7b 0a 20 20 20 20 20 20 46 74  Iter ){.      Ft
a030: 73 35 42 75 66 66 65 72 20 62 75 66 20 3d 20 7b  s5Buffer buf = {
a040: 30 2c 20 30 2c 20 30 7d 3b 20 2f 2a 20 42 75 69  0, 0, 0}; /* Bui
a050: 6c 64 20 75 70 20 61 49 6e 73 74 5b 5d 20 68 65  ld up aInst[] he
a060: 72 65 20 2a 2f 0a 20 20 20 20 20 20 69 6e 74 20  re */.      int 
a070: 6e 49 6e 73 74 20 3d 20 30 3b 20 20 20 20 20 20  nInst = 0;      
a080: 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65          /* Numbe
a090: 72 20 69 6e 73 74 61 6e 63 65 73 20 73 65 65 6e  r instances seen
a0a0: 20 73 6f 20 66 61 72 20 2a 2f 0a 20 20 20 20 20   so far */.     
a0b0: 20 69 6e 74 20 69 3b 0a 0a 20 20 20 20 20 20 2f   int i;..      /
a0c0: 2a 20 49 6e 69 74 69 61 6c 69 7a 65 20 61 6c 6c  * Initialize all
a0d0: 20 69 74 65 72 61 74 6f 72 73 20 2a 2f 0a 20 20   iterators */.  
a0e0: 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e      for(i=0; i<n
a0f0: 49 74 65 72 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  Iter; i++){.    
a100: 20 20 20 20 63 6f 6e 73 74 20 75 38 20 2a 61 3b      const u8 *a;
a110: 0a 20 20 20 20 20 20 20 20 69 6e 74 20 6e 20 3d  .        int n =
a120: 20 66 74 73 35 43 73 72 50 6f 73 6c 69 73 74 28   fts5CsrPoslist(
a130: 70 43 73 72 2c 20 69 2c 20 26 61 29 3b 0a 20 20  pCsr, i, &a);.  
a140: 20 20 20 20 20 20 73 71 6c 69 74 65 33 46 74 73        sqlite3Fts
a150: 35 50 6f 73 6c 69 73 74 52 65 61 64 65 72 49 6e  5PoslistReaderIn
a160: 69 74 28 2d 31 2c 20 61 2c 20 6e 2c 20 26 61 49  it(-1, a, n, &aI
a170: 74 65 72 5b 69 5d 29 3b 0a 20 20 20 20 20 20 7d  ter[i]);.      }
a180: 0a 0a 20 20 20 20 20 20 77 68 69 6c 65 28 20 31  ..      while( 1
a190: 20 29 7b 0a 20 20 20 20 20 20 20 20 69 6e 74 20   ){.        int 
a1a0: 2a 61 49 6e 73 74 3b 0a 20 20 20 20 20 20 20 20  *aInst;.        
a1b0: 69 6e 74 20 69 42 65 73 74 20 3d 20 2d 31 3b 0a  int iBest = -1;.
a1c0: 20 20 20 20 20 20 20 20 66 6f 72 28 69 3d 30 3b          for(i=0;
a1d0: 20 69 3c 6e 49 74 65 72 3b 20 69 2b 2b 29 7b 0a   i<nIter; i++){.
a1e0: 20 20 20 20 20 20 20 20 20 20 69 66 28 20 28 61            if( (a
a1f0: 49 74 65 72 5b 69 5d 2e 62 45 6f 66 3d 3d 30 29  Iter[i].bEof==0)
a200: 20 0a 20 20 20 20 20 20 20 20 20 20 20 26 26 20   .           && 
a210: 28 69 42 65 73 74 3c 30 20 7c 7c 20 61 49 74 65  (iBest<0 || aIte
a220: 72 5b 69 5d 2e 69 50 6f 73 3c 61 49 74 65 72 5b  r[i].iPos<aIter[
a230: 69 42 65 73 74 5d 2e 69 50 6f 73 29 20 0a 20 20  iBest].iPos) .  
a240: 20 20 20 20 20 20 20 20 29 7b 0a 20 20 20 20 20          ){.     
a250: 20 20 20 20 20 20 20 69 42 65 73 74 20 3d 20 69         iBest = i
a260: 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20  ;.          }.  
a270: 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 20        }..       
a280: 20 69 66 28 20 69 42 65 73 74 3c 30 20 29 20 62   if( iBest<0 ) b
a290: 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 6e 49  reak;.        nI
a2a0: 6e 73 74 2b 2b 3b 0a 20 20 20 20 20 20 20 20 69  nst++;.        i
a2b0: 66 28 20 73 71 6c 69 74 65 33 46 74 73 35 42 75  f( sqlite3Fts5Bu
a2c0: 66 66 65 72 47 72 6f 77 28 26 72 63 2c 20 26 62  fferGrow(&rc, &b
a2d0: 75 66 2c 20 6e 49 6e 73 74 20 2a 20 73 69 7a 65  uf, nInst * size
a2e0: 6f 66 28 69 6e 74 29 20 2a 20 33 29 20 29 20 62  of(int) * 3) ) b
a2f0: 72 65 61 6b 3b 0a 0a 20 20 20 20 20 20 20 20 61  reak;..        a
a300: 49 6e 73 74 20 3d 20 26 28 28 69 6e 74 2a 29 62  Inst = &((int*)b
a310: 75 66 2e 70 29 5b 33 20 2a 20 28 6e 49 6e 73 74  uf.p)[3 * (nInst
a320: 2d 31 29 5d 3b 0a 20 20 20 20 20 20 20 20 61 49  -1)];.        aI
a330: 6e 73 74 5b 30 5d 20 3d 20 69 42 65 73 74 3b 0a  nst[0] = iBest;.
a340: 20 20 20 20 20 20 20 20 61 49 6e 73 74 5b 31 5d          aInst[1]
a350: 20 3d 20 46 54 53 35 5f 50 4f 53 32 43 4f 4c 55   = FTS5_POS2COLU
a360: 4d 4e 28 61 49 74 65 72 5b 69 42 65 73 74 5d 2e  MN(aIter[iBest].
a370: 69 50 6f 73 29 3b 0a 20 20 20 20 20 20 20 20 61  iPos);.        a
a380: 49 6e 73 74 5b 32 5d 20 3d 20 46 54 53 35 5f 50  Inst[2] = FTS5_P
a390: 4f 53 32 4f 46 46 53 45 54 28 61 49 74 65 72 5b  OS2OFFSET(aIter[
a3a0: 69 42 65 73 74 5d 2e 69 50 6f 73 29 3b 0a 20 20  iBest].iPos);.  
a3b0: 20 20 20 20 20 20 73 71 6c 69 74 65 33 46 74 73        sqlite3Fts
a3c0: 35 50 6f 73 6c 69 73 74 52 65 61 64 65 72 4e 65  5PoslistReaderNe
a3d0: 78 74 28 26 61 49 74 65 72 5b 69 42 65 73 74 5d  xt(&aIter[iBest]
a3e0: 29 3b 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20 20  );.      }..    
a3f0: 20 20 70 43 73 72 2d 3e 61 49 6e 73 74 20 3d 20    pCsr->aInst = 
a400: 28 69 6e 74 2a 29 62 75 66 2e 70 3b 0a 20 20 20  (int*)buf.p;.   
a410: 20 20 20 70 43 73 72 2d 3e 6e 49 6e 73 74 43 6f     pCsr->nInstCo
a420: 75 6e 74 20 3d 20 6e 49 6e 73 74 3b 0a 20 20 20  unt = nInst;.   
a430: 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28     sqlite3_free(
a440: 61 49 74 65 72 29 3b 0a 20 20 20 20 7d 0a 20 20  aIter);.    }.  
a450: 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  }.  return rc;.}
a460: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73  ..static int fts
a470: 35 41 70 69 49 6e 73 74 43 6f 75 6e 74 28 46 74  5ApiInstCount(Ft
a480: 73 35 43 6f 6e 74 65 78 74 20 2a 70 43 74 78 2c  s5Context *pCtx,
a490: 20 69 6e 74 20 2a 70 6e 49 6e 73 74 29 7b 0a 20   int *pnInst){. 
a4a0: 20 46 74 73 35 43 75 72 73 6f 72 20 2a 70 43 73   Fts5Cursor *pCs
a4b0: 72 20 3d 20 28 46 74 73 35 43 75 72 73 6f 72 2a  r = (Fts5Cursor*
a4c0: 29 70 43 74 78 3b 0a 20 20 69 6e 74 20 72 63 3b  )pCtx;.  int rc;
a4d0: 0a 20 20 69 66 28 20 53 51 4c 49 54 45 5f 4f 4b  .  if( SQLITE_OK
a4e0: 3d 3d 28 72 63 20 3d 20 66 74 73 35 43 61 63 68  ==(rc = fts5Cach
a4f0: 65 49 6e 73 74 41 72 72 61 79 28 70 43 73 72 29  eInstArray(pCsr)
a500: 29 20 29 7b 0a 20 20 20 20 2a 70 6e 49 6e 73 74  ) ){.    *pnInst
a510: 20 3d 20 70 43 73 72 2d 3e 6e 49 6e 73 74 43 6f   = pCsr->nInstCo
a520: 75 6e 74 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72  unt;.  }.  retur
a530: 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  n rc;.}..static 
a540: 69 6e 74 20 66 74 73 35 41 70 69 49 6e 73 74 28  int fts5ApiInst(
a550: 0a 20 20 46 74 73 35 43 6f 6e 74 65 78 74 20 2a  .  Fts5Context *
a560: 70 43 74 78 2c 20 0a 20 20 69 6e 74 20 69 49 64  pCtx, .  int iId
a570: 78 2c 20 0a 20 20 69 6e 74 20 2a 70 69 50 68 72  x, .  int *piPhr
a580: 61 73 65 2c 20 0a 20 20 69 6e 74 20 2a 70 69 43  ase, .  int *piC
a590: 6f 6c 2c 20 0a 20 20 69 6e 74 20 2a 70 69 4f 66  ol, .  int *piOf
a5a0: 66 0a 29 7b 0a 20 20 46 74 73 35 43 75 72 73 6f  f.){.  Fts5Curso
a5b0: 72 20 2a 70 43 73 72 20 3d 20 28 46 74 73 35 43  r *pCsr = (Fts5C
a5c0: 75 72 73 6f 72 2a 29 70 43 74 78 3b 0a 20 20 69  ursor*)pCtx;.  i
a5d0: 6e 74 20 72 63 3b 0a 20 20 69 66 28 20 53 51 4c  nt rc;.  if( SQL
a5e0: 49 54 45 5f 4f 4b 3d 3d 28 72 63 20 3d 20 66 74  ITE_OK==(rc = ft
a5f0: 73 35 43 61 63 68 65 49 6e 73 74 41 72 72 61 79  s5CacheInstArray
a600: 28 70 43 73 72 29 29 20 29 7b 0a 20 20 20 20 69  (pCsr)) ){.    i
a610: 66 28 20 69 49 64 78 3c 30 20 7c 7c 20 69 49 64  f( iIdx<0 || iId
a620: 78 3e 3d 70 43 73 72 2d 3e 6e 49 6e 73 74 43 6f  x>=pCsr->nInstCo
a630: 75 6e 74 20 29 7b 0a 20 20 20 20 20 20 72 63 20  unt ){.      rc 
a640: 3d 20 53 51 4c 49 54 45 5f 52 41 4e 47 45 3b 0a  = SQLITE_RANGE;.
a650: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
a660: 20 2a 70 69 50 68 72 61 73 65 20 3d 20 70 43 73   *piPhrase = pCs
a670: 72 2d 3e 61 49 6e 73 74 5b 69 49 64 78 2a 33 5d  r->aInst[iIdx*3]
a680: 3b 0a 20 20 20 20 20 20 2a 70 69 43 6f 6c 20 3d  ;.      *piCol =
a690: 20 70 43 73 72 2d 3e 61 49 6e 73 74 5b 69 49 64   pCsr->aInst[iId
a6a0: 78 2a 33 20 2b 20 31 5d 3b 0a 20 20 20 20 20 20  x*3 + 1];.      
a6b0: 2a 70 69 4f 66 66 20 3d 20 70 43 73 72 2d 3e 61  *piOff = pCsr->a
a6c0: 49 6e 73 74 5b 69 49 64 78 2a 33 20 2b 20 32 5d  Inst[iIdx*3 + 2]
a6d0: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65  ;.    }.  }.  re
a6e0: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74  turn rc;.}..stat
a6f0: 69 63 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34  ic sqlite3_int64
a700: 20 66 74 73 35 41 70 69 52 6f 77 69 64 28 46 74   fts5ApiRowid(Ft
a710: 73 35 43 6f 6e 74 65 78 74 20 2a 70 43 74 78 29  s5Context *pCtx)
a720: 7b 0a 20 20 72 65 74 75 72 6e 20 66 74 73 35 43  {.  return fts5C
a730: 75 72 73 6f 72 52 6f 77 69 64 28 28 46 74 73 35  ursorRowid((Fts5
a740: 43 75 72 73 6f 72 2a 29 70 43 74 78 29 3b 0a 7d  Cursor*)pCtx);.}
a750: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73  ..static int fts
a760: 35 41 70 69 43 6f 6c 75 6d 6e 54 65 78 74 28 0a  5ApiColumnText(.
a770: 20 20 46 74 73 35 43 6f 6e 74 65 78 74 20 2a 70    Fts5Context *p
a780: 43 74 78 2c 20 0a 20 20 69 6e 74 20 69 43 6f 6c  Ctx, .  int iCol
a790: 2c 20 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  , .  const char 
a7a0: 2a 2a 70 7a 2c 20 0a 20 20 69 6e 74 20 2a 70 6e  **pz, .  int *pn
a7b0: 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53  .){.  int rc = S
a7c0: 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 46 74 73 35  QLITE_OK;.  Fts5
a7d0: 43 75 72 73 6f 72 20 2a 70 43 73 72 20 3d 20 28  Cursor *pCsr = (
a7e0: 46 74 73 35 43 75 72 73 6f 72 2a 29 70 43 74 78  Fts5Cursor*)pCtx
a7f0: 3b 0a 20 20 69 66 28 20 66 74 73 35 49 73 43 6f  ;.  if( fts5IsCo
a800: 6e 74 65 6e 74 6c 65 73 73 28 28 46 74 73 35 54  ntentless((Fts5T
a810: 61 62 6c 65 2a 29 28 70 43 73 72 2d 3e 62 61 73  able*)(pCsr->bas
a820: 65 2e 70 56 74 61 62 29 29 20 29 7b 0a 20 20 20  e.pVtab)) ){.   
a830: 20 2a 70 7a 20 3d 20 30 3b 0a 20 20 20 20 2a 70   *pz = 0;.    *p
a840: 6e 20 3d 20 30 3b 0a 20 20 7d 65 6c 73 65 7b 0a  n = 0;.  }else{.
a850: 20 20 20 20 72 63 20 3d 20 66 74 73 35 53 65 65      rc = fts5See
a860: 6b 43 75 72 73 6f 72 28 70 43 73 72 29 3b 0a 20  kCursor(pCsr);. 
a870: 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
a880: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 2a 70  E_OK ){.      *p
a890: 7a 20 3d 20 28 63 6f 6e 73 74 20 63 68 61 72 2a  z = (const char*
a8a0: 29 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f  )sqlite3_column_
a8b0: 74 65 78 74 28 70 43 73 72 2d 3e 70 53 74 6d 74  text(pCsr->pStmt
a8c0: 2c 20 69 43 6f 6c 2b 31 29 3b 0a 20 20 20 20 20  , iCol+1);.     
a8d0: 20 2a 70 6e 20 3d 20 73 71 6c 69 74 65 33 5f 63   *pn = sqlite3_c
a8e0: 6f 6c 75 6d 6e 5f 62 79 74 65 73 28 70 43 73 72  olumn_bytes(pCsr
a8f0: 2d 3e 70 53 74 6d 74 2c 20 69 43 6f 6c 2b 31 29  ->pStmt, iCol+1)
a900: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65  ;.    }.  }.  re
a910: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74  turn rc;.}..stat
a920: 69 63 20 69 6e 74 20 66 74 73 35 41 70 69 43 6f  ic int fts5ApiCo
a930: 6c 75 6d 6e 53 69 7a 65 28 46 74 73 35 43 6f 6e  lumnSize(Fts5Con
a940: 74 65 78 74 20 2a 70 43 74 78 2c 20 69 6e 74 20  text *pCtx, int 
a950: 69 43 6f 6c 2c 20 69 6e 74 20 2a 70 6e 54 6f 6b  iCol, int *pnTok
a960: 65 6e 29 7b 0a 20 20 46 74 73 35 43 75 72 73 6f  en){.  Fts5Curso
a970: 72 20 2a 70 43 73 72 20 3d 20 28 46 74 73 35 43  r *pCsr = (Fts5C
a980: 75 72 73 6f 72 2a 29 70 43 74 78 3b 0a 20 20 46  ursor*)pCtx;.  F
a990: 74 73 35 54 61 62 6c 65 20 2a 70 54 61 62 20 3d  ts5Table *pTab =
a9a0: 20 28 46 74 73 35 54 61 62 6c 65 2a 29 28 70 43   (Fts5Table*)(pC
a9b0: 73 72 2d 3e 62 61 73 65 2e 70 56 74 61 62 29 3b  sr->base.pVtab);
a9c0: 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49  .  int rc = SQLI
a9d0: 54 45 5f 4f 4b 3b 0a 0a 20 20 69 66 28 20 43 73  TE_OK;..  if( Cs
a9e0: 72 46 6c 61 67 54 65 73 74 28 70 43 73 72 2c 20  rFlagTest(pCsr, 
a9f0: 46 54 53 35 43 53 52 5f 52 45 51 55 49 52 45 5f  FTS5CSR_REQUIRE_
aa00: 44 4f 43 53 49 5a 45 29 20 29 7b 0a 20 20 20 20  DOCSIZE) ){.    
aa10: 69 36 34 20 69 52 6f 77 69 64 20 3d 20 66 74 73  i64 iRowid = fts
aa20: 35 43 75 72 73 6f 72 52 6f 77 69 64 28 70 43 73  5CursorRowid(pCs
aa30: 72 29 3b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c  r);.    rc = sql
aa40: 69 74 65 33 46 74 73 35 53 74 6f 72 61 67 65 44  ite3Fts5StorageD
aa50: 6f 63 73 69 7a 65 28 70 54 61 62 2d 3e 70 53 74  ocsize(pTab->pSt
aa60: 6f 72 61 67 65 2c 20 69 52 6f 77 69 64 2c 20 70  orage, iRowid, p
aa70: 43 73 72 2d 3e 61 43 6f 6c 75 6d 6e 53 69 7a 65  Csr->aColumnSize
aa80: 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20 69 43 6f  );.  }.  if( iCo
aa90: 6c 3c 30 20 29 7b 0a 20 20 20 20 69 6e 74 20 69  l<0 ){.    int i
aaa0: 3b 0a 20 20 20 20 2a 70 6e 54 6f 6b 65 6e 20 3d  ;.    *pnToken =
aab0: 20 30 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b   0;.    for(i=0;
aac0: 20 69 3c 70 54 61 62 2d 3e 70 43 6f 6e 66 69 67   i<pTab->pConfig
aad0: 2d 3e 6e 43 6f 6c 3b 20 69 2b 2b 29 7b 0a 20 20  ->nCol; i++){.  
aae0: 20 20 20 20 2a 70 6e 54 6f 6b 65 6e 20 2b 3d 20      *pnToken += 
aaf0: 70 43 73 72 2d 3e 61 43 6f 6c 75 6d 6e 53 69 7a  pCsr->aColumnSiz
ab00: 65 5b 69 5d 3b 0a 20 20 20 20 7d 0a 20 20 7d 65  e[i];.    }.  }e
ab10: 6c 73 65 20 69 66 28 20 69 43 6f 6c 3c 70 54 61  lse if( iCol<pTa
ab20: 62 2d 3e 70 43 6f 6e 66 69 67 2d 3e 6e 43 6f 6c  b->pConfig->nCol
ab30: 20 29 7b 0a 20 20 20 20 2a 70 6e 54 6f 6b 65 6e   ){.    *pnToken
ab40: 20 3d 20 70 43 73 72 2d 3e 61 43 6f 6c 75 6d 6e   = pCsr->aColumn
ab50: 53 69 7a 65 5b 69 43 6f 6c 5d 3b 0a 20 20 7d 65  Size[iCol];.  }e
ab60: 6c 73 65 7b 0a 20 20 20 20 2a 70 6e 54 6f 6b 65  lse{.    *pnToke
ab70: 6e 20 3d 20 30 3b 0a 20 20 20 20 72 63 20 3d 20  n = 0;.    rc = 
ab80: 53 51 4c 49 54 45 5f 52 41 4e 47 45 3b 0a 20 20  SQLITE_RANGE;.  
ab90: 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  }.  return rc;.}
aba0: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73  ..static int fts
abb0: 35 41 70 69 53 65 74 41 75 78 64 61 74 61 28 0a  5ApiSetAuxdata(.
abc0: 20 20 46 74 73 35 43 6f 6e 74 65 78 74 20 2a 70    Fts5Context *p
abd0: 43 74 78 2c 20 20 20 20 20 20 20 20 20 20 20 20  Ctx,            
abe0: 20 20 2f 2a 20 46 74 73 35 20 63 6f 6e 74 65 78    /* Fts5 contex
abf0: 74 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 50 74  t */.  void *pPt
ac00: 72 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  r,              
ac10: 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65         /* Pointe
ac20: 72 20 74 6f 20 73 61 76 65 20 61 73 20 61 75 78  r to save as aux
ac30: 64 61 74 61 20 2a 2f 0a 20 20 76 6f 69 64 28 2a  data */.  void(*
ac40: 78 44 65 6c 65 74 65 29 28 76 6f 69 64 2a 29 20  xDelete)(void*) 
ac50: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 65 73            /* Des
ac60: 74 72 75 63 74 6f 72 20 66 6f 72 20 70 50 74 72  tructor for pPtr
ac70: 20 28 6f 72 20 4e 55 4c 4c 29 20 2a 2f 0a 29 7b   (or NULL) */.){
ac80: 0a 20 20 46 74 73 35 43 75 72 73 6f 72 20 2a 70  .  Fts5Cursor *p
ac90: 43 73 72 20 3d 20 28 46 74 73 35 43 75 72 73 6f  Csr = (Fts5Curso
aca0: 72 2a 29 70 43 74 78 3b 0a 20 20 46 74 73 35 41  r*)pCtx;.  Fts5A
acb0: 75 78 64 61 74 61 20 2a 70 44 61 74 61 3b 0a 0a  uxdata *pData;..
acc0: 20 20 66 6f 72 28 70 44 61 74 61 3d 70 43 73 72    for(pData=pCsr
acd0: 2d 3e 70 41 75 78 64 61 74 61 3b 20 70 44 61 74  ->pAuxdata; pDat
ace0: 61 3b 20 70 44 61 74 61 3d 70 44 61 74 61 2d 3e  a; pData=pData->
acf0: 70 4e 65 78 74 29 7b 0a 20 20 20 20 69 66 28 20  pNext){.    if( 
ad00: 70 44 61 74 61 2d 3e 70 41 75 78 3d 3d 70 43 73  pData->pAux==pCs
ad10: 72 2d 3e 70 41 75 78 20 29 20 62 72 65 61 6b 3b  r->pAux ) break;
ad20: 0a 20 20 7d 0a 0a 20 20 69 66 28 20 70 44 61 74  .  }..  if( pDat
ad30: 61 20 29 7b 0a 20 20 20 20 69 66 28 20 70 44 61  a ){.    if( pDa
ad40: 74 61 2d 3e 78 44 65 6c 65 74 65 20 29 7b 0a 20  ta->xDelete ){. 
ad50: 20 20 20 20 20 70 44 61 74 61 2d 3e 78 44 65 6c       pData->xDel
ad60: 65 74 65 28 70 44 61 74 61 2d 3e 70 50 74 72 29  ete(pData->pPtr)
ad70: 3b 0a 20 20 20 20 7d 0a 20 20 7d 65 6c 73 65 7b  ;.    }.  }else{
ad80: 0a 20 20 20 20 70 44 61 74 61 20 3d 20 28 46 74  .    pData = (Ft
ad90: 73 35 41 75 78 64 61 74 61 2a 29 73 71 6c 69 74  s5Auxdata*)sqlit
ada0: 65 33 5f 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f 66  e3_malloc(sizeof
adb0: 28 46 74 73 35 41 75 78 64 61 74 61 29 29 3b 0a  (Fts5Auxdata));.
adc0: 20 20 20 20 69 66 28 20 70 44 61 74 61 3d 3d 30      if( pData==0
add0: 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 78 44   ){.      if( xD
ade0: 65 6c 65 74 65 20 29 20 78 44 65 6c 65 74 65 28  elete ) xDelete(
adf0: 70 50 74 72 29 3b 0a 20 20 20 20 20 20 72 65 74  pPtr);.      ret
ae00: 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  urn SQLITE_NOMEM
ae10: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 6d 65 6d 73  ;.    }.    mems
ae20: 65 74 28 70 44 61 74 61 2c 20 30 2c 20 73 69 7a  et(pData, 0, siz
ae30: 65 6f 66 28 46 74 73 35 41 75 78 64 61 74 61 29  eof(Fts5Auxdata)
ae40: 29 3b 0a 20 20 20 20 70 44 61 74 61 2d 3e 70 41  );.    pData->pA
ae50: 75 78 20 3d 20 70 43 73 72 2d 3e 70 41 75 78 3b  ux = pCsr->pAux;
ae60: 0a 20 20 20 20 70 44 61 74 61 2d 3e 70 4e 65 78  .    pData->pNex
ae70: 74 20 3d 20 70 43 73 72 2d 3e 70 41 75 78 64 61  t = pCsr->pAuxda
ae80: 74 61 3b 0a 20 20 20 20 70 43 73 72 2d 3e 70 41  ta;.    pCsr->pA
ae90: 75 78 64 61 74 61 20 3d 20 70 44 61 74 61 3b 0a  uxdata = pData;.
aea0: 20 20 7d 0a 0a 20 20 70 44 61 74 61 2d 3e 78 44    }..  pData->xD
aeb0: 65 6c 65 74 65 20 3d 20 78 44 65 6c 65 74 65 3b  elete = xDelete;
aec0: 0a 20 20 70 44 61 74 61 2d 3e 70 50 74 72 20 3d  .  pData->pPtr =
aed0: 20 70 50 74 72 3b 0a 20 20 72 65 74 75 72 6e 20   pPtr;.  return 
aee0: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 73 74  SQLITE_OK;.}..st
aef0: 61 74 69 63 20 76 6f 69 64 20 2a 66 74 73 35 41  atic void *fts5A
af00: 70 69 47 65 74 41 75 78 64 61 74 61 28 46 74 73  piGetAuxdata(Fts
af10: 35 43 6f 6e 74 65 78 74 20 2a 70 43 74 78 2c 20  5Context *pCtx, 
af20: 69 6e 74 20 62 43 6c 65 61 72 29 7b 0a 20 20 46  int bClear){.  F
af30: 74 73 35 43 75 72 73 6f 72 20 2a 70 43 73 72 20  ts5Cursor *pCsr 
af40: 3d 20 28 46 74 73 35 43 75 72 73 6f 72 2a 29 70  = (Fts5Cursor*)p
af50: 43 74 78 3b 0a 20 20 46 74 73 35 41 75 78 64 61  Ctx;.  Fts5Auxda
af60: 74 61 20 2a 70 44 61 74 61 3b 0a 20 20 76 6f 69  ta *pData;.  voi
af70: 64 20 2a 70 52 65 74 20 3d 20 30 3b 0a 0a 20 20  d *pRet = 0;..  
af80: 66 6f 72 28 70 44 61 74 61 3d 70 43 73 72 2d 3e  for(pData=pCsr->
af90: 70 41 75 78 64 61 74 61 3b 20 70 44 61 74 61 3b  pAuxdata; pData;
afa0: 20 70 44 61 74 61 3d 70 44 61 74 61 2d 3e 70 4e   pData=pData->pN
afb0: 65 78 74 29 7b 0a 20 20 20 20 69 66 28 20 70 44  ext){.    if( pD
afc0: 61 74 61 2d 3e 70 41 75 78 3d 3d 70 43 73 72 2d  ata->pAux==pCsr-
afd0: 3e 70 41 75 78 20 29 20 62 72 65 61 6b 3b 0a 20  >pAux ) break;. 
afe0: 20 7d 0a 0a 20 20 69 66 28 20 70 44 61 74 61 20   }..  if( pData 
aff0: 29 7b 0a 20 20 20 20 70 52 65 74 20 3d 20 70 44  ){.    pRet = pD
b000: 61 74 61 2d 3e 70 50 74 72 3b 0a 20 20 20 20 69  ata->pPtr;.    i
b010: 66 28 20 62 43 6c 65 61 72 20 29 7b 0a 20 20 20  f( bClear ){.   
b020: 20 20 20 70 44 61 74 61 2d 3e 70 50 74 72 20 3d     pData->pPtr =
b030: 20 30 3b 0a 20 20 20 20 20 20 70 44 61 74 61 2d   0;.      pData-
b040: 3e 78 44 65 6c 65 74 65 20 3d 20 30 3b 0a 20 20  >xDelete = 0;.  
b050: 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72    }.  }..  retur
b060: 6e 20 70 52 65 74 3b 0a 7d 0a 0a 73 74 61 74 69  n pRet;.}..stati
b070: 63 20 69 6e 74 20 66 74 73 35 41 70 69 51 75 65  c int fts5ApiQue
b080: 72 79 50 68 72 61 73 65 28 46 74 73 35 43 6f 6e  ryPhrase(Fts5Con
b090: 74 65 78 74 2a 2c 20 69 6e 74 2c 20 76 6f 69 64  text*, int, void
b0a0: 2a 2c 20 0a 20 20 20 20 69 6e 74 28 2a 29 28 63  *, .    int(*)(c
b0b0: 6f 6e 73 74 20 46 74 73 35 45 78 74 65 6e 73 69  onst Fts5Extensi
b0c0: 6f 6e 41 70 69 2a 2c 20 46 74 73 35 43 6f 6e 74  onApi*, Fts5Cont
b0d0: 65 78 74 2a 2c 20 76 6f 69 64 2a 29 0a 29 3b 0a  ext*, void*).);.
b0e0: 0a 73 74 61 74 69 63 20 63 6f 6e 73 74 20 46 74  .static const Ft
b0f0: 73 35 45 78 74 65 6e 73 69 6f 6e 41 70 69 20 73  s5ExtensionApi s
b100: 46 74 73 35 41 70 69 20 3d 20 7b 0a 20 20 31 2c  Fts5Api = {.  1,
b110: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b120: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 69              /* i
b130: 56 65 72 73 69 6f 6e 20 2a 2f 0a 20 20 66 74 73  Version */.  fts
b140: 35 41 70 69 55 73 65 72 44 61 74 61 2c 0a 20 20  5ApiUserData,.  
b150: 66 74 73 35 41 70 69 43 6f 6c 75 6d 6e 43 6f 75  fts5ApiColumnCou
b160: 6e 74 2c 0a 20 20 66 74 73 35 41 70 69 52 6f 77  nt,.  fts5ApiRow
b170: 43 6f 75 6e 74 2c 0a 20 20 66 74 73 35 41 70 69  Count,.  fts5Api
b180: 43 6f 6c 75 6d 6e 54 6f 74 61 6c 53 69 7a 65 2c  ColumnTotalSize,
b190: 0a 20 20 66 74 73 35 41 70 69 54 6f 6b 65 6e 69  .  fts5ApiTokeni
b1a0: 7a 65 2c 0a 20 20 66 74 73 35 41 70 69 50 68 72  ze,.  fts5ApiPhr
b1b0: 61 73 65 43 6f 75 6e 74 2c 0a 20 20 66 74 73 35  aseCount,.  fts5
b1c0: 41 70 69 50 68 72 61 73 65 53 69 7a 65 2c 0a 20  ApiPhraseSize,. 
b1d0: 20 66 74 73 35 41 70 69 49 6e 73 74 43 6f 75 6e   fts5ApiInstCoun
b1e0: 74 2c 0a 20 20 66 74 73 35 41 70 69 49 6e 73 74  t,.  fts5ApiInst
b1f0: 2c 0a 20 20 66 74 73 35 41 70 69 52 6f 77 69 64  ,.  fts5ApiRowid
b200: 2c 0a 20 20 66 74 73 35 41 70 69 43 6f 6c 75 6d  ,.  fts5ApiColum
b210: 6e 54 65 78 74 2c 0a 20 20 66 74 73 35 41 70 69  nText,.  fts5Api
b220: 43 6f 6c 75 6d 6e 53 69 7a 65 2c 0a 20 20 66 74  ColumnSize,.  ft
b230: 73 35 41 70 69 51 75 65 72 79 50 68 72 61 73 65  s5ApiQueryPhrase
b240: 2c 0a 20 20 66 74 73 35 41 70 69 53 65 74 41 75  ,.  fts5ApiSetAu
b250: 78 64 61 74 61 2c 0a 20 20 66 74 73 35 41 70 69  xdata,.  fts5Api
b260: 47 65 74 41 75 78 64 61 74 61 2c 0a 7d 3b 0a 0a  GetAuxdata,.};..
b270: 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74  ./*.** Implement
b280: 61 74 69 6f 6e 20 6f 66 20 41 50 49 20 66 75 6e  ation of API fun
b290: 63 74 69 6f 6e 20 78 51 75 65 72 79 50 68 72 61  ction xQueryPhra
b2a0: 73 65 28 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  se()..*/.static 
b2b0: 69 6e 74 20 66 74 73 35 41 70 69 51 75 65 72 79  int fts5ApiQuery
b2c0: 50 68 72 61 73 65 28 0a 20 20 46 74 73 35 43 6f  Phrase(.  Fts5Co
b2d0: 6e 74 65 78 74 20 2a 70 43 74 78 2c 20 0a 20 20  ntext *pCtx, .  
b2e0: 69 6e 74 20 69 50 68 72 61 73 65 2c 20 0a 20 20  int iPhrase, .  
b2f0: 76 6f 69 64 20 2a 70 55 73 65 72 44 61 74 61 2c  void *pUserData,
b300: 0a 20 20 69 6e 74 28 2a 78 43 61 6c 6c 62 61 63  .  int(*xCallbac
b310: 6b 29 28 63 6f 6e 73 74 20 46 74 73 35 45 78 74  k)(const Fts5Ext
b320: 65 6e 73 69 6f 6e 41 70 69 2a 2c 20 46 74 73 35  ensionApi*, Fts5
b330: 43 6f 6e 74 65 78 74 2a 2c 20 76 6f 69 64 2a 29  Context*, void*)
b340: 0a 29 7b 0a 20 20 46 74 73 35 43 75 72 73 6f 72  .){.  Fts5Cursor
b350: 20 2a 70 43 73 72 20 3d 20 28 46 74 73 35 43 75   *pCsr = (Fts5Cu
b360: 72 73 6f 72 2a 29 70 43 74 78 3b 0a 20 20 46 74  rsor*)pCtx;.  Ft
b370: 73 35 54 61 62 6c 65 20 2a 70 54 61 62 20 3d 20  s5Table *pTab = 
b380: 28 46 74 73 35 54 61 62 6c 65 2a 29 28 70 43 73  (Fts5Table*)(pCs
b390: 72 2d 3e 62 61 73 65 2e 70 56 74 61 62 29 3b 0a  r->base.pVtab);.
b3a0: 20 20 69 6e 74 20 72 63 3b 0a 20 20 46 74 73 35    int rc;.  Fts5
b3b0: 43 75 72 73 6f 72 20 2a 70 4e 65 77 20 3d 20 30  Cursor *pNew = 0
b3c0: 3b 0a 0a 20 20 72 63 20 3d 20 66 74 73 35 4f 70  ;..  rc = fts5Op
b3d0: 65 6e 4d 65 74 68 6f 64 28 70 43 73 72 2d 3e 62  enMethod(pCsr->b
b3e0: 61 73 65 2e 70 56 74 61 62 2c 20 28 73 71 6c 69  ase.pVtab, (sqli
b3f0: 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 2a  te3_vtab_cursor*
b400: 2a 29 26 70 4e 65 77 29 3b 0a 20 20 69 66 28 20  *)&pNew);.  if( 
b410: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
b420: 0a 20 20 20 20 46 74 73 35 43 6f 6e 66 69 67 20  .    Fts5Config 
b430: 2a 70 43 6f 6e 66 20 3d 20 70 54 61 62 2d 3e 70  *pConf = pTab->p
b440: 43 6f 6e 66 69 67 3b 0a 20 20 20 20 70 4e 65 77  Config;.    pNew
b450: 2d 3e 69 64 78 4e 75 6d 20 3d 20 46 54 53 35 5f  ->idxNum = FTS5_
b460: 50 4c 41 4e 5f 4d 41 54 43 48 3b 0a 20 20 20 20  PLAN_MATCH;.    
b470: 70 4e 65 77 2d 3e 62 61 73 65 2e 70 56 74 61 62  pNew->base.pVtab
b480: 20 3d 20 28 73 71 6c 69 74 65 33 5f 76 74 61 62   = (sqlite3_vtab
b490: 2a 29 70 54 61 62 3b 0a 20 20 20 20 72 63 20 3d  *)pTab;.    rc =
b4a0: 20 73 71 6c 69 74 65 33 46 74 73 35 45 78 70 72   sqlite3Fts5Expr
b4b0: 50 68 72 61 73 65 45 78 70 72 28 70 43 6f 6e 66  PhraseExpr(pConf
b4c0: 2c 20 70 43 73 72 2d 3e 70 45 78 70 72 2c 20 69  , pCsr->pExpr, i
b4d0: 50 68 72 61 73 65 2c 20 26 70 4e 65 77 2d 3e 70  Phrase, &pNew->p
b4e0: 45 78 70 72 29 3b 0a 20 20 7d 0a 0a 20 20 69 66  Expr);.  }..  if
b4f0: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
b500: 29 7b 0a 20 20 20 20 66 6f 72 28 72 63 20 3d 20  ){.    for(rc = 
b510: 66 74 73 35 43 75 72 73 6f 72 46 69 72 73 74 28  fts5CursorFirst(
b520: 70 54 61 62 2c 20 70 4e 65 77 2c 20 30 29 3b 0a  pTab, pNew, 0);.
b530: 20 20 20 20 20 20 20 20 72 63 3d 3d 53 51 4c 49          rc==SQLI
b540: 54 45 5f 4f 4b 20 26 26 20 43 73 72 46 6c 61 67  TE_OK && CsrFlag
b550: 54 65 73 74 28 70 4e 65 77 2c 20 46 54 53 35 43  Test(pNew, FTS5C
b560: 53 52 5f 45 4f 46 29 3d 3d 30 3b 0a 20 20 20 20  SR_EOF)==0;.    
b570: 20 20 20 20 72 63 20 3d 20 66 74 73 35 4e 65 78      rc = fts5Nex
b580: 74 4d 65 74 68 6f 64 28 28 73 71 6c 69 74 65 33  tMethod((sqlite3
b590: 5f 76 74 61 62 5f 63 75 72 73 6f 72 2a 29 70 4e  _vtab_cursor*)pN
b5a0: 65 77 29 0a 20 20 20 20 29 7b 0a 20 20 20 20 20  ew).    ){.     
b5b0: 20 72 63 20 3d 20 78 43 61 6c 6c 62 61 63 6b 28   rc = xCallback(
b5c0: 26 73 46 74 73 35 41 70 69 2c 20 28 46 74 73 35  &sFts5Api, (Fts5
b5d0: 43 6f 6e 74 65 78 74 2a 29 70 4e 65 77 2c 20 70  Context*)pNew, p
b5e0: 55 73 65 72 44 61 74 61 29 3b 0a 20 20 20 20 20  UserData);.     
b5f0: 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
b600: 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 69 66  OK ){.        if
b610: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 44 4f 4e  ( rc==SQLITE_DON
b620: 45 20 29 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  E ) rc = SQLITE_
b630: 4f 4b 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61  OK;.        brea
b640: 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  k;.      }.    }
b650: 0a 20 20 7d 0a 0a 20 20 66 74 73 35 43 6c 6f 73  .  }..  fts5Clos
b660: 65 4d 65 74 68 6f 64 28 28 73 71 6c 69 74 65 33  eMethod((sqlite3
b670: 5f 76 74 61 62 5f 63 75 72 73 6f 72 2a 29 70 4e  _vtab_cursor*)pN
b680: 65 77 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63  ew);.  return rc
b690: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64  ;.}..static void
b6a0: 20 66 74 73 35 41 70 69 49 6e 76 6f 6b 65 28 0a   fts5ApiInvoke(.
b6b0: 20 20 46 74 73 35 41 75 78 69 6c 69 61 72 79 20    Fts5Auxiliary 
b6c0: 2a 70 41 75 78 2c 0a 20 20 46 74 73 35 43 75 72  *pAux,.  Fts5Cur
b6d0: 73 6f 72 20 2a 70 43 73 72 2c 0a 20 20 73 71 6c  sor *pCsr,.  sql
b6e0: 69 74 65 33 5f 63 6f 6e 74 65 78 74 20 2a 63 6f  ite3_context *co
b6f0: 6e 74 65 78 74 2c 0a 20 20 69 6e 74 20 61 72 67  ntext,.  int arg
b700: 63 2c 0a 20 20 73 71 6c 69 74 65 33 5f 76 61 6c  c,.  sqlite3_val
b710: 75 65 20 2a 2a 61 72 67 76 0a 29 7b 0a 20 20 61  ue **argv.){.  a
b720: 73 73 65 72 74 28 20 70 43 73 72 2d 3e 70 41 75  ssert( pCsr->pAu
b730: 78 3d 3d 30 20 29 3b 0a 20 20 70 43 73 72 2d 3e  x==0 );.  pCsr->
b740: 70 41 75 78 20 3d 20 70 41 75 78 3b 0a 20 20 70  pAux = pAux;.  p
b750: 41 75 78 2d 3e 78 46 75 6e 63 28 26 73 46 74 73  Aux->xFunc(&sFts
b760: 35 41 70 69 2c 20 28 46 74 73 35 43 6f 6e 74 65  5Api, (Fts5Conte
b770: 78 74 2a 29 70 43 73 72 2c 20 63 6f 6e 74 65 78  xt*)pCsr, contex
b780: 74 2c 20 61 72 67 63 2c 20 61 72 67 76 29 3b 0a  t, argc, argv);.
b790: 20 20 70 43 73 72 2d 3e 70 41 75 78 20 3d 20 30    pCsr->pAux = 0
b7a0: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64  ;.}..static void
b7b0: 20 66 74 73 35 41 70 69 43 61 6c 6c 62 61 63 6b   fts5ApiCallback
b7c0: 28 0a 20 20 73 71 6c 69 74 65 33 5f 63 6f 6e 74  (.  sqlite3_cont
b7d0: 65 78 74 20 2a 63 6f 6e 74 65 78 74 2c 0a 20 20  ext *context,.  
b7e0: 69 6e 74 20 61 72 67 63 2c 0a 20 20 73 71 6c 69  int argc,.  sqli
b7f0: 74 65 33 5f 76 61 6c 75 65 20 2a 2a 61 72 67 76  te3_value **argv
b800: 0a 29 7b 0a 0a 20 20 46 74 73 35 41 75 78 69 6c  .){..  Fts5Auxil
b810: 69 61 72 79 20 2a 70 41 75 78 3b 0a 20 20 46 74  iary *pAux;.  Ft
b820: 73 35 43 75 72 73 6f 72 20 2a 70 43 73 72 3b 0a  s5Cursor *pCsr;.
b830: 20 20 69 36 34 20 69 43 73 72 49 64 3b 0a 0a 20    i64 iCsrId;.. 
b840: 20 61 73 73 65 72 74 28 20 61 72 67 63 3e 3d 31   assert( argc>=1
b850: 20 29 3b 0a 20 20 70 41 75 78 20 3d 20 28 46 74   );.  pAux = (Ft
b860: 73 35 41 75 78 69 6c 69 61 72 79 2a 29 73 71 6c  s5Auxiliary*)sql
b870: 69 74 65 33 5f 75 73 65 72 5f 64 61 74 61 28 63  ite3_user_data(c
b880: 6f 6e 74 65 78 74 29 3b 0a 20 20 69 43 73 72 49  ontext);.  iCsrI
b890: 64 20 3d 20 73 71 6c 69 74 65 33 5f 76 61 6c 75  d = sqlite3_valu
b8a0: 65 5f 69 6e 74 36 34 28 61 72 67 76 5b 30 5d 29  e_int64(argv[0])
b8b0: 3b 0a 0a 20 20 66 6f 72 28 70 43 73 72 3d 70 41  ;..  for(pCsr=pA
b8c0: 75 78 2d 3e 70 47 6c 6f 62 61 6c 2d 3e 70 43 73  ux->pGlobal->pCs
b8d0: 72 3b 20 70 43 73 72 3b 20 70 43 73 72 3d 70 43  r; pCsr; pCsr=pC
b8e0: 73 72 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20  sr->pNext){.    
b8f0: 69 66 28 20 70 43 73 72 2d 3e 69 43 73 72 49 64  if( pCsr->iCsrId
b900: 3d 3d 69 43 73 72 49 64 20 29 20 62 72 65 61 6b  ==iCsrId ) break
b910: 3b 0a 20 20 7d 0a 20 20 69 66 28 20 70 43 73 72  ;.  }.  if( pCsr
b920: 3d 3d 30 20 29 7b 0a 20 20 20 20 63 68 61 72 20  ==0 ){.    char 
b930: 2a 7a 45 72 72 20 3d 20 73 71 6c 69 74 65 33 5f  *zErr = sqlite3_
b940: 6d 70 72 69 6e 74 66 28 22 6e 6f 20 73 75 63 68  mprintf("no such
b950: 20 63 75 72 73 6f 72 3a 20 25 6c 6c 64 22 2c 20   cursor: %lld", 
b960: 69 43 73 72 49 64 29 3b 0a 20 20 20 20 73 71 6c  iCsrId);.    sql
b970: 69 74 65 33 5f 72 65 73 75 6c 74 5f 65 72 72 6f  ite3_result_erro
b980: 72 28 63 6f 6e 74 65 78 74 2c 20 7a 45 72 72 2c  r(context, zErr,
b990: 20 2d 31 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20   -1);.  }else{. 
b9a0: 20 20 20 66 74 73 35 41 70 69 49 6e 76 6f 6b 65     fts5ApiInvoke
b9b0: 28 70 41 75 78 2c 20 70 43 73 72 2c 20 63 6f 6e  (pAux, pCsr, con
b9c0: 74 65 78 74 2c 20 61 72 67 63 2d 31 2c 20 26 61  text, argc-1, &a
b9d0: 72 67 76 5b 31 5d 29 3b 0a 20 20 7d 0a 7d 0a 0a  rgv[1]);.  }.}..
b9e0: 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 61 20 22  /*.** Return a "
b9f0: 70 6f 73 69 74 69 6f 6e 2d 6c 69 73 74 20 62 6c  position-list bl
ba00: 6f 62 22 20 63 6f 72 72 65 73 70 6f 6e 64 69 6e  ob" correspondin
ba10: 67 20 74 6f 20 74 68 65 20 63 75 72 72 65 6e 74  g to the current
ba20: 20 70 6f 73 69 74 69 6f 6e 20 6f 66 0a 2a 2a 20   position of.** 
ba30: 63 75 72 73 6f 72 20 70 43 73 72 20 76 69 61 20  cursor pCsr via 
ba40: 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 62  sqlite3_result_b
ba50: 6c 6f 62 28 29 2e 20 41 20 70 6f 73 69 74 69 6f  lob(). A positio
ba60: 6e 2d 6c 69 73 74 20 62 6c 6f 62 20 63 6f 6e 74  n-list blob cont
ba70: 61 69 6e 73 0a 2a 2a 20 74 68 65 20 63 75 72 72  ains.** the curr
ba80: 65 6e 74 20 70 6f 73 69 74 69 6f 6e 2d 6c 69 73  ent position-lis
ba90: 74 20 66 6f 72 20 65 61 63 68 20 70 68 72 61 73  t for each phras
baa0: 65 20 69 6e 20 74 68 65 20 71 75 65 72 79 20 61  e in the query a
bab0: 73 73 6f 63 69 61 74 65 64 20 77 69 74 68 0a 2a  ssociated with.*
bac0: 2a 20 63 75 72 73 6f 72 20 70 43 73 72 2e 0a 2a  * cursor pCsr..*
bad0: 2a 0a 2a 2a 20 41 20 70 6f 73 69 74 69 6f 6e 2d  *.** A position-
bae0: 6c 69 73 74 20 62 6c 6f 62 20 62 65 67 69 6e 73  list blob begins
baf0: 20 77 69 74 68 20 28 6e 50 68 72 61 73 65 2d 31   with (nPhrase-1
bb00: 29 20 76 61 72 69 6e 74 73 2c 20 77 68 65 72 65  ) varints, where
bb10: 20 6e 50 68 72 61 73 65 20 69 73 0a 2a 2a 20 74   nPhrase is.** t
bb20: 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 70 68 72  he number of phr
bb30: 61 73 65 73 20 69 6e 20 74 68 65 20 71 75 65 72  ases in the quer
bb40: 79 2e 20 46 6f 6c 6c 6f 77 69 6e 67 20 74 68 65  y. Following the
bb50: 20 76 61 72 69 6e 74 73 20 61 72 65 20 74 68 65   varints are the
bb60: 0a 2a 2a 20 63 6f 6e 63 61 74 65 6e 61 74 65 64  .** concatenated
bb70: 20 70 6f 73 69 74 69 6f 6e 20 6c 69 73 74 73 20   position lists 
bb80: 66 6f 72 20 65 61 63 68 20 70 68 72 61 73 65 2c  for each phrase,
bb90: 20 69 6e 20 6f 72 64 65 72 2e 0a 2a 2a 0a 2a 2a   in order..**.**
bba0: 20 54 68 65 20 66 69 72 73 74 20 76 61 72 69 6e   The first varin
bbb0: 74 20 28 69 66 20 69 74 20 65 78 69 73 74 73 29  t (if it exists)
bbc0: 20 63 6f 6e 74 61 69 6e 73 20 74 68 65 20 73 69   contains the si
bbd0: 7a 65 20 6f 66 20 74 68 65 20 70 6f 73 69 74 69  ze of the positi
bbe0: 6f 6e 20 6c 69 73 74 0a 2a 2a 20 66 6f 72 20 70  on list.** for p
bbf0: 68 72 61 73 65 20 30 2e 20 54 68 65 20 73 65 63  hrase 0. The sec
bc00: 6f 6e 64 20 28 73 61 6d 65 20 64 69 73 63 6c 61  ond (same discla
bc10: 69 6d 65 72 29 20 63 6f 6e 74 61 69 6e 73 20 74  imer) contains t
bc20: 68 65 20 73 69 7a 65 20 6f 66 20 70 6f 73 69 74  he size of posit
bc30: 69 6f 6e 0a 2a 2a 20 6c 69 73 74 20 31 2e 20 41  ion.** list 1. A
bc40: 6e 64 20 73 6f 20 6f 6e 2e 20 54 68 65 72 65 20  nd so on. There 
bc50: 69 73 20 6e 6f 20 73 69 7a 65 20 66 69 65 6c 64  is no size field
bc60: 20 66 6f 72 20 74 68 65 20 66 69 6e 61 6c 20 70   for the final p
bc70: 6f 73 69 74 69 6f 6e 20 6c 69 73 74 2c 0a 2a 2a  osition list,.**
bc80: 20 61 73 20 69 74 20 63 61 6e 20 62 65 20 64 65   as it can be de
bc90: 72 69 76 65 64 20 66 72 6f 6d 20 74 68 65 20 74  rived from the t
bca0: 6f 74 61 6c 20 73 69 7a 65 20 6f 66 20 74 68 65  otal size of the
bcb0: 20 62 6c 6f 62 2e 0a 2a 2f 0a 73 74 61 74 69 63   blob..*/.static
bcc0: 20 69 6e 74 20 66 74 73 35 50 6f 73 6c 69 73 74   int fts5Poslist
bcd0: 42 6c 6f 62 28 73 71 6c 69 74 65 33 5f 63 6f 6e  Blob(sqlite3_con
bce0: 74 65 78 74 20 2a 70 43 74 78 2c 20 46 74 73 35  text *pCtx, Fts5
bcf0: 43 75 72 73 6f 72 20 2a 70 43 73 72 29 7b 0a 20  Cursor *pCsr){. 
bd00: 20 69 6e 74 20 69 3b 0a 20 20 69 6e 74 20 72 63   int i;.  int rc
bd10: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20   = SQLITE_OK;.  
bd20: 69 6e 74 20 6e 50 68 72 61 73 65 20 3d 20 73 71  int nPhrase = sq
bd30: 6c 69 74 65 33 46 74 73 35 45 78 70 72 50 68 72  lite3Fts5ExprPhr
bd40: 61 73 65 43 6f 75 6e 74 28 70 43 73 72 2d 3e 70  aseCount(pCsr->p
bd50: 45 78 70 72 29 3b 0a 20 20 46 74 73 35 42 75 66  Expr);.  Fts5Buf
bd60: 66 65 72 20 76 61 6c 3b 0a 0a 20 20 6d 65 6d 73  fer val;..  mems
bd70: 65 74 28 26 76 61 6c 2c 20 30 2c 20 73 69 7a 65  et(&val, 0, size
bd80: 6f 66 28 46 74 73 35 42 75 66 66 65 72 29 29 3b  of(Fts5Buffer));
bd90: 0a 0a 20 20 2f 2a 20 41 70 70 65 6e 64 20 74 68  ..  /* Append th
bda0: 65 20 76 61 72 69 6e 74 73 20 2a 2f 0a 20 20 66  e varints */.  f
bdb0: 6f 72 28 69 3d 30 3b 20 69 3c 28 6e 50 68 72 61  or(i=0; i<(nPhra
bdc0: 73 65 2d 31 29 3b 20 69 2b 2b 29 7b 0a 20 20 20  se-1); i++){.   
bdd0: 20 63 6f 6e 73 74 20 75 38 20 2a 64 75 6d 6d 79   const u8 *dummy
bde0: 3b 0a 20 20 20 20 69 6e 74 20 6e 42 79 74 65 20  ;.    int nByte 
bdf0: 3d 20 73 71 6c 69 74 65 33 46 74 73 35 45 78 70  = sqlite3Fts5Exp
be00: 72 50 6f 73 6c 69 73 74 28 70 43 73 72 2d 3e 70  rPoslist(pCsr->p
be10: 45 78 70 72 2c 20 69 2c 20 26 64 75 6d 6d 79 29  Expr, i, &dummy)
be20: 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 46 74 73  ;.    sqlite3Fts
be30: 35 42 75 66 66 65 72 41 70 70 65 6e 64 56 61 72  5BufferAppendVar
be40: 69 6e 74 28 26 72 63 2c 20 26 76 61 6c 2c 20 6e  int(&rc, &val, n
be50: 42 79 74 65 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a  Byte);.  }..  /*
be60: 20 41 70 70 65 6e 64 20 74 68 65 20 70 6f 73 69   Append the posi
be70: 74 69 6f 6e 20 6c 69 73 74 73 20 2a 2f 0a 20 20  tion lists */.  
be80: 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 50 68 72 61  for(i=0; i<nPhra
be90: 73 65 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 63 6f  se; i++){.    co
bea0: 6e 73 74 20 75 38 20 2a 70 50 6f 73 6c 69 73 74  nst u8 *pPoslist
beb0: 3b 0a 20 20 20 20 69 6e 74 20 6e 50 6f 73 6c 69  ;.    int nPosli
bec0: 73 74 3b 0a 20 20 20 20 6e 50 6f 73 6c 69 73 74  st;.    nPoslist
bed0: 20 3d 20 73 71 6c 69 74 65 33 46 74 73 35 45 78   = sqlite3Fts5Ex
bee0: 70 72 50 6f 73 6c 69 73 74 28 70 43 73 72 2d 3e  prPoslist(pCsr->
bef0: 70 45 78 70 72 2c 20 69 2c 20 26 70 50 6f 73 6c  pExpr, i, &pPosl
bf00: 69 73 74 29 3b 0a 20 20 20 20 73 71 6c 69 74 65  ist);.    sqlite
bf10: 33 46 74 73 35 42 75 66 66 65 72 41 70 70 65 6e  3Fts5BufferAppen
bf20: 64 42 6c 6f 62 28 26 72 63 2c 20 26 76 61 6c 2c  dBlob(&rc, &val,
bf30: 20 6e 50 6f 73 6c 69 73 74 2c 20 70 50 6f 73 6c   nPoslist, pPosl
bf40: 69 73 74 29 3b 0a 20 20 7d 0a 0a 20 20 73 71 6c  ist);.  }..  sql
bf50: 69 74 65 33 5f 72 65 73 75 6c 74 5f 62 6c 6f 62  ite3_result_blob
bf60: 28 70 43 74 78 2c 20 76 61 6c 2e 70 2c 20 76 61  (pCtx, val.p, va
bf70: 6c 2e 6e 2c 20 73 71 6c 69 74 65 33 5f 66 72 65  l.n, sqlite3_fre
bf80: 65 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b  e);.  return rc;
bf90: 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 54 68 69 73 20  .}../* .** This 
bfa0: 69 73 20 74 68 65 20 78 43 6f 6c 75 6d 6e 20 6d  is the xColumn m
bfb0: 65 74 68 6f 64 2c 20 63 61 6c 6c 65 64 20 62 79  ethod, called by
bfc0: 20 53 51 4c 69 74 65 20 74 6f 20 72 65 71 75 65   SQLite to reque
bfd0: 73 74 20 61 20 76 61 6c 75 65 20 66 72 6f 6d 0a  st a value from.
bfe0: 2a 2a 20 74 68 65 20 72 6f 77 20 74 68 61 74 20  ** the row that 
bff0: 74 68 65 20 73 75 70 70 6c 69 65 64 20 63 75 72  the supplied cur
c000: 73 6f 72 20 63 75 72 72 65 6e 74 6c 79 20 70 6f  sor currently po
c010: 69 6e 74 73 20 74 6f 2e 0a 2a 2f 0a 73 74 61 74  ints to..*/.stat
c020: 69 63 20 69 6e 74 20 66 74 73 35 43 6f 6c 75 6d  ic int fts5Colum
c030: 6e 4d 65 74 68 6f 64 28 0a 20 20 73 71 6c 69 74  nMethod(.  sqlit
c040: 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a  e3_vtab_cursor *
c050: 70 43 75 72 73 6f 72 2c 20 20 20 2f 2a 20 43 75  pCursor,   /* Cu
c060: 72 73 6f 72 20 74 6f 20 72 65 74 72 69 65 76 65  rsor to retrieve
c070: 20 76 61 6c 75 65 20 66 72 6f 6d 20 2a 2f 0a 20   value from */. 
c080: 20 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74   sqlite3_context
c090: 20 2a 70 43 74 78 2c 20 20 20 20 20 20 20 20 20   *pCtx,         
c0a0: 20 2f 2a 20 43 6f 6e 74 65 78 74 20 66 6f 72 20   /* Context for 
c0b0: 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 78  sqlite3_result_x
c0c0: 78 78 28 29 20 63 61 6c 6c 73 20 2a 2f 0a 20 20  xx() calls */.  
c0d0: 69 6e 74 20 69 43 6f 6c 20 20 20 20 20 20 20 20  int iCol        
c0e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c0f0: 2f 2a 20 49 6e 64 65 78 20 6f 66 20 63 6f 6c 75  /* Index of colu
c100: 6d 6e 20 74 6f 20 72 65 61 64 20 76 61 6c 75 65  mn to read value
c110: 20 66 72 6f 6d 20 2a 2f 0a 29 7b 0a 20 20 46 74   from */.){.  Ft
c120: 73 35 54 61 62 6c 65 20 2a 70 54 61 62 20 3d 20  s5Table *pTab = 
c130: 28 46 74 73 35 54 61 62 6c 65 2a 29 28 70 43 75  (Fts5Table*)(pCu
c140: 72 73 6f 72 2d 3e 70 56 74 61 62 29 3b 0a 20 20  rsor->pVtab);.  
c150: 46 74 73 35 43 6f 6e 66 69 67 20 2a 70 43 6f 6e  Fts5Config *pCon
c160: 66 69 67 20 3d 20 70 54 61 62 2d 3e 70 43 6f 6e  fig = pTab->pCon
c170: 66 69 67 3b 0a 20 20 46 74 73 35 43 75 72 73 6f  fig;.  Fts5Curso
c180: 72 20 2a 70 43 73 72 20 3d 20 28 46 74 73 35 43  r *pCsr = (Fts5C
c190: 75 72 73 6f 72 2a 29 70 43 75 72 73 6f 72 3b 0a  ursor*)pCursor;.
c1a0: 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
c1b0: 45 5f 4f 4b 3b 0a 20 20 0a 20 20 61 73 73 65 72  E_OK;.  .  asser
c1c0: 74 28 20 43 73 72 46 6c 61 67 54 65 73 74 28 70  t( CsrFlagTest(p
c1d0: 43 73 72 2c 20 46 54 53 35 43 53 52 5f 45 4f 46  Csr, FTS5CSR_EOF
c1e0: 29 3d 3d 30 20 29 3b 0a 0a 20 20 69 66 28 20 70  )==0 );..  if( p
c1f0: 43 73 72 2d 3e 69 64 78 4e 75 6d 3d 3d 46 54 53  Csr->idxNum==FTS
c200: 35 5f 50 4c 41 4e 5f 53 50 45 43 49 41 4c 20 29  5_PLAN_SPECIAL )
c210: 7b 0a 20 20 20 20 69 66 28 20 69 43 6f 6c 3d 3d  {.    if( iCol==
c220: 70 43 6f 6e 66 69 67 2d 3e 6e 43 6f 6c 20 29 7b  pConfig->nCol ){
c230: 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 72  .      sqlite3_r
c240: 65 73 75 6c 74 5f 74 65 78 74 28 70 43 74 78 2c  esult_text(pCtx,
c250: 20 70 43 73 72 2d 3e 7a 53 70 65 63 69 61 6c 2c   pCsr->zSpecial,
c260: 20 2d 31 2c 20 53 51 4c 49 54 45 5f 54 52 41 4e   -1, SQLITE_TRAN
c270: 53 49 45 4e 54 29 3b 0a 20 20 20 20 7d 0a 20 20  SIENT);.    }.  
c280: 7d 65 6c 73 65 0a 0a 20 20 69 66 28 20 69 43 6f  }else..  if( iCo
c290: 6c 3d 3d 70 43 6f 6e 66 69 67 2d 3e 6e 43 6f 6c  l==pConfig->nCol
c2a0: 20 29 7b 0a 20 20 20 20 2f 2a 20 55 73 65 72 20   ){.    /* User 
c2b0: 69 73 20 72 65 71 75 65 73 74 69 6e 67 20 74 68  is requesting th
c2c0: 65 20 76 61 6c 75 65 20 6f 66 20 74 68 65 20 73  e value of the s
c2d0: 70 65 63 69 61 6c 20 63 6f 6c 75 6d 6e 20 77 69  pecial column wi
c2e0: 74 68 20 74 68 65 20 73 61 6d 65 20 6e 61 6d 65  th the same name
c2f0: 0a 20 20 20 20 2a 2a 20 61 73 20 74 68 65 20 74  .    ** as the t
c300: 61 62 6c 65 2e 20 52 65 74 75 72 6e 20 74 68 65  able. Return the
c310: 20 63 75 72 73 6f 72 20 69 6e 74 65 67 65 72 20   cursor integer 
c320: 69 64 20 6e 75 6d 62 65 72 2e 20 54 68 69 73 20  id number. This 
c330: 76 61 6c 75 65 20 69 73 20 6f 6e 6c 79 0a 20 20  value is only.  
c340: 20 20 2a 2a 20 75 73 65 66 75 6c 20 69 6e 20 74    ** useful in t
c350: 68 61 74 20 69 74 20 6d 61 79 20 62 65 20 70 61  hat it may be pa
c360: 73 73 65 64 20 61 73 20 74 68 65 20 66 69 72 73  ssed as the firs
c370: 74 20 61 72 67 75 6d 65 6e 74 20 74 6f 20 61 6e  t argument to an
c380: 20 46 54 53 35 0a 20 20 20 20 2a 2a 20 61 75 78   FTS5.    ** aux
c390: 69 6c 69 61 72 79 20 66 75 6e 63 74 69 6f 6e 2e  iliary function.
c3a0: 20 20 2a 2f 0a 20 20 20 20 73 71 6c 69 74 65 33    */.    sqlite3
c3b0: 5f 72 65 73 75 6c 74 5f 69 6e 74 36 34 28 70 43  _result_int64(pC
c3c0: 74 78 2c 20 70 43 73 72 2d 3e 69 43 73 72 49 64  tx, pCsr->iCsrId
c3d0: 29 3b 0a 20 20 7d 65 6c 73 65 20 69 66 28 20 69  );.  }else if( i
c3e0: 43 6f 6c 3d 3d 70 43 6f 6e 66 69 67 2d 3e 6e 43  Col==pConfig->nC
c3f0: 6f 6c 2b 31 20 29 7b 0a 0a 20 20 20 20 2f 2a 20  ol+1 ){..    /* 
c400: 54 68 65 20 76 61 6c 75 65 20 6f 66 20 74 68 65  The value of the
c410: 20 22 72 61 6e 6b 22 20 63 6f 6c 75 6d 6e 2e 20   "rank" column. 
c420: 2a 2f 0a 20 20 20 20 69 66 28 20 46 54 53 35 5f  */.    if( FTS5_
c430: 50 4c 41 4e 28 70 43 73 72 2d 3e 69 64 78 4e 75  PLAN(pCsr->idxNu
c440: 6d 29 3d 3d 46 54 53 35 5f 50 4c 41 4e 5f 53 4f  m)==FTS5_PLAN_SO
c450: 55 52 43 45 20 29 7b 0a 20 20 20 20 20 20 66 74  URCE ){.      ft
c460: 73 35 50 6f 73 6c 69 73 74 42 6c 6f 62 28 70 43  s5PoslistBlob(pC
c470: 74 78 2c 20 70 43 73 72 29 3b 0a 20 20 20 20 7d  tx, pCsr);.    }
c480: 65 6c 73 65 20 69 66 28 20 0a 20 20 20 20 20 20  else if( .      
c490: 20 20 46 54 53 35 5f 50 4c 41 4e 28 70 43 73 72    FTS5_PLAN(pCsr
c4a0: 2d 3e 69 64 78 4e 75 6d 29 3d 3d 46 54 53 35 5f  ->idxNum)==FTS5_
c4b0: 50 4c 41 4e 5f 4d 41 54 43 48 0a 20 20 20 20 20  PLAN_MATCH.     
c4c0: 7c 7c 20 46 54 53 35 5f 50 4c 41 4e 28 70 43 73  || FTS5_PLAN(pCs
c4d0: 72 2d 3e 69 64 78 4e 75 6d 29 3d 3d 46 54 53 35  r->idxNum)==FTS5
c4e0: 5f 50 4c 41 4e 5f 53 4f 52 54 45 44 5f 4d 41 54  _PLAN_SORTED_MAT
c4f0: 43 48 0a 20 20 20 20 29 7b 0a 20 20 20 20 20 20  CH.    ){.      
c500: 69 66 28 20 70 43 73 72 2d 3e 70 52 61 6e 6b 20  if( pCsr->pRank 
c510: 7c 7c 20 53 51 4c 49 54 45 5f 4f 4b 3d 3d 28 72  || SQLITE_OK==(r
c520: 63 20 3d 20 66 74 73 35 46 69 6e 64 52 61 6e 6b  c = fts5FindRank
c530: 46 75 6e 63 74 69 6f 6e 28 70 43 73 72 29 29 20  Function(pCsr)) 
c540: 29 7b 0a 20 20 20 20 20 20 20 20 66 74 73 35 41  ){.        fts5A
c550: 70 69 49 6e 76 6f 6b 65 28 70 43 73 72 2d 3e 70  piInvoke(pCsr->p
c560: 52 61 6e 6b 2c 20 70 43 73 72 2c 20 70 43 74 78  Rank, pCsr, pCtx
c570: 2c 20 70 43 73 72 2d 3e 6e 52 61 6e 6b 41 72 67  , pCsr->nRankArg
c580: 2c 20 70 43 73 72 2d 3e 61 70 52 61 6e 6b 41 72  , pCsr->apRankAr
c590: 67 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  g);.      }.    
c5a0: 7d 0a 20 20 7d 65 6c 73 65 20 69 66 28 20 21 66  }.  }else if( !f
c5b0: 74 73 35 49 73 43 6f 6e 74 65 6e 74 6c 65 73 73  ts5IsContentless
c5c0: 28 70 54 61 62 29 20 29 7b 0a 20 20 20 20 72 63  (pTab) ){.    rc
c5d0: 20 3d 20 66 74 73 35 53 65 65 6b 43 75 72 73 6f   = fts5SeekCurso
c5e0: 72 28 70 43 73 72 29 3b 0a 20 20 20 20 69 66 28  r(pCsr);.    if(
c5f0: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
c600: 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f  {.      sqlite3_
c610: 72 65 73 75 6c 74 5f 76 61 6c 75 65 28 70 43 74  result_value(pCt
c620: 78 2c 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d  x, sqlite3_colum
c630: 6e 5f 76 61 6c 75 65 28 70 43 73 72 2d 3e 70 53  n_value(pCsr->pS
c640: 74 6d 74 2c 20 69 43 6f 6c 2b 31 29 29 3b 0a 20  tmt, iCol+1));. 
c650: 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72     }.  }.  retur
c660: 6e 20 72 63 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20  n rc;.}.../*.** 
c670: 54 68 69 73 20 72 6f 75 74 69 6e 65 20 69 6d 70  This routine imp
c680: 6c 65 6d 65 6e 74 73 20 74 68 65 20 78 46 69 6e  lements the xFin
c690: 64 46 75 6e 63 74 69 6f 6e 20 6d 65 74 68 6f 64  dFunction method
c6a0: 20 66 6f 72 20 74 68 65 20 46 54 53 33 0a 2a 2a   for the FTS3.**
c6b0: 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 2e 0a   virtual table..
c6c0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74  */.static int ft
c6d0: 73 35 46 69 6e 64 46 75 6e 63 74 69 6f 6e 4d 65  s5FindFunctionMe
c6e0: 74 68 6f 64 28 0a 20 20 73 71 6c 69 74 65 33 5f  thod(.  sqlite3_
c6f0: 76 74 61 62 20 2a 70 56 74 61 62 2c 20 20 20 20  vtab *pVtab,    
c700: 20 20 20 20 20 20 20 20 2f 2a 20 56 69 72 74 75          /* Virtu
c710: 61 6c 20 74 61 62 6c 65 20 68 61 6e 64 6c 65 20  al table handle 
c720: 2a 2f 0a 20 20 69 6e 74 20 6e 41 72 67 2c 20 20  */.  int nArg,  
c730: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c740: 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
c750: 66 20 53 51 4c 20 66 75 6e 63 74 69 6f 6e 20 61  f SQL function a
c760: 72 67 75 6d 65 6e 74 73 20 2a 2f 0a 20 20 63 6f  rguments */.  co
c770: 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 2c  nst char *zName,
c780: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
c790: 20 4e 61 6d 65 20 6f 66 20 53 51 4c 20 66 75 6e   Name of SQL fun
c7a0: 63 74 69 6f 6e 20 2a 2f 0a 20 20 76 6f 69 64 20  ction */.  void 
c7b0: 28 2a 2a 70 78 46 75 6e 63 29 28 73 71 6c 69 74  (**pxFunc)(sqlit
c7c0: 65 33 5f 63 6f 6e 74 65 78 74 2a 2c 69 6e 74 2c  e3_context*,int,
c7d0: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 2a 2a 29  sqlite3_value**)
c7e0: 2c 20 2f 2a 20 4f 55 54 3a 20 52 65 73 75 6c 74  , /* OUT: Result
c7f0: 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 2a 70 70 41   */.  void **ppA
c800: 72 67 20 20 20 20 20 20 20 20 20 20 20 20 20 20  rg              
c810: 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 55 73        /* OUT: Us
c820: 65 72 20 64 61 74 61 20 66 6f 72 20 2a 70 78 46  er data for *pxF
c830: 75 6e 63 20 2a 2f 0a 29 7b 0a 20 20 46 74 73 35  unc */.){.  Fts5
c840: 54 61 62 6c 65 20 2a 70 54 61 62 20 3d 20 28 46  Table *pTab = (F
c850: 74 73 35 54 61 62 6c 65 2a 29 70 56 74 61 62 3b  ts5Table*)pVtab;
c860: 0a 20 20 46 74 73 35 41 75 78 69 6c 69 61 72 79  .  Fts5Auxiliary
c870: 20 2a 70 41 75 78 3b 0a 0a 20 20 70 41 75 78 20   *pAux;..  pAux 
c880: 3d 20 66 74 73 35 46 69 6e 64 41 75 78 69 6c 69  = fts5FindAuxili
c890: 61 72 79 28 70 54 61 62 2c 20 7a 4e 61 6d 65 29  ary(pTab, zName)
c8a0: 3b 0a 20 20 69 66 28 20 70 41 75 78 20 29 7b 0a  ;.  if( pAux ){.
c8b0: 20 20 20 20 2a 70 78 46 75 6e 63 20 3d 20 66 74      *pxFunc = ft
c8c0: 73 35 41 70 69 43 61 6c 6c 62 61 63 6b 3b 0a 20  s5ApiCallback;. 
c8d0: 20 20 20 2a 70 70 41 72 67 20 3d 20 28 76 6f 69     *ppArg = (voi
c8e0: 64 2a 29 70 41 75 78 3b 0a 20 20 20 20 72 65 74  d*)pAux;.    ret
c8f0: 75 72 6e 20 31 3b 0a 20 20 7d 0a 0a 20 20 2f 2a  urn 1;.  }..  /*
c900: 20 4e 6f 20 66 75 6e 63 74 69 6f 6e 20 6f 66 20   No function of 
c910: 74 68 65 20 73 70 65 63 69 66 69 65 64 20 6e 61  the specified na
c920: 6d 65 20 77 61 73 20 66 6f 75 6e 64 2e 20 52 65  me was found. Re
c930: 74 75 72 6e 20 30 2e 20 2a 2f 0a 20 20 72 65 74  turn 0. */.  ret
c940: 75 72 6e 20 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  urn 0;.}../*.** 
c950: 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f  Implementation o
c960: 66 20 46 54 53 33 20 78 52 65 6e 61 6d 65 20 6d  f FTS3 xRename m
c970: 65 74 68 6f 64 2e 20 52 65 6e 61 6d 65 20 61 6e  ethod. Rename an
c980: 20 66 74 73 35 20 74 61 62 6c 65 2e 0a 2a 2f 0a   fts5 table..*/.
c990: 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 52  static int fts5R
c9a0: 65 6e 61 6d 65 4d 65 74 68 6f 64 28 0a 20 20 73  enameMethod(.  s
c9b0: 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56 74  qlite3_vtab *pVt
c9c0: 61 62 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f  ab,            /
c9d0: 2a 20 56 69 72 74 75 61 6c 20 74 61 62 6c 65 20  * Virtual table 
c9e0: 68 61 6e 64 6c 65 20 2a 2f 0a 20 20 63 6f 6e 73  handle */.  cons
c9f0: 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 20 20 20  t char *zName   
ca00: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
ca10: 65 77 20 6e 61 6d 65 20 6f 66 20 74 61 62 6c 65  ew name of table
ca20: 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20   */.){.  int rc 
ca30: 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 72  = SQLITE_OK;.  r
ca40: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
ca50: 2a 2a 20 54 68 65 20 78 53 61 76 65 70 6f 69 6e  ** The xSavepoin
ca60: 74 28 29 20 6d 65 74 68 6f 64 2e 0a 2a 2a 0a 2a  t() method..**.*
ca70: 2a 20 46 6c 75 73 68 20 74 68 65 20 63 6f 6e 74  * Flush the cont
ca80: 65 6e 74 73 20 6f 66 20 74 68 65 20 70 65 6e 64  ents of the pend
ca90: 69 6e 67 2d 74 65 72 6d 73 20 74 61 62 6c 65 20  ing-terms table 
caa0: 74 6f 20 64 69 73 6b 2e 0a 2a 2f 0a 73 74 61 74  to disk..*/.stat
cab0: 69 63 20 69 6e 74 20 66 74 73 35 53 61 76 65 70  ic int fts5Savep
cac0: 6f 69 6e 74 4d 65 74 68 6f 64 28 73 71 6c 69 74  ointMethod(sqlit
cad0: 65 33 5f 76 74 61 62 20 2a 70 56 74 61 62 2c 20  e3_vtab *pVtab, 
cae0: 69 6e 74 20 69 53 61 76 65 70 6f 69 6e 74 29 7b  int iSavepoint){
caf0: 0a 20 20 46 74 73 35 54 61 62 6c 65 20 2a 70 54  .  Fts5Table *pT
cb00: 61 62 20 3d 20 28 46 74 73 35 54 61 62 6c 65 2a  ab = (Fts5Table*
cb10: 29 70 56 74 61 62 3b 0a 20 20 66 74 73 35 43 68  )pVtab;.  fts5Ch
cb20: 65 63 6b 54 72 61 6e 73 61 63 74 69 6f 6e 53 74  eckTransactionSt
cb30: 61 74 65 28 70 54 61 62 2c 20 46 54 53 35 5f 53  ate(pTab, FTS5_S
cb40: 41 56 45 50 4f 49 4e 54 2c 20 69 53 61 76 65 70  AVEPOINT, iSavep
cb50: 6f 69 6e 74 29 3b 0a 20 20 72 65 74 75 72 6e 20  oint);.  return 
cb60: 73 71 6c 69 74 65 33 46 74 73 35 53 74 6f 72 61  sqlite3Fts5Stora
cb70: 67 65 53 79 6e 63 28 70 54 61 62 2d 3e 70 53 74  geSync(pTab->pSt
cb80: 6f 72 61 67 65 2c 20 30 29 3b 0a 7d 0a 0a 2f 2a  orage, 0);.}../*
cb90: 0a 2a 2a 20 54 68 65 20 78 52 65 6c 65 61 73 65  .** The xRelease
cba0: 28 29 20 6d 65 74 68 6f 64 2e 0a 2a 2a 0a 2a 2a  () method..**.**
cbb0: 20 54 68 69 73 20 69 73 20 61 20 6e 6f 2d 6f 70   This is a no-op
cbc0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
cbd0: 66 74 73 35 52 65 6c 65 61 73 65 4d 65 74 68 6f  fts5ReleaseMetho
cbe0: 64 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a  d(sqlite3_vtab *
cbf0: 70 56 74 61 62 2c 20 69 6e 74 20 69 53 61 76 65  pVtab, int iSave
cc00: 70 6f 69 6e 74 29 7b 0a 20 20 46 74 73 35 54 61  point){.  Fts5Ta
cc10: 62 6c 65 20 2a 70 54 61 62 20 3d 20 28 46 74 73  ble *pTab = (Fts
cc20: 35 54 61 62 6c 65 2a 29 70 56 74 61 62 3b 0a 20  5Table*)pVtab;. 
cc30: 20 66 74 73 35 43 68 65 63 6b 54 72 61 6e 73 61   fts5CheckTransa
cc40: 63 74 69 6f 6e 53 74 61 74 65 28 70 54 61 62 2c  ctionState(pTab,
cc50: 20 46 54 53 35 5f 52 45 4c 45 41 53 45 2c 20 69   FTS5_RELEASE, i
cc60: 53 61 76 65 70 6f 69 6e 74 29 3b 0a 20 20 72 65  Savepoint);.  re
cc70: 74 75 72 6e 20 73 71 6c 69 74 65 33 46 74 73 35  turn sqlite3Fts5
cc80: 53 74 6f 72 61 67 65 53 79 6e 63 28 70 54 61 62  StorageSync(pTab
cc90: 2d 3e 70 53 74 6f 72 61 67 65 2c 20 30 29 3b 0a  ->pStorage, 0);.
cca0: 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 78 52 6f  }../*.** The xRo
ccb0: 6c 6c 62 61 63 6b 54 6f 28 29 20 6d 65 74 68 6f  llbackTo() metho
ccc0: 64 2e 0a 2a 2a 0a 2a 2a 20 44 69 73 63 61 72 64  d..**.** Discard
ccd0: 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66   the contents of
cce0: 20 74 68 65 20 70 65 6e 64 69 6e 67 20 74 65 72   the pending ter
ccf0: 6d 73 20 74 61 62 6c 65 2e 0a 2a 2f 0a 73 74 61  ms table..*/.sta
cd00: 74 69 63 20 69 6e 74 20 66 74 73 35 52 6f 6c 6c  tic int fts5Roll
cd10: 62 61 63 6b 54 6f 4d 65 74 68 6f 64 28 73 71 6c  backToMethod(sql
cd20: 69 74 65 33 5f 76 74 61 62 20 2a 70 56 74 61 62  ite3_vtab *pVtab
cd30: 2c 20 69 6e 74 20 69 53 61 76 65 70 6f 69 6e 74  , int iSavepoint
cd40: 29 7b 0a 20 20 46 74 73 35 54 61 62 6c 65 20 2a  ){.  Fts5Table *
cd50: 70 54 61 62 20 3d 20 28 46 74 73 35 54 61 62 6c  pTab = (Fts5Tabl
cd60: 65 2a 29 70 56 74 61 62 3b 0a 20 20 66 74 73 35  e*)pVtab;.  fts5
cd70: 43 68 65 63 6b 54 72 61 6e 73 61 63 74 69 6f 6e  CheckTransaction
cd80: 53 74 61 74 65 28 70 54 61 62 2c 20 46 54 53 35  State(pTab, FTS5
cd90: 5f 52 4f 4c 4c 42 41 43 4b 54 4f 2c 20 69 53 61  _ROLLBACKTO, iSa
cda0: 76 65 70 6f 69 6e 74 29 3b 0a 20 20 72 65 74 75  vepoint);.  retu
cdb0: 72 6e 20 73 71 6c 69 74 65 33 46 74 73 35 53 74  rn sqlite3Fts5St
cdc0: 6f 72 61 67 65 52 6f 6c 6c 62 61 63 6b 28 70 54  orageRollback(pT
cdd0: 61 62 2d 3e 70 53 74 6f 72 61 67 65 29 3b 0a 7d  ab->pStorage);.}
cde0: 0a 0a 2f 2a 0a 2a 2a 20 52 65 67 69 73 74 65 72  ../*.** Register
cdf0: 20 61 20 6e 65 77 20 61 75 78 69 6c 69 61 72 79   a new auxiliary
ce00: 20 66 75 6e 63 74 69 6f 6e 20 77 69 74 68 20 67   function with g
ce10: 6c 6f 62 61 6c 20 63 6f 6e 74 65 78 74 20 70 47  lobal context pG
ce20: 6c 6f 62 61 6c 2e 0a 2a 2f 0a 73 74 61 74 69 63  lobal..*/.static
ce30: 20 69 6e 74 20 66 74 73 35 43 72 65 61 74 65 41   int fts5CreateA
ce40: 75 78 28 0a 20 20 66 74 73 35 5f 61 70 69 20 2a  ux(.  fts5_api *
ce50: 70 41 70 69 2c 20 20 20 20 20 20 20 20 20 20 20  pApi,           
ce60: 20 20 20 20 20 20 2f 2a 20 47 6c 6f 62 61 6c 20        /* Global 
ce70: 63 6f 6e 74 65 78 74 20 28 6f 6e 65 20 70 65 72  context (one per
ce80: 20 64 62 20 68 61 6e 64 6c 65 29 20 2a 2f 0a 20   db handle) */. 
ce90: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61   const char *zNa
cea0: 6d 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  me,             
ceb0: 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 6e 65 77 20   /* Name of new 
cec0: 66 75 6e 63 74 69 6f 6e 20 2a 2f 0a 20 20 76 6f  function */.  vo
ced0: 69 64 20 2a 70 55 73 65 72 44 61 74 61 2c 20 20  id *pUserData,  
cee0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
cef0: 20 55 73 65 72 20 64 61 74 61 20 66 6f 72 20 61   User data for a
cf00: 75 78 2e 20 66 75 6e 63 74 69 6f 6e 20 2a 2f 0a  ux. function */.
cf10: 20 20 66 74 73 35 5f 65 78 74 65 6e 73 69 6f 6e    fts5_extension
cf20: 5f 66 75 6e 63 74 69 6f 6e 20 78 46 75 6e 63 2c  _function xFunc,
cf30: 20 20 2f 2a 20 41 75 78 2e 20 66 75 6e 63 74 69    /* Aux. functi
cf40: 6f 6e 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f  on implementatio
cf50: 6e 20 2a 2f 0a 20 20 76 6f 69 64 28 2a 78 44 65  n */.  void(*xDe
cf60: 73 74 72 6f 79 29 28 76 6f 69 64 2a 29 20 20 20  stroy)(void*)   
cf70: 20 20 20 20 20 20 20 2f 2a 20 44 65 73 74 72 75         /* Destru
cf80: 63 74 6f 72 20 66 6f 72 20 70 55 73 65 72 44 61  ctor for pUserDa
cf90: 74 61 20 2a 2f 0a 29 7b 0a 20 20 46 74 73 35 47  ta */.){.  Fts5G
cfa0: 6c 6f 62 61 6c 20 2a 70 47 6c 6f 62 61 6c 20 3d  lobal *pGlobal =
cfb0: 20 28 46 74 73 35 47 6c 6f 62 61 6c 2a 29 70 41   (Fts5Global*)pA
cfc0: 70 69 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 73  pi;.  int rc = s
cfd0: 71 6c 69 74 65 33 5f 6f 76 65 72 6c 6f 61 64 5f  qlite3_overload_
cfe0: 66 75 6e 63 74 69 6f 6e 28 70 47 6c 6f 62 61 6c  function(pGlobal
cff0: 2d 3e 64 62 2c 20 7a 4e 61 6d 65 2c 20 2d 31 29  ->db, zName, -1)
d000: 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  ;.  if( rc==SQLI
d010: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 46 74 73  TE_OK ){.    Fts
d020: 35 41 75 78 69 6c 69 61 72 79 20 2a 70 41 75 78  5Auxiliary *pAux
d030: 3b 0a 20 20 20 20 69 6e 74 20 6e 42 79 74 65 3b  ;.    int nByte;
d040: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d050: 20 20 20 20 20 20 2f 2a 20 42 79 74 65 73 20 6f        /* Bytes o
d060: 66 20 73 70 61 63 65 20 74 6f 20 61 6c 6c 6f 63  f space to alloc
d070: 61 74 65 20 2a 2f 0a 0a 20 20 20 20 6e 42 79 74  ate */..    nByt
d080: 65 20 3d 20 73 69 7a 65 6f 66 28 46 74 73 35 41  e = sizeof(Fts5A
d090: 75 78 69 6c 69 61 72 79 29 20 2b 20 73 74 72 6c  uxiliary) + strl
d0a0: 65 6e 28 7a 4e 61 6d 65 29 20 2b 20 31 3b 0a 20  en(zName) + 1;. 
d0b0: 20 20 20 70 41 75 78 20 3d 20 28 46 74 73 35 41     pAux = (Fts5A
d0c0: 75 78 69 6c 69 61 72 79 2a 29 73 71 6c 69 74 65  uxiliary*)sqlite
d0d0: 33 5f 6d 61 6c 6c 6f 63 28 6e 42 79 74 65 29 3b  3_malloc(nByte);
d0e0: 0a 20 20 20 20 69 66 28 20 70 41 75 78 20 29 7b  .    if( pAux ){
d0f0: 0a 20 20 20 20 20 20 6d 65 6d 73 65 74 28 70 41  .      memset(pA
d100: 75 78 2c 20 30 2c 20 6e 42 79 74 65 29 3b 0a 20  ux, 0, nByte);. 
d110: 20 20 20 20 20 70 41 75 78 2d 3e 7a 46 75 6e 63       pAux->zFunc
d120: 20 3d 20 28 63 68 61 72 2a 29 26 70 41 75 78 5b   = (char*)&pAux[
d130: 31 5d 3b 0a 20 20 20 20 20 20 73 74 72 63 70 79  1];.      strcpy
d140: 28 70 41 75 78 2d 3e 7a 46 75 6e 63 2c 20 7a 4e  (pAux->zFunc, zN
d150: 61 6d 65 29 3b 0a 20 20 20 20 20 20 70 41 75 78  ame);.      pAux
d160: 2d 3e 70 47 6c 6f 62 61 6c 20 3d 20 70 47 6c 6f  ->pGlobal = pGlo
d170: 62 61 6c 3b 0a 20 20 20 20 20 20 70 41 75 78 2d  bal;.      pAux-
d180: 3e 70 55 73 65 72 44 61 74 61 20 3d 20 70 55 73  >pUserData = pUs
d190: 65 72 44 61 74 61 3b 0a 20 20 20 20 20 20 70 41  erData;.      pA
d1a0: 75 78 2d 3e 78 46 75 6e 63 20 3d 20 78 46 75 6e  ux->xFunc = xFun
d1b0: 63 3b 0a 20 20 20 20 20 20 70 41 75 78 2d 3e 78  c;.      pAux->x
d1c0: 44 65 73 74 72 6f 79 20 3d 20 78 44 65 73 74 72  Destroy = xDestr
d1d0: 6f 79 3b 0a 20 20 20 20 20 20 70 41 75 78 2d 3e  oy;.      pAux->
d1e0: 70 4e 65 78 74 20 3d 20 70 47 6c 6f 62 61 6c 2d  pNext = pGlobal-
d1f0: 3e 70 41 75 78 3b 0a 20 20 20 20 20 20 70 47 6c  >pAux;.      pGl
d200: 6f 62 61 6c 2d 3e 70 41 75 78 20 3d 20 70 41 75  obal->pAux = pAu
d210: 78 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  x;.    }else{.  
d220: 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
d230: 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d 0a 20 20 7d  NOMEM;.    }.  }
d240: 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ..  return rc;.}
d250: 0a 0a 2f 2a 0a 2a 2a 20 52 65 67 69 73 74 65 72  ../*.** Register
d260: 20 61 20 6e 65 77 20 74 6f 6b 65 6e 69 7a 65 72   a new tokenizer
d270: 2e 20 54 68 69 73 20 69 73 20 74 68 65 20 69 6d  . This is the im
d280: 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20  plementation of 
d290: 74 68 65 20 0a 2a 2a 20 66 74 73 35 5f 61 70 69  the .** fts5_api
d2a0: 2e 78 43 72 65 61 74 65 54 6f 6b 65 6e 69 7a 65  .xCreateTokenize
d2b0: 72 28 29 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73  r() method..*/.s
d2c0: 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 43 72  tatic int fts5Cr
d2d0: 65 61 74 65 54 6f 6b 65 6e 69 7a 65 72 28 0a 20  eateTokenizer(. 
d2e0: 20 66 74 73 35 5f 61 70 69 20 2a 70 41 70 69 2c   fts5_api *pApi,
d2f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d300: 20 2f 2a 20 47 6c 6f 62 61 6c 20 63 6f 6e 74 65   /* Global conte
d310: 78 74 20 28 6f 6e 65 20 70 65 72 20 64 62 20 68  xt (one per db h
d320: 61 6e 64 6c 65 29 20 2a 2f 0a 20 20 63 6f 6e 73  andle) */.  cons
d330: 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 2c 20 20  t char *zName,  
d340: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
d350: 61 6d 65 20 6f 66 20 6e 65 77 20 66 75 6e 63 74  ame of new funct
d360: 69 6f 6e 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70  ion */.  void *p
d370: 55 73 65 72 44 61 74 61 2c 20 20 20 20 20 20 20  UserData,       
d380: 20 20 20 20 20 20 20 20 20 2f 2a 20 55 73 65 72           /* User
d390: 20 64 61 74 61 20 66 6f 72 20 61 75 78 2e 20 66   data for aux. f
d3a0: 75 6e 63 74 69 6f 6e 20 2a 2f 0a 20 20 66 74 73  unction */.  fts
d3b0: 35 5f 74 6f 6b 65 6e 69 7a 65 72 20 2a 70 54 6f  5_tokenizer *pTo
d3c0: 6b 65 6e 69 7a 65 72 2c 20 20 20 20 20 2f 2a 20  kenizer,     /* 
d3d0: 54 6f 6b 65 6e 69 7a 65 72 20 69 6d 70 6c 65 6d  Tokenizer implem
d3e0: 65 6e 74 61 74 69 6f 6e 20 2a 2f 0a 20 20 76 6f  entation */.  vo
d3f0: 69 64 28 2a 78 44 65 73 74 72 6f 79 29 28 76 6f  id(*xDestroy)(vo
d400: 69 64 2a 29 20 20 20 20 20 20 20 20 20 20 2f 2a  id*)          /*
d410: 20 44 65 73 74 72 75 63 74 6f 72 20 66 6f 72 20   Destructor for 
d420: 70 55 73 65 72 44 61 74 61 20 2a 2f 0a 29 7b 0a  pUserData */.){.
d430: 20 20 46 74 73 35 47 6c 6f 62 61 6c 20 2a 70 47    Fts5Global *pG
d440: 6c 6f 62 61 6c 20 3d 20 28 46 74 73 35 47 6c 6f  lobal = (Fts5Glo
d450: 62 61 6c 2a 29 70 41 70 69 3b 0a 20 20 46 74 73  bal*)pApi;.  Fts
d460: 35 54 6f 6b 65 6e 69 7a 65 72 4d 6f 64 75 6c 65  5TokenizerModule
d470: 20 2a 70 4e 65 77 3b 0a 20 20 69 6e 74 20 6e 42   *pNew;.  int nB
d480: 79 74 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  yte;            
d490: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42 79 74            /* Byt
d4a0: 65 73 20 6f 66 20 73 70 61 63 65 20 74 6f 20 61  es of space to a
d4b0: 6c 6c 6f 63 61 74 65 20 2a 2f 0a 20 20 69 6e 74  llocate */.  int
d4c0: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
d4d0: 0a 0a 20 20 6e 42 79 74 65 20 3d 20 73 69 7a 65  ..  nByte = size
d4e0: 6f 66 28 46 74 73 35 54 6f 6b 65 6e 69 7a 65 72  of(Fts5Tokenizer
d4f0: 4d 6f 64 75 6c 65 29 20 2b 20 73 74 72 6c 65 6e  Module) + strlen
d500: 28 7a 4e 61 6d 65 29 20 2b 20 31 3b 0a 20 20 70  (zName) + 1;.  p
d510: 4e 65 77 20 3d 20 28 46 74 73 35 54 6f 6b 65 6e  New = (Fts5Token
d520: 69 7a 65 72 4d 6f 64 75 6c 65 2a 29 73 71 6c 69  izerModule*)sqli
d530: 74 65 33 5f 6d 61 6c 6c 6f 63 28 6e 42 79 74 65  te3_malloc(nByte
d540: 29 3b 0a 20 20 69 66 28 20 70 4e 65 77 20 29 7b  );.  if( pNew ){
d550: 0a 20 20 20 20 6d 65 6d 73 65 74 28 70 4e 65 77  .    memset(pNew
d560: 2c 20 30 2c 20 6e 42 79 74 65 29 3b 0a 20 20 20  , 0, nByte);.   
d570: 20 70 4e 65 77 2d 3e 7a 4e 61 6d 65 20 3d 20 28   pNew->zName = (
d580: 63 68 61 72 2a 29 26 70 4e 65 77 5b 31 5d 3b 0a  char*)&pNew[1];.
d590: 20 20 20 20 73 74 72 63 70 79 28 70 4e 65 77 2d      strcpy(pNew-
d5a0: 3e 7a 4e 61 6d 65 2c 20 7a 4e 61 6d 65 29 3b 0a  >zName, zName);.
d5b0: 20 20 20 20 70 4e 65 77 2d 3e 70 55 73 65 72 44      pNew->pUserD
d5c0: 61 74 61 20 3d 20 70 55 73 65 72 44 61 74 61 3b  ata = pUserData;
d5d0: 0a 20 20 20 20 70 4e 65 77 2d 3e 78 20 3d 20 2a  .    pNew->x = *
d5e0: 70 54 6f 6b 65 6e 69 7a 65 72 3b 0a 20 20 20 20  pTokenizer;.    
d5f0: 70 4e 65 77 2d 3e 78 44 65 73 74 72 6f 79 20 3d  pNew->xDestroy =
d600: 20 78 44 65 73 74 72 6f 79 3b 0a 20 20 20 20 70   xDestroy;.    p
d610: 4e 65 77 2d 3e 70 4e 65 78 74 20 3d 20 70 47 6c  New->pNext = pGl
d620: 6f 62 61 6c 2d 3e 70 54 6f 6b 3b 0a 20 20 20 20  obal->pTok;.    
d630: 70 47 6c 6f 62 61 6c 2d 3e 70 54 6f 6b 20 3d 20  pGlobal->pTok = 
d640: 70 4e 65 77 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  pNew;.  }else{. 
d650: 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e     rc = SQLITE_N
d660: 4f 4d 45 4d 3b 0a 20 20 7d 0a 0a 20 20 72 65 74  OMEM;.  }..  ret
d670: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
d680: 20 46 69 6e 64 20 61 20 74 6f 6b 65 6e 69 7a 65   Find a tokenize
d690: 72 2e 20 54 68 69 73 20 69 73 20 74 68 65 20 69  r. This is the i
d6a0: 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66  mplementation of
d6b0: 20 74 68 65 20 0a 2a 2a 20 66 74 73 35 5f 61 70   the .** fts5_ap
d6c0: 69 2e 78 46 69 6e 64 54 6f 6b 65 6e 69 7a 65 72  i.xFindTokenizer
d6d0: 28 29 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74  () method..*/.st
d6e0: 61 74 69 63 20 69 6e 74 20 66 74 73 35 46 69 6e  atic int fts5Fin
d6f0: 64 54 6f 6b 65 6e 69 7a 65 72 28 0a 20 20 66 74  dTokenizer(.  ft
d700: 73 35 5f 61 70 69 20 2a 70 41 70 69 2c 20 20 20  s5_api *pApi,   
d710: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
d720: 20 47 6c 6f 62 61 6c 20 63 6f 6e 74 65 78 74 20   Global context 
d730: 28 6f 6e 65 20 70 65 72 20 64 62 20 68 61 6e 64  (one per db hand
d740: 6c 65 29 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63  le) */.  const c
d750: 68 61 72 20 2a 7a 4e 61 6d 65 2c 20 20 20 20 20  har *zName,     
d760: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65           /* Name
d770: 20 6f 66 20 6e 65 77 20 66 75 6e 63 74 69 6f 6e   of new function
d780: 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 2a 70 70 55   */.  void **ppU
d790: 73 65 72 44 61 74 61 2c 0a 20 20 66 74 73 35 5f  serData,.  fts5_
d7a0: 74 6f 6b 65 6e 69 7a 65 72 20 2a 70 54 6f 6b 65  tokenizer *pToke
d7b0: 6e 69 7a 65 72 20 20 20 20 20 20 2f 2a 20 50 6f  nizer      /* Po
d7c0: 70 75 6c 61 74 65 20 74 68 69 73 20 6f 62 6a 65  pulate this obje
d7d0: 63 74 20 2a 2f 0a 29 7b 0a 20 20 46 74 73 35 47  ct */.){.  Fts5G
d7e0: 6c 6f 62 61 6c 20 2a 70 47 6c 6f 62 61 6c 20 3d  lobal *pGlobal =
d7f0: 20 28 46 74 73 35 47 6c 6f 62 61 6c 2a 29 70 41   (Fts5Global*)pA
d800: 70 69 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53  pi;.  int rc = S
d810: 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 46 74 73 35  QLITE_OK;.  Fts5
d820: 54 6f 6b 65 6e 69 7a 65 72 4d 6f 64 75 6c 65 20  TokenizerModule 
d830: 2a 70 54 6f 6b 3b 0a 0a 20 20 66 6f 72 28 70 54  *pTok;..  for(pT
d840: 6f 6b 3d 70 47 6c 6f 62 61 6c 2d 3e 70 54 6f 6b  ok=pGlobal->pTok
d850: 3b 20 70 54 6f 6b 3b 20 70 54 6f 6b 3d 70 54 6f  ; pTok; pTok=pTo
d860: 6b 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20 69  k->pNext){.    i
d870: 66 28 20 73 71 6c 69 74 65 33 5f 73 74 72 69 63  f( sqlite3_stric
d880: 6d 70 28 7a 4e 61 6d 65 2c 20 70 54 6f 6b 2d 3e  mp(zName, pTok->
d890: 7a 4e 61 6d 65 29 3d 3d 30 20 29 20 62 72 65 61  zName)==0 ) brea
d8a0: 6b 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 70 54  k;.  }..  if( pT
d8b0: 6f 6b 20 29 7b 0a 20 20 20 20 2a 70 54 6f 6b 65  ok ){.    *pToke
d8c0: 6e 69 7a 65 72 20 3d 20 70 54 6f 6b 2d 3e 78 3b  nizer = pTok->x;
d8d0: 0a 20 20 20 20 2a 70 70 55 73 65 72 44 61 74 61  .    *ppUserData
d8e0: 20 3d 20 70 54 6f 6b 2d 3e 70 55 73 65 72 44 61   = pTok->pUserDa
d8f0: 74 61 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ta;.  }else{.   
d900: 20 6d 65 6d 73 65 74 28 70 54 6f 6b 65 6e 69 7a   memset(pTokeniz
d910: 65 72 2c 20 30 2c 20 73 69 7a 65 6f 66 28 66 74  er, 0, sizeof(ft
d920: 73 35 5f 74 6f 6b 65 6e 69 7a 65 72 29 29 3b 0a  s5_tokenizer));.
d930: 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
d940: 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20 72 65  ERROR;.  }..  re
d950: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 69 6e 74 20  turn rc;.}..int 
d960: 73 71 6c 69 74 65 33 46 74 73 35 47 65 74 54 6f  sqlite3Fts5GetTo
d970: 6b 65 6e 69 7a 65 72 28 0a 20 20 46 74 73 35 47  kenizer(.  Fts5G
d980: 6c 6f 62 61 6c 20 2a 70 47 6c 6f 62 61 6c 2c 20  lobal *pGlobal, 
d990: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 2a  .  const char **
d9a0: 61 7a 41 72 67 2c 0a 20 20 69 6e 74 20 6e 41 72  azArg,.  int nAr
d9b0: 67 2c 0a 20 20 46 74 73 35 54 6f 6b 65 6e 69 7a  g,.  Fts5Tokeniz
d9c0: 65 72 20 2a 2a 70 70 54 6f 6b 2c 0a 20 20 66 74  er **ppTok,.  ft
d9d0: 73 35 5f 74 6f 6b 65 6e 69 7a 65 72 20 2a 2a 70  s5_tokenizer **p
d9e0: 70 54 6f 6b 41 70 69 0a 29 7b 0a 20 20 46 74 73  pTokApi.){.  Fts
d9f0: 35 54 6f 6b 65 6e 69 7a 65 72 4d 6f 64 75 6c 65  5TokenizerModule
da00: 20 2a 70 4d 6f 64 20 3d 20 30 3b 0a 20 20 69 6e   *pMod = 0;.  in
da10: 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b  t rc = SQLITE_OK
da20: 3b 0a 20 20 69 66 28 20 6e 41 72 67 3d 3d 30 20  ;.  if( nArg==0 
da30: 29 7b 0a 20 20 20 20 70 4d 6f 64 20 3d 20 70 47  ){.    pMod = pG
da40: 6c 6f 62 61 6c 2d 3e 70 54 6f 6b 3b 0a 20 20 7d  lobal->pTok;.  }
da50: 65 6c 73 65 7b 0a 20 20 20 20 66 6f 72 28 70 4d  else{.    for(pM
da60: 6f 64 3d 70 47 6c 6f 62 61 6c 2d 3e 70 54 6f 6b  od=pGlobal->pTok
da70: 3b 20 70 4d 6f 64 3b 20 70 4d 6f 64 3d 70 4d 6f  ; pMod; pMod=pMo
da80: 64 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20 20  d->pNext){.     
da90: 20 69 66 28 20 73 71 6c 69 74 65 33 5f 73 74 72   if( sqlite3_str
daa0: 69 63 6d 70 28 61 7a 41 72 67 5b 30 5d 2c 20 70  icmp(azArg[0], p
dab0: 4d 6f 64 2d 3e 7a 4e 61 6d 65 29 3d 3d 30 20 29  Mod->zName)==0 )
dac0: 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 20 20   break;.    }.  
dad0: 7d 0a 0a 20 20 69 66 28 20 70 4d 6f 64 3d 3d 30  }..  if( pMod==0
dae0: 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 53 51 4c   ){.    rc = SQL
daf0: 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 7d 65 6c  ITE_ERROR;.  }el
db00: 73 65 7b 0a 20 20 20 20 72 63 20 3d 20 70 4d 6f  se{.    rc = pMo
db10: 64 2d 3e 78 2e 78 43 72 65 61 74 65 28 70 4d 6f  d->x.xCreate(pMo
db20: 64 2d 3e 70 55 73 65 72 44 61 74 61 2c 20 26 61  d->pUserData, &a
db30: 7a 41 72 67 5b 31 5d 2c 20 28 6e 41 72 67 3f 6e  zArg[1], (nArg?n
db40: 41 72 67 2d 31 3a 30 29 2c 20 70 70 54 6f 6b 29  Arg-1:0), ppTok)
db50: 3b 0a 20 20 20 20 2a 70 70 54 6f 6b 41 70 69 20  ;.    *ppTokApi 
db60: 3d 20 26 70 4d 6f 64 2d 3e 78 3b 0a 20 20 7d 0a  = &pMod->x;.  }.
db70: 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54  .  if( rc!=SQLIT
db80: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 2a 70 70 54  E_OK ){.    *ppT
db90: 6f 6b 41 70 69 20 3d 20 30 3b 0a 20 20 20 20 2a  okApi = 0;.    *
dba0: 70 70 54 6f 6b 20 3d 20 30 3b 0a 20 20 7d 0a 0a  ppTok = 0;.  }..
dbb0: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
dbc0: 73 74 61 74 69 63 20 76 6f 69 64 20 66 74 73 35  static void fts5
dbd0: 4d 6f 64 75 6c 65 44 65 73 74 72 6f 79 28 76 6f  ModuleDestroy(vo
dbe0: 69 64 20 2a 70 43 74 78 29 7b 0a 20 20 46 74 73  id *pCtx){.  Fts
dbf0: 35 54 6f 6b 65 6e 69 7a 65 72 4d 6f 64 75 6c 65  5TokenizerModule
dc00: 20 2a 70 54 6f 6b 2c 20 2a 70 4e 65 78 74 54 6f   *pTok, *pNextTo
dc10: 6b 3b 0a 20 20 46 74 73 35 41 75 78 69 6c 69 61  k;.  Fts5Auxilia
dc20: 72 79 20 2a 70 41 75 78 2c 20 2a 70 4e 65 78 74  ry *pAux, *pNext
dc30: 41 75 78 3b 0a 20 20 46 74 73 35 47 6c 6f 62 61  Aux;.  Fts5Globa
dc40: 6c 20 2a 70 47 6c 6f 62 61 6c 20 3d 20 28 46 74  l *pGlobal = (Ft
dc50: 73 35 47 6c 6f 62 61 6c 2a 29 70 43 74 78 3b 0a  s5Global*)pCtx;.
dc60: 0a 20 20 66 6f 72 28 70 41 75 78 3d 70 47 6c 6f  .  for(pAux=pGlo
dc70: 62 61 6c 2d 3e 70 41 75 78 3b 20 70 41 75 78 3b  bal->pAux; pAux;
dc80: 20 70 41 75 78 3d 70 4e 65 78 74 41 75 78 29 7b   pAux=pNextAux){
dc90: 0a 20 20 20 20 70 4e 65 78 74 41 75 78 20 3d 20  .    pNextAux = 
dca0: 70 41 75 78 2d 3e 70 4e 65 78 74 3b 0a 20 20 20  pAux->pNext;.   
dcb0: 20 69 66 28 20 70 41 75 78 2d 3e 78 44 65 73 74   if( pAux->xDest
dcc0: 72 6f 79 20 29 20 70 41 75 78 2d 3e 78 44 65 73  roy ) pAux->xDes
dcd0: 74 72 6f 79 28 70 41 75 78 2d 3e 70 55 73 65 72  troy(pAux->pUser
dce0: 44 61 74 61 29 3b 0a 20 20 20 20 73 71 6c 69 74  Data);.    sqlit
dcf0: 65 33 5f 66 72 65 65 28 70 41 75 78 29 3b 0a 20  e3_free(pAux);. 
dd00: 20 7d 0a 0a 20 20 66 6f 72 28 70 54 6f 6b 3d 70   }..  for(pTok=p
dd10: 47 6c 6f 62 61 6c 2d 3e 70 54 6f 6b 3b 20 70 54  Global->pTok; pT
dd20: 6f 6b 3b 20 70 54 6f 6b 3d 70 4e 65 78 74 54 6f  ok; pTok=pNextTo
dd30: 6b 29 7b 0a 20 20 20 20 70 4e 65 78 74 54 6f 6b  k){.    pNextTok
dd40: 20 3d 20 70 54 6f 6b 2d 3e 70 4e 65 78 74 3b 0a   = pTok->pNext;.
dd50: 20 20 20 20 69 66 28 20 70 54 6f 6b 2d 3e 78 44      if( pTok->xD
dd60: 65 73 74 72 6f 79 20 29 20 70 54 6f 6b 2d 3e 78  estroy ) pTok->x
dd70: 44 65 73 74 72 6f 79 28 70 54 6f 6b 2d 3e 70 55  Destroy(pTok->pU
dd80: 73 65 72 44 61 74 61 29 3b 0a 20 20 20 20 73 71  serData);.    sq
dd90: 6c 69 74 65 33 5f 66 72 65 65 28 70 54 6f 6b 29  lite3_free(pTok)
dda0: 3b 0a 20 20 7d 0a 0a 20 20 73 71 6c 69 74 65 33  ;.  }..  sqlite3
ddb0: 5f 66 72 65 65 28 70 47 6c 6f 62 61 6c 29 3b 0a  _free(pGlobal);.
ddc0: 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 66  }..static void f
ddd0: 74 73 35 46 74 73 35 46 75 6e 63 28 0a 20 20 73  ts5Fts5Func(.  s
dde0: 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74 20 2a  qlite3_context *
ddf0: 70 43 74 78 2c 20 20 20 20 20 20 20 20 20 20 2f  pCtx,          /
de00: 2a 20 46 75 6e 63 74 69 6f 6e 20 63 61 6c 6c 20  * Function call 
de10: 63 6f 6e 74 65 78 74 20 2a 2f 0a 20 20 69 6e 74  context */.  int
de20: 20 6e 41 72 67 2c 20 20 20 20 20 20 20 20 20 20   nArg,          
de30: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
de40: 4e 75 6d 62 65 72 20 6f 66 20 61 72 67 73 20 2a  Number of args *
de50: 2f 0a 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75  /.  sqlite3_valu
de60: 65 20 2a 2a 61 70 56 61 6c 20 20 20 20 20 20 20  e **apVal       
de70: 20 20 20 20 2f 2a 20 46 75 6e 63 74 69 6f 6e 20      /* Function 
de80: 61 72 67 75 6d 65 6e 74 73 20 2a 2f 0a 29 7b 0a  arguments */.){.
de90: 20 20 46 74 73 35 47 6c 6f 62 61 6c 20 2a 70 47    Fts5Global *pG
dea0: 6c 6f 62 61 6c 20 3d 20 28 46 74 73 35 47 6c 6f  lobal = (Fts5Glo
deb0: 62 61 6c 2a 29 73 71 6c 69 74 65 33 5f 75 73 65  bal*)sqlite3_use
dec0: 72 5f 64 61 74 61 28 70 43 74 78 29 3b 0a 20 20  r_data(pCtx);.  
ded0: 63 68 61 72 20 62 75 66 5b 38 5d 3b 0a 20 20 61  char buf[8];.  a
dee0: 73 73 65 72 74 28 20 6e 41 72 67 3d 3d 30 20 29  ssert( nArg==0 )
def0: 3b 0a 20 20 61 73 73 65 72 74 28 20 73 69 7a 65  ;.  assert( size
df00: 6f 66 28 62 75 66 29 3e 3d 73 69 7a 65 6f 66 28  of(buf)>=sizeof(
df10: 70 47 6c 6f 62 61 6c 29 20 29 3b 0a 20 20 6d 65  pGlobal) );.  me
df20: 6d 63 70 79 28 62 75 66 2c 20 28 76 6f 69 64 2a  mcpy(buf, (void*
df30: 29 26 70 47 6c 6f 62 61 6c 2c 20 73 69 7a 65 6f  )&pGlobal, sizeo
df40: 66 28 70 47 6c 6f 62 61 6c 29 29 3b 0a 20 20 73  f(pGlobal));.  s
df50: 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 62 6c  qlite3_result_bl
df60: 6f 62 28 70 43 74 78 2c 20 62 75 66 2c 20 73 69  ob(pCtx, buf, si
df70: 7a 65 6f 66 28 70 47 6c 6f 62 61 6c 29 2c 20 53  zeof(pGlobal), S
df80: 51 4c 49 54 45 5f 54 52 41 4e 53 49 45 4e 54 29  QLITE_TRANSIENT)
df90: 3b 0a 7d 0a 0a 69 6e 74 20 73 71 6c 69 74 65 33  ;.}..int sqlite3
dfa0: 46 74 73 35 49 6e 69 74 28 73 71 6c 69 74 65 33  Fts5Init(sqlite3
dfb0: 20 2a 64 62 29 7b 0a 20 20 73 74 61 74 69 63 20   *db){.  static 
dfc0: 63 6f 6e 73 74 20 73 71 6c 69 74 65 33 5f 6d 6f  const sqlite3_mo
dfd0: 64 75 6c 65 20 66 74 73 35 4d 6f 64 20 3d 20 7b  dule fts5Mod = {
dfe0: 0a 20 20 20 20 2f 2a 20 69 56 65 72 73 69 6f 6e  .    /* iVersion
dff0: 20 20 20 20 20 20 2a 2f 20 32 2c 0a 20 20 20 20        */ 2,.    
e000: 2f 2a 20 78 43 72 65 61 74 65 20 20 20 20 20 20  /* xCreate      
e010: 20 2a 2f 20 66 74 73 35 43 72 65 61 74 65 4d 65   */ fts5CreateMe
e020: 74 68 6f 64 2c 0a 20 20 20 20 2f 2a 20 78 43 6f  thod,.    /* xCo
e030: 6e 6e 65 63 74 20 20 20 20 20 20 2a 2f 20 66 74  nnect      */ ft
e040: 73 35 43 6f 6e 6e 65 63 74 4d 65 74 68 6f 64 2c  s5ConnectMethod,
e050: 0a 20 20 20 20 2f 2a 20 78 42 65 73 74 49 6e 64  .    /* xBestInd
e060: 65 78 20 20 20 20 2a 2f 20 66 74 73 35 42 65 73  ex    */ fts5Bes
e070: 74 49 6e 64 65 78 4d 65 74 68 6f 64 2c 0a 20 20  tIndexMethod,.  
e080: 20 20 2f 2a 20 78 44 69 73 63 6f 6e 6e 65 63 74    /* xDisconnect
e090: 20 20 20 2a 2f 20 66 74 73 35 44 69 73 63 6f 6e     */ fts5Discon
e0a0: 6e 65 63 74 4d 65 74 68 6f 64 2c 0a 20 20 20 20  nectMethod,.    
e0b0: 2f 2a 20 78 44 65 73 74 72 6f 79 20 20 20 20 20  /* xDestroy     
e0c0: 20 2a 2f 20 66 74 73 35 44 65 73 74 72 6f 79 4d   */ fts5DestroyM
e0d0: 65 74 68 6f 64 2c 0a 20 20 20 20 2f 2a 20 78 4f  ethod,.    /* xO
e0e0: 70 65 6e 20 20 20 20 20 20 20 20 20 2a 2f 20 66  pen         */ f
e0f0: 74 73 35 4f 70 65 6e 4d 65 74 68 6f 64 2c 0a 20  ts5OpenMethod,. 
e100: 20 20 20 2f 2a 20 78 43 6c 6f 73 65 20 20 20 20     /* xClose    
e110: 20 20 20 20 2a 2f 20 66 74 73 35 43 6c 6f 73 65      */ fts5Close
e120: 4d 65 74 68 6f 64 2c 0a 20 20 20 20 2f 2a 20 78  Method,.    /* x
e130: 46 69 6c 74 65 72 20 20 20 20 20 20 20 2a 2f 20  Filter       */ 
e140: 66 74 73 35 46 69 6c 74 65 72 4d 65 74 68 6f 64  fts5FilterMethod
e150: 2c 0a 20 20 20 20 2f 2a 20 78 4e 65 78 74 20 20  ,.    /* xNext  
e160: 20 20 20 20 20 20 20 2a 2f 20 66 74 73 35 4e 65         */ fts5Ne
e170: 78 74 4d 65 74 68 6f 64 2c 0a 20 20 20 20 2f 2a  xtMethod,.    /*
e180: 20 78 45 6f 66 20 20 20 20 20 20 20 20 20 20 2a   xEof          *
e190: 2f 20 66 74 73 35 45 6f 66 4d 65 74 68 6f 64 2c  / fts5EofMethod,
e1a0: 0a 20 20 20 20 2f 2a 20 78 43 6f 6c 75 6d 6e 20  .    /* xColumn 
e1b0: 20 20 20 20 20 20 2a 2f 20 66 74 73 35 43 6f 6c        */ fts5Col
e1c0: 75 6d 6e 4d 65 74 68 6f 64 2c 0a 20 20 20 20 2f  umnMethod,.    /
e1d0: 2a 20 78 52 6f 77 69 64 20 20 20 20 20 20 20 20  * xRowid        
e1e0: 2a 2f 20 66 74 73 35 52 6f 77 69 64 4d 65 74 68  */ fts5RowidMeth
e1f0: 6f 64 2c 0a 20 20 20 20 2f 2a 20 78 55 70 64 61  od,.    /* xUpda
e200: 74 65 20 20 20 20 20 20 20 2a 2f 20 66 74 73 35  te       */ fts5
e210: 55 70 64 61 74 65 4d 65 74 68 6f 64 2c 0a 20 20  UpdateMethod,.  
e220: 20 20 2f 2a 20 78 42 65 67 69 6e 20 20 20 20 20    /* xBegin     
e230: 20 20 20 2a 2f 20 66 74 73 35 42 65 67 69 6e 4d     */ fts5BeginM
e240: 65 74 68 6f 64 2c 0a 20 20 20 20 2f 2a 20 78 53  ethod,.    /* xS
e250: 79 6e 63 20 20 20 20 20 20 20 20 20 2a 2f 20 66  ync         */ f
e260: 74 73 35 53 79 6e 63 4d 65 74 68 6f 64 2c 0a 20  ts5SyncMethod,. 
e270: 20 20 20 2f 2a 20 78 43 6f 6d 6d 69 74 20 20 20     /* xCommit   
e280: 20 20 20 20 2a 2f 20 66 74 73 35 43 6f 6d 6d 69      */ fts5Commi
e290: 74 4d 65 74 68 6f 64 2c 0a 20 20 20 20 2f 2a 20  tMethod,.    /* 
e2a0: 78 52 6f 6c 6c 62 61 63 6b 20 20 20 20 20 2a 2f  xRollback     */
e2b0: 20 66 74 73 35 52 6f 6c 6c 62 61 63 6b 4d 65 74   fts5RollbackMet
e2c0: 68 6f 64 2c 0a 20 20 20 20 2f 2a 20 78 46 69 6e  hod,.    /* xFin
e2d0: 64 46 75 6e 63 74 69 6f 6e 20 2a 2f 20 66 74 73  dFunction */ fts
e2e0: 35 46 69 6e 64 46 75 6e 63 74 69 6f 6e 4d 65 74  5FindFunctionMet
e2f0: 68 6f 64 2c 0a 20 20 20 20 2f 2a 20 78 52 65 6e  hod,.    /* xRen
e300: 61 6d 65 20 20 20 20 20 20 20 2a 2f 20 66 74 73  ame       */ fts
e310: 35 52 65 6e 61 6d 65 4d 65 74 68 6f 64 2c 0a 20  5RenameMethod,. 
e320: 20 20 20 2f 2a 20 78 53 61 76 65 70 6f 69 6e 74     /* xSavepoint
e330: 20 20 20 20 2a 2f 20 66 74 73 35 53 61 76 65 70      */ fts5Savep
e340: 6f 69 6e 74 4d 65 74 68 6f 64 2c 0a 20 20 20 20  ointMethod,.    
e350: 2f 2a 20 78 52 65 6c 65 61 73 65 20 20 20 20 20  /* xRelease     
e360: 20 2a 2f 20 66 74 73 35 52 65 6c 65 61 73 65 4d   */ fts5ReleaseM
e370: 65 74 68 6f 64 2c 0a 20 20 20 20 2f 2a 20 78 52  ethod,.    /* xR
e380: 6f 6c 6c 62 61 63 6b 54 6f 20 20 20 2a 2f 20 66  ollbackTo   */ f
e390: 74 73 35 52 6f 6c 6c 62 61 63 6b 54 6f 4d 65 74  ts5RollbackToMet
e3a0: 68 6f 64 2c 0a 20 20 7d 3b 0a 0a 20 20 69 6e 74  hod,.  };..  int
e3b0: 20 72 63 3b 0a 20 20 46 74 73 35 47 6c 6f 62 61   rc;.  Fts5Globa
e3c0: 6c 20 2a 70 47 6c 6f 62 61 6c 20 3d 20 30 3b 0a  l *pGlobal = 0;.
e3d0: 20 20 70 47 6c 6f 62 61 6c 20 3d 20 28 46 74 73    pGlobal = (Fts
e3e0: 35 47 6c 6f 62 61 6c 2a 29 73 71 6c 69 74 65 33  5Global*)sqlite3
e3f0: 5f 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 46  _malloc(sizeof(F
e400: 74 73 35 47 6c 6f 62 61 6c 29 29 3b 0a 0a 20 20  ts5Global));..  
e410: 69 66 28 20 70 47 6c 6f 62 61 6c 3d 3d 30 20 29  if( pGlobal==0 )
e420: 7b 0a 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54  {.    rc = SQLIT
e430: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 65 6c 73 65  E_NOMEM;.  }else
e440: 7b 0a 20 20 20 20 76 6f 69 64 20 2a 70 20 3d 20  {.    void *p = 
e450: 28 76 6f 69 64 2a 29 70 47 6c 6f 62 61 6c 3b 0a  (void*)pGlobal;.
e460: 20 20 20 20 6d 65 6d 73 65 74 28 70 47 6c 6f 62      memset(pGlob
e470: 61 6c 2c 20 30 2c 20 73 69 7a 65 6f 66 28 46 74  al, 0, sizeof(Ft
e480: 73 35 47 6c 6f 62 61 6c 29 29 3b 0a 20 20 20 20  s5Global));.    
e490: 70 47 6c 6f 62 61 6c 2d 3e 64 62 20 3d 20 64 62  pGlobal->db = db
e4a0: 3b 0a 20 20 20 20 70 47 6c 6f 62 61 6c 2d 3e 61  ;.    pGlobal->a
e4b0: 70 69 2e 69 56 65 72 73 69 6f 6e 20 3d 20 31 3b  pi.iVersion = 1;
e4c0: 0a 20 20 20 20 70 47 6c 6f 62 61 6c 2d 3e 61 70  .    pGlobal->ap
e4d0: 69 2e 78 43 72 65 61 74 65 46 75 6e 63 74 69 6f  i.xCreateFunctio
e4e0: 6e 20 3d 20 66 74 73 35 43 72 65 61 74 65 41 75  n = fts5CreateAu
e4f0: 78 3b 0a 20 20 20 20 70 47 6c 6f 62 61 6c 2d 3e  x;.    pGlobal->
e500: 61 70 69 2e 78 43 72 65 61 74 65 54 6f 6b 65 6e  api.xCreateToken
e510: 69 7a 65 72 20 3d 20 66 74 73 35 43 72 65 61 74  izer = fts5Creat
e520: 65 54 6f 6b 65 6e 69 7a 65 72 3b 0a 20 20 20 20  eTokenizer;.    
e530: 70 47 6c 6f 62 61 6c 2d 3e 61 70 69 2e 78 46 69  pGlobal->api.xFi
e540: 6e 64 54 6f 6b 65 6e 69 7a 65 72 20 3d 20 66 74  ndTokenizer = ft
e550: 73 35 46 69 6e 64 54 6f 6b 65 6e 69 7a 65 72 3b  s5FindTokenizer;
e560: 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65  .    rc = sqlite
e570: 33 5f 63 72 65 61 74 65 5f 6d 6f 64 75 6c 65 5f  3_create_module_
e580: 76 32 28 64 62 2c 20 22 66 74 73 35 22 2c 20 26  v2(db, "fts5", &
e590: 66 74 73 35 4d 6f 64 2c 20 70 2c 20 66 74 73 35  fts5Mod, p, fts5
e5a0: 4d 6f 64 75 6c 65 44 65 73 74 72 6f 79 29 3b 0a  ModuleDestroy);.
e5b0: 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49      if( rc==SQLI
e5c0: 54 45 5f 4f 4b 20 29 20 72 63 20 3d 20 73 71 6c  TE_OK ) rc = sql
e5d0: 69 74 65 33 46 74 73 35 49 6e 64 65 78 49 6e 69  ite3Fts5IndexIni
e5e0: 74 28 64 62 29 3b 0a 20 20 20 20 69 66 28 20 72  t(db);.    if( r
e5f0: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72  c==SQLITE_OK ) r
e600: 63 20 3d 20 73 71 6c 69 74 65 33 46 74 73 35 45  c = sqlite3Fts5E
e610: 78 70 72 49 6e 69 74 28 70 47 6c 6f 62 61 6c 2c  xprInit(pGlobal,
e620: 20 64 62 29 3b 0a 20 20 20 20 69 66 28 20 72 63   db);.    if( rc
e630: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 63  ==SQLITE_OK ) rc
e640: 20 3d 20 73 71 6c 69 74 65 33 46 74 73 35 41 75   = sqlite3Fts5Au
e650: 78 49 6e 69 74 28 26 70 47 6c 6f 62 61 6c 2d 3e  xInit(&pGlobal->
e660: 61 70 69 29 3b 0a 20 20 20 20 69 66 28 20 72 63  api);.    if( rc
e670: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 63  ==SQLITE_OK ) rc
e680: 20 3d 20 73 71 6c 69 74 65 33 46 74 73 35 54 6f   = sqlite3Fts5To
e690: 6b 65 6e 69 7a 65 72 49 6e 69 74 28 26 70 47 6c  kenizerInit(&pGl
e6a0: 6f 62 61 6c 2d 3e 61 70 69 29 3b 0a 20 20 20 20  obal->api);.    
e6b0: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
e6c0: 4b 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20  K ){.      rc = 
e6d0: 73 71 6c 69 74 65 33 5f 63 72 65 61 74 65 5f 66  sqlite3_create_f
e6e0: 75 6e 63 74 69 6f 6e 28 0a 20 20 20 20 20 20 20  unction(.       
e6f0: 20 20 20 64 62 2c 20 22 66 74 73 35 22 2c 20 30     db, "fts5", 0
e700: 2c 20 53 51 4c 49 54 45 5f 55 54 46 38 2c 20 70  , SQLITE_UTF8, p
e710: 2c 20 66 74 73 35 46 74 73 35 46 75 6e 63 2c 20  , fts5Fts5Func, 
e720: 30 2c 20 30 0a 20 20 20 20 20 20 29 3b 0a 20 20  0, 0.      );.  
e730: 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e    }.  }.  return
e740: 20 72 63 3b 0a 7d 0a 0a 0a                        rc;.}...