/ Hex Artifact Content
Login

Artifact 41b852b654f79f522668bc7ba292755fb261f855:


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 54 6f 6b 65 6e 69 7a 65  /.  Fts5Tokenize
0af0: 72 4d 6f 64 75 6c 65 20 2a 70 44 66 6c 74 54 6f  rModule *pDfltTo
0b00: 6b 3b 20 20 2f 2a 20 44 65 66 61 75 6c 74 20 74  k;  /* Default t
0b10: 6f 6b 65 6e 69 7a 65 72 20 6d 6f 64 75 6c 65 20  okenizer module 
0b20: 2a 2f 0a 20 20 46 74 73 35 43 75 72 73 6f 72 20  */.  Fts5Cursor 
0b30: 2a 70 43 73 72 3b 20 20 20 20 20 20 20 20 20 20  *pCsr;          
0b40: 20 20 20 20 20 2f 2a 20 46 69 72 73 74 20 69 6e       /* First in
0b50: 20 6c 69 73 74 20 6f 66 20 61 6c 6c 20 6f 70 65   list of all ope
0b60: 6e 20 63 75 72 73 6f 72 73 20 2a 2f 0a 7d 3b 0a  n cursors */.};.
0b70: 0a 2f 2a 0a 2a 2a 20 45 61 63 68 20 61 75 78 69  ./*.** Each auxi
0b80: 6c 69 61 72 79 20 66 75 6e 63 74 69 6f 6e 20 72  liary function r
0b90: 65 67 69 73 74 65 72 65 64 20 77 69 74 68 20 74  egistered with t
0ba0: 68 65 20 46 54 53 35 20 6d 6f 64 75 6c 65 20 69  he FTS5 module i
0bb0: 73 20 72 65 70 72 65 73 65 6e 74 65 64 0a 2a 2a  s represented.**
0bc0: 20 62 79 20 61 6e 20 6f 62 6a 65 63 74 20 6f 66   by an object of
0bd0: 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 74   the following t
0be0: 79 70 65 2e 20 41 6c 6c 20 73 75 63 68 20 6f 62  ype. All such ob
0bf0: 6a 65 63 74 73 20 61 72 65 20 73 74 6f 72 65 64  jects are stored
0c00: 20 61 73 20 70 61 72 74 0a 2a 2a 20 6f 66 20 74   as part.** of t
0c10: 68 65 20 46 74 73 35 47 6c 6f 62 61 6c 2e 70 41  he Fts5Global.pA
0c20: 75 78 20 6c 69 73 74 2e 0a 2a 2f 0a 73 74 72 75  ux list..*/.stru
0c30: 63 74 20 46 74 73 35 41 75 78 69 6c 69 61 72 79  ct Fts5Auxiliary
0c40: 20 7b 0a 20 20 46 74 73 35 47 6c 6f 62 61 6c 20   {.  Fts5Global 
0c50: 2a 70 47 6c 6f 62 61 6c 3b 20 20 20 20 20 20 20  *pGlobal;       
0c60: 20 20 20 20 20 2f 2a 20 47 6c 6f 62 61 6c 20 63       /* Global c
0c70: 6f 6e 74 65 78 74 20 66 6f 72 20 74 68 69 73 20  ontext for this 
0c80: 66 75 6e 63 74 69 6f 6e 20 2a 2f 0a 20 20 63 68  function */.  ch
0c90: 61 72 20 2a 7a 46 75 6e 63 3b 20 20 20 20 20 20  ar *zFunc;      
0ca0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0cb0: 20 46 75 6e 63 74 69 6f 6e 20 6e 61 6d 65 20 28   Function name (
0cc0: 6e 75 6c 2d 74 65 72 6d 69 6e 61 74 65 64 29 20  nul-terminated) 
0cd0: 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 55 73 65 72  */.  void *pUser
0ce0: 44 61 74 61 3b 20 20 20 20 20 20 20 20 20 20 20  Data;           
0cf0: 20 20 20 20 20 2f 2a 20 55 73 65 72 2d 64 61 74       /* User-dat
0d00: 61 20 70 6f 69 6e 74 65 72 20 2a 2f 0a 20 20 66  a pointer */.  f
0d10: 74 73 35 5f 65 78 74 65 6e 73 69 6f 6e 5f 66 75  ts5_extension_fu
0d20: 6e 63 74 69 6f 6e 20 78 46 75 6e 63 3b 20 20 2f  nction xFunc;  /
0d30: 2a 20 43 61 6c 6c 62 61 63 6b 20 66 75 6e 63 74  * Callback funct
0d40: 69 6f 6e 20 2a 2f 0a 20 20 76 6f 69 64 20 28 2a  ion */.  void (*
0d50: 78 44 65 73 74 72 6f 79 29 28 76 6f 69 64 2a 29  xDestroy)(void*)
0d60: 3b 20 20 20 20 20 20 20 20 2f 2a 20 44 65 73 74  ;        /* Dest
0d70: 72 75 63 74 6f 72 20 66 75 6e 63 74 69 6f 6e 20  ructor function 
0d80: 2a 2f 0a 20 20 46 74 73 35 41 75 78 69 6c 69 61  */.  Fts5Auxilia
0d90: 72 79 20 2a 70 4e 65 78 74 3b 20 20 20 20 20 20  ry *pNext;      
0da0: 20 20 20 20 20 2f 2a 20 4e 65 78 74 20 72 65 67       /* Next reg
0db0: 69 73 74 65 72 65 64 20 61 75 78 69 6c 69 61 72  istered auxiliar
0dc0: 79 20 66 75 6e 63 74 69 6f 6e 20 2a 2f 0a 7d 3b  y function */.};
0dd0: 0a 0a 2f 2a 0a 2a 2a 20 45 61 63 68 20 74 6f 6b  ../*.** Each tok
0de0: 65 6e 69 7a 65 72 20 6d 6f 64 75 6c 65 20 72 65  enizer module re
0df0: 67 69 73 74 65 72 65 64 20 77 69 74 68 20 74 68  gistered with th
0e00: 65 20 46 54 53 35 20 6d 6f 64 75 6c 65 20 69 73  e FTS5 module is
0e10: 20 72 65 70 72 65 73 65 6e 74 65 64 0a 2a 2a 20   represented.** 
0e20: 62 79 20 61 6e 20 6f 62 6a 65 63 74 20 6f 66 20  by an object of 
0e30: 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 74 79  the following ty
0e40: 70 65 2e 20 41 6c 6c 20 73 75 63 68 20 6f 62 6a  pe. All such obj
0e50: 65 63 74 73 20 61 72 65 20 73 74 6f 72 65 64 20  ects are stored 
0e60: 61 73 20 70 61 72 74 0a 2a 2a 20 6f 66 20 74 68  as part.** of th
0e70: 65 20 46 74 73 35 47 6c 6f 62 61 6c 2e 70 54 6f  e Fts5Global.pTo
0e80: 6b 20 6c 69 73 74 2e 0a 2a 2f 0a 73 74 72 75 63  k list..*/.struc
0e90: 74 20 46 74 73 35 54 6f 6b 65 6e 69 7a 65 72 4d  t Fts5TokenizerM
0ea0: 6f 64 75 6c 65 20 7b 0a 20 20 63 68 61 72 20 2a  odule {.  char *
0eb0: 7a 4e 61 6d 65 3b 20 20 20 20 20 20 20 20 20 20  zName;          
0ec0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 61 6d            /* Nam
0ed0: 65 20 6f 66 20 74 6f 6b 65 6e 69 7a 65 72 20 2a  e of tokenizer *
0ee0: 2f 0a 20 20 76 6f 69 64 20 2a 70 55 73 65 72 44  /.  void *pUserD
0ef0: 61 74 61 3b 20 20 20 20 20 20 20 20 20 20 20 20  ata;            
0f00: 20 20 20 20 2f 2a 20 55 73 65 72 20 70 6f 69 6e      /* User poin
0f10: 74 65 72 20 70 61 73 73 65 64 20 74 6f 20 78 43  ter passed to xC
0f20: 72 65 61 74 65 28 29 20 2a 2f 0a 20 20 66 74 73  reate() */.  fts
0f30: 35 5f 74 6f 6b 65 6e 69 7a 65 72 20 78 3b 20 20  5_tokenizer x;  
0f40: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
0f50: 54 6f 6b 65 6e 69 7a 65 72 20 66 75 6e 63 74 69  Tokenizer functi
0f60: 6f 6e 73 20 2a 2f 0a 20 20 76 6f 69 64 20 28 2a  ons */.  void (*
0f70: 78 44 65 73 74 72 6f 79 29 28 76 6f 69 64 2a 29  xDestroy)(void*)
0f80: 3b 20 20 20 20 20 20 20 20 2f 2a 20 44 65 73 74  ;        /* Dest
0f90: 72 75 63 74 6f 72 20 66 75 6e 63 74 69 6f 6e 20  ructor function 
0fa0: 2a 2f 0a 20 20 46 74 73 35 54 6f 6b 65 6e 69 7a  */.  Fts5Tokeniz
0fb0: 65 72 4d 6f 64 75 6c 65 20 2a 70 4e 65 78 74 3b  erModule *pNext;
0fc0: 20 20 20 20 20 2f 2a 20 4e 65 78 74 20 72 65 67       /* Next reg
0fd0: 69 73 74 65 72 65 64 20 74 6f 6b 65 6e 69 7a 65  istered tokenize
0fe0: 72 20 6d 6f 64 75 6c 65 20 2a 2f 0a 7d 3b 0a 0a  r module */.};..
0ff0: 2f 2a 0a 2a 2a 20 56 69 72 74 75 61 6c 2d 74 61  /*.** Virtual-ta
1000: 62 6c 65 20 6f 62 6a 65 63 74 2e 0a 2a 2f 0a 73  ble object..*/.s
1010: 74 72 75 63 74 20 46 74 73 35 54 61 62 6c 65 20  truct Fts5Table 
1020: 7b 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62  {.  sqlite3_vtab
1030: 20 62 61 73 65 3b 20 20 20 20 20 20 20 20 20 20   base;          
1040: 20 20 20 20 2f 2a 20 42 61 73 65 20 63 6c 61 73      /* Base clas
1050: 73 20 75 73 65 64 20 62 79 20 53 51 4c 69 74 65  s used by SQLite
1060: 20 63 6f 72 65 20 2a 2f 0a 20 20 46 74 73 35 43   core */.  Fts5C
1070: 6f 6e 66 69 67 20 2a 70 43 6f 6e 66 69 67 3b 20  onfig *pConfig; 
1080: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 56 69             /* Vi
1090: 72 74 75 61 6c 20 74 61 62 6c 65 20 63 6f 6e 66  rtual table conf
10a0: 69 67 75 72 61 74 69 6f 6e 20 2a 2f 0a 20 20 46  iguration */.  F
10b0: 74 73 35 49 6e 64 65 78 20 2a 70 49 6e 64 65 78  ts5Index *pIndex
10c0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  ;              /
10d0: 2a 20 46 75 6c 6c 2d 74 65 78 74 20 69 6e 64 65  * Full-text inde
10e0: 78 20 2a 2f 0a 20 20 46 74 73 35 53 74 6f 72 61  x */.  Fts5Stora
10f0: 67 65 20 2a 70 53 74 6f 72 61 67 65 3b 20 20 20  ge *pStorage;   
1100: 20 20 20 20 20 20 20 2f 2a 20 44 6f 63 75 6d 65         /* Docume
1110: 6e 74 20 73 74 6f 72 65 20 2a 2f 0a 20 20 46 74  nt store */.  Ft
1120: 73 35 47 6c 6f 62 61 6c 20 2a 70 47 6c 6f 62 61  s5Global *pGloba
1130: 6c 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  l;            /*
1140: 20 47 6c 6f 62 61 6c 20 28 63 6f 6e 6e 65 63 74   Global (connect
1150: 69 6f 6e 20 77 69 64 65 29 20 64 61 74 61 20 2a  ion wide) data *
1160: 2f 0a 20 20 46 74 73 35 43 75 72 73 6f 72 20 2a  /.  Fts5Cursor *
1170: 70 53 6f 72 74 43 73 72 3b 20 20 20 20 20 20 20  pSortCsr;       
1180: 20 20 20 20 2f 2a 20 53 6f 72 74 20 64 61 74 61      /* Sort data
1190: 20 66 72 6f 6d 20 74 68 69 73 20 63 75 72 73 6f   from this curso
11a0: 72 20 2a 2f 0a 23 69 66 64 65 66 20 53 51 4c 49  r */.#ifdef SQLI
11b0: 54 45 5f 44 45 42 55 47 0a 20 20 73 74 72 75 63  TE_DEBUG.  struc
11c0: 74 20 46 74 73 35 54 72 61 6e 73 61 63 74 69 6f  t Fts5Transactio
11d0: 6e 53 74 61 74 65 20 74 73 3b 0a 23 65 6e 64 69  nState ts;.#endi
11e0: 66 0a 7d 3b 0a 0a 73 74 72 75 63 74 20 46 74 73  f.};..struct Fts
11f0: 35 4d 61 74 63 68 50 68 72 61 73 65 20 7b 0a 20  5MatchPhrase {. 
1200: 20 46 74 73 35 42 75 66 66 65 72 20 2a 70 50 6f   Fts5Buffer *pPo
1210: 73 6c 69 73 74 3b 20 20 20 20 20 20 20 20 20 20  slist;          
1220: 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 63   /* Pointer to c
1230: 75 72 72 65 6e 74 20 70 6f 73 6c 69 73 74 20 2a  urrent poslist *
1240: 2f 0a 20 20 69 6e 74 20 6e 54 65 72 6d 3b 20 20  /.  int nTerm;  
1250: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1260: 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 70      /* Size of p
1270: 68 72 61 73 65 20 69 6e 20 74 65 72 6d 73 20 2a  hrase in terms *
1280: 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 70 53 74 6d  /.};../*.** pStm
1290: 74 3a 0a 2a 2a 20 20 20 53 45 4c 45 43 54 20 72  t:.**   SELECT r
12a0: 6f 77 69 64 2c 20 3c 66 74 73 3e 20 46 52 4f 4d  owid, <fts> FROM
12b0: 20 3c 66 74 73 3e 20 4f 52 44 45 52 20 42 59 20   <fts> ORDER BY 
12c0: 2b 72 61 6e 6b 3b 0a 2a 2a 0a 2a 2a 20 61 49 64  +rank;.**.** aId
12d0: 78 5b 5d 3a 0a 2a 2a 20 20 20 54 68 65 72 65 20  x[]:.**   There 
12e0: 69 73 20 6f 6e 65 20 65 6e 74 72 79 20 69 6e 20  is one entry in 
12f0: 74 68 65 20 61 49 64 78 5b 5d 20 61 72 72 61 79  the aIdx[] array
1300: 20 66 6f 72 20 65 61 63 68 20 70 68 72 61 73 65   for each phrase
1310: 20 69 6e 20 74 68 65 20 71 75 65 72 79 2c 0a 2a   in the query,.*
1320: 2a 20 20 20 74 68 65 20 76 61 6c 75 65 20 6f 66  *   the value of
1330: 20 77 68 69 63 68 20 69 73 20 74 68 65 20 6f 66   which is the of
1340: 66 73 65 74 20 77 69 74 68 69 6e 20 61 50 6f 73  fset within aPos
1350: 6c 69 73 74 5b 5d 20 66 6f 6c 6c 6f 77 69 6e 67  list[] following
1360: 20 74 68 65 20 6c 61 73 74 20 0a 2a 2a 20 20 20   the last .**   
1370: 62 79 74 65 20 6f 66 20 74 68 65 20 70 6f 73 69  byte of the posi
1380: 74 69 6f 6e 20 6c 69 73 74 20 66 6f 72 20 74 68  tion list for th
1390: 65 20 63 6f 72 72 65 73 70 6f 6e 64 69 6e 67 20  e corresponding 
13a0: 70 68 72 61 73 65 2e 0a 2a 2f 0a 73 74 72 75 63  phrase..*/.struc
13b0: 74 20 46 74 73 35 53 6f 72 74 65 72 20 7b 0a 20  t Fts5Sorter {. 
13c0: 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70   sqlite3_stmt *p
13d0: 53 74 6d 74 3b 0a 20 20 69 36 34 20 69 52 6f 77  Stmt;.  i64 iRow
13e0: 69 64 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  id;             
13f0: 20 20 20 20 20 20 20 20 2f 2a 20 43 75 72 72 65          /* Curre
1400: 6e 74 20 72 6f 77 69 64 20 2a 2f 0a 20 20 63 6f  nt rowid */.  co
1410: 6e 73 74 20 75 38 20 2a 61 50 6f 73 6c 69 73 74  nst u8 *aPoslist
1420: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ;             /*
1430: 20 50 6f 73 69 74 69 6f 6e 20 6c 69 73 74 73 20   Position lists 
1440: 66 6f 72 20 63 75 72 72 65 6e 74 20 72 6f 77 20  for current row 
1450: 2a 2f 0a 20 20 69 6e 74 20 6e 49 64 78 3b 20 20  */.  int nIdx;  
1460: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1470: 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
1480: 66 20 65 6e 74 72 69 65 73 20 69 6e 20 61 49 64  f entries in aId
1490: 78 5b 5d 20 2a 2f 0a 20 20 69 6e 74 20 61 49 64  x[] */.  int aId
14a0: 78 5b 30 5d 3b 20 20 20 20 20 20 20 20 20 20 20  x[0];           
14b0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 66 66 73           /* Offs
14c0: 65 74 73 20 69 6e 74 6f 20 61 50 6f 73 6c 69 73  ets into aPoslis
14d0: 74 20 66 6f 72 20 63 75 72 72 65 6e 74 20 72 6f  t for current ro
14e0: 77 20 2a 2f 0a 7d 3b 0a 0a 0a 2f 2a 0a 2a 2a 20  w */.};.../*.** 
14f0: 56 69 72 74 75 61 6c 2d 74 61 62 6c 65 20 63 75  Virtual-table cu
1500: 72 73 6f 72 20 6f 62 6a 65 63 74 2e 0a 2a 2a 0a  rsor object..**.
1510: 2a 2a 20 7a 53 70 65 63 69 61 6c 3a 0a 2a 2a 20  ** zSpecial:.** 
1520: 20 20 49 66 20 74 68 69 73 20 69 73 20 61 20 27    If this is a '
1530: 73 70 65 63 69 61 6c 27 20 71 75 65 72 79 20 28  special' query (
1540: 72 65 66 65 72 20 74 6f 20 66 75 6e 63 74 69 6f  refer to functio
1550: 6e 20 66 74 73 35 53 70 65 63 69 61 6c 4d 61 74  n fts5SpecialMat
1560: 63 68 28 29 29 2c 20 0a 2a 2a 20 20 20 74 68 65  ch()), .**   the
1570: 6e 20 74 68 69 73 20 76 61 72 69 61 62 6c 65 20  n this variable 
1580: 70 6f 69 6e 74 73 20 74 6f 20 61 20 6e 75 6c 2d  points to a nul-
1590: 74 65 72 6d 69 6e 61 74 65 64 20 62 75 66 66 65  terminated buffe
15a0: 72 20 63 6f 6e 74 61 69 6e 69 6e 67 20 74 68 65  r containing the
15b0: 0a 2a 2a 20 20 20 72 65 73 75 6c 74 20 74 6f 20  .**   result to 
15c0: 72 65 74 75 72 6e 20 74 68 72 6f 75 67 68 20 74  return through t
15d0: 68 65 20 74 61 62 6c 65 2d 6e 61 6d 65 20 63 6f  he table-name co
15e0: 6c 75 6d 6e 2e 20 49 74 20 69 73 20 6e 75 6c 2d  lumn. It is nul-
15f0: 74 65 72 6d 69 6e 61 74 65 64 0a 2a 2a 20 20 20  terminated.**   
1600: 61 6e 64 20 73 68 6f 75 6c 64 20 65 76 65 6e 74  and should event
1610: 75 61 6c 6c 79 20 62 65 20 66 72 65 65 64 20 75  ually be freed u
1620: 73 69 6e 67 20 73 71 6c 69 74 65 33 5f 66 72 65  sing sqlite3_fre
1630: 65 28 29 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 46  e()..*/.struct F
1640: 74 73 35 43 75 72 73 6f 72 20 7b 0a 20 20 73 71  ts5Cursor {.  sq
1650: 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f  lite3_vtab_curso
1660: 72 20 62 61 73 65 3b 20 20 20 20 20 20 20 2f 2a  r base;       /*
1670: 20 42 61 73 65 20 63 6c 61 73 73 20 75 73 65 64   Base class used
1680: 20 62 79 20 53 51 4c 69 74 65 20 63 6f 72 65 20   by SQLite core 
1690: 2a 2f 0a 20 20 69 6e 74 20 69 64 78 4e 75 6d 3b  */.  int idxNum;
16a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16b0: 20 20 20 20 20 2f 2a 20 69 64 78 4e 75 6d 20 70       /* idxNum p
16c0: 61 73 73 65 64 20 74 6f 20 78 46 69 6c 74 65 72  assed to xFilter
16d0: 28 29 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f  () */.  sqlite3_
16e0: 73 74 6d 74 20 2a 70 53 74 6d 74 3b 20 20 20 20  stmt *pStmt;    
16f0: 20 20 20 20 20 20 20 20 2f 2a 20 53 74 61 74 65          /* State
1700: 6d 65 6e 74 20 75 73 65 64 20 74 6f 20 72 65 61  ment used to rea
1710: 64 20 25 5f 63 6f 6e 74 65 6e 74 20 2a 2f 0a 20  d %_content */. 
1720: 20 46 74 73 35 45 78 70 72 20 2a 70 45 78 70 72   Fts5Expr *pExpr
1730: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
1740: 20 2f 2a 20 45 78 70 72 65 73 73 69 6f 6e 20 66   /* Expression f
1750: 6f 72 20 4d 41 54 43 48 20 71 75 65 72 69 65 73  or MATCH queries
1760: 20 2a 2f 0a 20 20 46 74 73 35 53 6f 72 74 65 72   */.  Fts5Sorter
1770: 20 2a 70 53 6f 72 74 65 72 3b 20 20 20 20 20 20   *pSorter;      
1780: 20 20 20 20 20 20 2f 2a 20 53 6f 72 74 65 72 20        /* Sorter 
1790: 66 6f 72 20 22 4f 52 44 45 52 20 42 59 20 72 61  for "ORDER BY ra
17a0: 6e 6b 22 20 71 75 65 72 69 65 73 20 2a 2f 0a 20  nk" queries */. 
17b0: 20 69 6e 74 20 63 73 72 66 6c 61 67 73 3b 20 20   int csrflags;  
17c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
17d0: 20 2f 2a 20 4d 61 73 6b 20 6f 66 20 63 75 72 73   /* Mask of curs
17e0: 6f 72 20 66 6c 61 67 73 20 28 73 65 65 20 62 65  or flags (see be
17f0: 6c 6f 77 29 20 2a 2f 0a 20 20 46 74 73 35 43 75  low) */.  Fts5Cu
1800: 72 73 6f 72 20 2a 70 4e 65 78 74 3b 20 20 20 20  rsor *pNext;    
1810: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 65 78            /* Nex
1820: 74 20 63 75 72 73 6f 72 20 69 6e 20 46 74 73 35  t cursor in Fts5
1830: 43 75 72 73 6f 72 2e 70 43 73 72 20 6c 69 73 74  Cursor.pCsr list
1840: 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 53 70 65   */.  char *zSpe
1850: 63 69 61 6c 3b 20 20 20 20 20 20 20 20 20 20 20  cial;           
1860: 20 20 20 20 20 20 2f 2a 20 52 65 73 75 6c 74 20        /* Result 
1870: 6f 66 20 73 70 65 63 69 61 6c 20 71 75 65 72 79  of special query
1880: 20 2a 2f 0a 0a 20 20 2f 2a 20 22 72 61 6e 6b 22   */..  /* "rank"
1890: 20 66 75 6e 63 74 69 6f 6e 2e 20 50 6f 70 75 6c   function. Popul
18a0: 61 74 65 64 20 6f 6e 20 64 65 6d 61 6e 64 20 66  ated on demand f
18b0: 72 6f 6d 20 76 74 61 62 2e 78 43 6f 6c 75 6d 6e  rom vtab.xColumn
18c0: 28 29 2e 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a  (). */.  char *z
18d0: 52 61 6e 6b 3b 20 20 20 20 20 20 20 20 20 20 20  Rank;           
18e0: 20 20 20 20 20 20 20 20 20 2f 2a 20 43 75 73 74           /* Cust
18f0: 6f 6d 20 72 61 6e 6b 20 66 75 6e 63 74 69 6f 6e  om rank function
1900: 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 52 61 6e   */.  char *zRan
1910: 6b 41 72 67 73 3b 20 20 20 20 20 20 20 20 20 20  kArgs;          
1920: 20 20 20 20 20 20 2f 2a 20 43 75 73 74 6f 6d 20        /* Custom 
1930: 72 61 6e 6b 20 66 75 6e 63 74 69 6f 6e 20 61 72  rank function ar
1940: 67 73 20 2a 2f 0a 20 20 46 74 73 35 41 75 78 69  gs */.  Fts5Auxi
1950: 6c 69 61 72 79 20 2a 70 52 61 6e 6b 3b 20 20 20  liary *pRank;   
1960: 20 20 20 20 20 20 20 20 2f 2a 20 52 61 6e 6b 20          /* Rank 
1970: 63 61 6c 6c 62 61 63 6b 20 28 6f 72 20 4e 55 4c  callback (or NUL
1980: 4c 29 20 2a 2f 0a 20 20 69 6e 74 20 6e 52 61 6e  L) */.  int nRan
1990: 6b 41 72 67 3b 20 20 20 20 20 20 20 20 20 20 20  kArg;           
19a0: 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65          /* Numbe
19b0: 72 20 6f 66 20 74 72 61 69 6c 69 6e 67 20 61 72  r of trailing ar
19c0: 67 75 6d 65 6e 74 73 20 66 6f 72 20 72 61 6e 6b  guments for rank
19d0: 28 29 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f  () */.  sqlite3_
19e0: 76 61 6c 75 65 20 2a 2a 61 70 52 61 6e 6b 41 72  value **apRankAr
19f0: 67 3b 20 20 20 20 20 20 2f 2a 20 41 72 72 61 79  g;      /* Array
1a00: 20 6f 66 20 74 72 61 69 6c 69 6e 67 20 61 72 67   of trailing arg
1a10: 75 6d 65 6e 74 73 20 2a 2f 0a 20 20 73 71 6c 69  uments */.  sqli
1a20: 74 65 33 5f 73 74 6d 74 20 2a 70 52 61 6e 6b 41  te3_stmt *pRankA
1a30: 72 67 53 74 6d 74 3b 20 20 20 20 20 2f 2a 20 4f  rgStmt;     /* O
1a40: 72 69 67 69 6e 20 6f 66 20 6f 62 6a 65 63 74 73  rigin of objects
1a50: 20 69 6e 20 61 70 52 61 6e 6b 41 72 67 5b 5d 20   in apRankArg[] 
1a60: 2a 2f 0a 0a 20 20 2f 2a 20 56 61 72 69 61 62 6c  */..  /* Variabl
1a70: 65 73 20 75 73 65 64 20 62 79 20 61 75 78 69 6c  es used by auxil
1a80: 69 61 72 79 20 66 75 6e 63 74 69 6f 6e 73 20 2a  iary functions *
1a90: 2f 0a 20 20 69 36 34 20 69 43 73 72 49 64 3b 20  /.  i64 iCsrId; 
1aa0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1ab0: 20 20 20 20 2f 2a 20 43 75 72 73 6f 72 20 69 64      /* Cursor id
1ac0: 20 2a 2f 0a 20 20 46 74 73 35 41 75 78 69 6c 69   */.  Fts5Auxili
1ad0: 61 72 79 20 2a 70 41 75 78 3b 20 20 20 20 20 20  ary *pAux;      
1ae0: 20 20 20 20 20 20 2f 2a 20 43 75 72 72 65 6e 74        /* Current
1af0: 6c 79 20 65 78 65 63 75 74 69 6e 67 20 65 78 74  ly executing ext
1b00: 65 6e 73 69 6f 6e 20 66 75 6e 63 74 69 6f 6e 20  ension function 
1b10: 2a 2f 0a 20 20 46 74 73 35 41 75 78 64 61 74 61  */.  Fts5Auxdata
1b20: 20 2a 70 41 75 78 64 61 74 61 3b 20 20 20 20 20   *pAuxdata;     
1b30: 20 20 20 20 20 2f 2a 20 46 69 72 73 74 20 69 6e       /* First in
1b40: 20 6c 69 6e 6b 65 64 20 6c 69 73 74 20 6f 66 20   linked list of 
1b50: 73 61 76 65 64 20 61 75 78 2d 64 61 74 61 20 2a  saved aux-data *
1b60: 2f 0a 20 20 69 6e 74 20 2a 61 43 6f 6c 75 6d 6e  /.  int *aColumn
1b70: 53 69 7a 65 3b 20 20 20 20 20 20 20 20 20 20 20  Size;           
1b80: 20 20 20 20 2f 2a 20 56 61 6c 75 65 73 20 66 6f      /* Values fo
1b90: 72 20 78 43 6f 6c 75 6d 6e 53 69 7a 65 28 29 20  r xColumnSize() 
1ba0: 2a 2f 0a 0a 20 20 69 6e 74 20 6e 49 6e 73 74 43  */..  int nInstC
1bb0: 6f 75 6e 74 3b 20 20 20 20 20 20 20 20 20 20 20  ount;           
1bc0: 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20        /* Number 
1bd0: 6f 66 20 70 68 72 61 73 65 20 69 6e 73 74 61 6e  of phrase instan
1be0: 63 65 73 20 2a 2f 0a 20 20 69 6e 74 20 2a 61 49  ces */.  int *aI
1bf0: 6e 73 74 3b 20 20 20 20 20 20 20 20 20 20 20 20  nst;            
1c00: 20 20 20 20 20 20 20 20 20 2f 2a 20 33 20 69 6e           /* 3 in
1c10: 74 65 67 65 72 73 20 70 65 72 20 70 68 72 61 73  tegers per phras
1c20: 65 20 69 6e 73 74 61 6e 63 65 20 2a 2f 0a 7d 3b  e instance */.};
1c30: 0a 0a 2f 2a 0a 2a 2a 20 56 61 6c 75 65 73 20 66  ../*.** Values f
1c40: 6f 72 20 46 74 73 35 43 75 72 73 6f 72 2e 63 73  or Fts5Cursor.cs
1c50: 72 66 6c 61 67 73 0a 2a 2f 0a 23 64 65 66 69 6e  rflags.*/.#defin
1c60: 65 20 46 54 53 35 43 53 52 5f 52 45 51 55 49 52  e FTS5CSR_REQUIR
1c70: 45 5f 43 4f 4e 54 45 4e 54 20 20 20 30 78 30 31  E_CONTENT   0x01
1c80: 0a 23 64 65 66 69 6e 65 20 46 54 53 35 43 53 52  .#define FTS5CSR
1c90: 5f 52 45 51 55 49 52 45 5f 44 4f 43 53 49 5a 45  _REQUIRE_DOCSIZE
1ca0: 20 20 20 30 78 30 32 0a 23 64 65 66 69 6e 65 20     0x02.#define 
1cb0: 46 54 53 35 43 53 52 5f 45 4f 46 20 20 20 20 20  FTS5CSR_EOF     
1cc0: 20 20 20 20 20 20 20 20 20 20 30 78 30 34 0a 23            0x04.#
1cd0: 64 65 66 69 6e 65 20 46 54 53 35 43 53 52 5f 46  define FTS5CSR_F
1ce0: 52 45 45 5f 5a 52 41 4e 4b 20 20 20 20 20 20 20  REE_ZRANK       
1cf0: 20 30 78 30 38 0a 0a 2f 2a 0a 2a 2a 20 4d 61 63   0x08../*.** Mac
1d00: 72 6f 73 20 74 6f 20 53 65 74 28 29 2c 20 43 6c  ros to Set(), Cl
1d10: 65 61 72 28 29 20 61 6e 64 20 54 65 73 74 28 29  ear() and Test()
1d20: 20 63 75 72 73 6f 72 20 66 6c 61 67 73 2e 0a 2a   cursor flags..*
1d30: 2f 0a 23 64 65 66 69 6e 65 20 43 73 72 46 6c 61  /.#define CsrFla
1d40: 67 53 65 74 28 70 43 73 72 2c 20 66 6c 61 67 29  gSet(pCsr, flag)
1d50: 20 20 20 28 28 70 43 73 72 29 2d 3e 63 73 72 66     ((pCsr)->csrf
1d60: 6c 61 67 73 20 7c 3d 20 28 66 6c 61 67 29 29 0a  lags |= (flag)).
1d70: 23 64 65 66 69 6e 65 20 43 73 72 46 6c 61 67 43  #define CsrFlagC
1d80: 6c 65 61 72 28 70 43 73 72 2c 20 66 6c 61 67 29  lear(pCsr, flag)
1d90: 20 28 28 70 43 73 72 29 2d 3e 63 73 72 66 6c 61   ((pCsr)->csrfla
1da0: 67 73 20 26 3d 20 7e 28 66 6c 61 67 29 29 0a 23  gs &= ~(flag)).#
1db0: 64 65 66 69 6e 65 20 43 73 72 46 6c 61 67 54 65  define CsrFlagTe
1dc0: 73 74 28 70 43 73 72 2c 20 66 6c 61 67 29 20 20  st(pCsr, flag)  
1dd0: 28 28 70 43 73 72 29 2d 3e 63 73 72 66 6c 61 67  ((pCsr)->csrflag
1de0: 73 20 26 20 28 66 6c 61 67 29 29 0a 0a 73 74 72  s & (flag))..str
1df0: 75 63 74 20 46 74 73 35 41 75 78 64 61 74 61 20  uct Fts5Auxdata 
1e00: 7b 0a 20 20 46 74 73 35 41 75 78 69 6c 69 61 72  {.  Fts5Auxiliar
1e10: 79 20 2a 70 41 75 78 3b 20 20 20 20 20 20 20 20  y *pAux;        
1e20: 20 20 20 20 2f 2a 20 45 78 74 65 6e 73 69 6f 6e      /* Extension
1e30: 20 74 6f 20 77 68 69 63 68 20 74 68 69 73 20 62   to which this b
1e40: 65 6c 6f 6e 67 73 20 2a 2f 0a 20 20 76 6f 69 64  elongs */.  void
1e50: 20 2a 70 50 74 72 3b 20 20 20 20 20 20 20 20 20   *pPtr;         
1e60: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50              /* P
1e70: 6f 69 6e 74 65 72 20 76 61 6c 75 65 20 2a 2f 0a  ointer value */.
1e80: 20 20 76 6f 69 64 28 2a 78 44 65 6c 65 74 65 29    void(*xDelete)
1e90: 28 76 6f 69 64 2a 29 3b 20 20 20 20 20 20 20 20  (void*);        
1ea0: 20 20 2f 2a 20 44 65 73 74 72 75 63 74 6f 72 20    /* Destructor 
1eb0: 2a 2f 0a 20 20 46 74 73 35 41 75 78 64 61 74 61  */.  Fts5Auxdata
1ec0: 20 2a 70 4e 65 78 74 3b 20 20 20 20 20 20 20 20   *pNext;        
1ed0: 20 20 20 20 20 2f 2a 20 4e 65 78 74 20 6f 62 6a       /* Next obj
1ee0: 65 63 74 20 69 6e 20 6c 69 6e 6b 65 64 20 6c 69  ect in linked li
1ef0: 73 74 20 2a 2f 0a 7d 3b 0a 0a 23 69 66 64 65 66  st */.};..#ifdef
1f00: 20 53 51 4c 49 54 45 5f 44 45 42 55 47 0a 23 64   SQLITE_DEBUG.#d
1f10: 65 66 69 6e 65 20 46 54 53 35 5f 42 45 47 49 4e  efine FTS5_BEGIN
1f20: 20 20 20 20 20 20 31 0a 23 64 65 66 69 6e 65 20        1.#define 
1f30: 46 54 53 35 5f 53 59 4e 43 20 20 20 20 20 20 20  FTS5_SYNC       
1f40: 32 0a 23 64 65 66 69 6e 65 20 46 54 53 35 5f 43  2.#define FTS5_C
1f50: 4f 4d 4d 49 54 20 20 20 20 20 33 0a 23 64 65 66  OMMIT     3.#def
1f60: 69 6e 65 20 46 54 53 35 5f 52 4f 4c 4c 42 41 43  ine FTS5_ROLLBAC
1f70: 4b 20 20 20 34 0a 23 64 65 66 69 6e 65 20 46 54  K   4.#define FT
1f80: 53 35 5f 53 41 56 45 50 4f 49 4e 54 20 20 35 0a  S5_SAVEPOINT  5.
1f90: 23 64 65 66 69 6e 65 20 46 54 53 35 5f 52 45 4c  #define FTS5_REL
1fa0: 45 41 53 45 20 20 20 20 36 0a 23 64 65 66 69 6e  EASE    6.#defin
1fb0: 65 20 46 54 53 35 5f 52 4f 4c 4c 42 41 43 4b 54  e FTS5_ROLLBACKT
1fc0: 4f 20 37 0a 73 74 61 74 69 63 20 76 6f 69 64 20  O 7.static void 
1fd0: 66 74 73 35 43 68 65 63 6b 54 72 61 6e 73 61 63  fts5CheckTransac
1fe0: 74 69 6f 6e 53 74 61 74 65 28 46 74 73 35 54 61  tionState(Fts5Ta
1ff0: 62 6c 65 20 2a 70 2c 20 69 6e 74 20 6f 70 2c 20  ble *p, int op, 
2000: 69 6e 74 20 69 53 61 76 65 70 6f 69 6e 74 29 7b  int iSavepoint){
2010: 0a 20 20 73 77 69 74 63 68 28 20 6f 70 20 29 7b  .  switch( op ){
2020: 0a 20 20 20 20 63 61 73 65 20 46 54 53 35 5f 42  .    case FTS5_B
2030: 45 47 49 4e 3a 0a 20 20 20 20 20 20 61 73 73 65  EGIN:.      asse
2040: 72 74 28 20 70 2d 3e 74 73 2e 65 53 74 61 74 65  rt( p->ts.eState
2050: 3d 3d 30 20 29 3b 0a 20 20 20 20 20 20 70 2d 3e  ==0 );.      p->
2060: 74 73 2e 65 53 74 61 74 65 20 3d 20 31 3b 0a 20  ts.eState = 1;. 
2070: 20 20 20 20 20 70 2d 3e 74 73 2e 69 53 61 76 65       p->ts.iSave
2080: 70 6f 69 6e 74 20 3d 20 2d 31 3b 0a 20 20 20 20  point = -1;.    
2090: 20 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20 63 61    break;..    ca
20a0: 73 65 20 46 54 53 35 5f 53 59 4e 43 3a 0a 20 20  se FTS5_SYNC:.  
20b0: 20 20 20 20 61 73 73 65 72 74 28 20 70 2d 3e 74      assert( p->t
20c0: 73 2e 65 53 74 61 74 65 3d 3d 31 20 29 3b 0a 20  s.eState==1 );. 
20d0: 20 20 20 20 20 70 2d 3e 74 73 2e 65 53 74 61 74       p->ts.eStat
20e0: 65 20 3d 20 32 3b 0a 20 20 20 20 20 20 62 72 65  e = 2;.      bre
20f0: 61 6b 3b 0a 0a 20 20 20 20 63 61 73 65 20 46 54  ak;..    case FT
2100: 53 35 5f 43 4f 4d 4d 49 54 3a 0a 20 20 20 20 20  S5_COMMIT:.     
2110: 20 61 73 73 65 72 74 28 20 70 2d 3e 74 73 2e 65   assert( p->ts.e
2120: 53 74 61 74 65 3d 3d 32 20 29 3b 0a 20 20 20 20  State==2 );.    
2130: 20 20 70 2d 3e 74 73 2e 65 53 74 61 74 65 20 3d    p->ts.eState =
2140: 20 30 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b   0;.      break;
2150: 0a 0a 20 20 20 20 63 61 73 65 20 46 54 53 35 5f  ..    case FTS5_
2160: 52 4f 4c 4c 42 41 43 4b 3a 0a 20 20 20 20 20 20  ROLLBACK:.      
2170: 61 73 73 65 72 74 28 20 70 2d 3e 74 73 2e 65 53  assert( p->ts.eS
2180: 74 61 74 65 3d 3d 31 20 7c 7c 20 70 2d 3e 74 73  tate==1 || p->ts
2190: 2e 65 53 74 61 74 65 3d 3d 32 20 7c 7c 20 70 2d  .eState==2 || p-
21a0: 3e 74 73 2e 65 53 74 61 74 65 3d 3d 30 20 29 3b  >ts.eState==0 );
21b0: 0a 20 20 20 20 20 20 70 2d 3e 74 73 2e 65 53 74  .      p->ts.eSt
21c0: 61 74 65 20 3d 20 30 3b 0a 20 20 20 20 20 20 62  ate = 0;.      b
21d0: 72 65 61 6b 3b 0a 0a 20 20 20 20 63 61 73 65 20  reak;..    case 
21e0: 46 54 53 35 5f 53 41 56 45 50 4f 49 4e 54 3a 0a  FTS5_SAVEPOINT:.
21f0: 20 20 20 20 20 20 61 73 73 65 72 74 28 20 70 2d        assert( p-
2200: 3e 74 73 2e 65 53 74 61 74 65 3d 3d 31 20 29 3b  >ts.eState==1 );
2210: 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20 69  .      assert( i
2220: 53 61 76 65 70 6f 69 6e 74 3e 3d 30 20 29 3b 0a  Savepoint>=0 );.
2230: 20 20 20 20 20 20 61 73 73 65 72 74 28 20 69 53        assert( iS
2240: 61 76 65 70 6f 69 6e 74 3e 70 2d 3e 74 73 2e 69  avepoint>p->ts.i
2250: 53 61 76 65 70 6f 69 6e 74 20 29 3b 0a 20 20 20  Savepoint );.   
2260: 20 20 20 70 2d 3e 74 73 2e 69 53 61 76 65 70 6f     p->ts.iSavepo
2270: 69 6e 74 20 3d 20 69 53 61 76 65 70 6f 69 6e 74  int = iSavepoint
2280: 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20  ;.      break;. 
2290: 20 20 20 20 20 0a 20 20 20 20 63 61 73 65 20 46       .    case F
22a0: 54 53 35 5f 52 45 4c 45 41 53 45 3a 0a 20 20 20  TS5_RELEASE:.   
22b0: 20 20 20 61 73 73 65 72 74 28 20 70 2d 3e 74 73     assert( p->ts
22c0: 2e 65 53 74 61 74 65 3d 3d 31 20 29 3b 0a 20 20  .eState==1 );.  
22d0: 20 20 20 20 61 73 73 65 72 74 28 20 69 53 61 76      assert( iSav
22e0: 65 70 6f 69 6e 74 3e 3d 30 20 29 3b 0a 20 20 20  epoint>=0 );.   
22f0: 20 20 20 61 73 73 65 72 74 28 20 69 53 61 76 65     assert( iSave
2300: 70 6f 69 6e 74 3c 3d 70 2d 3e 74 73 2e 69 53 61  point<=p->ts.iSa
2310: 76 65 70 6f 69 6e 74 20 29 3b 0a 20 20 20 20 20  vepoint );.     
2320: 20 70 2d 3e 74 73 2e 69 53 61 76 65 70 6f 69 6e   p->ts.iSavepoin
2330: 74 20 3d 20 69 53 61 76 65 70 6f 69 6e 74 2d 31  t = iSavepoint-1
2340: 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 0a  ;.      break;..
2350: 20 20 20 20 63 61 73 65 20 46 54 53 35 5f 52 4f      case FTS5_RO
2360: 4c 4c 42 41 43 4b 54 4f 3a 0a 20 20 20 20 20 20  LLBACKTO:.      
2370: 61 73 73 65 72 74 28 20 70 2d 3e 74 73 2e 65 53  assert( p->ts.eS
2380: 74 61 74 65 3d 3d 31 20 29 3b 0a 20 20 20 20 20  tate==1 );.     
2390: 20 61 73 73 65 72 74 28 20 69 53 61 76 65 70 6f   assert( iSavepo
23a0: 69 6e 74 3e 3d 30 20 29 3b 0a 20 20 20 20 20 20  int>=0 );.      
23b0: 61 73 73 65 72 74 28 20 69 53 61 76 65 70 6f 69  assert( iSavepoi
23c0: 6e 74 3c 3d 70 2d 3e 74 73 2e 69 53 61 76 65 70  nt<=p->ts.iSavep
23d0: 6f 69 6e 74 20 29 3b 0a 20 20 20 20 20 20 70 2d  oint );.      p-
23e0: 3e 74 73 2e 69 53 61 76 65 70 6f 69 6e 74 20 3d  >ts.iSavepoint =
23f0: 20 69 53 61 76 65 70 6f 69 6e 74 3b 0a 20 20 20   iSavepoint;.   
2400: 20 20 20 62 72 65 61 6b 3b 0a 20 20 7d 0a 7d 0a     break;.  }.}.
2410: 23 65 6c 73 65 0a 23 20 64 65 66 69 6e 65 20 66  #else.# define f
2420: 74 73 35 43 68 65 63 6b 54 72 61 6e 73 61 63 74  ts5CheckTransact
2430: 69 6f 6e 53 74 61 74 65 28 78 2c 79 2c 7a 29 0a  ionState(x,y,z).
2440: 23 65 6e 64 69 66 0a 0a 2f 2a 0a 2a 2a 20 52 65  #endif../*.** Re
2450: 74 75 72 6e 20 74 72 75 65 20 69 66 20 70 54 61  turn true if pTa
2460: 62 20 69 73 20 61 20 63 6f 6e 74 65 6e 74 6c 65  b is a contentle
2470: 73 73 20 74 61 62 6c 65 2e 0a 2a 2f 0a 73 74 61  ss table..*/.sta
2480: 74 69 63 20 69 6e 74 20 66 74 73 35 49 73 43 6f  tic int fts5IsCo
2490: 6e 74 65 6e 74 6c 65 73 73 28 46 74 73 35 54 61  ntentless(Fts5Ta
24a0: 62 6c 65 20 2a 70 54 61 62 29 7b 0a 20 20 72 65  ble *pTab){.  re
24b0: 74 75 72 6e 20 70 54 61 62 2d 3e 70 43 6f 6e 66  turn pTab->pConf
24c0: 69 67 2d 3e 65 43 6f 6e 74 65 6e 74 3d 3d 46 54  ig->eContent==FT
24d0: 53 35 5f 43 4f 4e 54 45 4e 54 5f 4e 4f 4e 45 3b  S5_CONTENT_NONE;
24e0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6c 6f 73 65 20  .}../*.** Close 
24f0: 61 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20  a virtual table 
2500: 68 61 6e 64 6c 65 20 6f 70 65 6e 65 64 20 62 79  handle opened by
2510: 20 66 74 73 35 49 6e 69 74 56 74 61 62 28 29 2e   fts5InitVtab().
2520: 20 49 66 20 74 68 65 20 62 44 65 73 74 72 6f 79   If the bDestroy
2530: 0a 2a 2a 20 61 72 67 75 6d 65 6e 74 20 69 73 20  .** argument is 
2540: 6e 6f 6e 2d 7a 65 72 6f 2c 20 61 74 74 65 6d 70  non-zero, attemp
2550: 74 20 64 65 6c 65 74 65 20 74 68 65 20 73 68 61  t delete the sha
2560: 64 6f 77 20 74 61 62 6c 65 73 20 66 72 6f 6d 20  dow tables from 
2570: 74 65 68 20 64 61 74 61 62 61 73 65 0a 2a 2f 0a  teh database.*/.
2580: 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 46  static int fts5F
2590: 72 65 65 56 74 61 62 28 46 74 73 35 54 61 62 6c  reeVtab(Fts5Tabl
25a0: 65 20 2a 70 54 61 62 2c 20 69 6e 74 20 62 44 65  e *pTab, int bDe
25b0: 73 74 72 6f 79 29 7b 0a 20 20 69 6e 74 20 72 63  stroy){.  int rc
25c0: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20   = SQLITE_OK;.  
25d0: 69 66 28 20 70 54 61 62 20 29 7b 0a 20 20 20 20  if( pTab ){.    
25e0: 69 6e 74 20 72 63 32 3b 0a 20 20 20 20 72 63 32  int rc2;.    rc2
25f0: 20 3d 20 73 71 6c 69 74 65 33 46 74 73 35 49 6e   = sqlite3Fts5In
2600: 64 65 78 43 6c 6f 73 65 28 70 54 61 62 2d 3e 70  dexClose(pTab->p
2610: 49 6e 64 65 78 2c 20 62 44 65 73 74 72 6f 79 29  Index, bDestroy)
2620: 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51  ;.    if( rc==SQ
2630: 4c 49 54 45 5f 4f 4b 20 29 20 72 63 20 3d 20 72  LITE_OK ) rc = r
2640: 63 32 3b 0a 20 20 20 20 72 63 32 20 3d 20 73 71  c2;.    rc2 = sq
2650: 6c 69 74 65 33 46 74 73 35 53 74 6f 72 61 67 65  lite3Fts5Storage
2660: 43 6c 6f 73 65 28 70 54 61 62 2d 3e 70 53 74 6f  Close(pTab->pSto
2670: 72 61 67 65 2c 20 62 44 65 73 74 72 6f 79 29 3b  rage, bDestroy);
2680: 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  .    if( rc==SQL
2690: 49 54 45 5f 4f 4b 20 29 20 72 63 20 3d 20 72 63  ITE_OK ) rc = rc
26a0: 32 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 46 74  2;.    sqlite3Ft
26b0: 73 35 43 6f 6e 66 69 67 46 72 65 65 28 70 54 61  s5ConfigFree(pTa
26c0: 62 2d 3e 70 43 6f 6e 66 69 67 29 3b 0a 20 20 20  b->pConfig);.   
26d0: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 54   sqlite3_free(pT
26e0: 61 62 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72  ab);.  }.  retur
26f0: 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54  n rc;.}../*.** T
2700: 68 65 20 78 44 69 73 63 6f 6e 6e 65 63 74 28 29  he xDisconnect()
2710: 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20 6d   virtual table m
2720: 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69 63  ethod..*/.static
2730: 20 69 6e 74 20 66 74 73 35 44 69 73 63 6f 6e 6e   int fts5Disconn
2740: 65 63 74 4d 65 74 68 6f 64 28 73 71 6c 69 74 65  ectMethod(sqlite
2750: 33 5f 76 74 61 62 20 2a 70 56 74 61 62 29 7b 0a  3_vtab *pVtab){.
2760: 20 20 72 65 74 75 72 6e 20 66 74 73 35 46 72 65    return fts5Fre
2770: 65 56 74 61 62 28 28 46 74 73 35 54 61 62 6c 65  eVtab((Fts5Table
2780: 2a 29 70 56 74 61 62 2c 20 30 29 3b 0a 7d 0a 0a  *)pVtab, 0);.}..
2790: 2f 2a 0a 2a 2a 20 54 68 65 20 78 44 65 73 74 72  /*.** The xDestr
27a0: 6f 79 28 29 20 76 69 72 74 75 61 6c 20 74 61 62  oy() virtual tab
27b0: 6c 65 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74  le method..*/.st
27c0: 61 74 69 63 20 69 6e 74 20 66 74 73 35 44 65 73  atic int fts5Des
27d0: 74 72 6f 79 4d 65 74 68 6f 64 28 73 71 6c 69 74  troyMethod(sqlit
27e0: 65 33 5f 76 74 61 62 20 2a 70 56 74 61 62 29 7b  e3_vtab *pVtab){
27f0: 0a 20 20 72 65 74 75 72 6e 20 66 74 73 35 46 72  .  return fts5Fr
2800: 65 65 56 74 61 62 28 28 46 74 73 35 54 61 62 6c  eeVtab((Fts5Tabl
2810: 65 2a 29 70 56 74 61 62 2c 20 31 29 3b 0a 7d 0a  e*)pVtab, 1);.}.
2820: 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63  ./*.** This func
2830: 74 69 6f 6e 20 69 73 20 74 68 65 20 69 6d 70 6c  tion is the impl
2840: 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 62 6f  ementation of bo
2850: 74 68 20 74 68 65 20 78 43 6f 6e 6e 65 63 74 20  th the xConnect 
2860: 61 6e 64 20 78 43 72 65 61 74 65 0a 2a 2a 20 6d  and xCreate.** m
2870: 65 74 68 6f 64 73 20 6f 66 20 74 68 65 20 46 54  ethods of the FT
2880: 53 33 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65  S3 virtual table
2890: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 72 67 76  ..**.** The argv
28a0: 5b 5d 20 61 72 72 61 79 20 63 6f 6e 74 61 69 6e  [] array contain
28b0: 73 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 3a  s the following:
28c0: 0a 2a 2a 0a 2a 2a 20 20 20 61 72 67 76 5b 30 5d  .**.**   argv[0]
28d0: 20 20 20 2d 3e 20 6d 6f 64 75 6c 65 20 6e 61 6d     -> module nam
28e0: 65 20 20 28 22 66 74 73 35 22 29 0a 2a 2a 20 20  e  ("fts5").**  
28f0: 20 61 72 67 76 5b 31 5d 20 20 20 2d 3e 20 64 61   argv[1]   -> da
2900: 74 61 62 61 73 65 20 6e 61 6d 65 0a 2a 2a 20 20  tabase name.**  
2910: 20 61 72 67 76 5b 32 5d 20 20 20 2d 3e 20 74 61   argv[2]   -> ta
2920: 62 6c 65 20 6e 61 6d 65 0a 2a 2a 20 20 20 61 72  ble name.**   ar
2930: 67 76 5b 2e 2e 2e 5d 20 2d 3e 20 22 63 6f 6c 75  gv[...] -> "colu
2940: 6d 6e 20 6e 61 6d 65 22 20 61 6e 64 20 6f 74 68  mn name" and oth
2950: 65 72 20 6d 6f 64 75 6c 65 20 61 72 67 75 6d 65  er module argume
2960: 6e 74 20 66 69 65 6c 64 73 2e 0a 2a 2f 0a 73 74  nt fields..*/.st
2970: 61 74 69 63 20 69 6e 74 20 66 74 73 35 49 6e 69  atic int fts5Ini
2980: 74 56 74 61 62 28 0a 20 20 69 6e 74 20 62 43 72  tVtab(.  int bCr
2990: 65 61 74 65 2c 20 20 20 20 20 20 20 20 20 20 20  eate,           
29a0: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65           /* True
29b0: 20 66 6f 72 20 78 43 72 65 61 74 65 2c 20 66 61   for xCreate, fa
29c0: 6c 73 65 20 66 6f 72 20 78 43 6f 6e 6e 65 63 74  lse for xConnect
29d0: 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 20 2a 64   */.  sqlite3 *d
29e0: 62 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  b,              
29f0: 20 20 20 20 20 20 2f 2a 20 54 68 65 20 53 51 4c        /* The SQL
2a00: 69 74 65 20 64 61 74 61 62 61 73 65 20 63 6f 6e  ite database con
2a10: 6e 65 63 74 69 6f 6e 20 2a 2f 0a 20 20 76 6f 69  nection */.  voi
2a20: 64 20 2a 70 41 75 78 2c 20 20 20 20 20 20 20 20  d *pAux,        
2a30: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
2a40: 48 61 73 68 20 74 61 62 6c 65 20 63 6f 6e 74 61  Hash table conta
2a50: 69 6e 69 6e 67 20 74 6f 6b 65 6e 69 7a 65 72 73  ining tokenizers
2a60: 20 2a 2f 0a 20 20 69 6e 74 20 61 72 67 63 2c 20   */.  int argc, 
2a70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2a80: 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20        /* Number 
2a90: 6f 66 20 65 6c 65 6d 65 6e 74 73 20 69 6e 20 61  of elements in a
2aa0: 72 67 76 20 61 72 72 61 79 20 2a 2f 0a 20 20 63  rgv array */.  c
2ab0: 6f 6e 73 74 20 63 68 61 72 20 2a 20 63 6f 6e 73  onst char * cons
2ac0: 74 20 2a 61 72 67 76 2c 20 20 20 20 20 20 20 2f  t *argv,       /
2ad0: 2a 20 78 43 72 65 61 74 65 2f 78 43 6f 6e 6e 65  * xCreate/xConne
2ae0: 63 74 20 61 72 67 75 6d 65 6e 74 20 61 72 72 61  ct argument arra
2af0: 79 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 76  y */.  sqlite3_v
2b00: 74 61 62 20 2a 2a 70 70 56 54 61 62 2c 20 20 20  tab **ppVTab,   
2b10: 20 20 20 20 20 20 20 2f 2a 20 57 72 69 74 65 20         /* Write 
2b20: 74 68 65 20 72 65 73 75 6c 74 69 6e 67 20 76 74  the resulting vt
2b30: 61 62 20 73 74 72 75 63 74 75 72 65 20 68 65 72  ab structure her
2b40: 65 20 2a 2f 0a 20 20 63 68 61 72 20 2a 2a 70 7a  e */.  char **pz
2b50: 45 72 72 20 20 20 20 20 20 20 20 20 20 20 20 20  Err             
2b60: 20 20 20 20 20 20 20 2f 2a 20 57 72 69 74 65 20         /* Write 
2b70: 61 6e 79 20 65 72 72 6f 72 20 6d 65 73 73 61 67  any error messag
2b80: 65 20 68 65 72 65 20 2a 2f 0a 29 7b 0a 20 20 46  e here */.){.  F
2b90: 74 73 35 47 6c 6f 62 61 6c 20 2a 70 47 6c 6f 62  ts5Global *pGlob
2ba0: 61 6c 20 3d 20 28 46 74 73 35 47 6c 6f 62 61 6c  al = (Fts5Global
2bb0: 2a 29 70 41 75 78 3b 0a 20 20 63 6f 6e 73 74 20  *)pAux;.  const 
2bc0: 63 68 61 72 20 2a 2a 61 7a 43 6f 6e 66 69 67 20  char **azConfig 
2bd0: 3d 20 28 63 6f 6e 73 74 20 63 68 61 72 2a 2a 29  = (const char**)
2be0: 61 72 67 76 3b 0a 20 20 69 6e 74 20 72 63 20 3d  argv;.  int rc =
2bf0: 20 53 51 4c 49 54 45 5f 4f 4b 3b 20 20 20 20 20   SQLITE_OK;     
2c00: 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72          /* Retur
2c10: 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 46 74 73 35  n code */.  Fts5
2c20: 43 6f 6e 66 69 67 20 2a 70 43 6f 6e 66 69 67 3b  Config *pConfig;
2c30: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52              /* R
2c40: 65 73 75 6c 74 73 20 6f 66 20 70 61 72 73 69 6e  esults of parsin
2c50: 67 20 61 72 67 63 2f 61 72 67 76 20 2a 2f 0a 20  g argc/argv */. 
2c60: 20 46 74 73 35 54 61 62 6c 65 20 2a 70 54 61 62   Fts5Table *pTab
2c70: 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20   = 0;           
2c80: 20 2f 2a 20 4e 65 77 20 76 69 72 74 75 61 6c 20   /* New virtual 
2c90: 74 61 62 6c 65 20 6f 62 6a 65 63 74 20 2a 2f 0a  table object */.
2ca0: 0a 20 20 2f 2a 20 41 6c 6c 6f 63 61 74 65 20 74  .  /* Allocate t
2cb0: 68 65 20 6e 65 77 20 76 74 61 62 20 6f 62 6a 65  he new vtab obje
2cc0: 63 74 20 61 6e 64 20 70 61 72 73 65 20 74 68 65  ct and parse the
2cd0: 20 63 6f 6e 66 69 67 75 72 61 74 69 6f 6e 20 2a   configuration *
2ce0: 2f 0a 20 20 70 54 61 62 20 3d 20 28 46 74 73 35  /.  pTab = (Fts5
2cf0: 54 61 62 6c 65 2a 29 73 71 6c 69 74 65 33 46 74  Table*)sqlite3Ft
2d00: 73 35 4d 61 6c 6c 6f 63 5a 65 72 6f 28 26 72 63  s5MallocZero(&rc
2d10: 2c 20 73 69 7a 65 6f 66 28 46 74 73 35 54 61 62  , sizeof(Fts5Tab
2d20: 6c 65 29 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d  le));.  if( rc==
2d30: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
2d40: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 46 74 73   rc = sqlite3Fts
2d50: 35 43 6f 6e 66 69 67 50 61 72 73 65 28 70 47 6c  5ConfigParse(pGl
2d60: 6f 62 61 6c 2c 20 64 62 2c 20 61 72 67 63 2c 20  obal, db, argc, 
2d70: 61 7a 43 6f 6e 66 69 67 2c 20 26 70 43 6f 6e 66  azConfig, &pConf
2d80: 69 67 2c 20 70 7a 45 72 72 29 3b 0a 20 20 20 20  ig, pzErr);.    
2d90: 61 73 73 65 72 74 28 20 28 72 63 3d 3d 53 51 4c  assert( (rc==SQL
2da0: 49 54 45 5f 4f 4b 20 26 26 20 2a 70 7a 45 72 72  ITE_OK && *pzErr
2db0: 3d 3d 30 29 20 7c 7c 20 70 43 6f 6e 66 69 67 3d  ==0) || pConfig=
2dc0: 3d 30 20 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20  =0 );.  }.  if( 
2dd0: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
2de0: 0a 20 20 20 20 70 54 61 62 2d 3e 70 43 6f 6e 66  .    pTab->pConf
2df0: 69 67 20 3d 20 70 43 6f 6e 66 69 67 3b 0a 20 20  ig = pConfig;.  
2e00: 20 20 70 54 61 62 2d 3e 70 47 6c 6f 62 61 6c 20    pTab->pGlobal 
2e10: 3d 20 70 47 6c 6f 62 61 6c 3b 0a 20 20 7d 0a 0a  = pGlobal;.  }..
2e20: 20 20 2f 2a 20 4f 70 65 6e 20 74 68 65 20 69 6e    /* Open the in
2e30: 64 65 78 20 73 75 62 2d 73 79 73 74 65 6d 20 2a  dex sub-system *
2e40: 2f 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  /.  if( rc==SQLI
2e50: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20  TE_OK ){.    rc 
2e60: 3d 20 73 71 6c 69 74 65 33 46 74 73 35 49 6e 64  = sqlite3Fts5Ind
2e70: 65 78 4f 70 65 6e 28 70 43 6f 6e 66 69 67 2c 20  exOpen(pConfig, 
2e80: 62 43 72 65 61 74 65 2c 20 26 70 54 61 62 2d 3e  bCreate, &pTab->
2e90: 70 49 6e 64 65 78 2c 20 70 7a 45 72 72 29 3b 0a  pIndex, pzErr);.
2ea0: 20 20 7d 0a 0a 20 20 2f 2a 20 4f 70 65 6e 20 74    }..  /* Open t
2eb0: 68 65 20 73 74 6f 72 61 67 65 20 73 75 62 2d 73  he storage sub-s
2ec0: 79 73 74 65 6d 20 2a 2f 0a 20 20 69 66 28 20 72  ystem */.  if( r
2ed0: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
2ee0: 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
2ef0: 46 74 73 35 53 74 6f 72 61 67 65 4f 70 65 6e 28  Fts5StorageOpen(
2f00: 0a 20 20 20 20 20 20 20 20 70 43 6f 6e 66 69 67  .        pConfig
2f10: 2c 20 70 54 61 62 2d 3e 70 49 6e 64 65 78 2c 20  , pTab->pIndex, 
2f20: 62 43 72 65 61 74 65 2c 20 26 70 54 61 62 2d 3e  bCreate, &pTab->
2f30: 70 53 74 6f 72 61 67 65 2c 20 70 7a 45 72 72 0a  pStorage, pzErr.
2f40: 20 20 20 20 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a      );.  }..  /*
2f50: 20 43 61 6c 6c 20 73 71 6c 69 74 65 33 5f 64 65   Call sqlite3_de
2f60: 63 6c 61 72 65 5f 76 74 61 62 28 29 20 2a 2f 0a  clare_vtab() */.
2f70: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
2f80: 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20  _OK ){.    rc = 
2f90: 73 71 6c 69 74 65 33 46 74 73 35 43 6f 6e 66 69  sqlite3Fts5Confi
2fa0: 67 44 65 63 6c 61 72 65 56 74 61 62 28 70 43 6f  gDeclareVtab(pCo
2fb0: 6e 66 69 67 29 3b 0a 20 20 7d 0a 0a 20 20 69 66  nfig);.  }..  if
2fc0: 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
2fd0: 29 7b 0a 20 20 20 20 66 74 73 35 46 72 65 65 56  ){.    fts5FreeV
2fe0: 74 61 62 28 70 54 61 62 2c 20 30 29 3b 0a 20 20  tab(pTab, 0);.  
2ff0: 20 20 70 54 61 62 20 3d 20 30 3b 0a 20 20 7d 65    pTab = 0;.  }e
3000: 6c 73 65 20 69 66 28 20 62 43 72 65 61 74 65 20  lse if( bCreate 
3010: 29 7b 0a 20 20 20 20 66 74 73 35 43 68 65 63 6b  ){.    fts5Check
3020: 54 72 61 6e 73 61 63 74 69 6f 6e 53 74 61 74 65  TransactionState
3030: 28 70 54 61 62 2c 20 46 54 53 35 5f 42 45 47 49  (pTab, FTS5_BEGI
3040: 4e 2c 20 30 29 3b 0a 20 20 7d 0a 20 20 2a 70 70  N, 0);.  }.  *pp
3050: 56 54 61 62 20 3d 20 28 73 71 6c 69 74 65 33 5f  VTab = (sqlite3_
3060: 76 74 61 62 2a 29 70 54 61 62 3b 0a 20 20 72 65  vtab*)pTab;.  re
3070: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
3080: 2a 20 54 68 65 20 78 43 6f 6e 6e 65 63 74 28 29  * The xConnect()
3090: 20 61 6e 64 20 78 43 72 65 61 74 65 28 29 20 6d   and xCreate() m
30a0: 65 74 68 6f 64 73 20 66 6f 72 20 74 68 65 20 76  ethods for the v
30b0: 69 72 74 75 61 6c 20 74 61 62 6c 65 2e 20 41 6c  irtual table. Al
30c0: 6c 20 74 68 65 0a 2a 2a 20 77 6f 72 6b 20 69 73  l the.** work is
30d0: 20 64 6f 6e 65 20 69 6e 20 66 75 6e 63 74 69 6f   done in functio
30e0: 6e 20 66 74 73 35 49 6e 69 74 56 74 61 62 28 29  n fts5InitVtab()
30f0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
3100: 66 74 73 35 43 6f 6e 6e 65 63 74 4d 65 74 68 6f  fts5ConnectMetho
3110: 64 28 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62  d(.  sqlite3 *db
3120: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
3130: 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65       /* Database
3140: 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 2a 2f 0a 20   connection */. 
3150: 20 76 6f 69 64 20 2a 70 41 75 78 2c 20 20 20 20   void *pAux,    
3160: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3170: 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 74   /* Pointer to t
3180: 6f 6b 65 6e 69 7a 65 72 20 68 61 73 68 20 74 61  okenizer hash ta
3190: 62 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 61 72 67  ble */.  int arg
31a0: 63 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  c,              
31b0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
31c0: 65 72 20 6f 66 20 65 6c 65 6d 65 6e 74 73 20 69  er of elements i
31d0: 6e 20 61 72 67 76 20 61 72 72 61 79 20 2a 2f 0a  n argv array */.
31e0: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 20 63    const char * c
31f0: 6f 6e 73 74 20 2a 61 72 67 76 2c 20 20 20 20 20  onst *argv,     
3200: 20 20 2f 2a 20 78 43 72 65 61 74 65 2f 78 43 6f    /* xCreate/xCo
3210: 6e 6e 65 63 74 20 61 72 67 75 6d 65 6e 74 20 61  nnect argument a
3220: 72 72 61 79 20 2a 2f 0a 20 20 73 71 6c 69 74 65  rray */.  sqlite
3230: 33 5f 76 74 61 62 20 2a 2a 70 70 56 74 61 62 2c  3_vtab **ppVtab,
3240: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54            /* OUT
3250: 3a 20 4e 65 77 20 73 71 6c 69 74 65 33 5f 76 74  : New sqlite3_vt
3260: 61 62 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 63  ab object */.  c
3270: 68 61 72 20 2a 2a 70 7a 45 72 72 20 20 20 20 20  har **pzErr     
3280: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
3290: 2a 20 4f 55 54 3a 20 73 71 6c 69 74 65 33 5f 6d  * OUT: sqlite3_m
32a0: 61 6c 6c 6f 63 27 64 20 65 72 72 6f 72 20 6d 65  alloc'd error me
32b0: 73 73 61 67 65 20 2a 2f 0a 29 7b 0a 20 20 72 65  ssage */.){.  re
32c0: 74 75 72 6e 20 66 74 73 35 49 6e 69 74 56 74 61  turn fts5InitVta
32d0: 62 28 30 2c 20 64 62 2c 20 70 41 75 78 2c 20 61  b(0, db, pAux, a
32e0: 72 67 63 2c 20 61 72 67 76 2c 20 70 70 56 74 61  rgc, argv, ppVta
32f0: 62 2c 20 70 7a 45 72 72 29 3b 0a 7d 0a 73 74 61  b, pzErr);.}.sta
3300: 74 69 63 20 69 6e 74 20 66 74 73 35 43 72 65 61  tic int fts5Crea
3310: 74 65 4d 65 74 68 6f 64 28 0a 20 20 73 71 6c 69  teMethod(.  sqli
3320: 74 65 33 20 2a 64 62 2c 20 20 20 20 20 20 20 20  te3 *db,        
3330: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44              /* D
3340: 61 74 61 62 61 73 65 20 63 6f 6e 6e 65 63 74 69  atabase connecti
3350: 6f 6e 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 41  on */.  void *pA
3360: 75 78 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ux,             
3370: 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74          /* Point
3380: 65 72 20 74 6f 20 74 6f 6b 65 6e 69 7a 65 72 20  er to tokenizer 
3390: 68 61 73 68 20 74 61 62 6c 65 20 2a 2f 0a 20 20  hash table */.  
33a0: 69 6e 74 20 61 72 67 63 2c 20 20 20 20 20 20 20  int argc,       
33b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
33c0: 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 65 6c 65  /* Number of ele
33d0: 6d 65 6e 74 73 20 69 6e 20 61 72 67 76 20 61 72  ments in argv ar
33e0: 72 61 79 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63  ray */.  const c
33f0: 68 61 72 20 2a 20 63 6f 6e 73 74 20 2a 61 72 67  har * const *arg
3400: 76 2c 20 20 20 20 20 20 20 2f 2a 20 78 43 72 65  v,       /* xCre
3410: 61 74 65 2f 78 43 6f 6e 6e 65 63 74 20 61 72 67  ate/xConnect arg
3420: 75 6d 65 6e 74 20 61 72 72 61 79 20 2a 2f 0a 20  ument array */. 
3430: 20 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 2a   sqlite3_vtab **
3440: 70 70 56 74 61 62 2c 20 20 20 20 20 20 20 20 20  ppVtab,         
3450: 20 2f 2a 20 4f 55 54 3a 20 4e 65 77 20 73 71 6c   /* OUT: New sql
3460: 69 74 65 33 5f 76 74 61 62 20 6f 62 6a 65 63 74  ite3_vtab object
3470: 20 2a 2f 0a 20 20 63 68 61 72 20 2a 2a 70 7a 45   */.  char **pzE
3480: 72 72 20 20 20 20 20 20 20 20 20 20 20 20 20 20  rr              
3490: 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 73 71        /* OUT: sq
34a0: 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 27 64 20 65  lite3_malloc'd e
34b0: 72 72 6f 72 20 6d 65 73 73 61 67 65 20 2a 2f 0a  rror message */.
34c0: 29 7b 0a 20 20 72 65 74 75 72 6e 20 66 74 73 35  ){.  return fts5
34d0: 49 6e 69 74 56 74 61 62 28 31 2c 20 64 62 2c 20  InitVtab(1, db, 
34e0: 70 41 75 78 2c 20 61 72 67 63 2c 20 61 72 67 76  pAux, argc, argv
34f0: 2c 20 70 70 56 74 61 62 2c 20 70 7a 45 72 72 29  , ppVtab, pzErr)
3500: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 74  ;.}../*.** The t
3510: 68 72 65 65 20 71 75 65 72 79 20 70 6c 61 6e 73  hree query plans
3520: 20 78 42 65 73 74 49 6e 64 65 78 20 6d 61 79 20   xBestIndex may 
3530: 63 68 6f 6f 73 65 20 62 65 74 77 65 65 6e 2e 0a  choose between..
3540: 2a 2f 0a 23 64 65 66 69 6e 65 20 46 54 53 35 5f  */.#define FTS5_
3550: 50 4c 41 4e 5f 53 43 41 4e 20 20 20 20 20 20 20  PLAN_SCAN       
3560: 20 20 20 20 31 20 20 20 20 20 20 20 2f 2a 20 4e      1       /* N
3570: 6f 20 75 73 61 62 6c 65 20 63 6f 6e 73 74 72 61  o usable constra
3580: 69 6e 74 20 2a 2f 0a 23 64 65 66 69 6e 65 20 46  int */.#define F
3590: 54 53 35 5f 50 4c 41 4e 5f 4d 41 54 43 48 20 20  TS5_PLAN_MATCH  
35a0: 20 20 20 20 20 20 20 20 32 20 20 20 20 20 20 20          2       
35b0: 2f 2a 20 28 3c 74 62 6c 3e 20 4d 41 54 43 48 20  /* (<tbl> MATCH 
35c0: 3f 29 20 2a 2f 0a 23 64 65 66 69 6e 65 20 46 54  ?) */.#define FT
35d0: 53 35 5f 50 4c 41 4e 5f 53 4f 52 54 45 44 5f 4d  S5_PLAN_SORTED_M
35e0: 41 54 43 48 20 20 20 33 20 20 20 20 20 20 20 2f  ATCH   3       /
35f0: 2a 20 28 3c 74 62 6c 3e 20 4d 41 54 43 48 20 3f  * (<tbl> MATCH ?
3600: 20 4f 52 44 45 52 20 42 59 20 72 61 6e 6b 29 20   ORDER BY rank) 
3610: 2a 2f 0a 23 64 65 66 69 6e 65 20 46 54 53 35 5f  */.#define FTS5_
3620: 50 4c 41 4e 5f 52 4f 57 49 44 20 20 20 20 20 20  PLAN_ROWID      
3630: 20 20 20 20 34 20 20 20 20 20 20 20 2f 2a 20 28      4       /* (
3640: 72 6f 77 69 64 20 3d 20 3f 29 20 2a 2f 0a 23 64  rowid = ?) */.#d
3650: 65 66 69 6e 65 20 46 54 53 35 5f 50 4c 41 4e 5f  efine FTS5_PLAN_
3660: 53 4f 55 52 43 45 20 20 20 20 20 20 20 20 20 35  SOURCE         5
3670: 20 20 20 20 20 20 20 2f 2a 20 41 20 73 6f 75 72         /* A sour
3680: 63 65 20 63 75 72 73 6f 72 20 66 6f 72 20 53 4f  ce cursor for SO
3690: 52 54 45 44 5f 4d 41 54 43 48 20 2a 2f 0a 23 64  RTED_MATCH */.#d
36a0: 65 66 69 6e 65 20 46 54 53 35 5f 50 4c 41 4e 5f  efine FTS5_PLAN_
36b0: 53 50 45 43 49 41 4c 20 20 20 20 20 20 20 20 36  SPECIAL        6
36c0: 20 20 20 20 20 20 20 2f 2a 20 41 6e 20 69 6e 74         /* An int
36d0: 65 72 6e 61 6c 20 71 75 65 72 79 20 2a 2f 0a 0a  ernal query */..
36e0: 23 64 65 66 69 6e 65 20 46 54 53 35 5f 50 4c 41  #define FTS5_PLA
36f0: 4e 28 69 64 78 4e 75 6d 29 20 28 28 69 64 78 4e  N(idxNum) ((idxN
3700: 75 6d 29 20 26 20 30 78 37 29 0a 0a 23 64 65 66  um) & 0x7)..#def
3710: 69 6e 65 20 46 54 53 35 5f 4f 52 44 45 52 5f 44  ine FTS5_ORDER_D
3720: 45 53 43 20 20 20 38 20 20 20 20 20 20 20 2f 2a  ESC   8       /*
3730: 20 4f 52 44 45 52 20 42 59 20 72 6f 77 69 64 20   ORDER BY rowid 
3740: 44 45 53 43 20 2a 2f 0a 23 64 65 66 69 6e 65 20  DESC */.#define 
3750: 46 54 53 35 5f 4f 52 44 45 52 5f 41 53 43 20 20  FTS5_ORDER_ASC  
3760: 20 31 36 20 20 20 20 20 20 20 2f 2a 20 4f 52 44   16       /* ORD
3770: 45 52 20 42 59 20 72 6f 77 69 64 20 41 53 43 20  ER BY rowid ASC 
3780: 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 53 65 61 72 63 68  */../*.** Search
3790: 20 74 68 65 20 6f 62 6a 65 63 74 20 70 61 73 73   the object pass
37a0: 65 64 20 61 73 20 74 68 65 20 66 69 72 73 74 20  ed as the first 
37b0: 61 72 67 75 6d 65 6e 74 20 66 6f 72 20 61 20 75  argument for a u
37c0: 73 61 62 6c 65 20 63 6f 6e 73 74 72 61 69 6e 74  sable constraint
37d0: 0a 2a 2a 20 6f 6e 20 63 6f 6c 75 6d 6e 20 69 43  .** on column iC
37e0: 6f 6c 20 75 73 69 6e 67 20 6f 70 65 72 61 74 6f  ol using operato
37f0: 72 20 65 4f 70 2e 20 49 66 20 6f 6e 65 20 69 73  r eOp. If one is
3800: 20 66 6f 75 6e 64 2c 20 72 65 74 75 72 6e 20 69   found, return i
3810: 74 73 20 69 6e 64 65 78 20 69 6e 0a 2a 2a 20 74  ts index in.** t
3820: 68 65 20 70 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74  he pInfo->aConst
3830: 72 61 69 6e 74 5b 5d 20 61 72 72 61 79 2e 20 49  raint[] array. I
3840: 66 20 6e 6f 20 73 75 63 68 20 63 6f 6e 73 74 72  f no such constr
3850: 61 69 6e 74 20 69 73 20 66 6f 75 6e 64 2c 20 72  aint is found, r
3860: 65 74 75 72 6e 0a 2a 2a 20 61 20 6e 65 67 61 74  eturn.** a negat
3870: 69 76 65 20 76 61 6c 75 65 2e 0a 2a 2f 0a 73 74  ive value..*/.st
3880: 61 74 69 63 20 69 6e 74 20 66 74 73 35 46 69 6e  atic int fts5Fin
3890: 64 43 6f 6e 73 74 72 61 69 6e 74 28 73 71 6c 69  dConstraint(sqli
38a0: 74 65 33 5f 69 6e 64 65 78 5f 69 6e 66 6f 20 2a  te3_index_info *
38b0: 70 49 6e 66 6f 2c 20 69 6e 74 20 65 4f 70 2c 20  pInfo, int eOp, 
38c0: 69 6e 74 20 69 43 6f 6c 29 7b 0a 20 20 69 6e 74  int iCol){.  int
38d0: 20 69 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69   i;.  for(i=0; i
38e0: 3c 70 49 6e 66 6f 2d 3e 6e 43 6f 6e 73 74 72 61  <pInfo->nConstra
38f0: 69 6e 74 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 73  int; i++){.    s
3900: 74 72 75 63 74 20 73 71 6c 69 74 65 33 5f 69 6e  truct sqlite3_in
3910: 64 65 78 5f 63 6f 6e 73 74 72 61 69 6e 74 20 2a  dex_constraint *
3920: 70 20 3d 20 26 70 49 6e 66 6f 2d 3e 61 43 6f 6e  p = &pInfo->aCon
3930: 73 74 72 61 69 6e 74 5b 69 5d 3b 0a 20 20 20 20  straint[i];.    
3940: 69 66 28 20 70 2d 3e 75 73 61 62 6c 65 20 26 26  if( p->usable &&
3950: 20 70 2d 3e 69 43 6f 6c 75 6d 6e 3d 3d 69 43 6f   p->iColumn==iCo
3960: 6c 20 26 26 20 70 2d 3e 6f 70 3d 3d 65 4f 70 20  l && p->op==eOp 
3970: 29 20 72 65 74 75 72 6e 20 69 3b 0a 20 20 7d 0a  ) return i;.  }.
3980: 20 20 72 65 74 75 72 6e 20 2d 31 3b 0a 7d 0a 0a    return -1;.}..
3990: 2f 2a 20 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74  /* .** Implement
39a0: 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 78 42 65  ation of the xBe
39b0: 73 74 49 6e 64 65 78 20 6d 65 74 68 6f 64 20 66  stIndex method f
39c0: 6f 72 20 46 54 53 35 20 74 61 62 6c 65 73 2e 20  or FTS5 tables. 
39d0: 54 68 65 72 65 0a 2a 2a 20 61 72 65 20 74 68 72  There.** are thr
39e0: 65 65 20 70 6f 73 73 69 62 6c 65 20 73 74 72 61  ee possible stra
39f0: 74 65 67 69 65 73 2c 20 69 6e 20 6f 72 64 65 72  tegies, in order
3a00: 20 6f 66 20 70 72 65 66 65 72 65 6e 63 65 3a 0a   of preference:.
3a10: 2a 2a 0a 2a 2a 20 20 20 31 2e 20 46 75 6c 6c 2d  **.**   1. Full-
3a20: 74 65 78 74 20 73 65 61 72 63 68 20 75 73 69 6e  text search usin
3a30: 67 20 61 20 4d 41 54 43 48 20 6f 70 65 72 61 74  g a MATCH operat
3a40: 6f 72 2e 0a 2a 2a 20 20 20 32 2e 20 41 20 62 79  or..**   2. A by
3a50: 2d 72 6f 77 69 64 20 6c 6f 6f 6b 75 70 2e 0a 2a  -rowid lookup..*
3a60: 2a 20 20 20 33 2e 20 41 20 66 75 6c 6c 2d 74 61  *   3. A full-ta
3a70: 62 6c 65 20 73 63 61 6e 2e 0a 2a 2f 0a 73 74 61  ble scan..*/.sta
3a80: 74 69 63 20 69 6e 74 20 66 74 73 35 42 65 73 74  tic int fts5Best
3a90: 49 6e 64 65 78 4d 65 74 68 6f 64 28 73 71 6c 69  IndexMethod(sqli
3aa0: 74 65 33 5f 76 74 61 62 20 2a 70 56 54 61 62 2c  te3_vtab *pVTab,
3ab0: 20 73 71 6c 69 74 65 33 5f 69 6e 64 65 78 5f 69   sqlite3_index_i
3ac0: 6e 66 6f 20 2a 70 49 6e 66 6f 29 7b 0a 20 20 46  nfo *pInfo){.  F
3ad0: 74 73 35 54 61 62 6c 65 20 2a 70 54 61 62 20 3d  ts5Table *pTab =
3ae0: 20 28 46 74 73 35 54 61 62 6c 65 2a 29 70 56 54   (Fts5Table*)pVT
3af0: 61 62 3b 0a 20 20 46 74 73 35 43 6f 6e 66 69 67  ab;.  Fts5Config
3b00: 20 2a 70 43 6f 6e 66 69 67 20 3d 20 70 54 61 62   *pConfig = pTab
3b10: 2d 3e 70 43 6f 6e 66 69 67 3b 0a 20 20 69 6e 74  ->pConfig;.  int
3b20: 20 69 43 6f 6e 73 3b 0a 20 20 69 6e 74 20 65 50   iCons;.  int eP
3b30: 6c 61 6e 20 3d 20 46 54 53 35 5f 50 4c 41 4e 5f  lan = FTS5_PLAN_
3b40: 53 43 41 4e 3b 0a 20 20 69 6e 74 20 69 52 61 6e  SCAN;.  int iRan
3b50: 6b 4d 61 74 63 68 3b 0a 0a 20 20 69 43 6f 6e 73  kMatch;..  iCons
3b60: 20 3d 20 66 74 73 35 46 69 6e 64 43 6f 6e 73 74   = fts5FindConst
3b70: 72 61 69 6e 74 28 70 49 6e 66 6f 2c 53 51 4c 49  raint(pInfo,SQLI
3b80: 54 45 5f 49 4e 44 45 58 5f 43 4f 4e 53 54 52 41  TE_INDEX_CONSTRA
3b90: 49 4e 54 5f 4d 41 54 43 48 2c 70 43 6f 6e 66 69  INT_MATCH,pConfi
3ba0: 67 2d 3e 6e 43 6f 6c 29 3b 0a 20 20 69 66 28 20  g->nCol);.  if( 
3bb0: 69 43 6f 6e 73 3e 3d 30 20 29 7b 0a 20 20 20 20  iCons>=0 ){.    
3bc0: 65 50 6c 61 6e 20 3d 20 46 54 53 35 5f 50 4c 41  ePlan = FTS5_PLA
3bd0: 4e 5f 4d 41 54 43 48 3b 0a 20 20 20 20 70 49 6e  N_MATCH;.    pIn
3be0: 66 6f 2d 3e 65 73 74 69 6d 61 74 65 64 43 6f 73  fo->estimatedCos
3bf0: 74 20 3d 20 31 2e 30 3b 0a 20 20 7d 65 6c 73 65  t = 1.0;.  }else
3c00: 7b 0a 20 20 20 20 69 43 6f 6e 73 20 3d 20 66 74  {.    iCons = ft
3c10: 73 35 46 69 6e 64 43 6f 6e 73 74 72 61 69 6e 74  s5FindConstraint
3c20: 28 70 49 6e 66 6f 2c 20 53 51 4c 49 54 45 5f 49  (pInfo, SQLITE_I
3c30: 4e 44 45 58 5f 43 4f 4e 53 54 52 41 49 4e 54 5f  NDEX_CONSTRAINT_
3c40: 45 51 2c 20 2d 31 29 3b 0a 20 20 20 20 69 66 28  EQ, -1);.    if(
3c50: 20 69 43 6f 6e 73 3e 3d 30 20 29 7b 0a 20 20 20   iCons>=0 ){.   
3c60: 20 20 20 65 50 6c 61 6e 20 3d 20 46 54 53 35 5f     ePlan = FTS5_
3c70: 50 4c 41 4e 5f 52 4f 57 49 44 3b 0a 20 20 20 20  PLAN_ROWID;.    
3c80: 20 20 70 49 6e 66 6f 2d 3e 65 73 74 69 6d 61 74    pInfo->estimat
3c90: 65 64 43 6f 73 74 20 3d 20 32 2e 30 3b 0a 20 20  edCost = 2.0;.  
3ca0: 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 66 28 20 69    }.  }..  if( i
3cb0: 43 6f 6e 73 3e 3d 30 20 29 7b 0a 20 20 20 20 70  Cons>=0 ){.    p
3cc0: 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74 72 61 69 6e  Info->aConstrain
3cd0: 74 55 73 61 67 65 5b 69 43 6f 6e 73 5d 2e 61 72  tUsage[iCons].ar
3ce0: 67 76 49 6e 64 65 78 20 3d 20 31 3b 0a 20 20 20  gvIndex = 1;.   
3cf0: 20 70 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74 72 61   pInfo->aConstra
3d00: 69 6e 74 55 73 61 67 65 5b 69 43 6f 6e 73 5d 2e  intUsage[iCons].
3d10: 6f 6d 69 74 20 3d 20 31 3b 0a 20 20 7d 65 6c 73  omit = 1;.  }els
3d20: 65 7b 0a 20 20 20 20 70 49 6e 66 6f 2d 3e 65 73  e{.    pInfo->es
3d30: 74 69 6d 61 74 65 64 43 6f 73 74 20 3d 20 31 30  timatedCost = 10
3d40: 30 30 30 30 30 30 2e 30 3b 0a 20 20 7d 0a 0a 20  000000.0;.  }.. 
3d50: 20 69 66 28 20 70 49 6e 66 6f 2d 3e 6e 4f 72 64   if( pInfo->nOrd
3d60: 65 72 42 79 3d 3d 31 20 29 7b 0a 20 20 20 20 69  erBy==1 ){.    i
3d70: 6e 74 20 69 53 6f 72 74 20 3d 20 70 49 6e 66 6f  nt iSort = pInfo
3d80: 2d 3e 61 4f 72 64 65 72 42 79 5b 30 5d 2e 69 43  ->aOrderBy[0].iC
3d90: 6f 6c 75 6d 6e 3b 0a 20 20 20 20 69 66 28 20 69  olumn;.    if( i
3da0: 53 6f 72 74 3c 30 20 29 7b 0a 20 20 20 20 20 20  Sort<0 ){.      
3db0: 2f 2a 20 4f 52 44 45 52 20 42 59 20 72 6f 77 69  /* ORDER BY rowi
3dc0: 64 20 5b 41 53 43 7c 44 45 53 43 5d 20 2a 2f 0a  d [ASC|DESC] */.
3dd0: 20 20 20 20 20 20 70 49 6e 66 6f 2d 3e 6f 72 64        pInfo->ord
3de0: 65 72 42 79 43 6f 6e 73 75 6d 65 64 20 3d 20 31  erByConsumed = 1
3df0: 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20  ;.    }else if( 
3e00: 69 53 6f 72 74 3d 3d 28 70 43 6f 6e 66 69 67 2d  iSort==(pConfig-
3e10: 3e 6e 43 6f 6c 2b 31 29 20 26 26 20 65 50 6c 61  >nCol+1) && ePla
3e20: 6e 3d 3d 46 54 53 35 5f 50 4c 41 4e 5f 4d 41 54  n==FTS5_PLAN_MAT
3e30: 43 48 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20 4f  CH ){.      /* O
3e40: 52 44 45 52 20 42 59 20 72 61 6e 6b 20 5b 41 53  RDER BY rank [AS
3e50: 43 7c 44 45 53 43 5d 20 2a 2f 0a 20 20 20 20 20  C|DESC] */.     
3e60: 20 70 49 6e 66 6f 2d 3e 6f 72 64 65 72 42 79 43   pInfo->orderByC
3e70: 6f 6e 73 75 6d 65 64 20 3d 20 31 3b 0a 20 20 20  onsumed = 1;.   
3e80: 20 20 20 65 50 6c 61 6e 20 3d 20 46 54 53 35 5f     ePlan = FTS5_
3e90: 50 4c 41 4e 5f 53 4f 52 54 45 44 5f 4d 41 54 43  PLAN_SORTED_MATC
3ea0: 48 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69 66  H;.    }..    if
3eb0: 28 20 70 49 6e 66 6f 2d 3e 6f 72 64 65 72 42 79  ( pInfo->orderBy
3ec0: 43 6f 6e 73 75 6d 65 64 20 29 7b 0a 20 20 20 20  Consumed ){.    
3ed0: 20 20 65 50 6c 61 6e 20 7c 3d 20 70 49 6e 66 6f    ePlan |= pInfo
3ee0: 2d 3e 61 4f 72 64 65 72 42 79 5b 30 5d 2e 64 65  ->aOrderBy[0].de
3ef0: 73 63 20 3f 20 46 54 53 35 5f 4f 52 44 45 52 5f  sc ? FTS5_ORDER_
3f00: 44 45 53 43 20 3a 20 46 54 53 35 5f 4f 52 44 45  DESC : FTS5_ORDE
3f10: 52 5f 41 53 43 3b 0a 20 20 20 20 7d 0a 20 20 7d  R_ASC;.    }.  }
3f20: 0a 0a 20 20 69 52 61 6e 6b 4d 61 74 63 68 20 3d  ..  iRankMatch =
3f30: 20 66 74 73 35 46 69 6e 64 43 6f 6e 73 74 72 61   fts5FindConstra
3f40: 69 6e 74 28 0a 20 20 20 20 20 20 70 49 6e 66 6f  int(.      pInfo
3f50: 2c 20 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f 43  , SQLITE_INDEX_C
3f60: 4f 4e 53 54 52 41 49 4e 54 5f 4d 41 54 43 48 2c  ONSTRAINT_MATCH,
3f70: 20 70 43 6f 6e 66 69 67 2d 3e 6e 43 6f 6c 2b 31   pConfig->nCol+1
3f80: 0a 20 20 29 3b 0a 20 20 69 66 28 20 69 52 61 6e  .  );.  if( iRan
3f90: 6b 4d 61 74 63 68 3e 3d 30 20 29 7b 0a 20 20 20  kMatch>=0 ){.   
3fa0: 20 70 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74 72 61   pInfo->aConstra
3fb0: 69 6e 74 55 73 61 67 65 5b 69 52 61 6e 6b 4d 61  intUsage[iRankMa
3fc0: 74 63 68 5d 2e 61 72 67 76 49 6e 64 65 78 20 3d  tch].argvIndex =
3fd0: 20 31 20 2b 20 28 69 43 6f 6e 73 3e 3d 30 29 3b   1 + (iCons>=0);
3fe0: 0a 20 20 20 20 70 49 6e 66 6f 2d 3e 61 43 6f 6e  .    pInfo->aCon
3ff0: 73 74 72 61 69 6e 74 55 73 61 67 65 5b 69 52 61  straintUsage[iRa
4000: 6e 6b 4d 61 74 63 68 5d 2e 6f 6d 69 74 20 3d 20  nkMatch].omit = 
4010: 31 3b 0a 20 20 7d 0a 20 20 20 0a 20 20 70 49 6e  1;.  }.   .  pIn
4020: 66 6f 2d 3e 69 64 78 4e 75 6d 20 3d 20 65 50 6c  fo->idxNum = ePl
4030: 61 6e 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c  an;.  return SQL
4040: 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  ITE_OK;.}../*.**
4050: 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20   Implementation 
4060: 6f 66 20 78 4f 70 65 6e 20 6d 65 74 68 6f 64 2e  of xOpen method.
4070: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66  .*/.static int f
4080: 74 73 35 4f 70 65 6e 4d 65 74 68 6f 64 28 73 71  ts5OpenMethod(sq
4090: 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56 54 61  lite3_vtab *pVTa
40a0: 62 2c 20 73 71 6c 69 74 65 33 5f 76 74 61 62 5f  b, sqlite3_vtab_
40b0: 63 75 72 73 6f 72 20 2a 2a 70 70 43 73 72 29 7b  cursor **ppCsr){
40c0: 0a 20 20 46 74 73 35 54 61 62 6c 65 20 2a 70 54  .  Fts5Table *pT
40d0: 61 62 20 3d 20 28 46 74 73 35 54 61 62 6c 65 2a  ab = (Fts5Table*
40e0: 29 70 56 54 61 62 3b 0a 20 20 46 74 73 35 43 6f  )pVTab;.  Fts5Co
40f0: 6e 66 69 67 20 2a 70 43 6f 6e 66 69 67 20 3d 20  nfig *pConfig = 
4100: 70 54 61 62 2d 3e 70 43 6f 6e 66 69 67 3b 0a 20  pTab->pConfig;. 
4110: 20 46 74 73 35 43 75 72 73 6f 72 20 2a 70 43 73   Fts5Cursor *pCs
4120: 72 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  r;              
4130: 20 2f 2a 20 4e 65 77 20 63 75 72 73 6f 72 20 6f   /* New cursor o
4140: 62 6a 65 63 74 20 2a 2f 0a 20 20 69 6e 74 20 6e  bject */.  int n
4150: 42 79 74 65 3b 20 20 20 20 20 20 20 20 20 20 20  Byte;           
4160: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42 79             /* By
4170: 74 65 73 20 6f 66 20 73 70 61 63 65 20 74 6f 20  tes of space to 
4180: 61 6c 6c 6f 63 61 74 65 20 2a 2f 0a 20 20 69 6e  allocate */.  in
4190: 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b  t rc = SQLITE_OK
41a0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ;             /*
41b0: 20 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a   Return code */.
41c0: 0a 20 20 6e 42 79 74 65 20 3d 20 73 69 7a 65 6f  .  nByte = sizeo
41d0: 66 28 46 74 73 35 43 75 72 73 6f 72 29 20 2b 20  f(Fts5Cursor) + 
41e0: 70 43 6f 6e 66 69 67 2d 3e 6e 43 6f 6c 20 2a 20  pConfig->nCol * 
41f0: 73 69 7a 65 6f 66 28 69 6e 74 29 3b 0a 20 20 70  sizeof(int);.  p
4200: 43 73 72 20 3d 20 28 46 74 73 35 43 75 72 73 6f  Csr = (Fts5Curso
4210: 72 2a 29 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f  r*)sqlite3_mallo
4220: 63 28 6e 42 79 74 65 29 3b 0a 20 20 69 66 28 20  c(nByte);.  if( 
4230: 70 43 73 72 20 29 7b 0a 20 20 20 20 46 74 73 35  pCsr ){.    Fts5
4240: 47 6c 6f 62 61 6c 20 2a 70 47 6c 6f 62 61 6c 20  Global *pGlobal 
4250: 3d 20 70 54 61 62 2d 3e 70 47 6c 6f 62 61 6c 3b  = pTab->pGlobal;
4260: 0a 20 20 20 20 6d 65 6d 73 65 74 28 70 43 73 72  .    memset(pCsr
4270: 2c 20 30 2c 20 6e 42 79 74 65 29 3b 0a 20 20 20  , 0, nByte);.   
4280: 20 70 43 73 72 2d 3e 61 43 6f 6c 75 6d 6e 53 69   pCsr->aColumnSi
4290: 7a 65 20 3d 20 28 69 6e 74 2a 29 26 70 43 73 72  ze = (int*)&pCsr
42a0: 5b 31 5d 3b 0a 20 20 20 20 70 43 73 72 2d 3e 70  [1];.    pCsr->p
42b0: 4e 65 78 74 20 3d 20 70 47 6c 6f 62 61 6c 2d 3e  Next = pGlobal->
42c0: 70 43 73 72 3b 0a 20 20 20 20 70 47 6c 6f 62 61  pCsr;.    pGloba
42d0: 6c 2d 3e 70 43 73 72 20 3d 20 70 43 73 72 3b 0a  l->pCsr = pCsr;.
42e0: 20 20 20 20 70 43 73 72 2d 3e 69 43 73 72 49 64      pCsr->iCsrId
42f0: 20 3d 20 2b 2b 70 47 6c 6f 62 61 6c 2d 3e 69 4e   = ++pGlobal->iN
4300: 65 78 74 49 64 3b 0a 20 20 7d 65 6c 73 65 7b 0a  extId;.  }else{.
4310: 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
4320: 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 20 20 2a 70 70  NOMEM;.  }.  *pp
4330: 43 73 72 20 3d 20 28 73 71 6c 69 74 65 33 5f 76  Csr = (sqlite3_v
4340: 74 61 62 5f 63 75 72 73 6f 72 2a 29 70 43 73 72  tab_cursor*)pCsr
4350: 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ;.  return rc;.}
4360: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73  ..static int fts
4370: 35 53 74 6d 74 54 79 70 65 28 69 6e 74 20 69 64  5StmtType(int id
4380: 78 4e 75 6d 29 7b 0a 20 20 69 66 28 20 46 54 53  xNum){.  if( FTS
4390: 35 5f 50 4c 41 4e 28 69 64 78 4e 75 6d 29 3d 3d  5_PLAN(idxNum)==
43a0: 46 54 53 35 5f 50 4c 41 4e 5f 53 43 41 4e 20 29  FTS5_PLAN_SCAN )
43b0: 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 28 69 64  {.    return (id
43c0: 78 4e 75 6d 26 46 54 53 35 5f 4f 52 44 45 52 5f  xNum&FTS5_ORDER_
43d0: 41 53 43 29 20 3f 20 46 54 53 35 5f 53 54 4d 54  ASC) ? FTS5_STMT
43e0: 5f 53 43 41 4e 5f 41 53 43 20 3a 20 46 54 53 35  _SCAN_ASC : FTS5
43f0: 5f 53 54 4d 54 5f 53 43 41 4e 5f 44 45 53 43 3b  _STMT_SCAN_DESC;
4400: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 46 54  .  }.  return FT
4410: 53 35 5f 53 54 4d 54 5f 4c 4f 4f 4b 55 50 3b 0a  S5_STMT_LOOKUP;.
4420: 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75  }../*.** This fu
4430: 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64  nction is called
4440: 20 61 66 74 65 72 20 74 68 65 20 63 75 72 73 6f   after the curso
4450: 72 20 70 61 73 73 65 64 20 61 73 20 74 68 65 20  r passed as the 
4460: 6f 6e 6c 79 20 61 72 67 75 6d 65 6e 74 0a 2a 2a  only argument.**
4470: 20 69 73 20 6d 6f 76 65 64 20 74 6f 20 70 6f 69   is moved to poi
4480: 6e 74 20 61 74 20 61 20 64 69 66 66 65 72 65 6e  nt at a differen
4490: 74 20 72 6f 77 2e 20 49 74 20 63 6c 65 61 72 73  t row. It clears
44a0: 20 61 6c 6c 20 63 61 63 68 65 64 20 64 61 74 61   all cached data
44b0: 20 0a 2a 2a 20 73 70 65 63 69 66 69 63 20 74 6f   .** specific to
44c0: 20 74 68 65 20 70 72 65 76 69 6f 75 73 20 72 6f   the previous ro
44d0: 77 20 73 74 6f 72 65 64 20 62 79 20 74 68 65 20  w stored by the 
44e0: 63 75 72 73 6f 72 20 6f 62 6a 65 63 74 2e 0a 2a  cursor object..*
44f0: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 66 74  /.static void ft
4500: 73 35 43 73 72 4e 65 77 72 6f 77 28 46 74 73 35  s5CsrNewrow(Fts5
4510: 43 75 72 73 6f 72 20 2a 70 43 73 72 29 7b 0a 20  Cursor *pCsr){. 
4520: 20 43 73 72 46 6c 61 67 53 65 74 28 70 43 73 72   CsrFlagSet(pCsr
4530: 2c 20 46 54 53 35 43 53 52 5f 52 45 51 55 49 52  , FTS5CSR_REQUIR
4540: 45 5f 43 4f 4e 54 45 4e 54 20 7c 20 46 54 53 35  E_CONTENT | FTS5
4550: 43 53 52 5f 52 45 51 55 49 52 45 5f 44 4f 43 53  CSR_REQUIRE_DOCS
4560: 49 5a 45 20 29 3b 0a 20 20 73 71 6c 69 74 65 33  IZE );.  sqlite3
4570: 5f 66 72 65 65 28 70 43 73 72 2d 3e 61 49 6e 73  _free(pCsr->aIns
4580: 74 29 3b 0a 20 20 70 43 73 72 2d 3e 61 49 6e 73  t);.  pCsr->aIns
4590: 74 20 3d 20 30 3b 0a 20 20 70 43 73 72 2d 3e 6e  t = 0;.  pCsr->n
45a0: 49 6e 73 74 43 6f 75 6e 74 20 3d 20 30 3b 0a 7d  InstCount = 0;.}
45b0: 0a 0a 2f 2a 0a 2a 2a 20 43 6c 6f 73 65 20 74 68  ../*.** Close th
45c0: 65 20 63 75 72 73 6f 72 2e 20 20 46 6f 72 20 61  e cursor.  For a
45d0: 64 64 69 74 69 6f 6e 61 6c 20 69 6e 66 6f 72 6d  dditional inform
45e0: 61 74 69 6f 6e 20 73 65 65 20 74 68 65 20 64 6f  ation see the do
45f0: 63 75 6d 65 6e 74 61 74 69 6f 6e 0a 2a 2a 20 6f  cumentation.** o
4600: 6e 20 74 68 65 20 78 43 6c 6f 73 65 20 6d 65 74  n the xClose met
4610: 68 6f 64 20 6f 66 20 74 68 65 20 76 69 72 74 75  hod of the virtu
4620: 61 6c 20 74 61 62 6c 65 20 69 6e 74 65 72 66 61  al table interfa
4630: 63 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  ce..*/.static in
4640: 74 20 66 74 73 35 43 6c 6f 73 65 4d 65 74 68 6f  t fts5CloseMetho
4650: 64 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63  d(sqlite3_vtab_c
4660: 75 72 73 6f 72 20 2a 70 43 75 72 73 6f 72 29 7b  ursor *pCursor){
4670: 0a 20 20 46 74 73 35 54 61 62 6c 65 20 2a 70 54  .  Fts5Table *pT
4680: 61 62 20 3d 20 28 46 74 73 35 54 61 62 6c 65 2a  ab = (Fts5Table*
4690: 29 28 70 43 75 72 73 6f 72 2d 3e 70 56 74 61 62  )(pCursor->pVtab
46a0: 29 3b 0a 20 20 46 74 73 35 43 75 72 73 6f 72 20  );.  Fts5Cursor 
46b0: 2a 70 43 73 72 20 3d 20 28 46 74 73 35 43 75 72  *pCsr = (Fts5Cur
46c0: 73 6f 72 2a 29 70 43 75 72 73 6f 72 3b 0a 20 20  sor*)pCursor;.  
46d0: 46 74 73 35 43 75 72 73 6f 72 20 2a 2a 70 70 3b  Fts5Cursor **pp;
46e0: 0a 20 20 46 74 73 35 41 75 78 64 61 74 61 20 2a  .  Fts5Auxdata *
46f0: 70 44 61 74 61 3b 0a 20 20 46 74 73 35 41 75 78  pData;.  Fts5Aux
4700: 64 61 74 61 20 2a 70 4e 65 78 74 3b 0a 0a 20 20  data *pNext;..  
4710: 66 74 73 35 43 73 72 4e 65 77 72 6f 77 28 70 43  fts5CsrNewrow(pC
4720: 73 72 29 3b 0a 20 20 69 66 28 20 70 43 73 72 2d  sr);.  if( pCsr-
4730: 3e 70 53 74 6d 74 20 29 7b 0a 20 20 20 20 69 6e  >pStmt ){.    in
4740: 74 20 65 53 74 6d 74 20 3d 20 66 74 73 35 53 74  t eStmt = fts5St
4750: 6d 74 54 79 70 65 28 70 43 73 72 2d 3e 69 64 78  mtType(pCsr->idx
4760: 4e 75 6d 29 3b 0a 20 20 20 20 73 71 6c 69 74 65  Num);.    sqlite
4770: 33 46 74 73 35 53 74 6f 72 61 67 65 53 74 6d 74  3Fts5StorageStmt
4780: 52 65 6c 65 61 73 65 28 70 54 61 62 2d 3e 70 53  Release(pTab->pS
4790: 74 6f 72 61 67 65 2c 20 65 53 74 6d 74 2c 20 70  torage, eStmt, p
47a0: 43 73 72 2d 3e 70 53 74 6d 74 29 3b 0a 20 20 7d  Csr->pStmt);.  }
47b0: 0a 20 20 69 66 28 20 70 43 73 72 2d 3e 70 53 6f  .  if( pCsr->pSo
47c0: 72 74 65 72 20 29 7b 0a 20 20 20 20 46 74 73 35  rter ){.    Fts5
47d0: 53 6f 72 74 65 72 20 2a 70 53 6f 72 74 65 72 20  Sorter *pSorter 
47e0: 3d 20 70 43 73 72 2d 3e 70 53 6f 72 74 65 72 3b  = pCsr->pSorter;
47f0: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 69 6e  .    sqlite3_fin
4800: 61 6c 69 7a 65 28 70 53 6f 72 74 65 72 2d 3e 70  alize(pSorter->p
4810: 53 74 6d 74 29 3b 0a 20 20 20 20 73 71 6c 69 74  Stmt);.    sqlit
4820: 65 33 5f 66 72 65 65 28 70 53 6f 72 74 65 72 29  e3_free(pSorter)
4830: 3b 0a 20 20 7d 0a 20 20 0a 20 20 69 66 28 20 70  ;.  }.  .  if( p
4840: 43 73 72 2d 3e 69 64 78 4e 75 6d 21 3d 46 54 53  Csr->idxNum!=FTS
4850: 35 5f 50 4c 41 4e 5f 53 4f 55 52 43 45 20 29 7b  5_PLAN_SOURCE ){
4860: 0a 20 20 20 20 73 71 6c 69 74 65 33 46 74 73 35  .    sqlite3Fts5
4870: 45 78 70 72 46 72 65 65 28 70 43 73 72 2d 3e 70  ExprFree(pCsr->p
4880: 45 78 70 72 29 3b 0a 20 20 7d 0a 0a 20 20 66 6f  Expr);.  }..  fo
4890: 72 28 70 44 61 74 61 3d 70 43 73 72 2d 3e 70 41  r(pData=pCsr->pA
48a0: 75 78 64 61 74 61 3b 20 70 44 61 74 61 3b 20 70  uxdata; pData; p
48b0: 44 61 74 61 3d 70 4e 65 78 74 29 7b 0a 20 20 20  Data=pNext){.   
48c0: 20 70 4e 65 78 74 20 3d 20 70 44 61 74 61 2d 3e   pNext = pData->
48d0: 70 4e 65 78 74 3b 0a 20 20 20 20 69 66 28 20 70  pNext;.    if( p
48e0: 44 61 74 61 2d 3e 78 44 65 6c 65 74 65 20 29 20  Data->xDelete ) 
48f0: 70 44 61 74 61 2d 3e 78 44 65 6c 65 74 65 28 70  pData->xDelete(p
4900: 44 61 74 61 2d 3e 70 50 74 72 29 3b 0a 20 20 20  Data->pPtr);.   
4910: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 44   sqlite3_free(pD
4920: 61 74 61 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20  ata);.  }..  /* 
4930: 52 65 6d 6f 76 65 20 74 68 65 20 63 75 72 73 6f  Remove the curso
4940: 72 20 66 72 6f 6d 20 74 68 65 20 46 74 73 35 47  r from the Fts5G
4950: 6c 6f 62 61 6c 2e 70 43 73 72 20 6c 69 73 74 20  lobal.pCsr list 
4960: 2a 2f 0a 20 20 66 6f 72 28 70 70 3d 26 70 54 61  */.  for(pp=&pTa
4970: 62 2d 3e 70 47 6c 6f 62 61 6c 2d 3e 70 43 73 72  b->pGlobal->pCsr
4980: 3b 20 28 2a 70 70 29 21 3d 70 43 73 72 3b 20 70  ; (*pp)!=pCsr; p
4990: 70 3d 26 28 2a 70 70 29 2d 3e 70 4e 65 78 74 29  p=&(*pp)->pNext)
49a0: 3b 0a 20 20 2a 70 70 20 3d 20 70 43 73 72 2d 3e  ;.  *pp = pCsr->
49b0: 70 4e 65 78 74 3b 0a 0a 20 20 73 71 6c 69 74 65  pNext;..  sqlite
49c0: 33 5f 66 69 6e 61 6c 69 7a 65 28 70 43 73 72 2d  3_finalize(pCsr-
49d0: 3e 70 52 61 6e 6b 41 72 67 53 74 6d 74 29 3b 0a  >pRankArgStmt);.
49e0: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70    sqlite3_free(p
49f0: 43 73 72 2d 3e 61 70 52 61 6e 6b 41 72 67 29 3b  Csr->apRankArg);
4a00: 0a 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65  ..  sqlite3_free
4a10: 28 70 43 73 72 2d 3e 7a 53 70 65 63 69 61 6c 29  (pCsr->zSpecial)
4a20: 3b 0a 20 20 69 66 28 20 43 73 72 46 6c 61 67 54  ;.  if( CsrFlagT
4a30: 65 73 74 28 70 43 73 72 2c 20 46 54 53 35 43 53  est(pCsr, FTS5CS
4a40: 52 5f 46 52 45 45 5f 5a 52 41 4e 4b 29 20 29 7b  R_FREE_ZRANK) ){
4a50: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65  .    sqlite3_fre
4a60: 65 28 70 43 73 72 2d 3e 7a 52 61 6e 6b 29 3b 0a  e(pCsr->zRank);.
4a70: 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65      sqlite3_free
4a80: 28 70 43 73 72 2d 3e 7a 52 61 6e 6b 41 72 67 73  (pCsr->zRankArgs
4a90: 29 3b 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65 33  );.  }.  sqlite3
4aa0: 5f 66 72 65 65 28 70 43 73 72 29 3b 0a 20 20 72  _free(pCsr);.  r
4ab0: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
4ac0: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 66  .}..static int f
4ad0: 74 73 35 53 6f 72 74 65 72 4e 65 78 74 28 46 74  ts5SorterNext(Ft
4ae0: 73 35 43 75 72 73 6f 72 20 2a 70 43 73 72 29 7b  s5Cursor *pCsr){
4af0: 0a 20 20 46 74 73 35 53 6f 72 74 65 72 20 2a 70  .  Fts5Sorter *p
4b00: 53 6f 72 74 65 72 20 3d 20 70 43 73 72 2d 3e 70  Sorter = pCsr->p
4b10: 53 6f 72 74 65 72 3b 0a 20 20 69 6e 74 20 72 63  Sorter;.  int rc
4b20: 3b 0a 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65  ;..  rc = sqlite
4b30: 33 5f 73 74 65 70 28 70 53 6f 72 74 65 72 2d 3e  3_step(pSorter->
4b40: 70 53 74 6d 74 29 3b 0a 20 20 69 66 28 20 72 63  pStmt);.  if( rc
4b50: 3d 3d 53 51 4c 49 54 45 5f 44 4f 4e 45 20 29 7b  ==SQLITE_DONE ){
4b60: 0a 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45  .    rc = SQLITE
4b70: 5f 4f 4b 3b 0a 20 20 20 20 43 73 72 46 6c 61 67  _OK;.    CsrFlag
4b80: 53 65 74 28 70 43 73 72 2c 20 46 54 53 35 43 53  Set(pCsr, FTS5CS
4b90: 52 5f 45 4f 46 29 3b 0a 20 20 7d 65 6c 73 65 20  R_EOF);.  }else 
4ba0: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 52  if( rc==SQLITE_R
4bb0: 4f 57 20 29 7b 0a 20 20 20 20 63 6f 6e 73 74 20  OW ){.    const 
4bc0: 75 38 20 2a 61 3b 0a 20 20 20 20 63 6f 6e 73 74  u8 *a;.    const
4bd0: 20 75 38 20 2a 61 42 6c 6f 62 3b 0a 20 20 20 20   u8 *aBlob;.    
4be0: 69 6e 74 20 6e 42 6c 6f 62 3b 0a 20 20 20 20 69  int nBlob;.    i
4bf0: 6e 74 20 69 3b 0a 20 20 20 20 69 6e 74 20 69 4f  nt i;.    int iO
4c00: 66 66 20 3d 20 30 3b 0a 20 20 20 20 72 63 20 3d  ff = 0;.    rc =
4c10: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20 20   SQLITE_OK;..   
4c20: 20 70 53 6f 72 74 65 72 2d 3e 69 52 6f 77 69 64   pSorter->iRowid
4c30: 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d   = sqlite3_colum
4c40: 6e 5f 69 6e 74 36 34 28 70 53 6f 72 74 65 72 2d  n_int64(pSorter-
4c50: 3e 70 53 74 6d 74 2c 20 30 29 3b 0a 20 20 20 20  >pStmt, 0);.    
4c60: 6e 42 6c 6f 62 20 3d 20 73 71 6c 69 74 65 33 5f  nBlob = sqlite3_
4c70: 63 6f 6c 75 6d 6e 5f 62 79 74 65 73 28 70 53 6f  column_bytes(pSo
4c80: 72 74 65 72 2d 3e 70 53 74 6d 74 2c 20 31 29 3b  rter->pStmt, 1);
4c90: 0a 20 20 20 20 61 42 6c 6f 62 20 3d 20 61 20 3d  .    aBlob = a =
4ca0: 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f   sqlite3_column_
4cb0: 62 6c 6f 62 28 70 53 6f 72 74 65 72 2d 3e 70 53  blob(pSorter->pS
4cc0: 74 6d 74 2c 20 31 29 3b 0a 0a 20 20 20 20 66 6f  tmt, 1);..    fo
4cd0: 72 28 69 3d 30 3b 20 69 3c 28 70 53 6f 72 74 65  r(i=0; i<(pSorte
4ce0: 72 2d 3e 6e 49 64 78 2d 31 29 3b 20 69 2b 2b 29  r->nIdx-1); i++)
4cf0: 7b 0a 20 20 20 20 20 20 69 6e 74 20 69 56 61 6c  {.      int iVal
4d00: 3b 0a 20 20 20 20 20 20 61 20 2b 3d 20 67 65 74  ;.      a += get
4d10: 56 61 72 69 6e 74 33 32 28 61 2c 20 69 56 61 6c  Varint32(a, iVal
4d20: 29 3b 0a 20 20 20 20 20 20 69 4f 66 66 20 2b 3d  );.      iOff +=
4d30: 20 69 56 61 6c 3b 0a 20 20 20 20 20 20 70 53 6f   iVal;.      pSo
4d40: 72 74 65 72 2d 3e 61 49 64 78 5b 69 5d 20 3d 20  rter->aIdx[i] = 
4d50: 69 4f 66 66 3b 0a 20 20 20 20 7d 0a 20 20 20 20  iOff;.    }.    
4d60: 70 53 6f 72 74 65 72 2d 3e 61 49 64 78 5b 69 5d  pSorter->aIdx[i]
4d70: 20 3d 20 26 61 42 6c 6f 62 5b 6e 42 6c 6f 62 5d   = &aBlob[nBlob]
4d80: 20 2d 20 61 3b 0a 0a 20 20 20 20 70 53 6f 72 74   - a;..    pSort
4d90: 65 72 2d 3e 61 50 6f 73 6c 69 73 74 20 3d 20 61  er->aPoslist = a
4da0: 3b 0a 20 20 20 20 66 74 73 35 43 73 72 4e 65 77  ;.    fts5CsrNew
4db0: 72 6f 77 28 70 43 73 72 29 3b 0a 20 20 7d 0a 0a  row(pCsr);.  }..
4dc0: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
4dd0: 2f 2a 0a 2a 2a 20 41 64 76 61 6e 63 65 20 74 68  /*.** Advance th
4de0: 65 20 63 75 72 73 6f 72 20 74 6f 20 74 68 65 20  e cursor to the 
4df0: 6e 65 78 74 20 72 6f 77 20 69 6e 20 74 68 65 20  next row in the 
4e00: 74 61 62 6c 65 20 74 68 61 74 20 6d 61 74 63 68  table that match
4e10: 65 73 20 74 68 65 20 0a 2a 2a 20 73 65 61 72 63  es the .** searc
4e20: 68 20 63 72 69 74 65 72 69 61 2e 0a 2a 2a 0a 2a  h criteria..**.*
4e30: 2a 20 52 65 74 75 72 6e 20 53 51 4c 49 54 45 5f  * Return SQLITE_
4e40: 4f 4b 20 69 66 20 6e 6f 74 68 69 6e 67 20 67 6f  OK if nothing go
4e50: 65 73 20 77 72 6f 6e 67 2e 20 20 53 51 4c 49 54  es wrong.  SQLIT
4e60: 45 5f 4f 4b 20 69 73 20 72 65 74 75 72 6e 65 64  E_OK is returned
4e70: 0a 2a 2a 20 65 76 65 6e 20 69 66 20 77 65 20 72  .** even if we r
4e80: 65 61 63 68 20 65 6e 64 2d 6f 66 2d 66 69 6c 65  each end-of-file
4e90: 2e 20 20 54 68 65 20 66 74 73 35 45 6f 66 4d 65  .  The fts5EofMe
4ea0: 74 68 6f 64 28 29 20 77 69 6c 6c 20 62 65 20 63  thod() will be c
4eb0: 61 6c 6c 65 64 0a 2a 2a 20 73 75 62 73 65 71 75  alled.** subsequ
4ec0: 65 6e 74 6c 79 20 74 6f 20 64 65 74 65 72 6d 69  ently to determi
4ed0: 6e 65 20 77 68 65 74 68 65 72 20 6f 72 20 6e 6f  ne whether or no
4ee0: 74 20 61 6e 20 45 4f 46 20 77 61 73 20 68 69 74  t an EOF was hit
4ef0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
4f00: 66 74 73 35 4e 65 78 74 4d 65 74 68 6f 64 28 73  fts5NextMethod(s
4f10: 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73  qlite3_vtab_curs
4f20: 6f 72 20 2a 70 43 75 72 73 6f 72 29 7b 0a 20 20  or *pCursor){.  
4f30: 46 74 73 35 43 75 72 73 6f 72 20 2a 70 43 73 72  Fts5Cursor *pCsr
4f40: 20 3d 20 28 46 74 73 35 43 75 72 73 6f 72 2a 29   = (Fts5Cursor*)
4f50: 70 43 75 72 73 6f 72 3b 0a 20 20 69 6e 74 20 65  pCursor;.  int e
4f60: 50 6c 61 6e 20 3d 20 46 54 53 35 5f 50 4c 41 4e  Plan = FTS5_PLAN
4f70: 28 70 43 73 72 2d 3e 69 64 78 4e 75 6d 29 3b 0a  (pCsr->idxNum);.
4f80: 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
4f90: 45 5f 4f 4b 3b 0a 0a 20 20 73 77 69 74 63 68 28  E_OK;..  switch(
4fa0: 20 65 50 6c 61 6e 20 29 7b 0a 20 20 20 20 63 61   ePlan ){.    ca
4fb0: 73 65 20 46 54 53 35 5f 50 4c 41 4e 5f 4d 41 54  se FTS5_PLAN_MAT
4fc0: 43 48 3a 0a 20 20 20 20 63 61 73 65 20 46 54 53  CH:.    case FTS
4fd0: 35 5f 50 4c 41 4e 5f 53 4f 55 52 43 45 3a 0a 20  5_PLAN_SOURCE:. 
4fe0: 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65       rc = sqlite
4ff0: 33 46 74 73 35 45 78 70 72 4e 65 78 74 28 70 43  3Fts5ExprNext(pC
5000: 73 72 2d 3e 70 45 78 70 72 29 3b 0a 20 20 20 20  sr->pExpr);.    
5010: 20 20 69 66 28 20 73 71 6c 69 74 65 33 46 74 73    if( sqlite3Fts
5020: 35 45 78 70 72 45 6f 66 28 70 43 73 72 2d 3e 70  5ExprEof(pCsr->p
5030: 45 78 70 72 29 20 29 7b 0a 20 20 20 20 20 20 20  Expr) ){.       
5040: 20 43 73 72 46 6c 61 67 53 65 74 28 70 43 73 72   CsrFlagSet(pCsr
5050: 2c 20 46 54 53 35 43 53 52 5f 45 4f 46 29 3b 0a  , FTS5CSR_EOF);.
5060: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 66 74        }.      ft
5070: 73 35 43 73 72 4e 65 77 72 6f 77 28 70 43 73 72  s5CsrNewrow(pCsr
5080: 29 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a  );.      break;.
5090: 0a 20 20 20 20 63 61 73 65 20 46 54 53 35 5f 50  .    case FTS5_P
50a0: 4c 41 4e 5f 53 50 45 43 49 41 4c 3a 20 7b 0a 20  LAN_SPECIAL: {. 
50b0: 20 20 20 20 20 43 73 72 46 6c 61 67 53 65 74 28       CsrFlagSet(
50c0: 70 43 73 72 2c 20 46 54 53 35 43 53 52 5f 45 4f  pCsr, FTS5CSR_EO
50d0: 46 29 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b  F);.      break;
50e0: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 63 61 73 65  .    }..    case
50f0: 20 46 54 53 35 5f 50 4c 41 4e 5f 53 4f 52 54 45   FTS5_PLAN_SORTE
5100: 44 5f 4d 41 54 43 48 3a 20 7b 0a 20 20 20 20 20  D_MATCH: {.     
5110: 20 72 63 20 3d 20 66 74 73 35 53 6f 72 74 65 72   rc = fts5Sorter
5120: 4e 65 78 74 28 70 43 73 72 29 3b 0a 20 20 20 20  Next(pCsr);.    
5130: 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 0a    break;.    }..
5140: 20 20 20 20 64 65 66 61 75 6c 74 3a 0a 20 20 20      default:.   
5150: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f     rc = sqlite3_
5160: 73 74 65 70 28 70 43 73 72 2d 3e 70 53 74 6d 74  step(pCsr->pStmt
5170: 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 21  );.      if( rc!
5180: 3d 53 51 4c 49 54 45 5f 52 4f 57 20 29 7b 0a 20  =SQLITE_ROW ){. 
5190: 20 20 20 20 20 20 20 43 73 72 46 6c 61 67 53 65         CsrFlagSe
51a0: 74 28 70 43 73 72 2c 20 46 54 53 35 43 53 52 5f  t(pCsr, FTS5CSR_
51b0: 45 4f 46 29 3b 0a 20 20 20 20 20 20 20 20 72 63  EOF);.        rc
51c0: 20 3d 20 73 71 6c 69 74 65 33 5f 72 65 73 65 74   = sqlite3_reset
51d0: 28 70 43 73 72 2d 3e 70 53 74 6d 74 29 3b 0a 20  (pCsr->pStmt);. 
51e0: 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20       }else{.    
51f0: 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
5200: 4f 4b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  OK;.      }.    
5210: 20 20 62 72 65 61 6b 3b 0a 20 20 7d 0a 20 20 0a    break;.  }.  .
5220: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
5230: 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 43  static int fts5C
5240: 75 72 73 6f 72 46 69 72 73 74 53 6f 72 74 65 64  ursorFirstSorted
5250: 28 46 74 73 35 54 61 62 6c 65 20 2a 70 54 61 62  (Fts5Table *pTab
5260: 2c 20 46 74 73 35 43 75 72 73 6f 72 20 2a 70 43  , Fts5Cursor *pC
5270: 73 72 2c 20 69 6e 74 20 62 41 73 63 29 7b 0a 20  sr, int bAsc){. 
5280: 20 46 74 73 35 43 6f 6e 66 69 67 20 2a 70 43 6f   Fts5Config *pCo
5290: 6e 66 69 67 20 3d 20 70 54 61 62 2d 3e 70 43 6f  nfig = pTab->pCo
52a0: 6e 66 69 67 3b 0a 20 20 46 74 73 35 53 6f 72 74  nfig;.  Fts5Sort
52b0: 65 72 20 2a 70 53 6f 72 74 65 72 3b 0a 20 20 69  er *pSorter;.  i
52c0: 6e 74 20 6e 50 68 72 61 73 65 3b 0a 20 20 69 6e  nt nPhrase;.  in
52d0: 74 20 6e 42 79 74 65 3b 0a 20 20 69 6e 74 20 72  t nByte;.  int r
52e0: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  c = SQLITE_OK;. 
52f0: 20 63 68 61 72 20 2a 7a 53 71 6c 3b 0a 20 20 63   char *zSql;.  c
5300: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 52 61 6e 6b  onst char *zRank
5310: 20 3d 20 70 43 73 72 2d 3e 7a 52 61 6e 6b 3b 0a   = pCsr->zRank;.
5320: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 52    const char *zR
5330: 61 6e 6b 41 72 67 73 20 3d 20 70 43 73 72 2d 3e  ankArgs = pCsr->
5340: 7a 52 61 6e 6b 41 72 67 73 3b 0a 20 20 0a 20 20  zRankArgs;.  .  
5350: 6e 50 68 72 61 73 65 20 3d 20 73 71 6c 69 74 65  nPhrase = sqlite
5360: 33 46 74 73 35 45 78 70 72 50 68 72 61 73 65 43  3Fts5ExprPhraseC
5370: 6f 75 6e 74 28 70 43 73 72 2d 3e 70 45 78 70 72  ount(pCsr->pExpr
5380: 29 3b 0a 20 20 6e 42 79 74 65 20 3d 20 73 69 7a  );.  nByte = siz
5390: 65 6f 66 28 46 74 73 35 53 6f 72 74 65 72 29 20  eof(Fts5Sorter) 
53a0: 2b 20 73 69 7a 65 6f 66 28 69 6e 74 29 20 2a 20  + sizeof(int) * 
53b0: 6e 50 68 72 61 73 65 3b 0a 20 20 70 53 6f 72 74  nPhrase;.  pSort
53c0: 65 72 20 3d 20 28 46 74 73 35 53 6f 72 74 65 72  er = (Fts5Sorter
53d0: 2a 29 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63  *)sqlite3_malloc
53e0: 28 6e 42 79 74 65 29 3b 0a 20 20 69 66 28 20 70  (nByte);.  if( p
53f0: 53 6f 72 74 65 72 3d 3d 30 20 29 20 72 65 74 75  Sorter==0 ) retu
5400: 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b  rn SQLITE_NOMEM;
5410: 0a 20 20 6d 65 6d 73 65 74 28 70 53 6f 72 74 65  .  memset(pSorte
5420: 72 2c 20 30 2c 20 6e 42 79 74 65 29 3b 0a 20 20  r, 0, nByte);.  
5430: 70 53 6f 72 74 65 72 2d 3e 6e 49 64 78 20 3d 20  pSorter->nIdx = 
5440: 6e 50 68 72 61 73 65 3b 0a 0a 20 20 2f 2a 20 54  nPhrase;..  /* T
5450: 4f 44 4f 3a 20 49 74 20 77 6f 75 6c 64 20 62 65  ODO: It would be
5460: 20 62 65 74 74 65 72 20 74 6f 20 68 61 76 65 20   better to have 
5470: 73 6f 6d 65 20 73 79 73 74 65 6d 20 66 6f 72 20  some system for 
5480: 72 65 75 73 69 6e 67 20 73 74 61 74 65 6d 65 6e  reusing statemen
5490: 74 0a 20 20 2a 2a 20 68 61 6e 64 6c 65 73 20 68  t.  ** handles h
54a0: 65 72 65 2c 20 72 61 74 68 65 72 20 74 68 61 6e  ere, rather than
54b0: 20 70 72 65 70 61 72 69 6e 67 20 61 20 6e 65 77   preparing a new
54c0: 20 6f 6e 65 20 66 6f 72 20 65 61 63 68 20 71 75   one for each qu
54d0: 65 72 79 2e 20 42 75 74 20 74 68 61 74 0a 20 20  ery. But that.  
54e0: 2a 2a 20 69 73 20 6e 6f 74 20 70 6f 73 73 69 62  ** is not possib
54f0: 6c 65 20 61 73 20 53 51 4c 69 74 65 20 72 65 66  le as SQLite ref
5500: 65 72 65 6e 63 65 20 63 6f 75 6e 74 73 20 74 68  erence counts th
5510: 65 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20  e virtual table 
5520: 6f 62 6a 65 63 74 73 2e 0a 20 20 2a 2a 20 41 6e  objects..  ** An
5530: 64 20 73 69 6e 63 65 20 74 68 65 20 73 74 61 74  d since the stat
5540: 65 6d 65 6e 74 20 72 65 71 75 69 72 65 64 20 68  ement required h
5550: 65 72 65 20 72 65 61 64 73 20 66 72 6f 6d 20 74  ere reads from t
5560: 68 69 73 20 76 65 72 79 20 76 69 72 74 75 61 6c  his very virtual
5570: 20 0a 20 20 2a 2a 20 74 61 62 6c 65 2c 20 73 61   .  ** table, sa
5580: 76 69 6e 67 20 69 74 20 63 72 65 61 74 65 73 20  ving it creates 
5590: 61 20 63 69 72 63 75 6c 61 72 20 72 65 66 65 72  a circular refer
55a0: 65 6e 63 65 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20  ence..  **.  ** 
55b0: 49 66 20 53 51 4c 69 74 65 20 61 20 62 75 69 6c  If SQLite a buil
55c0: 74 2d 69 6e 20 73 74 61 74 65 6d 65 6e 74 20 63  t-in statement c
55d0: 61 63 68 65 2c 20 74 68 69 73 20 77 6f 75 6c 64  ache, this would
55e0: 6e 27 74 20 62 65 20 61 20 70 72 6f 62 6c 65 6d  n't be a problem
55f0: 2e 20 2a 2f 0a 20 20 7a 53 71 6c 20 3d 20 73 71  . */.  zSql = sq
5600: 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 53  lite3_mprintf("S
5610: 45 4c 45 43 54 20 72 6f 77 69 64 2c 20 72 61 6e  ELECT rowid, ran
5620: 6b 20 46 52 4f 4d 20 25 51 2e 25 51 20 4f 52 44  k FROM %Q.%Q ORD
5630: 45 52 20 42 59 20 25 73 28 25 73 25 73 25 73 29  ER BY %s(%s%s%s)
5640: 20 25 73 22 2c 0a 20 20 20 20 20 20 70 43 6f 6e   %s",.      pCon
5650: 66 69 67 2d 3e 7a 44 62 2c 20 70 43 6f 6e 66 69  fig->zDb, pConfi
5660: 67 2d 3e 7a 4e 61 6d 65 2c 20 7a 52 61 6e 6b 2c  g->zName, zRank,
5670: 20 70 43 6f 6e 66 69 67 2d 3e 7a 4e 61 6d 65 2c   pConfig->zName,
5680: 0a 20 20 20 20 20 20 28 7a 52 61 6e 6b 41 72 67  .      (zRankArg
5690: 73 20 3f 20 22 2c 20 22 20 3a 20 22 22 29 2c 0a  s ? ", " : ""),.
56a0: 20 20 20 20 20 20 28 7a 52 61 6e 6b 41 72 67 73        (zRankArgs
56b0: 20 3f 20 7a 52 61 6e 6b 41 72 67 73 20 3a 20 22   ? zRankArgs : "
56c0: 22 29 2c 0a 20 20 20 20 20 20 62 41 73 63 20 3f  "),.      bAsc ?
56d0: 20 22 41 53 43 22 20 3a 20 22 44 45 53 43 22 0a   "ASC" : "DESC".
56e0: 20 20 29 3b 0a 20 20 69 66 28 20 7a 53 71 6c 3d    );.  if( zSql=
56f0: 3d 30 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 53  =0 ){.    rc = S
5700: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d  QLITE_NOMEM;.  }
5710: 65 6c 73 65 7b 0a 20 20 20 20 72 63 20 3d 20 73  else{.    rc = s
5720: 71 6c 69 74 65 33 5f 70 72 65 70 61 72 65 5f 76  qlite3_prepare_v
5730: 32 28 70 43 6f 6e 66 69 67 2d 3e 64 62 2c 20 7a  2(pConfig->db, z
5740: 53 71 6c 2c 20 2d 31 2c 20 26 70 53 6f 72 74 65  Sql, -1, &pSorte
5750: 72 2d 3e 70 53 74 6d 74 2c 20 30 29 3b 0a 20 20  r->pStmt, 0);.  
5760: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a    sqlite3_free(z
5770: 53 71 6c 29 3b 0a 20 20 7d 0a 0a 20 20 70 43 73  Sql);.  }..  pCs
5780: 72 2d 3e 70 53 6f 72 74 65 72 20 3d 20 70 53 6f  r->pSorter = pSo
5790: 72 74 65 72 3b 0a 20 20 69 66 28 20 72 63 3d 3d  rter;.  if( rc==
57a0: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
57b0: 20 61 73 73 65 72 74 28 20 70 54 61 62 2d 3e 70   assert( pTab->p
57c0: 53 6f 72 74 43 73 72 3d 3d 30 20 29 3b 0a 20 20  SortCsr==0 );.  
57d0: 20 20 70 54 61 62 2d 3e 70 53 6f 72 74 43 73 72    pTab->pSortCsr
57e0: 20 3d 20 70 43 73 72 3b 0a 20 20 20 20 72 63 20   = pCsr;.    rc 
57f0: 3d 20 66 74 73 35 53 6f 72 74 65 72 4e 65 78 74  = fts5SorterNext
5800: 28 70 43 73 72 29 3b 0a 20 20 20 20 70 54 61 62  (pCsr);.    pTab
5810: 2d 3e 70 53 6f 72 74 43 73 72 20 3d 20 30 3b 0a  ->pSortCsr = 0;.
5820: 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 21 3d 53    }..  if( rc!=S
5830: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
5840: 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65  sqlite3_finalize
5850: 28 70 53 6f 72 74 65 72 2d 3e 70 53 74 6d 74 29  (pSorter->pStmt)
5860: 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72  ;.    sqlite3_fr
5870: 65 65 28 70 53 6f 72 74 65 72 29 3b 0a 20 20 20  ee(pSorter);.   
5880: 20 70 43 73 72 2d 3e 70 53 6f 72 74 65 72 20 3d   pCsr->pSorter =
5890: 20 30 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72   0;.  }..  retur
58a0: 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  n rc;.}..static 
58b0: 69 6e 74 20 66 74 73 35 43 75 72 73 6f 72 46 69  int fts5CursorFi
58c0: 72 73 74 28 46 74 73 35 54 61 62 6c 65 20 2a 70  rst(Fts5Table *p
58d0: 54 61 62 2c 20 46 74 73 35 43 75 72 73 6f 72 20  Tab, Fts5Cursor 
58e0: 2a 70 43 73 72 2c 20 69 6e 74 20 62 41 73 63 29  *pCsr, int bAsc)
58f0: 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 72 63  {.  int rc;.  rc
5900: 20 3d 20 73 71 6c 69 74 65 33 46 74 73 35 45 78   = sqlite3Fts5Ex
5910: 70 72 46 69 72 73 74 28 70 43 73 72 2d 3e 70 45  prFirst(pCsr->pE
5920: 78 70 72 2c 20 70 54 61 62 2d 3e 70 49 6e 64 65  xpr, pTab->pInde
5930: 78 2c 20 62 41 73 63 29 3b 0a 20 20 69 66 28 20  x, bAsc);.  if( 
5940: 73 71 6c 69 74 65 33 46 74 73 35 45 78 70 72 45  sqlite3Fts5ExprE
5950: 6f 66 28 70 43 73 72 2d 3e 70 45 78 70 72 29 20  of(pCsr->pExpr) 
5960: 29 7b 0a 20 20 20 20 43 73 72 46 6c 61 67 53 65  ){.    CsrFlagSe
5970: 74 28 70 43 73 72 2c 20 46 54 53 35 43 53 52 5f  t(pCsr, FTS5CSR_
5980: 45 4f 46 29 3b 0a 20 20 7d 0a 20 20 66 74 73 35  EOF);.  }.  fts5
5990: 43 73 72 4e 65 77 72 6f 77 28 70 43 73 72 29 3b  CsrNewrow(pCsr);
59a0: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
59b0: 0a 2f 2a 0a 2a 2a 20 50 72 6f 63 65 73 73 20 61  ./*.** Process a
59c0: 20 22 73 70 65 63 69 61 6c 22 20 71 75 65 72 79   "special" query
59d0: 2e 20 41 20 73 70 65 63 69 61 6c 20 71 75 65 72  . A special quer
59e0: 79 20 69 73 20 69 64 65 6e 74 69 66 69 65 64 20  y is identified 
59f0: 61 73 20 6f 6e 65 20 77 69 74 68 20 61 0a 2a 2a  as one with a.**
5a00: 20 4d 41 54 43 48 20 65 78 70 72 65 73 73 69 6f   MATCH expressio
5a10: 6e 20 74 68 61 74 20 62 65 67 69 6e 73 20 77 69  n that begins wi
5a20: 74 68 20 61 20 27 2a 27 20 63 68 61 72 61 63 74  th a '*' charact
5a30: 65 72 2e 20 54 68 65 20 72 65 6d 61 69 6e 64 65  er. The remainde
5a40: 72 20 6f 66 0a 2a 2a 20 74 68 65 20 74 65 78 74  r of.** the text
5a50: 20 70 61 73 73 65 64 20 74 6f 20 74 68 65 20 4d   passed to the M
5a60: 41 54 43 48 20 6f 70 65 72 61 74 6f 72 20 61 72  ATCH operator ar
5a70: 65 20 75 73 65 64 20 61 73 20 20 74 68 65 20 73  e used as  the s
5a80: 70 65 63 69 61 6c 20 71 75 65 72 79 0a 2a 2a 20  pecial query.** 
5a90: 70 61 72 61 6d 65 74 65 72 73 2e 0a 2a 2f 0a 73  parameters..*/.s
5aa0: 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 53 70  tatic int fts5Sp
5ab0: 65 63 69 61 6c 4d 61 74 63 68 28 0a 20 20 46 74  ecialMatch(.  Ft
5ac0: 73 35 54 61 62 6c 65 20 2a 70 54 61 62 2c 20 0a  s5Table *pTab, .
5ad0: 20 20 46 74 73 35 43 75 72 73 6f 72 20 2a 70 43    Fts5Cursor *pC
5ae0: 73 72 2c 20 0a 20 20 63 6f 6e 73 74 20 63 68 61  sr, .  const cha
5af0: 72 20 2a 7a 51 75 65 72 79 0a 29 7b 0a 20 20 69  r *zQuery.){.  i
5b00: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
5b10: 4b 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  K;             /
5b20: 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f  * Return code */
5b30: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
5b40: 20 3d 20 7a 51 75 65 72 79 3b 20 20 20 20 20 20   = zQuery;      
5b50: 20 20 20 2f 2a 20 53 70 65 63 69 61 6c 20 71 75     /* Special qu
5b60: 65 72 79 20 74 65 78 74 20 2a 2f 0a 20 20 69 6e  ery text */.  in
5b70: 74 20 6e 3b 20 20 20 20 20 20 20 20 20 20 20 20  t n;            
5b80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
5b90: 20 4e 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73   Number of bytes
5ba0: 20 69 6e 20 74 65 78 74 20 61 74 20 7a 20 2a 2f   in text at z */
5bb0: 0a 0a 20 20 77 68 69 6c 65 28 20 7a 5b 30 5d 3d  ..  while( z[0]=
5bc0: 3d 27 20 27 20 29 20 7a 2b 2b 3b 0a 20 20 66 6f  =' ' ) z++;.  fo
5bd0: 72 28 6e 3d 30 3b 20 7a 5b 6e 5d 20 26 26 20 7a  r(n=0; z[n] && z
5be0: 5b 6e 5d 21 3d 27 20 27 3b 20 6e 2b 2b 29 3b 0a  [n]!=' '; n++);.
5bf0: 0a 20 20 61 73 73 65 72 74 28 20 70 54 61 62 2d  .  assert( pTab-
5c00: 3e 62 61 73 65 2e 7a 45 72 72 4d 73 67 3d 3d 30  >base.zErrMsg==0
5c10: 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 43   );.  assert( pC
5c20: 73 72 2d 3e 7a 53 70 65 63 69 61 6c 3d 3d 30 20  sr->zSpecial==0 
5c30: 29 3b 0a 0a 20 20 69 66 28 20 30 3d 3d 73 71 6c  );..  if( 0==sql
5c40: 69 74 65 33 5f 73 74 72 6e 69 63 6d 70 28 22 72  ite3_strnicmp("r
5c50: 65 61 64 73 22 2c 20 7a 2c 20 6e 29 20 29 7b 0a  eads", z, n) ){.
5c60: 20 20 20 20 70 43 73 72 2d 3e 7a 53 70 65 63 69      pCsr->zSpeci
5c70: 61 6c 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72  al = sqlite3_mpr
5c80: 69 6e 74 66 28 22 25 64 22 2c 20 73 71 6c 69 74  intf("%d", sqlit
5c90: 65 33 46 74 73 35 49 6e 64 65 78 52 65 61 64 73  e3Fts5IndexReads
5ca0: 28 70 54 61 62 2d 3e 70 49 6e 64 65 78 29 29 3b  (pTab->pIndex));
5cb0: 0a 20 20 20 20 70 43 73 72 2d 3e 69 64 78 4e 75  .    pCsr->idxNu
5cc0: 6d 20 3d 20 46 54 53 35 5f 50 4c 41 4e 5f 53 50  m = FTS5_PLAN_SP
5cd0: 45 43 49 41 4c 3b 0a 20 20 20 20 69 66 28 20 70  ECIAL;.    if( p
5ce0: 43 73 72 2d 3e 7a 53 70 65 63 69 61 6c 3d 3d 30  Csr->zSpecial==0
5cf0: 20 29 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e   ) rc = SQLITE_N
5d00: 4f 4d 45 4d 3b 0a 20 20 7d 0a 20 20 65 6c 73 65  OMEM;.  }.  else
5d10: 7b 0a 20 20 20 20 2f 2a 20 41 6e 20 75 6e 72 65  {.    /* An unre
5d20: 63 6f 67 6e 69 7a 65 64 20 64 69 72 65 63 74 69  cognized directi
5d30: 76 65 2e 20 52 65 74 75 72 6e 20 61 6e 20 65 72  ve. Return an er
5d40: 72 6f 72 20 6d 65 73 73 61 67 65 2e 20 2a 2f 0a  ror message. */.
5d50: 20 20 20 20 70 54 61 62 2d 3e 62 61 73 65 2e 7a      pTab->base.z
5d60: 45 72 72 4d 73 67 20 3d 20 73 71 6c 69 74 65 33  ErrMsg = sqlite3
5d70: 5f 6d 70 72 69 6e 74 66 28 22 75 6e 6b 6e 6f 77  _mprintf("unknow
5d80: 6e 20 73 70 65 63 69 61 6c 20 71 75 65 72 79 3a  n special query:
5d90: 20 25 2e 2a 73 22 2c 20 6e 2c 20 7a 29 3b 0a 20   %.*s", n, z);. 
5da0: 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 45     rc = SQLITE_E
5db0: 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20 72 65 74  RROR;.  }..  ret
5dc0: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
5dd0: 20 53 65 61 72 63 68 20 66 6f 72 20 61 6e 20 61   Search for an a
5de0: 75 78 69 6c 69 61 72 79 20 66 75 6e 63 74 69 6f  uxiliary functio
5df0: 6e 20 6e 61 6d 65 64 20 7a 4e 61 6d 65 20 74 68  n named zName th
5e00: 61 74 20 63 61 6e 20 62 65 20 75 73 65 64 20 77  at can be used w
5e10: 69 74 68 20 74 61 62 6c 65 0a 2a 2a 20 70 54 61  ith table.** pTa
5e20: 62 2e 20 49 66 20 6f 6e 65 20 69 73 20 66 6f 75  b. If one is fou
5e30: 6e 64 2c 20 72 65 74 75 72 6e 20 61 20 70 6f 69  nd, return a poi
5e40: 6e 74 65 72 20 74 6f 20 74 68 65 20 63 6f 72 72  nter to the corr
5e50: 65 73 70 6f 6e 64 69 6e 67 20 46 74 73 35 41 75  esponding Fts5Au
5e60: 78 69 6c 69 61 72 79 0a 2a 2a 20 73 74 72 75 63  xiliary.** struc
5e70: 74 75 72 65 2e 20 4f 74 68 65 72 77 69 73 65 2c  ture. Otherwise,
5e80: 20 69 66 20 6e 6f 20 73 75 63 68 20 66 75 6e 63   if no such func
5e90: 74 69 6f 6e 20 65 78 69 73 74 73 2c 20 72 65 74  tion exists, ret
5ea0: 75 72 6e 20 4e 55 4c 4c 2e 0a 2a 2f 0a 73 74 61  urn NULL..*/.sta
5eb0: 74 69 63 20 46 74 73 35 41 75 78 69 6c 69 61 72  tic Fts5Auxiliar
5ec0: 79 20 2a 66 74 73 35 46 69 6e 64 41 75 78 69 6c  y *fts5FindAuxil
5ed0: 69 61 72 79 28 46 74 73 35 54 61 62 6c 65 20 2a  iary(Fts5Table *
5ee0: 70 54 61 62 2c 20 63 6f 6e 73 74 20 63 68 61 72  pTab, const char
5ef0: 20 2a 7a 4e 61 6d 65 29 7b 0a 20 20 46 74 73 35   *zName){.  Fts5
5f00: 41 75 78 69 6c 69 61 72 79 20 2a 70 41 75 78 3b  Auxiliary *pAux;
5f10: 0a 0a 20 20 66 6f 72 28 70 41 75 78 3d 70 54 61  ..  for(pAux=pTa
5f20: 62 2d 3e 70 47 6c 6f 62 61 6c 2d 3e 70 41 75 78  b->pGlobal->pAux
5f30: 3b 20 70 41 75 78 3b 20 70 41 75 78 3d 70 41 75  ; pAux; pAux=pAu
5f40: 78 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20 69  x->pNext){.    i
5f50: 66 28 20 73 71 6c 69 74 65 33 5f 73 74 72 69 63  f( sqlite3_stric
5f60: 6d 70 28 7a 4e 61 6d 65 2c 20 70 41 75 78 2d 3e  mp(zName, pAux->
5f70: 7a 46 75 6e 63 29 3d 3d 30 20 29 20 72 65 74 75  zFunc)==0 ) retu
5f80: 72 6e 20 70 41 75 78 3b 0a 20 20 7d 0a 0a 20 20  rn pAux;.  }..  
5f90: 2f 2a 20 4e 6f 20 66 75 6e 63 74 69 6f 6e 20 6f  /* No function o
5fa0: 66 20 74 68 65 20 73 70 65 63 69 66 69 65 64 20  f the specified 
5fb0: 6e 61 6d 65 20 77 61 73 20 66 6f 75 6e 64 2e 20  name was found. 
5fc0: 52 65 74 75 72 6e 20 30 2e 20 2a 2f 0a 20 20 72  Return 0. */.  r
5fd0: 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a 0a 73 74 61  eturn 0;.}...sta
5fe0: 74 69 63 20 69 6e 74 20 66 74 73 35 46 69 6e 64  tic int fts5Find
5ff0: 52 61 6e 6b 46 75 6e 63 74 69 6f 6e 28 46 74 73  RankFunction(Fts
6000: 35 43 75 72 73 6f 72 20 2a 70 43 73 72 29 7b 0a  5Cursor *pCsr){.
6010: 20 20 46 74 73 35 54 61 62 6c 65 20 2a 70 54 61    Fts5Table *pTa
6020: 62 20 3d 20 28 46 74 73 35 54 61 62 6c 65 2a 29  b = (Fts5Table*)
6030: 28 70 43 73 72 2d 3e 62 61 73 65 2e 70 56 74 61  (pCsr->base.pVta
6040: 62 29 3b 0a 20 20 46 74 73 35 43 6f 6e 66 69 67  b);.  Fts5Config
6050: 20 2a 70 43 6f 6e 66 69 67 20 3d 20 70 54 61 62   *pConfig = pTab
6060: 2d 3e 70 43 6f 6e 66 69 67 3b 0a 20 20 69 6e 74  ->pConfig;.  int
6070: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
6080: 0a 20 20 46 74 73 35 41 75 78 69 6c 69 61 72 79  .  Fts5Auxiliary
6090: 20 2a 70 41 75 78 20 3d 20 30 3b 0a 20 20 63 6f   *pAux = 0;.  co
60a0: 6e 73 74 20 63 68 61 72 20 2a 7a 52 61 6e 6b 20  nst char *zRank 
60b0: 3d 20 70 43 73 72 2d 3e 7a 52 61 6e 6b 3b 0a 20  = pCsr->zRank;. 
60c0: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 52 61   const char *zRa
60d0: 6e 6b 41 72 67 73 20 3d 20 70 43 73 72 2d 3e 7a  nkArgs = pCsr->z
60e0: 52 61 6e 6b 41 72 67 73 3b 0a 0a 20 20 69 66 28  RankArgs;..  if(
60f0: 20 7a 52 61 6e 6b 41 72 67 73 20 29 7b 0a 20 20   zRankArgs ){.  
6100: 20 20 63 68 61 72 20 2a 7a 53 71 6c 20 3d 20 73    char *zSql = s
6110: 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22  qlite3_mprintf("
6120: 53 45 4c 45 43 54 20 25 73 22 2c 20 7a 52 61 6e  SELECT %s", zRan
6130: 6b 41 72 67 73 29 3b 0a 20 20 20 20 69 66 28 20  kArgs);.    if( 
6140: 7a 53 71 6c 3d 3d 30 20 29 7b 0a 20 20 20 20 20  zSql==0 ){.     
6150: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d   rc = SQLITE_NOM
6160: 45 4d 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20  EM;.    }else{. 
6170: 20 20 20 20 20 73 71 6c 69 74 65 33 5f 73 74 6d       sqlite3_stm
6180: 74 20 2a 70 53 74 6d 74 20 3d 20 30 3b 0a 20 20  t *pStmt = 0;.  
6190: 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
61a0: 5f 70 72 65 70 61 72 65 5f 76 32 28 70 43 6f 6e  _prepare_v2(pCon
61b0: 66 69 67 2d 3e 64 62 2c 20 7a 53 71 6c 2c 20 2d  fig->db, zSql, -
61c0: 31 2c 20 26 70 53 74 6d 74 2c 20 30 29 3b 0a 20  1, &pStmt, 0);. 
61d0: 20 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65       sqlite3_fre
61e0: 65 28 7a 53 71 6c 29 3b 0a 20 20 20 20 20 20 61  e(zSql);.      a
61f0: 73 73 65 72 74 28 20 72 63 3d 3d 53 51 4c 49 54  ssert( rc==SQLIT
6200: 45 5f 4f 4b 20 7c 7c 20 70 43 73 72 2d 3e 70 52  E_OK || pCsr->pR
6210: 61 6e 6b 41 72 67 53 74 6d 74 3d 3d 30 20 29 3b  ankArgStmt==0 );
6220: 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53  .      if( rc==S
6230: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
6240: 20 20 20 20 69 66 28 20 53 51 4c 49 54 45 5f 52      if( SQLITE_R
6250: 4f 57 3d 3d 73 71 6c 69 74 65 33 5f 73 74 65 70  OW==sqlite3_step
6260: 28 70 53 74 6d 74 29 20 29 7b 0a 20 20 20 20 20  (pStmt) ){.     
6270: 20 20 20 20 20 69 6e 74 20 6e 42 79 74 65 3b 0a       int nByte;.
6280: 20 20 20 20 20 20 20 20 20 20 70 43 73 72 2d 3e            pCsr->
6290: 6e 52 61 6e 6b 41 72 67 20 3d 20 73 71 6c 69 74  nRankArg = sqlit
62a0: 65 33 5f 63 6f 6c 75 6d 6e 5f 63 6f 75 6e 74 28  e3_column_count(
62b0: 70 53 74 6d 74 29 3b 0a 20 20 20 20 20 20 20 20  pStmt);.        
62c0: 20 20 6e 42 79 74 65 20 3d 20 73 69 7a 65 6f 66    nByte = sizeof
62d0: 28 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 2a 29  (sqlite3_value*)
62e0: 2a 70 43 73 72 2d 3e 6e 52 61 6e 6b 41 72 67 3b  *pCsr->nRankArg;
62f0: 0a 20 20 20 20 20 20 20 20 20 20 70 43 73 72 2d  .          pCsr-
6300: 3e 61 70 52 61 6e 6b 41 72 67 20 3d 20 28 73 71  >apRankArg = (sq
6310: 6c 69 74 65 33 5f 76 61 6c 75 65 2a 2a 29 73 71  lite3_value**)sq
6320: 6c 69 74 65 33 46 74 73 35 4d 61 6c 6c 6f 63 5a  lite3Fts5MallocZ
6330: 65 72 6f 28 26 72 63 2c 20 6e 42 79 74 65 29 3b  ero(&rc, nByte);
6340: 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20 72  .          if( r
6350: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
6360: 20 20 20 20 20 20 20 20 20 20 20 20 69 6e 74 20              int 
6370: 69 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 66  i;.            f
6380: 6f 72 28 69 3d 30 3b 20 69 3c 70 43 73 72 2d 3e  or(i=0; i<pCsr->
6390: 6e 52 61 6e 6b 41 72 67 3b 20 69 2b 2b 29 7b 0a  nRankArg; i++){.
63a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 70 43                pC
63b0: 73 72 2d 3e 61 70 52 61 6e 6b 41 72 67 5b 69 5d  sr->apRankArg[i]
63c0: 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d   = sqlite3_colum
63d0: 6e 5f 76 61 6c 75 65 28 70 53 74 6d 74 2c 20 69  n_value(pStmt, i
63e0: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 7d  );.            }
63f0: 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20  .          }.   
6400: 20 20 20 20 20 20 20 70 43 73 72 2d 3e 70 52 61         pCsr->pRa
6410: 6e 6b 41 72 67 53 74 6d 74 20 3d 20 70 53 74 6d  nkArgStmt = pStm
6420: 74 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c 73 65  t;.        }else
6430: 7b 0a 20 20 20 20 20 20 20 20 20 20 72 63 20 3d  {.          rc =
6440: 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a   sqlite3_finaliz
6450: 65 28 70 53 74 6d 74 29 3b 0a 20 20 20 20 20 20  e(pStmt);.      
6460: 20 20 20 20 61 73 73 65 72 74 28 20 72 63 21 3d      assert( rc!=
6470: 53 51 4c 49 54 45 5f 4f 4b 20 29 3b 0a 20 20 20  SQLITE_OK );.   
6480: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20       }.      }. 
6490: 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 66 28 20     }.  }..  if( 
64a0: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
64b0: 0a 20 20 20 20 70 41 75 78 20 3d 20 66 74 73 35  .    pAux = fts5
64c0: 46 69 6e 64 41 75 78 69 6c 69 61 72 79 28 70 54  FindAuxiliary(pT
64d0: 61 62 2c 20 7a 52 61 6e 6b 29 3b 0a 20 20 20 20  ab, zRank);.    
64e0: 69 66 28 20 70 41 75 78 3d 3d 30 20 29 7b 0a 20  if( pAux==0 ){. 
64f0: 20 20 20 20 20 61 73 73 65 72 74 28 20 70 54 61       assert( pTa
6500: 62 2d 3e 62 61 73 65 2e 7a 45 72 72 4d 73 67 3d  b->base.zErrMsg=
6510: 3d 30 20 29 3b 0a 20 20 20 20 20 20 70 54 61 62  =0 );.      pTab
6520: 2d 3e 62 61 73 65 2e 7a 45 72 72 4d 73 67 20 3d  ->base.zErrMsg =
6530: 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66   sqlite3_mprintf
6540: 28 22 6e 6f 20 73 75 63 68 20 66 75 6e 63 74 69  ("no such functi
6550: 6f 6e 3a 20 25 73 22 2c 20 7a 52 61 6e 6b 29 3b  on: %s", zRank);
6560: 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49  .      rc = SQLI
6570: 54 45 5f 45 52 52 4f 52 3b 0a 20 20 20 20 7d 0a  TE_ERROR;.    }.
6580: 20 20 7d 0a 0a 20 20 70 43 73 72 2d 3e 70 52 61    }..  pCsr->pRa
6590: 6e 6b 20 3d 20 70 41 75 78 3b 0a 20 20 72 65 74  nk = pAux;.  ret
65a0: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 0a 73 74 61 74  urn rc;.}...stat
65b0: 69 63 20 69 6e 74 20 66 74 73 35 43 75 72 73 6f  ic int fts5Curso
65c0: 72 50 61 72 73 65 52 61 6e 6b 28 0a 20 20 46 74  rParseRank(.  Ft
65d0: 73 35 43 6f 6e 66 69 67 20 2a 70 43 6f 6e 66 69  s5Config *pConfi
65e0: 67 2c 0a 20 20 46 74 73 35 43 75 72 73 6f 72 20  g,.  Fts5Cursor 
65f0: 2a 70 43 73 72 2c 20 0a 20 20 73 71 6c 69 74 65  *pCsr, .  sqlite
6600: 33 5f 76 61 6c 75 65 20 2a 70 52 61 6e 6b 0a 29  3_value *pRank.)
6610: 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c  {.  int rc = SQL
6620: 49 54 45 5f 4f 4b 3b 0a 20 20 69 66 28 20 70 52  ITE_OK;.  if( pR
6630: 61 6e 6b 20 29 7b 0a 20 20 20 20 63 6f 6e 73 74  ank ){.    const
6640: 20 63 68 61 72 20 2a 7a 20 3d 20 28 63 6f 6e 73   char *z = (cons
6650: 74 20 63 68 61 72 2a 29 73 71 6c 69 74 65 33 5f  t char*)sqlite3_
6660: 76 61 6c 75 65 5f 74 65 78 74 28 70 52 61 6e 6b  value_text(pRank
6670: 29 3b 0a 20 20 20 20 63 68 61 72 20 2a 7a 52 61  );.    char *zRa
6680: 6e 6b 20 3d 20 30 3b 0a 20 20 20 20 63 68 61 72  nk = 0;.    char
6690: 20 2a 7a 52 61 6e 6b 41 72 67 73 20 3d 20 30 3b   *zRankArgs = 0;
66a0: 0a 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74  ..    rc = sqlit
66b0: 65 33 46 74 73 35 43 6f 6e 66 69 67 50 61 72 73  e3Fts5ConfigPars
66c0: 65 52 61 6e 6b 28 7a 2c 20 26 7a 52 61 6e 6b 2c  eRank(z, &zRank,
66d0: 20 26 7a 52 61 6e 6b 41 72 67 73 29 3b 0a 20 20   &zRankArgs);.  
66e0: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
66f0: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 70 43 73  _OK ){.      pCs
6700: 72 2d 3e 7a 52 61 6e 6b 20 3d 20 7a 52 61 6e 6b  r->zRank = zRank
6710: 3b 0a 20 20 20 20 20 20 70 43 73 72 2d 3e 7a 52  ;.      pCsr->zR
6720: 61 6e 6b 41 72 67 73 20 3d 20 7a 52 61 6e 6b 41  ankArgs = zRankA
6730: 72 67 73 3b 0a 20 20 20 20 20 20 43 73 72 46 6c  rgs;.      CsrFl
6740: 61 67 53 65 74 28 70 43 73 72 2c 20 46 54 53 35  agSet(pCsr, FTS5
6750: 43 53 52 5f 46 52 45 45 5f 5a 52 41 4e 4b 29 3b  CSR_FREE_ZRANK);
6760: 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 72  .    }else if( r
6770: 63 3d 3d 53 51 4c 49 54 45 5f 45 52 52 4f 52 20  c==SQLITE_ERROR 
6780: 29 7b 0a 20 20 20 20 20 20 70 43 73 72 2d 3e 62  ){.      pCsr->b
6790: 61 73 65 2e 70 56 74 61 62 2d 3e 7a 45 72 72 4d  ase.pVtab->zErrM
67a0: 73 67 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72  sg = sqlite3_mpr
67b0: 69 6e 74 66 28 0a 20 20 20 20 20 20 20 20 20 20  intf(.          
67c0: 22 70 61 72 73 65 20 65 72 72 6f 72 20 69 6e 20  "parse error in 
67d0: 72 61 6e 6b 20 66 75 6e 63 74 69 6f 6e 3a 20 25  rank function: %
67e0: 73 22 2c 20 7a 0a 20 20 20 20 20 20 29 3b 0a 20  s", z.      );. 
67f0: 20 20 20 7d 0a 20 20 7d 65 6c 73 65 7b 0a 20 20     }.  }else{.  
6800: 20 20 69 66 28 20 70 43 6f 6e 66 69 67 2d 3e 7a    if( pConfig->z
6810: 52 61 6e 6b 20 29 7b 0a 20 20 20 20 20 20 70 43  Rank ){.      pC
6820: 73 72 2d 3e 7a 52 61 6e 6b 20 3d 20 28 63 68 61  sr->zRank = (cha
6830: 72 2a 29 70 43 6f 6e 66 69 67 2d 3e 7a 52 61 6e  r*)pConfig->zRan
6840: 6b 3b 0a 20 20 20 20 20 20 70 43 73 72 2d 3e 7a  k;.      pCsr->z
6850: 52 61 6e 6b 41 72 67 73 20 3d 20 28 63 68 61 72  RankArgs = (char
6860: 2a 29 70 43 6f 6e 66 69 67 2d 3e 7a 52 61 6e 6b  *)pConfig->zRank
6870: 41 72 67 73 3b 0a 20 20 20 20 7d 65 6c 73 65 7b  Args;.    }else{
6880: 0a 20 20 20 20 20 20 70 43 73 72 2d 3e 7a 52 61  .      pCsr->zRa
6890: 6e 6b 20 3d 20 28 63 68 61 72 2a 29 46 54 53 35  nk = (char*)FTS5
68a0: 5f 44 45 46 41 55 4c 54 5f 52 41 4e 4b 3b 0a 20  _DEFAULT_RANK;. 
68b0: 20 20 20 20 20 70 43 73 72 2d 3e 7a 52 61 6e 6b       pCsr->zRank
68c0: 41 72 67 73 20 3d 20 30 3b 0a 20 20 20 20 7d 0a  Args = 0;.    }.
68d0: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b    }.  return rc;
68e0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 69  .}../*.** This i
68f0: 73 20 74 68 65 20 78 46 69 6c 74 65 72 20 69 6e  s the xFilter in
6900: 74 65 72 66 61 63 65 20 66 6f 72 20 74 68 65 20  terface for the 
6910: 76 69 72 74 75 61 6c 20 74 61 62 6c 65 2e 20 20  virtual table.  
6920: 53 65 65 0a 2a 2a 20 74 68 65 20 76 69 72 74 75  See.** the virtu
6930: 61 6c 20 74 61 62 6c 65 20 78 46 69 6c 74 65 72  al table xFilter
6940: 20 6d 65 74 68 6f 64 20 64 6f 63 75 6d 65 6e 74   method document
6950: 61 74 69 6f 6e 20 66 6f 72 20 61 64 64 69 74 69  ation for additi
6960: 6f 6e 61 6c 0a 2a 2a 20 69 6e 66 6f 72 6d 61 74  onal.** informat
6970: 69 6f 6e 2e 0a 2a 2a 20 0a 2a 2a 20 54 68 65 72  ion..** .** Ther
6980: 65 20 61 72 65 20 74 68 72 65 65 20 70 6f 73 73  e are three poss
6990: 69 62 6c 65 20 71 75 65 72 79 20 73 74 72 61 74  ible query strat
69a0: 65 67 69 65 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 31  egies:.**.**   1
69b0: 2e 20 46 75 6c 6c 2d 74 65 78 74 20 73 65 61 72  . Full-text sear
69c0: 63 68 20 75 73 69 6e 67 20 61 20 4d 41 54 43 48  ch using a MATCH
69d0: 20 6f 70 65 72 61 74 6f 72 2e 0a 2a 2a 20 20 20   operator..**   
69e0: 32 2e 20 41 20 62 79 2d 72 6f 77 69 64 20 6c 6f  2. A by-rowid lo
69f0: 6f 6b 75 70 2e 0a 2a 2a 20 20 20 33 2e 20 41 20  okup..**   3. A 
6a00: 66 75 6c 6c 2d 74 61 62 6c 65 20 73 63 61 6e 2e  full-table scan.
6a10: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66  .*/.static int f
6a20: 74 73 35 46 69 6c 74 65 72 4d 65 74 68 6f 64 28  ts5FilterMethod(
6a30: 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62 5f  .  sqlite3_vtab_
6a40: 63 75 72 73 6f 72 20 2a 70 43 75 72 73 6f 72 2c  cursor *pCursor,
6a50: 20 20 20 2f 2a 20 54 68 65 20 63 75 72 73 6f 72     /* The cursor
6a60: 20 75 73 65 64 20 66 6f 72 20 74 68 69 73 20 71   used for this q
6a70: 75 65 72 79 20 2a 2f 0a 20 20 69 6e 74 20 69 64  uery */.  int id
6a80: 78 4e 75 6d 2c 20 20 20 20 20 20 20 20 20 20 20  xNum,           
6a90: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 74 72            /* Str
6aa0: 61 74 65 67 79 20 69 6e 64 65 78 20 2a 2f 0a 20  ategy index */. 
6ab0: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 69 64 78   const char *idx
6ac0: 53 74 72 2c 20 20 20 20 20 20 20 20 20 20 20 20  Str,            
6ad0: 20 2f 2a 20 55 6e 75 73 65 64 20 2a 2f 0a 20 20   /* Unused */.  
6ae0: 69 6e 74 20 6e 56 61 6c 2c 20 20 20 20 20 20 20  int nVal,       
6af0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6b00: 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 65 6c 65  /* Number of ele
6b10: 6d 65 6e 74 73 20 69 6e 20 61 70 56 61 6c 20 2a  ments in apVal *
6b20: 2f 0a 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75  /.  sqlite3_valu
6b30: 65 20 2a 2a 61 70 56 61 6c 20 20 20 20 20 20 20  e **apVal       
6b40: 20 20 20 20 2f 2a 20 41 72 67 75 6d 65 6e 74 73      /* Arguments
6b50: 20 66 6f 72 20 74 68 65 20 69 6e 64 65 78 69 6e   for the indexin
6b60: 67 20 73 63 68 65 6d 65 20 2a 2f 0a 29 7b 0a 20  g scheme */.){. 
6b70: 20 46 74 73 35 54 61 62 6c 65 20 2a 70 54 61 62   Fts5Table *pTab
6b80: 20 3d 20 28 46 74 73 35 54 61 62 6c 65 2a 29 28   = (Fts5Table*)(
6b90: 70 43 75 72 73 6f 72 2d 3e 70 56 74 61 62 29 3b  pCursor->pVtab);
6ba0: 0a 20 20 46 74 73 35 43 75 72 73 6f 72 20 2a 70  .  Fts5Cursor *p
6bb0: 43 73 72 20 3d 20 28 46 74 73 35 43 75 72 73 6f  Csr = (Fts5Curso
6bc0: 72 2a 29 70 43 75 72 73 6f 72 3b 0a 20 20 69 6e  r*)pCursor;.  in
6bd0: 74 20 62 41 73 63 20 3d 20 28 28 69 64 78 4e 75  t bAsc = ((idxNu
6be0: 6d 20 26 20 46 54 53 35 5f 4f 52 44 45 52 5f 41  m & FTS5_ORDER_A
6bf0: 53 43 29 20 3f 20 31 20 3a 20 30 29 3b 0a 20 20  SC) ? 1 : 0);.  
6c00: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
6c10: 4f 4b 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 6e  OK;..  assert( n
6c20: 56 61 6c 3c 3d 32 20 29 3b 0a 20 20 61 73 73 65  Val<=2 );.  asse
6c30: 72 74 28 20 70 43 73 72 2d 3e 70 53 74 6d 74 3d  rt( pCsr->pStmt=
6c40: 3d 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  =0 );.  assert( 
6c50: 70 43 73 72 2d 3e 70 45 78 70 72 3d 3d 30 20 29  pCsr->pExpr==0 )
6c60: 3b 0a 20 20 61 73 73 65 72 74 28 20 70 43 73 72  ;.  assert( pCsr
6c70: 2d 3e 63 73 72 66 6c 61 67 73 3d 3d 30 20 29 3b  ->csrflags==0 );
6c80: 0a 20 20 61 73 73 65 72 74 28 20 70 43 73 72 2d  .  assert( pCsr-
6c90: 3e 70 52 61 6e 6b 3d 3d 30 20 29 3b 0a 20 20 61  >pRank==0 );.  a
6ca0: 73 73 65 72 74 28 20 70 43 73 72 2d 3e 7a 52 61  ssert( pCsr->zRa
6cb0: 6e 6b 3d 3d 30 20 29 3b 0a 20 20 61 73 73 65 72  nk==0 );.  asser
6cc0: 74 28 20 70 43 73 72 2d 3e 7a 52 61 6e 6b 41 72  t( pCsr->zRankAr
6cd0: 67 73 3d 3d 30 20 29 3b 0a 0a 20 20 69 66 28 20  gs==0 );..  if( 
6ce0: 70 54 61 62 2d 3e 70 53 6f 72 74 43 73 72 20 29  pTab->pSortCsr )
6cf0: 7b 0a 20 20 20 20 2f 2a 20 49 66 20 70 53 6f 72  {.    /* If pSor
6d00: 74 43 73 72 20 69 73 20 6e 6f 6e 2d 4e 55 4c 4c  tCsr is non-NULL
6d10: 2c 20 74 68 65 6e 20 74 68 69 73 20 63 61 6c 6c  , then this call
6d20: 20 69 73 20 62 65 69 6e 67 20 6d 61 64 65 20 61   is being made a
6d30: 73 20 70 61 72 74 20 6f 66 20 0a 20 20 20 20 2a  s part of .    *
6d40: 2a 20 70 72 6f 63 65 73 73 69 6e 67 20 66 6f 72  * processing for
6d50: 20 61 20 22 2e 2e 2e 20 4d 41 54 43 48 20 3c 65   a "... MATCH <e
6d60: 78 70 72 3e 20 4f 52 44 45 52 20 42 59 20 72 61  xpr> ORDER BY ra
6d70: 6e 6b 22 20 71 75 65 72 79 20 28 65 50 6c 61 6e  nk" query (ePlan
6d80: 20 69 73 0a 20 20 20 20 2a 2a 20 73 65 74 20 74   is.    ** set t
6d90: 6f 20 46 54 53 35 5f 50 4c 41 4e 5f 53 4f 52 54  o FTS5_PLAN_SORT
6da0: 45 44 5f 4d 41 54 43 48 29 2e 20 70 53 6f 72 74  ED_MATCH). pSort
6db0: 43 73 72 20 69 73 20 74 68 65 20 63 75 72 73 6f  Csr is the curso
6dc0: 72 20 74 68 61 74 20 77 69 6c 6c 0a 20 20 20 20  r that will.    
6dd0: 2a 2a 20 72 65 74 75 72 6e 20 72 65 73 75 6c 74  ** return result
6de0: 73 20 74 6f 20 74 68 65 20 75 73 65 72 20 66 6f  s to the user fo
6df0: 72 20 74 68 69 73 20 71 75 65 72 79 2e 20 54 68  r this query. Th
6e00: 65 20 63 75 72 72 65 6e 74 20 63 75 72 73 6f 72  e current cursor
6e10: 20 0a 20 20 20 20 2a 2a 20 28 70 43 75 72 73 6f   .    ** (pCurso
6e20: 72 29 20 69 73 20 75 73 65 64 20 74 6f 20 65 78  r) is used to ex
6e30: 65 63 75 74 65 20 74 68 65 20 71 75 65 72 79 20  ecute the query 
6e40: 69 73 73 75 65 64 20 62 79 20 66 75 6e 63 74 69  issued by functi
6e50: 6f 6e 20 0a 20 20 20 20 2a 2a 20 66 74 73 35 43  on .    ** fts5C
6e60: 75 72 73 6f 72 46 69 72 73 74 53 6f 72 74 65 64  ursorFirstSorted
6e70: 28 29 20 61 62 6f 76 65 2e 20 20 2a 2f 0a 20 20  () above.  */.  
6e80: 20 20 61 73 73 65 72 74 28 20 46 54 53 35 5f 50    assert( FTS5_P
6e90: 4c 41 4e 28 69 64 78 4e 75 6d 29 3d 3d 46 54 53  LAN(idxNum)==FTS
6ea0: 35 5f 50 4c 41 4e 5f 53 43 41 4e 20 29 3b 0a 20  5_PLAN_SCAN );. 
6eb0: 20 20 20 70 43 73 72 2d 3e 69 64 78 4e 75 6d 20     pCsr->idxNum 
6ec0: 3d 20 46 54 53 35 5f 50 4c 41 4e 5f 53 4f 55 52  = FTS5_PLAN_SOUR
6ed0: 43 45 3b 0a 20 20 20 20 70 43 73 72 2d 3e 70 45  CE;.    pCsr->pE
6ee0: 78 70 72 20 3d 20 70 54 61 62 2d 3e 70 53 6f 72  xpr = pTab->pSor
6ef0: 74 43 73 72 2d 3e 70 45 78 70 72 3b 0a 20 20 20  tCsr->pExpr;.   
6f00: 20 72 63 20 3d 20 66 74 73 35 43 75 72 73 6f 72   rc = fts5Cursor
6f10: 46 69 72 73 74 28 70 54 61 62 2c 20 70 43 73 72  First(pTab, pCsr
6f20: 2c 20 62 41 73 63 29 3b 0a 20 20 7d 65 6c 73 65  , bAsc);.  }else
6f30: 7b 0a 20 20 20 20 69 6e 74 20 65 50 6c 61 6e 20  {.    int ePlan 
6f40: 3d 20 46 54 53 35 5f 50 4c 41 4e 28 69 64 78 4e  = FTS5_PLAN(idxN
6f50: 75 6d 29 3b 0a 20 20 20 20 70 43 73 72 2d 3e 69  um);.    pCsr->i
6f60: 64 78 4e 75 6d 20 3d 20 69 64 78 4e 75 6d 3b 0a  dxNum = idxNum;.
6f70: 20 20 20 20 69 66 28 20 65 50 6c 61 6e 3d 3d 46      if( ePlan==F
6f80: 54 53 35 5f 50 4c 41 4e 5f 4d 41 54 43 48 20 7c  TS5_PLAN_MATCH |
6f90: 7c 20 65 50 6c 61 6e 3d 3d 46 54 53 35 5f 50 4c  | ePlan==FTS5_PL
6fa0: 41 4e 5f 53 4f 52 54 45 44 5f 4d 41 54 43 48 20  AN_SORTED_MATCH 
6fb0: 29 7b 0a 20 20 20 20 20 20 63 6f 6e 73 74 20 63  ){.      const c
6fc0: 68 61 72 20 2a 7a 45 78 70 72 20 3d 20 28 63 6f  har *zExpr = (co
6fd0: 6e 73 74 20 63 68 61 72 2a 29 73 71 6c 69 74 65  nst char*)sqlite
6fe0: 33 5f 76 61 6c 75 65 5f 74 65 78 74 28 61 70 56  3_value_text(apV
6ff0: 61 6c 5b 30 5d 29 3b 0a 0a 20 20 20 20 20 20 72  al[0]);..      r
7000: 63 20 3d 20 66 74 73 35 43 75 72 73 6f 72 50 61  c = fts5CursorPa
7010: 72 73 65 52 61 6e 6b 28 70 54 61 62 2d 3e 70 43  rseRank(pTab->pC
7020: 6f 6e 66 69 67 2c 20 70 43 73 72 2c 20 28 6e 56  onfig, pCsr, (nV
7030: 61 6c 3d 3d 32 20 3f 20 61 70 56 61 6c 5b 31 5d  al==2 ? apVal[1]
7040: 20 3a 20 30 29 29 3b 0a 20 20 20 20 20 20 69 66   : 0));.      if
7050: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
7060: 29 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20 7a  ){.        if( z
7070: 45 78 70 72 5b 30 5d 3d 3d 27 2a 27 20 29 7b 0a  Expr[0]=='*' ){.
7080: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65            /* The
7090: 20 75 73 65 72 20 68 61 73 20 69 73 73 75 65 64   user has issued
70a0: 20 61 20 71 75 65 72 79 20 6f 66 20 74 68 65 20   a query of the 
70b0: 66 6f 72 6d 20 22 4d 41 54 43 48 20 27 2a 2e 2e  form "MATCH '*..
70c0: 2e 27 22 2e 20 54 68 69 73 0a 20 20 20 20 20 20  .'". This.      
70d0: 20 20 20 20 2a 2a 20 69 6e 64 69 63 61 74 65 73      ** indicates
70e0: 20 74 68 61 74 20 74 68 65 20 4d 41 54 43 48 20   that the MATCH 
70f0: 65 78 70 72 65 73 73 69 6f 6e 20 69 73 20 6e 6f  expression is no
7100: 74 20 61 20 66 75 6c 6c 20 74 65 78 74 20 71 75  t a full text qu
7110: 65 72 79 2c 0a 20 20 20 20 20 20 20 20 20 20 2a  ery,.          *
7120: 2a 20 62 75 74 20 61 20 72 65 71 75 65 73 74 20  * but a request 
7130: 66 6f 72 20 61 6e 20 69 6e 74 65 72 6e 61 6c 20  for an internal 
7140: 70 61 72 61 6d 65 74 65 72 2e 20 20 2a 2f 0a 20  parameter.  */. 
7150: 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 66 74           rc = ft
7160: 73 35 53 70 65 63 69 61 6c 4d 61 74 63 68 28 70  s5SpecialMatch(p
7170: 54 61 62 2c 20 70 43 73 72 2c 20 26 7a 45 78 70  Tab, pCsr, &zExp
7180: 72 5b 31 5d 29 3b 0a 20 20 20 20 20 20 20 20 7d  r[1]);.        }
7190: 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 20 20  else{.          
71a0: 63 68 61 72 20 2a 2a 70 7a 45 72 72 20 3d 20 26  char **pzErr = &
71b0: 70 54 61 62 2d 3e 62 61 73 65 2e 7a 45 72 72 4d  pTab->base.zErrM
71c0: 73 67 3b 0a 20 20 20 20 20 20 20 20 20 20 72 63  sg;.          rc
71d0: 20 3d 20 73 71 6c 69 74 65 33 46 74 73 35 45 78   = sqlite3Fts5Ex
71e0: 70 72 4e 65 77 28 70 54 61 62 2d 3e 70 43 6f 6e  prNew(pTab->pCon
71f0: 66 69 67 2c 20 7a 45 78 70 72 2c 20 26 70 43 73  fig, zExpr, &pCs
7200: 72 2d 3e 70 45 78 70 72 2c 20 70 7a 45 72 72 29  r->pExpr, pzErr)
7210: 3b 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20  ;.          if( 
7220: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
7230: 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66 28  .            if(
7240: 20 65 50 6c 61 6e 3d 3d 46 54 53 35 5f 50 4c 41   ePlan==FTS5_PLA
7250: 4e 5f 4d 41 54 43 48 20 29 7b 0a 20 20 20 20 20  N_MATCH ){.     
7260: 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 66 74           rc = ft
7270: 73 35 43 75 72 73 6f 72 46 69 72 73 74 28 70 54  s5CursorFirst(pT
7280: 61 62 2c 20 70 43 73 72 2c 20 62 41 73 63 29 3b  ab, pCsr, bAsc);
7290: 0a 20 20 20 20 20 20 20 20 20 20 20 20 7d 65 6c  .            }el
72a0: 73 65 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20  se{.            
72b0: 20 20 72 63 20 3d 20 66 74 73 35 43 75 72 73 6f    rc = fts5Curso
72c0: 72 46 69 72 73 74 53 6f 72 74 65 64 28 70 54 61  rFirstSorted(pTa
72d0: 62 2c 20 70 43 73 72 2c 20 62 41 73 63 29 3b 0a  b, pCsr, bAsc);.
72e0: 20 20 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20              }.  
72f0: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
7300: 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20    }.      }.    
7310: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 2f 2a 20  }else{.      /* 
7320: 54 68 69 73 20 69 73 20 65 69 74 68 65 72 20 61  This is either a
7330: 20 66 75 6c 6c 2d 74 61 62 6c 65 20 73 63 61 6e   full-table scan
7340: 20 28 65 50 6c 61 6e 3d 3d 46 54 53 35 5f 50 4c   (ePlan==FTS5_PL
7350: 41 4e 5f 53 43 41 4e 29 20 6f 72 20 61 20 6c 6f  AN_SCAN) or a lo
7360: 6f 6b 75 70 0a 20 20 20 20 20 20 2a 2a 20 62 79  okup.      ** by
7370: 20 72 6f 77 69 64 20 28 65 50 6c 61 6e 3d 3d 46   rowid (ePlan==F
7380: 54 53 35 5f 50 4c 41 4e 5f 52 4f 57 49 44 29 2e  TS5_PLAN_ROWID).
7390: 20 20 2a 2f 0a 20 20 20 20 20 20 69 6e 74 20 65    */.      int e
73a0: 53 74 6d 74 20 3d 20 66 74 73 35 53 74 6d 74 54  Stmt = fts5StmtT
73b0: 79 70 65 28 69 64 78 4e 75 6d 29 3b 0a 20 20 20  ype(idxNum);.   
73c0: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 46     rc = sqlite3F
73d0: 74 73 35 53 74 6f 72 61 67 65 53 74 6d 74 28 0a  ts5StorageStmt(.
73e0: 20 20 20 20 20 20 20 20 20 20 70 54 61 62 2d 3e            pTab->
73f0: 70 53 74 6f 72 61 67 65 2c 20 65 53 74 6d 74 2c  pStorage, eStmt,
7400: 20 26 70 43 73 72 2d 3e 70 53 74 6d 74 2c 20 26   &pCsr->pStmt, &
7410: 70 54 61 62 2d 3e 62 61 73 65 2e 7a 45 72 72 4d  pTab->base.zErrM
7420: 73 67 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20  sg.      );.    
7430: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
7440: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 69  _OK ){.        i
7450: 66 28 20 65 50 6c 61 6e 3d 3d 46 54 53 35 5f 50  f( ePlan==FTS5_P
7460: 4c 41 4e 5f 52 4f 57 49 44 20 29 7b 0a 20 20 20  LAN_ROWID ){.   
7470: 20 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 62         sqlite3_b
7480: 69 6e 64 5f 76 61 6c 75 65 28 70 43 73 72 2d 3e  ind_value(pCsr->
7490: 70 53 74 6d 74 2c 20 31 2c 20 61 70 56 61 6c 5b  pStmt, 1, apVal[
74a0: 30 5d 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  0]);.        }. 
74b0: 20 20 20 20 20 20 20 72 63 20 3d 20 66 74 73 35         rc = fts5
74c0: 4e 65 78 74 4d 65 74 68 6f 64 28 70 43 75 72 73  NextMethod(pCurs
74d0: 6f 72 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  or);.      }.   
74e0: 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e   }.  }..  return
74f0: 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 54   rc;.}../* .** T
7500: 68 69 73 20 69 73 20 74 68 65 20 78 45 6f 66 20  his is the xEof 
7510: 6d 65 74 68 6f 64 20 6f 66 20 74 68 65 20 76 69  method of the vi
7520: 72 74 75 61 6c 20 74 61 62 6c 65 2e 20 53 51 4c  rtual table. SQL
7530: 69 74 65 20 63 61 6c 6c 73 20 74 68 69 73 20 0a  ite calls this .
7540: 2a 2a 20 72 6f 75 74 69 6e 65 20 74 6f 20 66 69  ** routine to fi
7550: 6e 64 20 6f 75 74 20 69 66 20 69 74 20 68 61 73  nd out if it has
7560: 20 72 65 61 63 68 65 64 20 74 68 65 20 65 6e 64   reached the end
7570: 20 6f 66 20 61 20 72 65 73 75 6c 74 20 73 65 74   of a result set
7580: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
7590: 66 74 73 35 45 6f 66 4d 65 74 68 6f 64 28 73 71  fts5EofMethod(sq
75a0: 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f  lite3_vtab_curso
75b0: 72 20 2a 70 43 75 72 73 6f 72 29 7b 0a 20 20 46  r *pCursor){.  F
75c0: 74 73 35 43 75 72 73 6f 72 20 2a 70 43 73 72 20  ts5Cursor *pCsr 
75d0: 3d 20 28 46 74 73 35 43 75 72 73 6f 72 2a 29 70  = (Fts5Cursor*)p
75e0: 43 75 72 73 6f 72 3b 0a 20 20 72 65 74 75 72 6e  Cursor;.  return
75f0: 20 28 43 73 72 46 6c 61 67 54 65 73 74 28 70 43   (CsrFlagTest(pC
7600: 73 72 2c 20 46 54 53 35 43 53 52 5f 45 4f 46 29  sr, FTS5CSR_EOF)
7610: 20 3f 20 31 20 3a 20 30 29 3b 0a 7d 0a 0a 2f 2a   ? 1 : 0);.}../*
7620: 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20 72  .** Return the r
7630: 6f 77 69 64 20 74 68 61 74 20 74 68 65 20 63 75  owid that the cu
7640: 72 73 6f 72 20 63 75 72 72 65 6e 74 6c 79 20 70  rsor currently p
7650: 6f 69 6e 74 73 20 74 6f 2e 0a 2a 2f 0a 73 74 61  oints to..*/.sta
7660: 74 69 63 20 69 36 34 20 66 74 73 35 43 75 72 73  tic i64 fts5Curs
7670: 6f 72 52 6f 77 69 64 28 46 74 73 35 43 75 72 73  orRowid(Fts5Curs
7680: 6f 72 20 2a 70 43 73 72 29 7b 0a 20 20 61 73 73  or *pCsr){.  ass
7690: 65 72 74 28 20 46 54 53 35 5f 50 4c 41 4e 28 70  ert( FTS5_PLAN(p
76a0: 43 73 72 2d 3e 69 64 78 4e 75 6d 29 3d 3d 46 54  Csr->idxNum)==FT
76b0: 53 35 5f 50 4c 41 4e 5f 4d 41 54 43 48 20 0a 20  S5_PLAN_MATCH . 
76c0: 20 20 20 20 20 20 7c 7c 20 46 54 53 35 5f 50 4c        || FTS5_PL
76d0: 41 4e 28 70 43 73 72 2d 3e 69 64 78 4e 75 6d 29  AN(pCsr->idxNum)
76e0: 3d 3d 46 54 53 35 5f 50 4c 41 4e 5f 53 4f 52 54  ==FTS5_PLAN_SORT
76f0: 45 44 5f 4d 41 54 43 48 20 0a 20 20 20 20 20 20  ED_MATCH .      
7700: 20 7c 7c 20 46 54 53 35 5f 50 4c 41 4e 28 70 43   || FTS5_PLAN(pC
7710: 73 72 2d 3e 69 64 78 4e 75 6d 29 3d 3d 46 54 53  sr->idxNum)==FTS
7720: 35 5f 50 4c 41 4e 5f 53 4f 55 52 43 45 20 0a 20  5_PLAN_SOURCE . 
7730: 20 29 3b 0a 20 20 69 66 28 20 70 43 73 72 2d 3e   );.  if( pCsr->
7740: 70 53 6f 72 74 65 72 20 29 7b 0a 20 20 20 20 72  pSorter ){.    r
7750: 65 74 75 72 6e 20 70 43 73 72 2d 3e 70 53 6f 72  eturn pCsr->pSor
7760: 74 65 72 2d 3e 69 52 6f 77 69 64 3b 0a 20 20 7d  ter->iRowid;.  }
7770: 65 6c 73 65 7b 0a 20 20 20 20 72 65 74 75 72 6e  else{.    return
7780: 20 73 71 6c 69 74 65 33 46 74 73 35 45 78 70 72   sqlite3Fts5Expr
7790: 52 6f 77 69 64 28 70 43 73 72 2d 3e 70 45 78 70  Rowid(pCsr->pExp
77a0: 72 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 20 0a 2a  r);.  }.}../* .*
77b0: 2a 20 54 68 69 73 20 69 73 20 74 68 65 20 78 52  * This is the xR
77c0: 6f 77 69 64 20 6d 65 74 68 6f 64 2e 20 54 68 65  owid method. The
77d0: 20 53 51 4c 69 74 65 20 63 6f 72 65 20 63 61 6c   SQLite core cal
77e0: 6c 73 20 74 68 69 73 20 72 6f 75 74 69 6e 65 20  ls this routine 
77f0: 74 6f 0a 2a 2a 20 72 65 74 72 69 65 76 65 20 74  to.** retrieve t
7800: 68 65 20 72 6f 77 69 64 20 66 6f 72 20 74 68 65  he rowid for the
7810: 20 63 75 72 72 65 6e 74 20 72 6f 77 20 6f 66 20   current row of 
7820: 74 68 65 20 72 65 73 75 6c 74 20 73 65 74 2e 20  the result set. 
7830: 66 74 73 35 0a 2a 2a 20 65 78 70 6f 73 65 73 20  fts5.** exposes 
7840: 25 5f 63 6f 6e 74 65 6e 74 2e 64 6f 63 69 64 20  %_content.docid 
7850: 61 73 20 74 68 65 20 72 6f 77 69 64 20 66 6f 72  as the rowid for
7860: 20 74 68 65 20 76 69 72 74 75 61 6c 20 74 61 62   the virtual tab
7870: 6c 65 2e 20 54 68 65 0a 2a 2a 20 72 6f 77 69 64  le. The.** rowid
7880: 20 73 68 6f 75 6c 64 20 62 65 20 77 72 69 74 74   should be writt
7890: 65 6e 20 74 6f 20 2a 70 52 6f 77 69 64 2e 0a 2a  en to *pRowid..*
78a0: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73  /.static int fts
78b0: 35 52 6f 77 69 64 4d 65 74 68 6f 64 28 73 71 6c  5RowidMethod(sql
78c0: 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72  ite3_vtab_cursor
78d0: 20 2a 70 43 75 72 73 6f 72 2c 20 73 71 6c 69 74   *pCursor, sqlit
78e0: 65 5f 69 6e 74 36 34 20 2a 70 52 6f 77 69 64 29  e_int64 *pRowid)
78f0: 7b 0a 20 20 46 74 73 35 43 75 72 73 6f 72 20 2a  {.  Fts5Cursor *
7900: 70 43 73 72 20 3d 20 28 46 74 73 35 43 75 72 73  pCsr = (Fts5Curs
7910: 6f 72 2a 29 70 43 75 72 73 6f 72 3b 0a 20 20 69  or*)pCursor;.  i
7920: 6e 74 20 65 50 6c 61 6e 20 3d 20 46 54 53 35 5f  nt ePlan = FTS5_
7930: 50 4c 41 4e 28 70 43 73 72 2d 3e 69 64 78 4e 75  PLAN(pCsr->idxNu
7940: 6d 29 3b 0a 20 20 0a 20 20 61 73 73 65 72 74 28  m);.  .  assert(
7950: 20 43 73 72 46 6c 61 67 54 65 73 74 28 70 43 73   CsrFlagTest(pCs
7960: 72 2c 20 46 54 53 35 43 53 52 5f 45 4f 46 29 3d  r, FTS5CSR_EOF)=
7970: 3d 30 20 29 3b 0a 20 20 73 77 69 74 63 68 28 20  =0 );.  switch( 
7980: 65 50 6c 61 6e 20 29 7b 0a 20 20 20 20 63 61 73  ePlan ){.    cas
7990: 65 20 46 54 53 35 5f 50 4c 41 4e 5f 53 50 45 43  e FTS5_PLAN_SPEC
79a0: 49 41 4c 3a 0a 20 20 20 20 20 20 2a 70 52 6f 77  IAL:.      *pRow
79b0: 69 64 20 3d 20 30 3b 0a 20 20 20 20 20 20 62 72  id = 0;.      br
79c0: 65 61 6b 3b 0a 0a 20 20 20 20 63 61 73 65 20 46  eak;..    case F
79d0: 54 53 35 5f 50 4c 41 4e 5f 53 4f 55 52 43 45 3a  TS5_PLAN_SOURCE:
79e0: 0a 20 20 20 20 63 61 73 65 20 46 54 53 35 5f 50  .    case FTS5_P
79f0: 4c 41 4e 5f 4d 41 54 43 48 3a 0a 20 20 20 20 63  LAN_MATCH:.    c
7a00: 61 73 65 20 46 54 53 35 5f 50 4c 41 4e 5f 53 4f  ase FTS5_PLAN_SO
7a10: 52 54 45 44 5f 4d 41 54 43 48 3a 0a 20 20 20 20  RTED_MATCH:.    
7a20: 20 20 2a 70 52 6f 77 69 64 20 3d 20 66 74 73 35    *pRowid = fts5
7a30: 43 75 72 73 6f 72 52 6f 77 69 64 28 70 43 73 72  CursorRowid(pCsr
7a40: 29 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a  );.      break;.
7a50: 0a 20 20 20 20 64 65 66 61 75 6c 74 3a 0a 20 20  .    default:.  
7a60: 20 20 20 20 2a 70 52 6f 77 69 64 20 3d 20 73 71      *pRowid = sq
7a70: 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 69 6e 74  lite3_column_int
7a80: 36 34 28 70 43 73 72 2d 3e 70 53 74 6d 74 2c 20  64(pCsr->pStmt, 
7a90: 30 29 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b  0);.      break;
7aa0: 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 53  .  }..  return S
7ab0: 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a  QLITE_OK;.}../*.
7ac0: 2a 2a 20 49 66 20 74 68 65 20 63 75 72 73 6f 72  ** If the cursor
7ad0: 20 72 65 71 75 69 72 65 73 20 73 65 65 6b 69 6e   requires seekin
7ae0: 67 20 28 62 53 65 65 6b 52 65 71 75 69 72 65 64  g (bSeekRequired
7af0: 20 66 6c 61 67 20 69 73 20 73 65 74 29 2c 20 73   flag is set), s
7b00: 65 65 6b 20 69 74 2e 0a 2a 2a 20 52 65 74 75 72  eek it..** Retur
7b10: 6e 20 53 51 4c 49 54 45 5f 4f 4b 20 69 66 20 6e  n SQLITE_OK if n
7b20: 6f 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2c 20  o error occurs, 
7b30: 6f 72 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72  or an SQLite err
7b40: 6f 72 20 63 6f 64 65 20 6f 74 68 65 72 77 69 73  or code otherwis
7b50: 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  e..*/.static int
7b60: 20 66 74 73 35 53 65 65 6b 43 75 72 73 6f 72 28   fts5SeekCursor(
7b70: 46 74 73 35 43 75 72 73 6f 72 20 2a 70 43 73 72  Fts5Cursor *pCsr
7b80: 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51  ){.  int rc = SQ
7b90: 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20 2f 2a 20 49  LITE_OK;..  /* I
7ba0: 66 20 74 68 65 20 63 75 72 73 6f 72 20 64 6f 65  f the cursor doe
7bb0: 73 20 6e 6f 74 20 79 65 74 20 68 61 76 65 20 61  s not yet have a
7bc0: 20 73 74 61 74 65 6d 65 6e 74 20 68 61 6e 64 6c   statement handl
7bd0: 65 2c 20 6f 62 74 61 69 6e 20 6f 6e 65 20 6e 6f  e, obtain one no
7be0: 77 2e 20 2a 2f 20 0a 20 20 69 66 28 20 70 43 73  w. */ .  if( pCs
7bf0: 72 2d 3e 70 53 74 6d 74 3d 3d 30 20 29 7b 0a 20  r->pStmt==0 ){. 
7c00: 20 20 20 46 74 73 35 54 61 62 6c 65 20 2a 70 54     Fts5Table *pT
7c10: 61 62 20 3d 20 28 46 74 73 35 54 61 62 6c 65 2a  ab = (Fts5Table*
7c20: 29 28 70 43 73 72 2d 3e 62 61 73 65 2e 70 56 74  )(pCsr->base.pVt
7c30: 61 62 29 3b 0a 20 20 20 20 69 6e 74 20 65 53 74  ab);.    int eSt
7c40: 6d 74 20 3d 20 66 74 73 35 53 74 6d 74 54 79 70  mt = fts5StmtTyp
7c50: 65 28 70 43 73 72 2d 3e 69 64 78 4e 75 6d 29 3b  e(pCsr->idxNum);
7c60: 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65  .    rc = sqlite
7c70: 33 46 74 73 35 53 74 6f 72 61 67 65 53 74 6d 74  3Fts5StorageStmt
7c80: 28 0a 20 20 20 20 20 20 20 20 70 54 61 62 2d 3e  (.        pTab->
7c90: 70 53 74 6f 72 61 67 65 2c 20 65 53 74 6d 74 2c  pStorage, eStmt,
7ca0: 20 26 70 43 73 72 2d 3e 70 53 74 6d 74 2c 20 26   &pCsr->pStmt, &
7cb0: 70 54 61 62 2d 3e 62 61 73 65 2e 7a 45 72 72 4d  pTab->base.zErrM
7cc0: 73 67 0a 20 20 20 20 29 3b 0a 20 20 20 20 61 73  sg.    );.    as
7cd0: 73 65 72 74 28 20 43 73 72 46 6c 61 67 54 65 73  sert( CsrFlagTes
7ce0: 74 28 70 43 73 72 2c 20 46 54 53 35 43 53 52 5f  t(pCsr, FTS5CSR_
7cf0: 52 45 51 55 49 52 45 5f 43 4f 4e 54 45 4e 54 29  REQUIRE_CONTENT)
7d00: 20 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72   );.  }..  if( r
7d10: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20  c==SQLITE_OK && 
7d20: 43 73 72 46 6c 61 67 54 65 73 74 28 70 43 73 72  CsrFlagTest(pCsr
7d30: 2c 20 46 54 53 35 43 53 52 5f 52 45 51 55 49 52  , FTS5CSR_REQUIR
7d40: 45 5f 43 4f 4e 54 45 4e 54 29 20 29 7b 0a 20 20  E_CONTENT) ){.  
7d50: 20 20 61 73 73 65 72 74 28 20 70 43 73 72 2d 3e    assert( pCsr->
7d60: 70 45 78 70 72 20 29 3b 0a 20 20 20 20 73 71 6c  pExpr );.    sql
7d70: 69 74 65 33 5f 72 65 73 65 74 28 70 43 73 72 2d  ite3_reset(pCsr-
7d80: 3e 70 53 74 6d 74 29 3b 0a 20 20 20 20 73 71 6c  >pStmt);.    sql
7d90: 69 74 65 33 5f 62 69 6e 64 5f 69 6e 74 36 34 28  ite3_bind_int64(
7da0: 70 43 73 72 2d 3e 70 53 74 6d 74 2c 20 31 2c 20  pCsr->pStmt, 1, 
7db0: 66 74 73 35 43 75 72 73 6f 72 52 6f 77 69 64 28  fts5CursorRowid(
7dc0: 70 43 73 72 29 29 3b 0a 20 20 20 20 72 63 20 3d  pCsr));.    rc =
7dd0: 20 73 71 6c 69 74 65 33 5f 73 74 65 70 28 70 43   sqlite3_step(pC
7de0: 73 72 2d 3e 70 53 74 6d 74 29 3b 0a 20 20 20 20  sr->pStmt);.    
7df0: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 52  if( rc==SQLITE_R
7e00: 4f 57 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d  OW ){.      rc =
7e10: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 20 20   SQLITE_OK;.    
7e20: 20 20 43 73 72 46 6c 61 67 43 6c 65 61 72 28 70    CsrFlagClear(p
7e30: 43 73 72 2c 20 46 54 53 35 43 53 52 5f 52 45 51  Csr, FTS5CSR_REQ
7e40: 55 49 52 45 5f 43 4f 4e 54 45 4e 54 29 3b 0a 20  UIRE_CONTENT);. 
7e50: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
7e60: 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 72 65 73  rc = sqlite3_res
7e70: 65 74 28 70 43 73 72 2d 3e 70 53 74 6d 74 29 3b  et(pCsr->pStmt);
7e80: 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53  .      if( rc==S
7e90: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
7ea0: 20 20 20 20 72 63 20 3d 20 46 54 53 35 5f 43 4f      rc = FTS5_CO
7eb0: 52 52 55 50 54 3b 0a 20 20 20 20 20 20 7d 0a 20  RRUPT;.      }. 
7ec0: 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72     }.  }.  retur
7ed0: 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  n rc;.}..static 
7ee0: 76 6f 69 64 20 66 74 73 35 53 65 74 56 74 61 62  void fts5SetVtab
7ef0: 45 72 72 6f 72 28 46 74 73 35 54 61 62 6c 65 20  Error(Fts5Table 
7f00: 2a 70 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  *p, const char *
7f10: 7a 46 6f 72 6d 61 74 2c 20 2e 2e 2e 29 7b 0a 20  zFormat, ...){. 
7f20: 20 76 61 5f 6c 69 73 74 20 61 70 3b 20 20 20 20   va_list ap;    
7f30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7f40: 20 2f 2a 20 2e 2e 2e 20 70 72 69 6e 74 66 20 61   /* ... printf a
7f50: 72 67 75 6d 65 6e 74 73 20 2a 2f 0a 20 20 76 61  rguments */.  va
7f60: 5f 73 74 61 72 74 28 61 70 2c 20 7a 46 6f 72 6d  _start(ap, zForm
7f70: 61 74 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70  at);.  assert( p
7f80: 2d 3e 62 61 73 65 2e 7a 45 72 72 4d 73 67 3d 3d  ->base.zErrMsg==
7f90: 30 20 29 3b 0a 20 20 70 2d 3e 62 61 73 65 2e 7a  0 );.  p->base.z
7fa0: 45 72 72 4d 73 67 20 3d 20 73 71 6c 69 74 65 33  ErrMsg = sqlite3
7fb0: 5f 76 6d 70 72 69 6e 74 66 28 7a 46 6f 72 6d 61  _vmprintf(zForma
7fc0: 74 2c 20 61 70 29 3b 0a 20 20 76 61 5f 65 6e 64  t, ap);.  va_end
7fd0: 28 61 70 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54  (ap);.}../*.** T
7fe0: 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20  his function is 
7ff0: 63 61 6c 6c 65 64 20 74 6f 20 68 61 6e 64 6c 65  called to handle
8000: 20 61 6e 20 46 54 53 20 49 4e 53 45 52 54 20 63   an FTS INSERT c
8010: 6f 6d 6d 61 6e 64 2e 20 49 6e 20 6f 74 68 65 72  ommand. In other
8020: 20 77 6f 72 64 73 2c 0a 2a 2a 20 61 6e 20 49 4e   words,.** an IN
8030: 53 45 52 54 20 73 74 61 74 65 6d 65 6e 74 20 6f  SERT statement o
8040: 66 20 74 68 65 20 66 6f 72 6d 3a 0a 2a 2a 0a 2a  f the form:.**.*
8050: 2a 20 20 20 20 20 49 4e 53 45 52 54 20 49 4e 54  *     INSERT INT
8060: 4f 20 66 74 73 28 66 74 73 29 20 56 41 4c 55 45  O fts(fts) VALUE
8070: 53 28 24 70 43 6d 64 29 0a 2a 2a 20 20 20 20 20  S($pCmd).**     
8080: 49 4e 53 45 52 54 20 49 4e 54 4f 20 66 74 73 28  INSERT INTO fts(
8090: 66 74 73 2c 20 72 61 6e 6b 29 20 56 41 4c 55 45  fts, rank) VALUE
80a0: 53 28 24 70 43 6d 64 2c 20 24 70 56 61 6c 29 0a  S($pCmd, $pVal).
80b0: 2a 2a 0a 2a 2a 20 41 72 67 75 6d 65 6e 74 20 70  **.** Argument p
80c0: 56 61 6c 20 69 73 20 74 68 65 20 76 61 6c 75 65  Val is the value
80d0: 20 61 73 73 69 67 6e 65 64 20 74 6f 20 63 6f 6c   assigned to col
80e0: 75 6d 6e 20 22 66 74 73 22 20 62 79 20 74 68 65  umn "fts" by the
80f0: 20 49 4e 53 45 52 54 20 0a 2a 2a 20 73 74 61 74   INSERT .** stat
8100: 65 6d 65 6e 74 2e 20 54 68 69 73 20 66 75 6e 63  ement. This func
8110: 74 69 6f 6e 20 72 65 74 75 72 6e 73 20 53 51 4c  tion returns SQL
8120: 49 54 45 5f 4f 4b 20 69 66 20 73 75 63 63 65 73  ITE_OK if succes
8130: 73 66 75 6c 2c 20 6f 72 20 61 6e 20 53 51 4c 69  sful, or an SQLi
8140: 74 65 0a 2a 2a 20 65 72 72 6f 72 20 63 6f 64 65  te.** error code
8150: 20 69 66 20 61 6e 20 65 72 72 6f 72 20 6f 63 63   if an error occ
8160: 75 72 73 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63  urs..**.** The c
8170: 6f 6d 6d 61 6e 64 73 20 69 6d 70 6c 65 6d 65 6e  ommands implemen
8180: 74 65 64 20 62 79 20 74 68 69 73 20 66 75 6e 63  ted by this func
8190: 74 69 6f 6e 20 61 72 65 20 64 6f 63 75 6d 65 6e  tion are documen
81a0: 74 65 64 20 69 6e 20 74 68 65 20 22 53 70 65 63  ted in the "Spec
81b0: 69 61 6c 0a 2a 2a 20 49 4e 53 45 52 54 20 44 69  ial.** INSERT Di
81c0: 72 65 63 74 69 76 65 73 22 20 73 65 63 74 69 6f  rectives" sectio
81d0: 6e 20 6f 66 20 74 68 65 20 64 6f 63 75 6d 65 6e  n of the documen
81e0: 74 61 74 69 6f 6e 2e 20 49 74 20 73 68 6f 75 6c  tation. It shoul
81f0: 64 20 62 65 20 75 70 64 61 74 65 64 20 69 66 0a  d be updated if.
8200: 2a 2a 20 6d 6f 72 65 20 63 6f 6d 6d 61 6e 64 73  ** more commands
8210: 20 61 72 65 20 61 64 64 65 64 20 74 6f 20 74 68   are added to th
8220: 69 73 20 66 75 6e 63 74 69 6f 6e 2e 0a 2a 2f 0a  is function..*/.
8230: 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 53  static int fts5S
8240: 70 65 63 69 61 6c 49 6e 73 65 72 74 28 0a 20 20  pecialInsert(.  
8250: 46 74 73 35 54 61 62 6c 65 20 2a 70 54 61 62 2c  Fts5Table *pTab,
8260: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8270: 2f 2a 20 46 74 73 35 20 74 61 62 6c 65 20 6f 62  /* Fts5 table ob
8280: 6a 65 63 74 20 2a 2f 0a 20 20 73 71 6c 69 74 65  ject */.  sqlite
8290: 33 5f 76 61 6c 75 65 20 2a 70 43 6d 64 2c 20 20  3_value *pCmd,  
82a0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 56 61 6c            /* Val
82b0: 75 65 20 69 6e 73 65 72 74 65 64 20 69 6e 74 6f  ue inserted into
82c0: 20 73 70 65 63 69 61 6c 20 63 6f 6c 75 6d 6e 20   special column 
82d0: 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 76 61 6c  */.  sqlite3_val
82e0: 75 65 20 2a 70 56 61 6c 20 20 20 20 20 20 20 20  ue *pVal        
82f0: 20 20 20 20 20 2f 2a 20 56 61 6c 75 65 20 69 6e       /* Value in
8300: 73 65 72 74 65 64 20 69 6e 74 6f 20 72 6f 77 69  serted into rowi
8310: 64 20 63 6f 6c 75 6d 6e 20 2a 2f 0a 29 7b 0a 20  d column */.){. 
8320: 20 46 74 73 35 43 6f 6e 66 69 67 20 2a 70 43 6f   Fts5Config *pCo
8330: 6e 66 69 67 20 3d 20 70 54 61 62 2d 3e 70 43 6f  nfig = pTab->pCo
8340: 6e 66 69 67 3b 0a 20 20 63 6f 6e 73 74 20 63 68  nfig;.  const ch
8350: 61 72 20 2a 7a 20 3d 20 28 63 6f 6e 73 74 20 63  ar *z = (const c
8360: 68 61 72 2a 29 73 71 6c 69 74 65 33 5f 76 61 6c  har*)sqlite3_val
8370: 75 65 5f 74 65 78 74 28 70 43 6d 64 29 3b 0a 20  ue_text(pCmd);. 
8380: 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
8390: 5f 4f 4b 3b 0a 20 20 69 6e 74 20 62 45 72 72 6f  _OK;.  int bErro
83a0: 72 20 3d 20 30 3b 0a 0a 20 20 69 66 28 20 30 3d  r = 0;..  if( 0=
83b0: 3d 73 71 6c 69 74 65 33 5f 73 74 72 69 63 6d 70  =sqlite3_stricmp
83c0: 28 22 64 65 6c 65 74 65 2d 61 6c 6c 22 2c 20 7a  ("delete-all", z
83d0: 29 20 29 7b 0a 20 20 20 20 69 66 28 20 70 43 6f  ) ){.    if( pCo
83e0: 6e 66 69 67 2d 3e 65 43 6f 6e 74 65 6e 74 3d 3d  nfig->eContent==
83f0: 46 54 53 35 5f 43 4f 4e 54 45 4e 54 5f 4e 4f 52  FTS5_CONTENT_NOR
8400: 4d 41 4c 20 29 7b 0a 20 20 20 20 20 20 66 74 73  MAL ){.      fts
8410: 35 53 65 74 56 74 61 62 45 72 72 6f 72 28 70 54  5SetVtabError(pT
8420: 61 62 2c 20 0a 20 20 20 20 20 20 20 20 20 20 22  ab, .          "
8430: 27 64 65 6c 65 74 65 2d 61 6c 6c 27 20 6d 61 79  'delete-all' may
8440: 20 6f 6e 6c 79 20 62 65 20 75 73 65 64 20 77 69   only be used wi
8450: 74 68 20 61 20 22 0a 20 20 20 20 20 20 20 20 20  th a ".         
8460: 20 22 63 6f 6e 74 65 6e 74 6c 65 73 73 20 6f 72   "contentless or
8470: 20 65 78 74 65 72 6e 61 6c 20 63 6f 6e 74 65 6e   external conten
8480: 74 20 66 74 73 35 20 74 61 62 6c 65 22 0a 20 20  t fts5 table".  
8490: 20 20 20 20 29 3b 0a 20 20 20 20 20 20 72 63 20      );.      rc 
84a0: 3d 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a  = SQLITE_ERROR;.
84b0: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
84c0: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 46 74 73   rc = sqlite3Fts
84d0: 35 53 74 6f 72 61 67 65 44 65 6c 65 74 65 41 6c  5StorageDeleteAl
84e0: 6c 28 70 54 61 62 2d 3e 70 53 74 6f 72 61 67 65  l(pTab->pStorage
84f0: 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 65 6c 73 65  );.    }.  }else
8500: 20 69 66 28 20 30 3d 3d 73 71 6c 69 74 65 33 5f   if( 0==sqlite3_
8510: 73 74 72 69 63 6d 70 28 22 72 65 62 75 69 6c 64  stricmp("rebuild
8520: 22 2c 20 7a 29 20 29 7b 0a 20 20 20 20 69 66 28  ", z) ){.    if(
8530: 20 70 43 6f 6e 66 69 67 2d 3e 65 43 6f 6e 74 65   pConfig->eConte
8540: 6e 74 3d 3d 46 54 53 35 5f 43 4f 4e 54 45 4e 54  nt==FTS5_CONTENT
8550: 5f 4e 4f 4e 45 20 29 7b 0a 20 20 20 20 20 20 66  _NONE ){.      f
8560: 74 73 35 53 65 74 56 74 61 62 45 72 72 6f 72 28  ts5SetVtabError(
8570: 70 54 61 62 2c 20 0a 20 20 20 20 20 20 20 20 20  pTab, .         
8580: 20 22 27 72 65 62 75 69 6c 64 27 20 6d 61 79 20   "'rebuild' may 
8590: 6e 6f 74 20 62 65 20 75 73 65 64 20 77 69 74 68  not be used with
85a0: 20 61 20 63 6f 6e 74 65 6e 74 6c 65 73 73 20 66   a contentless f
85b0: 74 73 35 20 74 61 62 6c 65 22 0a 20 20 20 20 20  ts5 table".     
85c0: 20 29 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 53   );.      rc = S
85d0: 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 20  QLITE_ERROR;.   
85e0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 72 63   }else{.      rc
85f0: 20 3d 20 73 71 6c 69 74 65 33 46 74 73 35 53 74   = sqlite3Fts5St
8600: 6f 72 61 67 65 52 65 62 75 69 6c 64 28 70 54 61  orageRebuild(pTa
8610: 62 2d 3e 70 53 74 6f 72 61 67 65 29 3b 0a 20 20  b->pStorage);.  
8620: 20 20 7d 0a 20 20 7d 65 6c 73 65 20 69 66 28 20    }.  }else if( 
8630: 30 3d 3d 73 71 6c 69 74 65 33 5f 73 74 72 69 63  0==sqlite3_stric
8640: 6d 70 28 22 6f 70 74 69 6d 69 7a 65 22 2c 20 7a  mp("optimize", z
8650: 29 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 73 71  ) ){.    rc = sq
8660: 6c 69 74 65 33 46 74 73 35 53 74 6f 72 61 67 65  lite3Fts5Storage
8670: 4f 70 74 69 6d 69 7a 65 28 70 54 61 62 2d 3e 70  Optimize(pTab->p
8680: 53 74 6f 72 61 67 65 29 3b 0a 20 20 7d 65 6c 73  Storage);.  }els
8690: 65 20 69 66 28 20 30 3d 3d 73 71 6c 69 74 65 33  e if( 0==sqlite3
86a0: 5f 73 74 72 69 63 6d 70 28 22 69 6e 74 65 67 72  _stricmp("integr
86b0: 69 74 79 2d 63 68 65 63 6b 22 2c 20 7a 29 20 29  ity-check", z) )
86c0: 7b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74  {.    rc = sqlit
86d0: 65 33 46 74 73 35 53 74 6f 72 61 67 65 49 6e 74  e3Fts5StorageInt
86e0: 65 67 72 69 74 79 28 70 54 61 62 2d 3e 70 53 74  egrity(pTab->pSt
86f0: 6f 72 61 67 65 29 3b 0a 20 20 7d 65 6c 73 65 7b  orage);.  }else{
8700: 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65  .    rc = sqlite
8710: 33 46 74 73 35 49 6e 64 65 78 4c 6f 61 64 43 6f  3Fts5IndexLoadCo
8720: 6e 66 69 67 28 70 54 61 62 2d 3e 70 49 6e 64 65  nfig(pTab->pInde
8730: 78 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d  x);.    if( rc==
8740: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
8750: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 46     rc = sqlite3F
8760: 74 73 35 43 6f 6e 66 69 67 53 65 74 56 61 6c 75  ts5ConfigSetValu
8770: 65 28 70 54 61 62 2d 3e 70 43 6f 6e 66 69 67 2c  e(pTab->pConfig,
8780: 20 7a 2c 20 70 56 61 6c 2c 20 26 62 45 72 72 6f   z, pVal, &bErro
8790: 72 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66  r);.    }.    if
87a0: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
87b0: 29 7b 0a 20 20 20 20 20 20 69 66 28 20 62 45 72  ){.      if( bEr
87c0: 72 6f 72 20 29 7b 0a 20 20 20 20 20 20 20 20 72  ror ){.        r
87d0: 63 20 3d 20 53 51 4c 49 54 45 5f 45 52 52 4f 52  c = SQLITE_ERROR
87e0: 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20  ;.      }else{. 
87f0: 20 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69         rc = sqli
8800: 74 65 33 46 74 73 35 53 74 6f 72 61 67 65 43 6f  te3Fts5StorageCo
8810: 6e 66 69 67 56 61 6c 75 65 28 70 54 61 62 2d 3e  nfigValue(pTab->
8820: 70 53 74 6f 72 61 67 65 2c 20 7a 2c 20 70 56 61  pStorage, z, pVa
8830: 6c 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  l);.      }.    
8840: 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72  }.  }.  return r
8850: 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  c;.}..static int
8860: 20 66 74 73 35 53 70 65 63 69 61 6c 44 65 6c 65   fts5SpecialDele
8870: 74 65 28 0a 20 20 46 74 73 35 54 61 62 6c 65 20  te(.  Fts5Table 
8880: 2a 70 54 61 62 2c 20 0a 20 20 73 71 6c 69 74 65  *pTab, .  sqlite
8890: 33 5f 76 61 6c 75 65 20 2a 2a 61 70 56 61 6c 2c  3_value **apVal,
88a0: 20 0a 20 20 73 71 6c 69 74 65 33 5f 69 6e 74 36   .  sqlite3_int6
88b0: 34 20 2a 70 69 52 6f 77 69 64 0a 29 7b 0a 20 20  4 *piRowid.){.  
88c0: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
88d0: 4f 4b 3b 0a 20 20 69 6e 74 20 65 54 79 70 65 31  OK;.  int eType1
88e0: 20 3d 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65   = sqlite3_value
88f0: 5f 74 79 70 65 28 61 70 56 61 6c 5b 31 5d 29 3b  _type(apVal[1]);
8900: 0a 20 20 69 66 28 20 65 54 79 70 65 31 3d 3d 53  .  if( eType1==S
8910: 51 4c 49 54 45 5f 49 4e 54 45 47 45 52 20 29 7b  QLITE_INTEGER ){
8920: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 69 6e 74  .    sqlite3_int
8930: 36 34 20 69 44 65 6c 20 3d 20 73 71 6c 69 74 65  64 iDel = sqlite
8940: 33 5f 76 61 6c 75 65 5f 69 6e 74 36 34 28 61 70  3_value_int64(ap
8950: 56 61 6c 5b 31 5d 29 3b 0a 20 20 20 20 72 63 20  Val[1]);.    rc 
8960: 3d 20 73 71 6c 69 74 65 33 46 74 73 35 53 74 6f  = sqlite3Fts5Sto
8970: 72 61 67 65 53 70 65 63 69 61 6c 44 65 6c 65 74  rageSpecialDelet
8980: 65 28 70 54 61 62 2d 3e 70 53 74 6f 72 61 67 65  e(pTab->pStorage
8990: 2c 20 69 44 65 6c 2c 20 26 61 70 56 61 6c 5b 32  , iDel, &apVal[2
89a0: 5d 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  ]);.  }.  return
89b0: 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 54   rc;.}../* .** T
89c0: 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20  his function is 
89d0: 74 68 65 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69  the implementati
89e0: 6f 6e 20 6f 66 20 74 68 65 20 78 55 70 64 61 74  on of the xUpdat
89f0: 65 20 63 61 6c 6c 62 61 63 6b 20 75 73 65 64 20  e callback used 
8a00: 62 79 20 0a 2a 2a 20 46 54 53 33 20 76 69 72 74  by .** FTS3 virt
8a10: 75 61 6c 20 74 61 62 6c 65 73 2e 20 49 74 20 69  ual tables. It i
8a20: 73 20 69 6e 76 6f 6b 65 64 20 62 79 20 53 51 4c  s invoked by SQL
8a30: 69 74 65 20 65 61 63 68 20 74 69 6d 65 20 61 20  ite each time a 
8a40: 72 6f 77 20 69 73 20 74 6f 20 62 65 0a 2a 2a 20  row is to be.** 
8a50: 69 6e 73 65 72 74 65 64 2c 20 75 70 64 61 74 65  inserted, update
8a60: 64 20 6f 72 20 64 65 6c 65 74 65 64 2e 0a 2a 2f  d or deleted..*/
8a70: 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35  .static int fts5
8a80: 55 70 64 61 74 65 4d 65 74 68 6f 64 28 0a 20 20  UpdateMethod(.  
8a90: 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56  sqlite3_vtab *pV
8aa0: 74 61 62 2c 20 20 20 20 20 20 20 20 20 20 20 20  tab,            
8ab0: 2f 2a 20 56 69 72 74 75 61 6c 20 74 61 62 6c 65  /* Virtual table
8ac0: 20 68 61 6e 64 6c 65 20 2a 2f 0a 20 20 69 6e 74   handle */.  int
8ad0: 20 6e 41 72 67 2c 20 20 20 20 20 20 20 20 20 20   nArg,          
8ae0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
8af0: 53 69 7a 65 20 6f 66 20 61 72 67 75 6d 65 6e 74  Size of argument
8b00: 20 61 72 72 61 79 20 2a 2f 0a 20 20 73 71 6c 69   array */.  sqli
8b10: 74 65 33 5f 76 61 6c 75 65 20 2a 2a 61 70 56 61  te3_value **apVa
8b20: 6c 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20 41  l,          /* A
8b30: 72 72 61 79 20 6f 66 20 61 72 67 75 6d 65 6e 74  rray of argument
8b40: 73 20 2a 2f 0a 20 20 73 71 6c 69 74 65 5f 69 6e  s */.  sqlite_in
8b50: 74 36 34 20 2a 70 52 6f 77 69 64 20 20 20 20 20  t64 *pRowid     
8b60: 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 54         /* OUT: T
8b70: 68 65 20 61 66 66 65 63 74 65 64 20 28 6f 72 20  he affected (or 
8b80: 65 66 66 65 63 74 65 64 29 20 72 6f 77 69 64 20  effected) rowid 
8b90: 2a 2f 0a 29 7b 0a 20 20 46 74 73 35 54 61 62 6c  */.){.  Fts5Tabl
8ba0: 65 20 2a 70 54 61 62 20 3d 20 28 46 74 73 35 54  e *pTab = (Fts5T
8bb0: 61 62 6c 65 2a 29 70 56 74 61 62 3b 0a 20 20 46  able*)pVtab;.  F
8bc0: 74 73 35 43 6f 6e 66 69 67 20 2a 70 43 6f 6e 66  ts5Config *pConf
8bd0: 69 67 20 3d 20 70 54 61 62 2d 3e 70 43 6f 6e 66  ig = pTab->pConf
8be0: 69 67 3b 0a 20 20 69 6e 74 20 65 54 79 70 65 30  ig;.  int eType0
8bf0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
8c00: 20 20 20 20 20 20 2f 2a 20 76 61 6c 75 65 5f 74        /* value_t
8c10: 79 70 65 28 29 20 6f 66 20 61 70 56 61 6c 5b 30  ype() of apVal[0
8c20: 5d 20 2a 2f 0a 20 20 69 6e 74 20 65 43 6f 6e 66  ] */.  int eConf
8c30: 6c 69 63 74 3b 20 20 20 20 20 20 20 20 20 20 20  lict;           
8c40: 20 20 20 20 20 20 20 2f 2a 20 4f 4e 20 43 4f 4e         /* ON CON
8c50: 46 4c 49 43 54 20 66 6f 72 20 74 68 69 73 20 44  FLICT for this D
8c60: 4d 4c 20 2a 2f 0a 20 20 69 6e 74 20 72 63 20 3d  ML */.  int rc =
8c70: 20 53 51 4c 49 54 45 5f 4f 4b 3b 20 20 20 20 20   SQLITE_OK;     
8c80: 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72          /* Retur
8c90: 6e 20 63 6f 64 65 20 2a 2f 0a 0a 20 20 2f 2a 20  n code */..  /* 
8ca0: 41 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 6d 75  A transaction mu
8cb0: 73 74 20 62 65 20 6f 70 65 6e 20 77 68 65 6e 20  st be open when 
8cc0: 74 68 69 73 20 69 73 20 63 61 6c 6c 65 64 2e 20  this is called. 
8cd0: 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 70 54 61  */.  assert( pTa
8ce0: 62 2d 3e 74 73 2e 65 53 74 61 74 65 3d 3d 31 20  b->ts.eState==1 
8cf0: 29 3b 0a 0a 20 20 2f 2a 20 41 20 64 65 6c 65 74  );..  /* A delet
8d00: 65 20 73 70 65 63 69 66 69 65 73 20 61 20 73 69  e specifies a si
8d10: 6e 67 6c 65 20 61 72 67 75 6d 65 6e 74 20 2d 20  ngle argument - 
8d20: 74 68 65 20 72 6f 77 69 64 20 6f 66 20 74 68 65  the rowid of the
8d30: 20 72 6f 77 20 74 6f 20 72 65 6d 6f 76 65 2e 0a   row to remove..
8d40: 20 20 2a 2a 20 55 70 64 61 74 65 20 61 6e 64 20    ** Update and 
8d50: 69 6e 73 65 72 74 20 6f 70 65 72 61 74 69 6f 6e  insert operation
8d60: 73 20 70 61 73 73 3a 0a 20 20 2a 2a 0a 20 20 2a  s pass:.  **.  *
8d70: 2a 20 20 20 31 2e 20 54 68 65 20 22 6f 6c 64 22  *   1. The "old"
8d80: 20 72 6f 77 69 64 2c 20 6f 72 20 4e 55 4c 4c 2e   rowid, or NULL.
8d90: 0a 20 20 2a 2a 20 20 20 32 2e 20 54 68 65 20 22  .  **   2. The "
8da0: 6e 65 77 22 20 72 6f 77 69 64 2e 0a 20 20 2a 2a  new" rowid..  **
8db0: 20 20 20 33 2e 20 56 61 6c 75 65 73 20 66 6f 72     3. Values for
8dc0: 20 65 61 63 68 20 6f 66 20 74 68 65 20 6e 43 6f   each of the nCo
8dd0: 6c 20 6d 61 74 63 68 61 62 6c 65 20 63 6f 6c 75  l matchable colu
8de0: 6d 6e 73 2e 0a 20 20 2a 2a 20 20 20 34 2e 20 56  mns..  **   4. V
8df0: 61 6c 75 65 73 20 66 6f 72 20 74 68 65 20 74 77  alues for the tw
8e00: 6f 20 68 69 64 64 65 6e 20 63 6f 6c 75 6d 6e 73  o hidden columns
8e10: 20 28 3c 74 61 62 6c 65 6e 61 6d 65 3e 20 61 6e   (<tablename> an
8e20: 64 20 22 72 61 6e 6b 22 29 2e 0a 20 20 2a 2f 0a  d "rank")..  */.
8e30: 20 20 61 73 73 65 72 74 28 20 6e 41 72 67 3d 3d    assert( nArg==
8e40: 31 20 7c 7c 20 6e 41 72 67 3d 3d 28 32 20 2b 20  1 || nArg==(2 + 
8e50: 70 43 6f 6e 66 69 67 2d 3e 6e 43 6f 6c 20 2b 20  pConfig->nCol + 
8e60: 32 29 20 29 3b 0a 0a 20 20 65 54 79 70 65 30 20  2) );..  eType0 
8e70: 3d 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f  = sqlite3_value_
8e80: 74 79 70 65 28 61 70 56 61 6c 5b 30 5d 29 3b 0a  type(apVal[0]);.
8e90: 20 20 65 43 6f 6e 66 6c 69 63 74 20 3d 20 73 71    eConflict = sq
8ea0: 6c 69 74 65 33 5f 76 74 61 62 5f 6f 6e 5f 63 6f  lite3_vtab_on_co
8eb0: 6e 66 6c 69 63 74 28 70 43 6f 6e 66 69 67 2d 3e  nflict(pConfig->
8ec0: 64 62 29 3b 0a 0a 20 20 61 73 73 65 72 74 28 20  db);..  assert( 
8ed0: 65 54 79 70 65 30 3d 3d 53 51 4c 49 54 45 5f 49  eType0==SQLITE_I
8ee0: 4e 54 45 47 45 52 20 7c 7c 20 65 54 79 70 65 30  NTEGER || eType0
8ef0: 3d 3d 53 51 4c 49 54 45 5f 4e 55 4c 4c 20 29 3b  ==SQLITE_NULL );
8f00: 0a 20 20 61 73 73 65 72 74 28 20 70 56 74 61 62  .  assert( pVtab
8f10: 2d 3e 7a 45 72 72 4d 73 67 3d 3d 30 20 29 3b 0a  ->zErrMsg==0 );.
8f20: 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
8f30: 45 5f 4f 4b 20 26 26 20 65 54 79 70 65 30 3d 3d  E_OK && eType0==
8f40: 53 51 4c 49 54 45 5f 49 4e 54 45 47 45 52 20 29  SQLITE_INTEGER )
8f50: 7b 0a 20 20 20 20 69 66 28 20 66 74 73 35 49 73  {.    if( fts5Is
8f60: 43 6f 6e 74 65 6e 74 6c 65 73 73 28 70 54 61 62  Contentless(pTab
8f70: 29 20 29 7b 0a 20 20 20 20 20 20 70 54 61 62 2d  ) ){.      pTab-
8f80: 3e 62 61 73 65 2e 7a 45 72 72 4d 73 67 20 3d 20  >base.zErrMsg = 
8f90: 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28  sqlite3_mprintf(
8fa0: 0a 20 20 20 20 20 20 20 20 20 20 22 63 61 6e 6e  .          "cann
8fb0: 6f 74 20 25 73 20 63 6f 6e 74 65 6e 74 6c 65 73  ot %s contentles
8fc0: 73 20 66 74 73 35 20 74 61 62 6c 65 3a 20 25 73  s fts5 table: %s
8fd0: 22 2c 20 0a 20 20 20 20 20 20 20 20 20 20 28 6e  ", .          (n
8fe0: 41 72 67 3e 31 20 3f 20 22 55 50 44 41 54 45 22  Arg>1 ? "UPDATE"
8ff0: 20 3a 20 22 44 45 4c 45 54 45 20 66 72 6f 6d 22   : "DELETE from"
9000: 29 2c 20 70 43 6f 6e 66 69 67 2d 3e 7a 4e 61 6d  ), pConfig->zNam
9010: 65 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20 20  e.      );.     
9020: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 45 52 52   rc = SQLITE_ERR
9030: 4f 52 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20  OR;.    }else{. 
9040: 20 20 20 20 20 69 36 34 20 69 44 65 6c 20 3d 20       i64 iDel = 
9050: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 69 6e  sqlite3_value_in
9060: 74 36 34 28 61 70 56 61 6c 5b 30 5d 29 3b 20 20  t64(apVal[0]);  
9070: 2f 2a 20 52 6f 77 69 64 20 74 6f 20 64 65 6c 65  /* Rowid to dele
9080: 74 65 20 2a 2f 0a 20 20 20 20 20 20 72 63 20 3d  te */.      rc =
9090: 20 73 71 6c 69 74 65 33 46 74 73 35 53 74 6f 72   sqlite3Fts5Stor
90a0: 61 67 65 44 65 6c 65 74 65 28 70 54 61 62 2d 3e  ageDelete(pTab->
90b0: 70 53 74 6f 72 61 67 65 2c 20 69 44 65 6c 29 3b  pStorage, iDel);
90c0: 0a 20 20 20 20 7d 0a 20 20 7d 65 6c 73 65 20 69  .    }.  }else i
90d0: 66 28 20 6e 41 72 67 3e 31 20 29 7b 0a 20 20 20  f( nArg>1 ){.   
90e0: 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a   sqlite3_value *
90f0: 70 43 6d 64 20 3d 20 61 70 56 61 6c 5b 32 20 2b  pCmd = apVal[2 +
9100: 20 70 43 6f 6e 66 69 67 2d 3e 6e 43 6f 6c 5d 3b   pConfig->nCol];
9110: 0a 20 20 20 20 69 66 28 20 53 51 4c 49 54 45 5f  .    if( SQLITE_
9120: 4e 55 4c 4c 21 3d 73 71 6c 69 74 65 33 5f 76 61  NULL!=sqlite3_va
9130: 6c 75 65 5f 74 79 70 65 28 70 43 6d 64 29 20 29  lue_type(pCmd) )
9140: 7b 0a 20 20 20 20 20 20 63 6f 6e 73 74 20 63 68  {.      const ch
9150: 61 72 20 2a 7a 20 3d 20 28 63 6f 6e 73 74 20 63  ar *z = (const c
9160: 68 61 72 2a 29 73 71 6c 69 74 65 33 5f 76 61 6c  har*)sqlite3_val
9170: 75 65 5f 74 65 78 74 28 70 43 6d 64 29 3b 0a 20  ue_text(pCmd);. 
9180: 20 20 20 20 20 69 66 28 20 70 43 6f 6e 66 69 67       if( pConfig
9190: 2d 3e 65 43 6f 6e 74 65 6e 74 21 3d 46 54 53 35  ->eContent!=FTS5
91a0: 5f 43 4f 4e 54 45 4e 54 5f 4e 4f 52 4d 41 4c 20  _CONTENT_NORMAL 
91b0: 0a 20 20 20 20 20 20 20 26 26 20 30 3d 3d 73 71  .       && 0==sq
91c0: 6c 69 74 65 33 5f 73 74 72 69 63 6d 70 28 22 64  lite3_stricmp("d
91d0: 65 6c 65 74 65 22 2c 20 7a 29 20 0a 20 20 20 20  elete", z) .    
91e0: 20 20 29 7b 0a 20 20 20 20 20 20 20 20 72 65 74    ){.        ret
91f0: 75 72 6e 20 66 74 73 35 53 70 65 63 69 61 6c 44  urn fts5SpecialD
9200: 65 6c 65 74 65 28 70 54 61 62 2c 20 61 70 56 61  elete(pTab, apVa
9210: 6c 2c 20 70 52 6f 77 69 64 29 3b 0a 20 20 20 20  l, pRowid);.    
9220: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20    }else{.       
9230: 20 72 65 74 75 72 6e 20 66 74 73 35 53 70 65 63   return fts5Spec
9240: 69 61 6c 49 6e 73 65 72 74 28 70 54 61 62 2c 20  ialInsert(pTab, 
9250: 70 43 6d 64 2c 20 61 70 56 61 6c 5b 32 20 2b 20  pCmd, apVal[2 + 
9260: 70 43 6f 6e 66 69 67 2d 3e 6e 43 6f 6c 20 2b 20  pConfig->nCol + 
9270: 31 5d 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  1]);.      }.   
9280: 20 7d 0a 20 20 7d 0a 0a 0a 20 20 69 66 28 20 72   }.  }...  if( r
9290: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20  c==SQLITE_OK && 
92a0: 6e 41 72 67 3e 31 20 29 7b 0a 20 20 20 20 72 63  nArg>1 ){.    rc
92b0: 20 3d 20 73 71 6c 69 74 65 33 46 74 73 35 53 74   = sqlite3Fts5St
92c0: 6f 72 61 67 65 49 6e 73 65 72 74 28 70 54 61 62  orageInsert(pTab
92d0: 2d 3e 70 53 74 6f 72 61 67 65 2c 20 61 70 56 61  ->pStorage, apVa
92e0: 6c 2c 20 65 43 6f 6e 66 6c 69 63 74 2c 20 70 52  l, eConflict, pR
92f0: 6f 77 69 64 29 3b 0a 20 20 7d 0a 0a 20 20 72 65  owid);.  }..  re
9300: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
9310: 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e  * Implementation
9320: 20 6f 66 20 78 53 79 6e 63 28 29 20 6d 65 74 68   of xSync() meth
9330: 6f 64 2e 20 0a 2a 2f 0a 73 74 61 74 69 63 20 69  od. .*/.static i
9340: 6e 74 20 66 74 73 35 53 79 6e 63 4d 65 74 68 6f  nt fts5SyncMetho
9350: 64 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a  d(sqlite3_vtab *
9360: 70 56 74 61 62 29 7b 0a 20 20 69 6e 74 20 72 63  pVtab){.  int rc
9370: 3b 0a 20 20 46 74 73 35 54 61 62 6c 65 20 2a 70  ;.  Fts5Table *p
9380: 54 61 62 20 3d 20 28 46 74 73 35 54 61 62 6c 65  Tab = (Fts5Table
9390: 2a 29 70 56 74 61 62 3b 0a 20 20 66 74 73 35 43  *)pVtab;.  fts5C
93a0: 68 65 63 6b 54 72 61 6e 73 61 63 74 69 6f 6e 53  heckTransactionS
93b0: 74 61 74 65 28 70 54 61 62 2c 20 46 54 53 35 5f  tate(pTab, FTS5_
93c0: 53 59 4e 43 2c 20 30 29 3b 0a 20 20 72 63 20 3d  SYNC, 0);.  rc =
93d0: 20 73 71 6c 69 74 65 33 46 74 73 35 53 74 6f 72   sqlite3Fts5Stor
93e0: 61 67 65 53 79 6e 63 28 70 54 61 62 2d 3e 70 53  ageSync(pTab->pS
93f0: 74 6f 72 61 67 65 2c 20 31 29 3b 0a 20 20 72 65  torage, 1);.  re
9400: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
9410: 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e  * Implementation
9420: 20 6f 66 20 78 42 65 67 69 6e 28 29 20 6d 65 74   of xBegin() met
9430: 68 6f 64 2e 20 0a 2a 2f 0a 73 74 61 74 69 63 20  hod. .*/.static 
9440: 69 6e 74 20 66 74 73 35 42 65 67 69 6e 4d 65 74  int fts5BeginMet
9450: 68 6f 64 28 73 71 6c 69 74 65 33 5f 76 74 61 62  hod(sqlite3_vtab
9460: 20 2a 70 56 74 61 62 29 7b 0a 20 20 66 74 73 35   *pVtab){.  fts5
9470: 43 68 65 63 6b 54 72 61 6e 73 61 63 74 69 6f 6e  CheckTransaction
9480: 53 74 61 74 65 28 28 46 74 73 35 54 61 62 6c 65  State((Fts5Table
9490: 2a 29 70 56 74 61 62 2c 20 46 54 53 35 5f 42 45  *)pVtab, FTS5_BE
94a0: 47 49 4e 2c 20 30 29 3b 0a 20 20 72 65 74 75 72  GIN, 0);.  retur
94b0: 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a  n SQLITE_OK;.}..
94c0: 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61  /*.** Implementa
94d0: 74 69 6f 6e 20 6f 66 20 78 43 6f 6d 6d 69 74 28  tion of xCommit(
94e0: 29 20 6d 65 74 68 6f 64 2e 20 54 68 69 73 20 69  ) method. This i
94f0: 73 20 61 20 6e 6f 2d 6f 70 2e 20 54 68 65 20 63  s a no-op. The c
9500: 6f 6e 74 65 6e 74 73 20 6f 66 0a 2a 2a 20 74 68  ontents of.** th
9510: 65 20 70 65 6e 64 69 6e 67 2d 74 65 72 6d 73 20  e pending-terms 
9520: 68 61 73 68 2d 74 61 62 6c 65 20 68 61 76 65 20  hash-table have 
9530: 61 6c 72 65 61 64 79 20 62 65 65 6e 20 66 6c 75  already been flu
9540: 73 68 65 64 20 69 6e 74 6f 20 74 68 65 20 64 61  shed into the da
9550: 74 61 62 61 73 65 0a 2a 2a 20 62 79 20 66 74 73  tabase.** by fts
9560: 35 53 79 6e 63 4d 65 74 68 6f 64 28 29 2e 0a 2a  5SyncMethod()..*
9570: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73  /.static int fts
9580: 35 43 6f 6d 6d 69 74 4d 65 74 68 6f 64 28 73 71  5CommitMethod(sq
9590: 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56 74 61  lite3_vtab *pVta
95a0: 62 29 7b 0a 20 20 66 74 73 35 43 68 65 63 6b 54  b){.  fts5CheckT
95b0: 72 61 6e 73 61 63 74 69 6f 6e 53 74 61 74 65 28  ransactionState(
95c0: 28 46 74 73 35 54 61 62 6c 65 2a 29 70 56 74 61  (Fts5Table*)pVta
95d0: 62 2c 20 46 54 53 35 5f 43 4f 4d 4d 49 54 2c 20  b, FTS5_COMMIT, 
95e0: 30 29 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c  0);.  return SQL
95f0: 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  ITE_OK;.}../*.**
9600: 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20   Implementation 
9610: 6f 66 20 78 52 6f 6c 6c 62 61 63 6b 28 29 2e 20  of xRollback(). 
9620: 44 69 73 63 61 72 64 20 74 68 65 20 63 6f 6e 74  Discard the cont
9630: 65 6e 74 73 20 6f 66 20 74 68 65 20 70 65 6e 64  ents of the pend
9640: 69 6e 67 2d 74 65 72 6d 73 0a 2a 2a 20 68 61 73  ing-terms.** has
9650: 68 2d 74 61 62 6c 65 2e 20 41 6e 79 20 63 68 61  h-table. Any cha
9660: 6e 67 65 73 20 6d 61 64 65 20 74 6f 20 74 68 65  nges made to the
9670: 20 64 61 74 61 62 61 73 65 20 61 72 65 20 72 65   database are re
9680: 76 65 72 74 65 64 20 62 79 20 53 51 4c 69 74 65  verted by SQLite
9690: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
96a0: 66 74 73 35 52 6f 6c 6c 62 61 63 6b 4d 65 74 68  fts5RollbackMeth
96b0: 6f 64 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20  od(sqlite3_vtab 
96c0: 2a 70 56 74 61 62 29 7b 0a 20 20 69 6e 74 20 72  *pVtab){.  int r
96d0: 63 3b 0a 20 20 46 74 73 35 54 61 62 6c 65 20 2a  c;.  Fts5Table *
96e0: 70 54 61 62 20 3d 20 28 46 74 73 35 54 61 62 6c  pTab = (Fts5Tabl
96f0: 65 2a 29 70 56 74 61 62 3b 0a 20 20 66 74 73 35  e*)pVtab;.  fts5
9700: 43 68 65 63 6b 54 72 61 6e 73 61 63 74 69 6f 6e  CheckTransaction
9710: 53 74 61 74 65 28 70 54 61 62 2c 20 46 54 53 35  State(pTab, FTS5
9720: 5f 52 4f 4c 4c 42 41 43 4b 2c 20 30 29 3b 0a 20  _ROLLBACK, 0);. 
9730: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 46 74 73   rc = sqlite3Fts
9740: 35 53 74 6f 72 61 67 65 52 6f 6c 6c 62 61 63 6b  5StorageRollback
9750: 28 70 54 61 62 2d 3e 70 53 74 6f 72 61 67 65 29  (pTab->pStorage)
9760: 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ;.  return rc;.}
9770: 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 2a 66  ..static void *f
9780: 74 73 35 41 70 69 55 73 65 72 44 61 74 61 28 46  ts5ApiUserData(F
9790: 74 73 35 43 6f 6e 74 65 78 74 20 2a 70 43 74 78  ts5Context *pCtx
97a0: 29 7b 0a 20 20 46 74 73 35 43 75 72 73 6f 72 20  ){.  Fts5Cursor 
97b0: 2a 70 43 73 72 20 3d 20 28 46 74 73 35 43 75 72  *pCsr = (Fts5Cur
97c0: 73 6f 72 2a 29 70 43 74 78 3b 0a 20 20 72 65 74  sor*)pCtx;.  ret
97d0: 75 72 6e 20 70 43 73 72 2d 3e 70 41 75 78 2d 3e  urn pCsr->pAux->
97e0: 70 55 73 65 72 44 61 74 61 3b 0a 7d 0a 0a 73 74  pUserData;.}..st
97f0: 61 74 69 63 20 69 6e 74 20 66 74 73 35 41 70 69  atic int fts5Api
9800: 43 6f 6c 75 6d 6e 43 6f 75 6e 74 28 46 74 73 35  ColumnCount(Fts5
9810: 43 6f 6e 74 65 78 74 20 2a 70 43 74 78 29 7b 0a  Context *pCtx){.
9820: 20 20 46 74 73 35 43 75 72 73 6f 72 20 2a 70 43    Fts5Cursor *pC
9830: 73 72 20 3d 20 28 46 74 73 35 43 75 72 73 6f 72  sr = (Fts5Cursor
9840: 2a 29 70 43 74 78 3b 0a 20 20 72 65 74 75 72 6e  *)pCtx;.  return
9850: 20 28 28 46 74 73 35 54 61 62 6c 65 2a 29 28 70   ((Fts5Table*)(p
9860: 43 73 72 2d 3e 62 61 73 65 2e 70 56 74 61 62 29  Csr->base.pVtab)
9870: 29 2d 3e 70 43 6f 6e 66 69 67 2d 3e 6e 43 6f 6c  )->pConfig->nCol
9880: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  ;.}..static int 
9890: 66 74 73 35 41 70 69 43 6f 6c 75 6d 6e 54 6f 74  fts5ApiColumnTot
98a0: 61 6c 53 69 7a 65 28 0a 20 20 46 74 73 35 43 6f  alSize(.  Fts5Co
98b0: 6e 74 65 78 74 20 2a 70 43 74 78 2c 20 0a 20 20  ntext *pCtx, .  
98c0: 69 6e 74 20 69 43 6f 6c 2c 20 0a 20 20 73 71 6c  int iCol, .  sql
98d0: 69 74 65 33 5f 69 6e 74 36 34 20 2a 70 6e 54 6f  ite3_int64 *pnTo
98e0: 6b 65 6e 0a 29 7b 0a 20 20 46 74 73 35 43 75 72  ken.){.  Fts5Cur
98f0: 73 6f 72 20 2a 70 43 73 72 20 3d 20 28 46 74 73  sor *pCsr = (Fts
9900: 35 43 75 72 73 6f 72 2a 29 70 43 74 78 3b 0a 20  5Cursor*)pCtx;. 
9910: 20 46 74 73 35 54 61 62 6c 65 20 2a 70 54 61 62   Fts5Table *pTab
9920: 20 3d 20 28 46 74 73 35 54 61 62 6c 65 2a 29 28   = (Fts5Table*)(
9930: 70 43 73 72 2d 3e 62 61 73 65 2e 70 56 74 61 62  pCsr->base.pVtab
9940: 29 3b 0a 20 20 72 65 74 75 72 6e 20 73 71 6c 69  );.  return sqli
9950: 74 65 33 46 74 73 35 53 74 6f 72 61 67 65 53 69  te3Fts5StorageSi
9960: 7a 65 28 70 54 61 62 2d 3e 70 53 74 6f 72 61 67  ze(pTab->pStorag
9970: 65 2c 20 69 43 6f 6c 2c 20 70 6e 54 6f 6b 65 6e  e, iCol, pnToken
9980: 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  );.}..static int
9990: 20 66 74 73 35 41 70 69 52 6f 77 43 6f 75 6e 74   fts5ApiRowCount
99a0: 28 46 74 73 35 43 6f 6e 74 65 78 74 20 2a 70 43  (Fts5Context *pC
99b0: 74 78 2c 20 69 36 34 20 2a 70 6e 52 6f 77 29 7b  tx, i64 *pnRow){
99c0: 0a 20 20 46 74 73 35 43 75 72 73 6f 72 20 2a 70  .  Fts5Cursor *p
99d0: 43 73 72 20 3d 20 28 46 74 73 35 43 75 72 73 6f  Csr = (Fts5Curso
99e0: 72 2a 29 70 43 74 78 3b 0a 20 20 46 74 73 35 54  r*)pCtx;.  Fts5T
99f0: 61 62 6c 65 20 2a 70 54 61 62 20 3d 20 28 46 74  able *pTab = (Ft
9a00: 73 35 54 61 62 6c 65 2a 29 28 70 43 73 72 2d 3e  s5Table*)(pCsr->
9a10: 62 61 73 65 2e 70 56 74 61 62 29 3b 0a 20 20 72  base.pVtab);.  r
9a20: 65 74 75 72 6e 20 73 71 6c 69 74 65 33 46 74 73  eturn sqlite3Fts
9a30: 35 53 74 6f 72 61 67 65 52 6f 77 43 6f 75 6e 74  5StorageRowCount
9a40: 28 70 54 61 62 2d 3e 70 53 74 6f 72 61 67 65 2c  (pTab->pStorage,
9a50: 20 70 6e 52 6f 77 29 3b 0a 7d 0a 0a 73 74 61 74   pnRow);.}..stat
9a60: 69 63 20 69 6e 74 20 66 74 73 35 41 70 69 54 6f  ic int fts5ApiTo
9a70: 6b 65 6e 69 7a 65 28 0a 20 20 46 74 73 35 43 6f  kenize(.  Fts5Co
9a80: 6e 74 65 78 74 20 2a 70 43 74 78 2c 20 0a 20 20  ntext *pCtx, .  
9a90: 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 54 65 78  const char *pTex
9aa0: 74 2c 20 69 6e 74 20 6e 54 65 78 74 2c 20 0a 20  t, int nText, . 
9ab0: 20 76 6f 69 64 20 2a 70 55 73 65 72 44 61 74 61   void *pUserData
9ac0: 2c 0a 20 20 69 6e 74 20 28 2a 78 54 6f 6b 65 6e  ,.  int (*xToken
9ad0: 29 28 76 6f 69 64 2a 2c 20 63 6f 6e 73 74 20 63  )(void*, const c
9ae0: 68 61 72 2a 2c 20 69 6e 74 2c 20 69 6e 74 2c 20  har*, int, int, 
9af0: 69 6e 74 29 0a 29 7b 0a 20 20 46 74 73 35 43 75  int).){.  Fts5Cu
9b00: 72 73 6f 72 20 2a 70 43 73 72 20 3d 20 28 46 74  rsor *pCsr = (Ft
9b10: 73 35 43 75 72 73 6f 72 2a 29 70 43 74 78 3b 0a  s5Cursor*)pCtx;.
9b20: 20 20 46 74 73 35 54 61 62 6c 65 20 2a 70 54 61    Fts5Table *pTa
9b30: 62 20 3d 20 28 46 74 73 35 54 61 62 6c 65 2a 29  b = (Fts5Table*)
9b40: 28 70 43 73 72 2d 3e 62 61 73 65 2e 70 56 74 61  (pCsr->base.pVta
9b50: 62 29 3b 0a 20 20 72 65 74 75 72 6e 20 73 71 6c  b);.  return sql
9b60: 69 74 65 33 46 74 73 35 54 6f 6b 65 6e 69 7a 65  ite3Fts5Tokenize
9b70: 28 70 54 61 62 2d 3e 70 43 6f 6e 66 69 67 2c 20  (pTab->pConfig, 
9b80: 70 54 65 78 74 2c 20 6e 54 65 78 74 2c 20 70 55  pText, nText, pU
9b90: 73 65 72 44 61 74 61 2c 20 78 54 6f 6b 65 6e 29  serData, xToken)
9ba0: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  ;.}..static int 
9bb0: 66 74 73 35 41 70 69 50 68 72 61 73 65 43 6f 75  fts5ApiPhraseCou
9bc0: 6e 74 28 46 74 73 35 43 6f 6e 74 65 78 74 20 2a  nt(Fts5Context *
9bd0: 70 43 74 78 29 7b 0a 20 20 46 74 73 35 43 75 72  pCtx){.  Fts5Cur
9be0: 73 6f 72 20 2a 70 43 73 72 20 3d 20 28 46 74 73  sor *pCsr = (Fts
9bf0: 35 43 75 72 73 6f 72 2a 29 70 43 74 78 3b 0a 20  5Cursor*)pCtx;. 
9c00: 20 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33 46   return sqlite3F
9c10: 74 73 35 45 78 70 72 50 68 72 61 73 65 43 6f 75  ts5ExprPhraseCou
9c20: 6e 74 28 70 43 73 72 2d 3e 70 45 78 70 72 29 3b  nt(pCsr->pExpr);
9c30: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 66  .}..static int f
9c40: 74 73 35 41 70 69 50 68 72 61 73 65 53 69 7a 65  ts5ApiPhraseSize
9c50: 28 46 74 73 35 43 6f 6e 74 65 78 74 20 2a 70 43  (Fts5Context *pC
9c60: 74 78 2c 20 69 6e 74 20 69 50 68 72 61 73 65 29  tx, int iPhrase)
9c70: 7b 0a 20 20 46 74 73 35 43 75 72 73 6f 72 20 2a  {.  Fts5Cursor *
9c80: 70 43 73 72 20 3d 20 28 46 74 73 35 43 75 72 73  pCsr = (Fts5Curs
9c90: 6f 72 2a 29 70 43 74 78 3b 0a 20 20 72 65 74 75  or*)pCtx;.  retu
9ca0: 72 6e 20 73 71 6c 69 74 65 33 46 74 73 35 45 78  rn sqlite3Fts5Ex
9cb0: 70 72 50 68 72 61 73 65 53 69 7a 65 28 70 43 73  prPhraseSize(pCs
9cc0: 72 2d 3e 70 45 78 70 72 2c 20 69 50 68 72 61 73  r->pExpr, iPhras
9cd0: 65 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  e);.}..static in
9ce0: 74 20 66 74 73 35 43 73 72 50 6f 73 6c 69 73 74  t fts5CsrPoslist
9cf0: 28 46 74 73 35 43 75 72 73 6f 72 20 2a 70 43 73  (Fts5Cursor *pCs
9d00: 72 2c 20 69 6e 74 20 69 50 68 72 61 73 65 2c 20  r, int iPhrase, 
9d10: 63 6f 6e 73 74 20 75 38 20 2a 2a 70 61 29 7b 0a  const u8 **pa){.
9d20: 20 20 69 6e 74 20 6e 3b 0a 20 20 69 66 28 20 70    int n;.  if( p
9d30: 43 73 72 2d 3e 70 53 6f 72 74 65 72 20 29 7b 0a  Csr->pSorter ){.
9d40: 20 20 20 20 46 74 73 35 53 6f 72 74 65 72 20 2a      Fts5Sorter *
9d50: 70 53 6f 72 74 65 72 20 3d 20 70 43 73 72 2d 3e  pSorter = pCsr->
9d60: 70 53 6f 72 74 65 72 3b 0a 20 20 20 20 69 6e 74  pSorter;.    int
9d70: 20 69 31 20 3d 20 28 69 50 68 72 61 73 65 3d 3d   i1 = (iPhrase==
9d80: 30 20 3f 20 30 20 3a 20 70 53 6f 72 74 65 72 2d  0 ? 0 : pSorter-
9d90: 3e 61 49 64 78 5b 69 50 68 72 61 73 65 2d 31 5d  >aIdx[iPhrase-1]
9da0: 29 3b 0a 20 20 20 20 6e 20 3d 20 70 53 6f 72 74  );.    n = pSort
9db0: 65 72 2d 3e 61 49 64 78 5b 69 50 68 72 61 73 65  er->aIdx[iPhrase
9dc0: 5d 20 2d 20 69 31 3b 0a 20 20 20 20 2a 70 61 20  ] - i1;.    *pa 
9dd0: 3d 20 26 70 53 6f 72 74 65 72 2d 3e 61 50 6f 73  = &pSorter->aPos
9de0: 6c 69 73 74 5b 69 31 5d 3b 0a 20 20 7d 65 6c 73  list[i1];.  }els
9df0: 65 7b 0a 20 20 20 20 6e 20 3d 20 73 71 6c 69 74  e{.    n = sqlit
9e00: 65 33 46 74 73 35 45 78 70 72 50 6f 73 6c 69 73  e3Fts5ExprPoslis
9e10: 74 28 70 43 73 72 2d 3e 70 45 78 70 72 2c 20 69  t(pCsr->pExpr, i
9e20: 50 68 72 61 73 65 2c 20 70 61 29 3b 0a 20 20 7d  Phrase, pa);.  }
9e30: 0a 20 20 72 65 74 75 72 6e 20 6e 3b 0a 7d 0a 0a  .  return n;.}..
9e40: 2f 2a 0a 2a 2a 20 45 6e 73 75 72 65 20 74 68 61  /*.** Ensure tha
9e50: 74 20 74 68 65 20 46 74 73 35 43 75 72 73 6f 72  t the Fts5Cursor
9e60: 2e 6e 49 6e 73 74 43 6f 75 6e 74 20 61 6e 64 20  .nInstCount and 
9e70: 61 49 6e 73 74 5b 5d 20 76 61 72 69 61 62 6c 65  aInst[] variable
9e80: 73 20 61 72 65 20 70 6f 70 75 6c 61 74 65 64 0a  s are populated.
9e90: 2a 2a 20 63 6f 72 72 65 63 74 6c 79 20 66 6f 72  ** correctly for
9ea0: 20 74 68 65 20 63 75 72 72 65 6e 74 20 76 69 65   the current vie
9eb0: 77 2e 20 52 65 74 75 72 6e 20 53 51 4c 49 54 45  w. Return SQLITE
9ec0: 5f 4f 4b 20 69 66 20 73 75 63 63 65 73 73 66 75  _OK if successfu
9ed0: 6c 2c 20 6f 72 20 61 6e 0a 2a 2a 20 53 51 4c 69  l, or an.** SQLi
9ee0: 74 65 20 65 72 72 6f 72 20 63 6f 64 65 20 6f 74  te error code ot
9ef0: 68 65 72 77 69 73 65 2e 0a 2a 2f 0a 73 74 61 74  herwise..*/.stat
9f00: 69 63 20 69 6e 74 20 66 74 73 35 43 61 63 68 65  ic int fts5Cache
9f10: 49 6e 73 74 41 72 72 61 79 28 46 74 73 35 43 75  InstArray(Fts5Cu
9f20: 72 73 6f 72 20 2a 70 43 73 72 29 7b 0a 20 20 69  rsor *pCsr){.  i
9f30: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
9f40: 4b 3b 0a 20 20 69 66 28 20 70 43 73 72 2d 3e 61  K;.  if( pCsr->a
9f50: 49 6e 73 74 3d 3d 30 20 29 7b 0a 20 20 20 20 46  Inst==0 ){.    F
9f60: 74 73 35 50 6f 73 6c 69 73 74 52 65 61 64 65 72  ts5PoslistReader
9f70: 20 2a 61 49 74 65 72 3b 20 20 20 20 20 2f 2a 20   *aIter;     /* 
9f80: 4f 6e 65 20 69 74 65 72 61 74 6f 72 20 66 6f 72  One iterator for
9f90: 20 65 61 63 68 20 70 68 72 61 73 65 20 2a 2f 0a   each phrase */.
9fa0: 20 20 20 20 69 6e 74 20 6e 49 74 65 72 3b 20 20      int nIter;  
9fb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9fc0: 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 69    /* Number of i
9fd0: 74 65 72 61 74 6f 72 73 2f 70 68 72 61 73 65 73  terators/phrases
9fe0: 20 2a 2f 0a 20 20 20 20 69 6e 74 20 6e 42 79 74   */.    int nByt
9ff0: 65 3b 0a 20 20 20 20 0a 20 20 20 20 6e 49 74 65  e;.    .    nIte
a000: 72 20 3d 20 73 71 6c 69 74 65 33 46 74 73 35 45  r = sqlite3Fts5E
a010: 78 70 72 50 68 72 61 73 65 43 6f 75 6e 74 28 70  xprPhraseCount(p
a020: 43 73 72 2d 3e 70 45 78 70 72 29 3b 0a 20 20 20  Csr->pExpr);.   
a030: 20 6e 42 79 74 65 20 3d 20 73 69 7a 65 6f 66 28   nByte = sizeof(
a040: 46 74 73 35 50 6f 73 6c 69 73 74 52 65 61 64 65  Fts5PoslistReade
a050: 72 29 20 2a 20 6e 49 74 65 72 3b 0a 20 20 20 20  r) * nIter;.    
a060: 61 49 74 65 72 20 3d 20 28 46 74 73 35 50 6f 73  aIter = (Fts5Pos
a070: 6c 69 73 74 52 65 61 64 65 72 2a 29 73 71 6c 69  listReader*)sqli
a080: 74 65 33 46 74 73 35 4d 61 6c 6c 6f 63 5a 65 72  te3Fts5MallocZer
a090: 6f 28 26 72 63 2c 20 6e 42 79 74 65 29 3b 0a 20  o(&rc, nByte);. 
a0a0: 20 20 20 69 66 28 20 61 49 74 65 72 20 29 7b 0a     if( aIter ){.
a0b0: 20 20 20 20 20 20 46 74 73 35 42 75 66 66 65 72        Fts5Buffer
a0c0: 20 62 75 66 20 3d 20 7b 30 2c 20 30 2c 20 30 7d   buf = {0, 0, 0}
a0d0: 3b 20 2f 2a 20 42 75 69 6c 64 20 75 70 20 61 49  ; /* Build up aI
a0e0: 6e 73 74 5b 5d 20 68 65 72 65 20 2a 2f 0a 20 20  nst[] here */.  
a0f0: 20 20 20 20 69 6e 74 20 6e 49 6e 73 74 20 3d 20      int nInst = 
a100: 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0;              
a110: 2f 2a 20 4e 75 6d 62 65 72 20 69 6e 73 74 61 6e  /* Number instan
a120: 63 65 73 20 73 65 65 6e 20 73 6f 20 66 61 72 20  ces seen so far 
a130: 2a 2f 0a 20 20 20 20 20 20 69 6e 74 20 69 3b 0a  */.      int i;.
a140: 0a 20 20 20 20 20 20 2f 2a 20 49 6e 69 74 69 61  .      /* Initia
a150: 6c 69 7a 65 20 61 6c 6c 20 69 74 65 72 61 74 6f  lize all iterato
a160: 72 73 20 2a 2f 0a 20 20 20 20 20 20 66 6f 72 28  rs */.      for(
a170: 69 3d 30 3b 20 69 3c 6e 49 74 65 72 3b 20 69 2b  i=0; i<nIter; i+
a180: 2b 29 7b 0a 20 20 20 20 20 20 20 20 63 6f 6e 73  +){.        cons
a190: 74 20 75 38 20 2a 61 3b 0a 20 20 20 20 20 20 20  t u8 *a;.       
a1a0: 20 69 6e 74 20 6e 20 3d 20 66 74 73 35 43 73 72   int n = fts5Csr
a1b0: 50 6f 73 6c 69 73 74 28 70 43 73 72 2c 20 69 2c  Poslist(pCsr, i,
a1c0: 20 26 61 29 3b 0a 20 20 20 20 20 20 20 20 73 71   &a);.        sq
a1d0: 6c 69 74 65 33 46 74 73 35 50 6f 73 6c 69 73 74  lite3Fts5Poslist
a1e0: 52 65 61 64 65 72 49 6e 69 74 28 2d 31 2c 20 61  ReaderInit(-1, a
a1f0: 2c 20 6e 2c 20 26 61 49 74 65 72 5b 69 5d 29 3b  , n, &aIter[i]);
a200: 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20  .      }..      
a210: 77 68 69 6c 65 28 20 31 20 29 7b 0a 20 20 20 20  while( 1 ){.    
a220: 20 20 20 20 69 6e 74 20 2a 61 49 6e 73 74 3b 0a      int *aInst;.
a230: 20 20 20 20 20 20 20 20 69 6e 74 20 69 42 65 73          int iBes
a240: 74 20 3d 20 2d 31 3b 0a 20 20 20 20 20 20 20 20  t = -1;.        
a250: 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 49 74 65 72  for(i=0; i<nIter
a260: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20  ; i++){.        
a270: 20 20 69 66 28 20 28 61 49 74 65 72 5b 69 5d 2e    if( (aIter[i].
a280: 62 45 6f 66 3d 3d 30 29 20 0a 20 20 20 20 20 20  bEof==0) .      
a290: 20 20 20 20 20 26 26 20 28 69 42 65 73 74 3c 30       && (iBest<0
a2a0: 20 7c 7c 20 61 49 74 65 72 5b 69 5d 2e 69 50 6f   || aIter[i].iPo
a2b0: 73 3c 61 49 74 65 72 5b 69 42 65 73 74 5d 2e 69  s<aIter[iBest].i
a2c0: 50 6f 73 29 20 0a 20 20 20 20 20 20 20 20 20 20  Pos) .          
a2d0: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 69  ){.            i
a2e0: 42 65 73 74 20 3d 20 69 3b 0a 20 20 20 20 20 20  Best = i;.      
a2f0: 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 7d 0a      }.        }.
a300: 0a 20 20 20 20 20 20 20 20 69 66 28 20 69 42 65  .        if( iBe
a310: 73 74 3c 30 20 29 20 62 72 65 61 6b 3b 0a 20 20  st<0 ) break;.  
a320: 20 20 20 20 20 20 6e 49 6e 73 74 2b 2b 3b 0a 20        nInst++;. 
a330: 20 20 20 20 20 20 20 69 66 28 20 73 71 6c 69 74         if( sqlit
a340: 65 33 46 74 73 35 42 75 66 66 65 72 47 72 6f 77  e3Fts5BufferGrow
a350: 28 26 72 63 2c 20 26 62 75 66 2c 20 6e 49 6e 73  (&rc, &buf, nIns
a360: 74 20 2a 20 73 69 7a 65 6f 66 28 69 6e 74 29 20  t * sizeof(int) 
a370: 2a 20 33 29 20 29 20 62 72 65 61 6b 3b 0a 0a 20  * 3) ) break;.. 
a380: 20 20 20 20 20 20 20 61 49 6e 73 74 20 3d 20 26         aInst = &
a390: 28 28 69 6e 74 2a 29 62 75 66 2e 70 29 5b 33 20  ((int*)buf.p)[3 
a3a0: 2a 20 28 6e 49 6e 73 74 2d 31 29 5d 3b 0a 20 20  * (nInst-1)];.  
a3b0: 20 20 20 20 20 20 61 49 6e 73 74 5b 30 5d 20 3d        aInst[0] =
a3c0: 20 69 42 65 73 74 3b 0a 20 20 20 20 20 20 20 20   iBest;.        
a3d0: 61 49 6e 73 74 5b 31 5d 20 3d 20 46 54 53 35 5f  aInst[1] = FTS5_
a3e0: 50 4f 53 32 43 4f 4c 55 4d 4e 28 61 49 74 65 72  POS2COLUMN(aIter
a3f0: 5b 69 42 65 73 74 5d 2e 69 50 6f 73 29 3b 0a 20  [iBest].iPos);. 
a400: 20 20 20 20 20 20 20 61 49 6e 73 74 5b 32 5d 20         aInst[2] 
a410: 3d 20 46 54 53 35 5f 50 4f 53 32 4f 46 46 53 45  = FTS5_POS2OFFSE
a420: 54 28 61 49 74 65 72 5b 69 42 65 73 74 5d 2e 69  T(aIter[iBest].i
a430: 50 6f 73 29 3b 0a 20 20 20 20 20 20 20 20 73 71  Pos);.        sq
a440: 6c 69 74 65 33 46 74 73 35 50 6f 73 6c 69 73 74  lite3Fts5Poslist
a450: 52 65 61 64 65 72 4e 65 78 74 28 26 61 49 74 65  ReaderNext(&aIte
a460: 72 5b 69 42 65 73 74 5d 29 3b 0a 20 20 20 20 20  r[iBest]);.     
a470: 20 7d 0a 0a 20 20 20 20 20 20 70 43 73 72 2d 3e   }..      pCsr->
a480: 61 49 6e 73 74 20 3d 20 28 69 6e 74 2a 29 62 75  aInst = (int*)bu
a490: 66 2e 70 3b 0a 20 20 20 20 20 20 70 43 73 72 2d  f.p;.      pCsr-
a4a0: 3e 6e 49 6e 73 74 43 6f 75 6e 74 20 3d 20 6e 49  >nInstCount = nI
a4b0: 6e 73 74 3b 0a 20 20 20 20 20 20 73 71 6c 69 74  nst;.      sqlit
a4c0: 65 33 5f 66 72 65 65 28 61 49 74 65 72 29 3b 0a  e3_free(aIter);.
a4d0: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75      }.  }.  retu
a4e0: 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63  rn rc;.}..static
a4f0: 20 69 6e 74 20 66 74 73 35 41 70 69 49 6e 73 74   int fts5ApiInst
a500: 43 6f 75 6e 74 28 46 74 73 35 43 6f 6e 74 65 78  Count(Fts5Contex
a510: 74 20 2a 70 43 74 78 2c 20 69 6e 74 20 2a 70 6e  t *pCtx, int *pn
a520: 49 6e 73 74 29 7b 0a 20 20 46 74 73 35 43 75 72  Inst){.  Fts5Cur
a530: 73 6f 72 20 2a 70 43 73 72 20 3d 20 28 46 74 73  sor *pCsr = (Fts
a540: 35 43 75 72 73 6f 72 2a 29 70 43 74 78 3b 0a 20  5Cursor*)pCtx;. 
a550: 20 69 6e 74 20 72 63 3b 0a 20 20 69 66 28 20 53   int rc;.  if( S
a560: 51 4c 49 54 45 5f 4f 4b 3d 3d 28 72 63 20 3d 20  QLITE_OK==(rc = 
a570: 66 74 73 35 43 61 63 68 65 49 6e 73 74 41 72 72  fts5CacheInstArr
a580: 61 79 28 70 43 73 72 29 29 20 29 7b 0a 20 20 20  ay(pCsr)) ){.   
a590: 20 2a 70 6e 49 6e 73 74 20 3d 20 70 43 73 72 2d   *pnInst = pCsr-
a5a0: 3e 6e 49 6e 73 74 43 6f 75 6e 74 3b 0a 20 20 7d  >nInstCount;.  }
a5b0: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
a5c0: 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35  .static int fts5
a5d0: 41 70 69 49 6e 73 74 28 0a 20 20 46 74 73 35 43  ApiInst(.  Fts5C
a5e0: 6f 6e 74 65 78 74 20 2a 70 43 74 78 2c 20 0a 20  ontext *pCtx, . 
a5f0: 20 69 6e 74 20 69 49 64 78 2c 20 0a 20 20 69 6e   int iIdx, .  in
a600: 74 20 2a 70 69 50 68 72 61 73 65 2c 20 0a 20 20  t *piPhrase, .  
a610: 69 6e 74 20 2a 70 69 43 6f 6c 2c 20 0a 20 20 69  int *piCol, .  i
a620: 6e 74 20 2a 70 69 4f 66 66 0a 29 7b 0a 20 20 46  nt *piOff.){.  F
a630: 74 73 35 43 75 72 73 6f 72 20 2a 70 43 73 72 20  ts5Cursor *pCsr 
a640: 3d 20 28 46 74 73 35 43 75 72 73 6f 72 2a 29 70  = (Fts5Cursor*)p
a650: 43 74 78 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 20  Ctx;.  int rc;. 
a660: 20 69 66 28 20 53 51 4c 49 54 45 5f 4f 4b 3d 3d   if( SQLITE_OK==
a670: 28 72 63 20 3d 20 66 74 73 35 43 61 63 68 65 49  (rc = fts5CacheI
a680: 6e 73 74 41 72 72 61 79 28 70 43 73 72 29 29 20  nstArray(pCsr)) 
a690: 29 7b 0a 20 20 20 20 69 66 28 20 69 49 64 78 3c  ){.    if( iIdx<
a6a0: 30 20 7c 7c 20 69 49 64 78 3e 3d 70 43 73 72 2d  0 || iIdx>=pCsr-
a6b0: 3e 6e 49 6e 73 74 43 6f 75 6e 74 20 29 7b 0a 20  >nInstCount ){. 
a6c0: 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45       rc = SQLITE
a6d0: 5f 52 41 4e 47 45 3b 0a 20 20 20 20 7d 65 6c 73  _RANGE;.    }els
a6e0: 65 7b 0a 20 20 20 20 20 20 2a 70 69 50 68 72 61  e{.      *piPhra
a6f0: 73 65 20 3d 20 70 43 73 72 2d 3e 61 49 6e 73 74  se = pCsr->aInst
a700: 5b 69 49 64 78 2a 33 5d 3b 0a 20 20 20 20 20 20  [iIdx*3];.      
a710: 2a 70 69 43 6f 6c 20 3d 20 70 43 73 72 2d 3e 61  *piCol = pCsr->a
a720: 49 6e 73 74 5b 69 49 64 78 2a 33 20 2b 20 31 5d  Inst[iIdx*3 + 1]
a730: 3b 0a 20 20 20 20 20 20 2a 70 69 4f 66 66 20 3d  ;.      *piOff =
a740: 20 70 43 73 72 2d 3e 61 49 6e 73 74 5b 69 49 64   pCsr->aInst[iId
a750: 78 2a 33 20 2b 20 32 5d 3b 0a 20 20 20 20 7d 0a  x*3 + 2];.    }.
a760: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b    }.  return rc;
a770: 0a 7d 0a 0a 73 74 61 74 69 63 20 73 71 6c 69 74  .}..static sqlit
a780: 65 33 5f 69 6e 74 36 34 20 66 74 73 35 41 70 69  e3_int64 fts5Api
a790: 52 6f 77 69 64 28 46 74 73 35 43 6f 6e 74 65 78  Rowid(Fts5Contex
a7a0: 74 20 2a 70 43 74 78 29 7b 0a 20 20 72 65 74 75  t *pCtx){.  retu
a7b0: 72 6e 20 66 74 73 35 43 75 72 73 6f 72 52 6f 77  rn fts5CursorRow
a7c0: 69 64 28 28 46 74 73 35 43 75 72 73 6f 72 2a 29  id((Fts5Cursor*)
a7d0: 70 43 74 78 29 3b 0a 7d 0a 0a 73 74 61 74 69 63  pCtx);.}..static
a7e0: 20 69 6e 74 20 66 74 73 35 41 70 69 43 6f 6c 75   int fts5ApiColu
a7f0: 6d 6e 54 65 78 74 28 0a 20 20 46 74 73 35 43 6f  mnText(.  Fts5Co
a800: 6e 74 65 78 74 20 2a 70 43 74 78 2c 20 0a 20 20  ntext *pCtx, .  
a810: 69 6e 74 20 69 43 6f 6c 2c 20 0a 20 20 63 6f 6e  int iCol, .  con
a820: 73 74 20 63 68 61 72 20 2a 2a 70 7a 2c 20 0a 20  st char **pz, . 
a830: 20 69 6e 74 20 2a 70 6e 0a 29 7b 0a 20 20 69 6e   int *pn.){.  in
a840: 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b  t rc = SQLITE_OK
a850: 3b 0a 20 20 46 74 73 35 43 75 72 73 6f 72 20 2a  ;.  Fts5Cursor *
a860: 70 43 73 72 20 3d 20 28 46 74 73 35 43 75 72 73  pCsr = (Fts5Curs
a870: 6f 72 2a 29 70 43 74 78 3b 0a 20 20 69 66 28 20  or*)pCtx;.  if( 
a880: 66 74 73 35 49 73 43 6f 6e 74 65 6e 74 6c 65 73  fts5IsContentles
a890: 73 28 28 46 74 73 35 54 61 62 6c 65 2a 29 28 70  s((Fts5Table*)(p
a8a0: 43 73 72 2d 3e 62 61 73 65 2e 70 56 74 61 62 29  Csr->base.pVtab)
a8b0: 29 20 29 7b 0a 20 20 20 20 2a 70 7a 20 3d 20 30  ) ){.    *pz = 0
a8c0: 3b 0a 20 20 20 20 2a 70 6e 20 3d 20 30 3b 0a 20  ;.    *pn = 0;. 
a8d0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 72 63 20 3d   }else{.    rc =
a8e0: 20 66 74 73 35 53 65 65 6b 43 75 72 73 6f 72 28   fts5SeekCursor(
a8f0: 70 43 73 72 29 3b 0a 20 20 20 20 69 66 28 20 72  pCsr);.    if( r
a900: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
a910: 20 20 20 20 20 20 2a 70 7a 20 3d 20 28 63 6f 6e        *pz = (con
a920: 73 74 20 63 68 61 72 2a 29 73 71 6c 69 74 65 33  st char*)sqlite3
a930: 5f 63 6f 6c 75 6d 6e 5f 74 65 78 74 28 70 43 73  _column_text(pCs
a940: 72 2d 3e 70 53 74 6d 74 2c 20 69 43 6f 6c 2b 31  r->pStmt, iCol+1
a950: 29 3b 0a 20 20 20 20 20 20 2a 70 6e 20 3d 20 73  );.      *pn = s
a960: 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 62 79  qlite3_column_by
a970: 74 65 73 28 70 43 73 72 2d 3e 70 53 74 6d 74 2c  tes(pCsr->pStmt,
a980: 20 69 43 6f 6c 2b 31 29 3b 0a 20 20 20 20 7d 0a   iCol+1);.    }.
a990: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b    }.  return rc;
a9a0: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 66  .}..static int f
a9b0: 74 73 35 41 70 69 43 6f 6c 75 6d 6e 53 69 7a 65  ts5ApiColumnSize
a9c0: 28 46 74 73 35 43 6f 6e 74 65 78 74 20 2a 70 43  (Fts5Context *pC
a9d0: 74 78 2c 20 69 6e 74 20 69 43 6f 6c 2c 20 69 6e  tx, int iCol, in
a9e0: 74 20 2a 70 6e 54 6f 6b 65 6e 29 7b 0a 20 20 46  t *pnToken){.  F
a9f0: 74 73 35 43 75 72 73 6f 72 20 2a 70 43 73 72 20  ts5Cursor *pCsr 
aa00: 3d 20 28 46 74 73 35 43 75 72 73 6f 72 2a 29 70  = (Fts5Cursor*)p
aa10: 43 74 78 3b 0a 20 20 46 74 73 35 54 61 62 6c 65  Ctx;.  Fts5Table
aa20: 20 2a 70 54 61 62 20 3d 20 28 46 74 73 35 54 61   *pTab = (Fts5Ta
aa30: 62 6c 65 2a 29 28 70 43 73 72 2d 3e 62 61 73 65  ble*)(pCsr->base
aa40: 2e 70 56 74 61 62 29 3b 0a 20 20 69 6e 74 20 72  .pVtab);.  int r
aa50: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 0a  c = SQLITE_OK;..
aa60: 20 20 69 66 28 20 43 73 72 46 6c 61 67 54 65 73    if( CsrFlagTes
aa70: 74 28 70 43 73 72 2c 20 46 54 53 35 43 53 52 5f  t(pCsr, FTS5CSR_
aa80: 52 45 51 55 49 52 45 5f 44 4f 43 53 49 5a 45 29  REQUIRE_DOCSIZE)
aa90: 20 29 7b 0a 20 20 20 20 69 36 34 20 69 52 6f 77   ){.    i64 iRow
aaa0: 69 64 20 3d 20 66 74 73 35 43 75 72 73 6f 72 52  id = fts5CursorR
aab0: 6f 77 69 64 28 70 43 73 72 29 3b 0a 20 20 20 20  owid(pCsr);.    
aac0: 72 63 20 3d 20 73 71 6c 69 74 65 33 46 74 73 35  rc = sqlite3Fts5
aad0: 53 74 6f 72 61 67 65 44 6f 63 73 69 7a 65 28 70  StorageDocsize(p
aae0: 54 61 62 2d 3e 70 53 74 6f 72 61 67 65 2c 20 69  Tab->pStorage, i
aaf0: 52 6f 77 69 64 2c 20 70 43 73 72 2d 3e 61 43 6f  Rowid, pCsr->aCo
ab00: 6c 75 6d 6e 53 69 7a 65 29 3b 0a 20 20 7d 0a 20  lumnSize);.  }. 
ab10: 20 69 66 28 20 69 43 6f 6c 3c 30 20 29 7b 0a 20   if( iCol<0 ){. 
ab20: 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20 2a 70     int i;.    *p
ab30: 6e 54 6f 6b 65 6e 20 3d 20 30 3b 0a 20 20 20 20  nToken = 0;.    
ab40: 66 6f 72 28 69 3d 30 3b 20 69 3c 70 54 61 62 2d  for(i=0; i<pTab-
ab50: 3e 70 43 6f 6e 66 69 67 2d 3e 6e 43 6f 6c 3b 20  >pConfig->nCol; 
ab60: 69 2b 2b 29 7b 0a 20 20 20 20 20 20 2a 70 6e 54  i++){.      *pnT
ab70: 6f 6b 65 6e 20 2b 3d 20 70 43 73 72 2d 3e 61 43  oken += pCsr->aC
ab80: 6f 6c 75 6d 6e 53 69 7a 65 5b 69 5d 3b 0a 20 20  olumnSize[i];.  
ab90: 20 20 7d 0a 20 20 7d 65 6c 73 65 20 69 66 28 20    }.  }else if( 
aba0: 69 43 6f 6c 3c 70 54 61 62 2d 3e 70 43 6f 6e 66  iCol<pTab->pConf
abb0: 69 67 2d 3e 6e 43 6f 6c 20 29 7b 0a 20 20 20 20  ig->nCol ){.    
abc0: 2a 70 6e 54 6f 6b 65 6e 20 3d 20 70 43 73 72 2d  *pnToken = pCsr-
abd0: 3e 61 43 6f 6c 75 6d 6e 53 69 7a 65 5b 69 43 6f  >aColumnSize[iCo
abe0: 6c 5d 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  l];.  }else{.   
abf0: 20 2a 70 6e 54 6f 6b 65 6e 20 3d 20 30 3b 0a 20   *pnToken = 0;. 
ac00: 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 52     rc = SQLITE_R
ac10: 41 4e 47 45 3b 0a 20 20 7d 0a 20 20 72 65 74 75  ANGE;.  }.  retu
ac20: 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63  rn rc;.}..static
ac30: 20 69 6e 74 20 66 74 73 35 41 70 69 53 65 74 41   int fts5ApiSetA
ac40: 75 78 64 61 74 61 28 0a 20 20 46 74 73 35 43 6f  uxdata(.  Fts5Co
ac50: 6e 74 65 78 74 20 2a 70 43 74 78 2c 20 20 20 20  ntext *pCtx,    
ac60: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 74 73            /* Fts
ac70: 35 20 63 6f 6e 74 65 78 74 20 2a 2f 0a 20 20 76  5 context */.  v
ac80: 6f 69 64 20 2a 70 50 74 72 2c 20 20 20 20 20 20  oid *pPtr,      
ac90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
aca0: 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 73 61 76  * Pointer to sav
acb0: 65 20 61 73 20 61 75 78 64 61 74 61 20 2a 2f 0a  e as auxdata */.
acc0: 20 20 76 6f 69 64 28 2a 78 44 65 6c 65 74 65 29    void(*xDelete)
acd0: 28 76 6f 69 64 2a 29 20 20 20 20 20 20 20 20 20  (void*)         
ace0: 20 20 2f 2a 20 44 65 73 74 72 75 63 74 6f 72 20    /* Destructor 
acf0: 66 6f 72 20 70 50 74 72 20 28 6f 72 20 4e 55 4c  for pPtr (or NUL
ad00: 4c 29 20 2a 2f 0a 29 7b 0a 20 20 46 74 73 35 43  L) */.){.  Fts5C
ad10: 75 72 73 6f 72 20 2a 70 43 73 72 20 3d 20 28 46  ursor *pCsr = (F
ad20: 74 73 35 43 75 72 73 6f 72 2a 29 70 43 74 78 3b  ts5Cursor*)pCtx;
ad30: 0a 20 20 46 74 73 35 41 75 78 64 61 74 61 20 2a  .  Fts5Auxdata *
ad40: 70 44 61 74 61 3b 0a 0a 20 20 66 6f 72 28 70 44  pData;..  for(pD
ad50: 61 74 61 3d 70 43 73 72 2d 3e 70 41 75 78 64 61  ata=pCsr->pAuxda
ad60: 74 61 3b 20 70 44 61 74 61 3b 20 70 44 61 74 61  ta; pData; pData
ad70: 3d 70 44 61 74 61 2d 3e 70 4e 65 78 74 29 7b 0a  =pData->pNext){.
ad80: 20 20 20 20 69 66 28 20 70 44 61 74 61 2d 3e 70      if( pData->p
ad90: 41 75 78 3d 3d 70 43 73 72 2d 3e 70 41 75 78 20  Aux==pCsr->pAux 
ada0: 29 20 62 72 65 61 6b 3b 0a 20 20 7d 0a 0a 20 20  ) break;.  }..  
adb0: 69 66 28 20 70 44 61 74 61 20 29 7b 0a 20 20 20  if( pData ){.   
adc0: 20 69 66 28 20 70 44 61 74 61 2d 3e 78 44 65 6c   if( pData->xDel
add0: 65 74 65 20 29 7b 0a 20 20 20 20 20 20 70 44 61  ete ){.      pDa
ade0: 74 61 2d 3e 78 44 65 6c 65 74 65 28 70 44 61 74  ta->xDelete(pDat
adf0: 61 2d 3e 70 50 74 72 29 3b 0a 20 20 20 20 7d 0a  a->pPtr);.    }.
ae00: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 70 44 61    }else{.    pDa
ae10: 74 61 20 3d 20 28 46 74 73 35 41 75 78 64 61 74  ta = (Fts5Auxdat
ae20: 61 2a 29 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f  a*)sqlite3_mallo
ae30: 63 28 73 69 7a 65 6f 66 28 46 74 73 35 41 75 78  c(sizeof(Fts5Aux
ae40: 64 61 74 61 29 29 3b 0a 20 20 20 20 69 66 28 20  data));.    if( 
ae50: 70 44 61 74 61 3d 3d 30 20 29 7b 0a 20 20 20 20  pData==0 ){.    
ae60: 20 20 69 66 28 20 78 44 65 6c 65 74 65 20 29 20    if( xDelete ) 
ae70: 78 44 65 6c 65 74 65 28 70 50 74 72 29 3b 0a 20  xDelete(pPtr);. 
ae80: 20 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49       return SQLI
ae90: 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d 0a  TE_NOMEM;.    }.
aea0: 20 20 20 20 6d 65 6d 73 65 74 28 70 44 61 74 61      memset(pData
aeb0: 2c 20 30 2c 20 73 69 7a 65 6f 66 28 46 74 73 35  , 0, sizeof(Fts5
aec0: 41 75 78 64 61 74 61 29 29 3b 0a 20 20 20 20 70  Auxdata));.    p
aed0: 44 61 74 61 2d 3e 70 41 75 78 20 3d 20 70 43 73  Data->pAux = pCs
aee0: 72 2d 3e 70 41 75 78 3b 0a 20 20 20 20 70 44 61  r->pAux;.    pDa
aef0: 74 61 2d 3e 70 4e 65 78 74 20 3d 20 70 43 73 72  ta->pNext = pCsr
af00: 2d 3e 70 41 75 78 64 61 74 61 3b 0a 20 20 20 20  ->pAuxdata;.    
af10: 70 43 73 72 2d 3e 70 41 75 78 64 61 74 61 20 3d  pCsr->pAuxdata =
af20: 20 70 44 61 74 61 3b 0a 20 20 7d 0a 0a 20 20 70   pData;.  }..  p
af30: 44 61 74 61 2d 3e 78 44 65 6c 65 74 65 20 3d 20  Data->xDelete = 
af40: 78 44 65 6c 65 74 65 3b 0a 20 20 70 44 61 74 61  xDelete;.  pData
af50: 2d 3e 70 50 74 72 20 3d 20 70 50 74 72 3b 0a 20  ->pPtr = pPtr;. 
af60: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
af70: 4b 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69  K;.}..static voi
af80: 64 20 2a 66 74 73 35 41 70 69 47 65 74 41 75 78  d *fts5ApiGetAux
af90: 64 61 74 61 28 46 74 73 35 43 6f 6e 74 65 78 74  data(Fts5Context
afa0: 20 2a 70 43 74 78 2c 20 69 6e 74 20 62 43 6c 65   *pCtx, int bCle
afb0: 61 72 29 7b 0a 20 20 46 74 73 35 43 75 72 73 6f  ar){.  Fts5Curso
afc0: 72 20 2a 70 43 73 72 20 3d 20 28 46 74 73 35 43  r *pCsr = (Fts5C
afd0: 75 72 73 6f 72 2a 29 70 43 74 78 3b 0a 20 20 46  ursor*)pCtx;.  F
afe0: 74 73 35 41 75 78 64 61 74 61 20 2a 70 44 61 74  ts5Auxdata *pDat
aff0: 61 3b 0a 20 20 76 6f 69 64 20 2a 70 52 65 74 20  a;.  void *pRet 
b000: 3d 20 30 3b 0a 0a 20 20 66 6f 72 28 70 44 61 74  = 0;..  for(pDat
b010: 61 3d 70 43 73 72 2d 3e 70 41 75 78 64 61 74 61  a=pCsr->pAuxdata
b020: 3b 20 70 44 61 74 61 3b 20 70 44 61 74 61 3d 70  ; pData; pData=p
b030: 44 61 74 61 2d 3e 70 4e 65 78 74 29 7b 0a 20 20  Data->pNext){.  
b040: 20 20 69 66 28 20 70 44 61 74 61 2d 3e 70 41 75    if( pData->pAu
b050: 78 3d 3d 70 43 73 72 2d 3e 70 41 75 78 20 29 20  x==pCsr->pAux ) 
b060: 62 72 65 61 6b 3b 0a 20 20 7d 0a 0a 20 20 69 66  break;.  }..  if
b070: 28 20 70 44 61 74 61 20 29 7b 0a 20 20 20 20 70  ( pData ){.    p
b080: 52 65 74 20 3d 20 70 44 61 74 61 2d 3e 70 50 74  Ret = pData->pPt
b090: 72 3b 0a 20 20 20 20 69 66 28 20 62 43 6c 65 61  r;.    if( bClea
b0a0: 72 20 29 7b 0a 20 20 20 20 20 20 70 44 61 74 61  r ){.      pData
b0b0: 2d 3e 70 50 74 72 20 3d 20 30 3b 0a 20 20 20 20  ->pPtr = 0;.    
b0c0: 20 20 70 44 61 74 61 2d 3e 78 44 65 6c 65 74 65    pData->xDelete
b0d0: 20 3d 20 30 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a   = 0;.    }.  }.
b0e0: 0a 20 20 72 65 74 75 72 6e 20 70 52 65 74 3b 0a  .  return pRet;.
b0f0: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74  }..static int ft
b100: 73 35 41 70 69 51 75 65 72 79 50 68 72 61 73 65  s5ApiQueryPhrase
b110: 28 46 74 73 35 43 6f 6e 74 65 78 74 2a 2c 20 69  (Fts5Context*, i
b120: 6e 74 2c 20 76 6f 69 64 2a 2c 20 0a 20 20 20 20  nt, void*, .    
b130: 69 6e 74 28 2a 29 28 63 6f 6e 73 74 20 46 74 73  int(*)(const Fts
b140: 35 45 78 74 65 6e 73 69 6f 6e 41 70 69 2a 2c 20  5ExtensionApi*, 
b150: 46 74 73 35 43 6f 6e 74 65 78 74 2a 2c 20 76 6f  Fts5Context*, vo
b160: 69 64 2a 29 0a 29 3b 0a 0a 73 74 61 74 69 63 20  id*).);..static 
b170: 63 6f 6e 73 74 20 46 74 73 35 45 78 74 65 6e 73  const Fts5Extens
b180: 69 6f 6e 41 70 69 20 73 46 74 73 35 41 70 69 20  ionApi sFts5Api 
b190: 3d 20 7b 0a 20 20 31 2c 20 20 20 20 20 20 20 20  = {.  1,        
b1a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b1b0: 20 20 20 20 2f 2a 20 69 56 65 72 73 69 6f 6e 20      /* iVersion 
b1c0: 2a 2f 0a 20 20 66 74 73 35 41 70 69 55 73 65 72  */.  fts5ApiUser
b1d0: 44 61 74 61 2c 0a 20 20 66 74 73 35 41 70 69 43  Data,.  fts5ApiC
b1e0: 6f 6c 75 6d 6e 43 6f 75 6e 74 2c 0a 20 20 66 74  olumnCount,.  ft
b1f0: 73 35 41 70 69 52 6f 77 43 6f 75 6e 74 2c 0a 20  s5ApiRowCount,. 
b200: 20 66 74 73 35 41 70 69 43 6f 6c 75 6d 6e 54 6f   fts5ApiColumnTo
b210: 74 61 6c 53 69 7a 65 2c 0a 20 20 66 74 73 35 41  talSize,.  fts5A
b220: 70 69 54 6f 6b 65 6e 69 7a 65 2c 0a 20 20 66 74  piTokenize,.  ft
b230: 73 35 41 70 69 50 68 72 61 73 65 43 6f 75 6e 74  s5ApiPhraseCount
b240: 2c 0a 20 20 66 74 73 35 41 70 69 50 68 72 61 73  ,.  fts5ApiPhras
b250: 65 53 69 7a 65 2c 0a 20 20 66 74 73 35 41 70 69  eSize,.  fts5Api
b260: 49 6e 73 74 43 6f 75 6e 74 2c 0a 20 20 66 74 73  InstCount,.  fts
b270: 35 41 70 69 49 6e 73 74 2c 0a 20 20 66 74 73 35  5ApiInst,.  fts5
b280: 41 70 69 52 6f 77 69 64 2c 0a 20 20 66 74 73 35  ApiRowid,.  fts5
b290: 41 70 69 43 6f 6c 75 6d 6e 54 65 78 74 2c 0a 20  ApiColumnText,. 
b2a0: 20 66 74 73 35 41 70 69 43 6f 6c 75 6d 6e 53 69   fts5ApiColumnSi
b2b0: 7a 65 2c 0a 20 20 66 74 73 35 41 70 69 51 75 65  ze,.  fts5ApiQue
b2c0: 72 79 50 68 72 61 73 65 2c 0a 20 20 66 74 73 35  ryPhrase,.  fts5
b2d0: 41 70 69 53 65 74 41 75 78 64 61 74 61 2c 0a 20  ApiSetAuxdata,. 
b2e0: 20 66 74 73 35 41 70 69 47 65 74 41 75 78 64 61   fts5ApiGetAuxda
b2f0: 74 61 2c 0a 7d 3b 0a 0a 0a 2f 2a 0a 2a 2a 20 49  ta,.};.../*.** I
b300: 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66  mplementation of
b310: 20 41 50 49 20 66 75 6e 63 74 69 6f 6e 20 78 51   API function xQ
b320: 75 65 72 79 50 68 72 61 73 65 28 29 2e 0a 2a 2f  ueryPhrase()..*/
b330: 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35  .static int fts5
b340: 41 70 69 51 75 65 72 79 50 68 72 61 73 65 28 0a  ApiQueryPhrase(.
b350: 20 20 46 74 73 35 43 6f 6e 74 65 78 74 20 2a 70    Fts5Context *p
b360: 43 74 78 2c 20 0a 20 20 69 6e 74 20 69 50 68 72  Ctx, .  int iPhr
b370: 61 73 65 2c 20 0a 20 20 76 6f 69 64 20 2a 70 55  ase, .  void *pU
b380: 73 65 72 44 61 74 61 2c 0a 20 20 69 6e 74 28 2a  serData,.  int(*
b390: 78 43 61 6c 6c 62 61 63 6b 29 28 63 6f 6e 73 74  xCallback)(const
b3a0: 20 46 74 73 35 45 78 74 65 6e 73 69 6f 6e 41 70   Fts5ExtensionAp
b3b0: 69 2a 2c 20 46 74 73 35 43 6f 6e 74 65 78 74 2a  i*, Fts5Context*
b3c0: 2c 20 76 6f 69 64 2a 29 0a 29 7b 0a 20 20 46 74  , void*).){.  Ft
b3d0: 73 35 43 75 72 73 6f 72 20 2a 70 43 73 72 20 3d  s5Cursor *pCsr =
b3e0: 20 28 46 74 73 35 43 75 72 73 6f 72 2a 29 70 43   (Fts5Cursor*)pC
b3f0: 74 78 3b 0a 20 20 46 74 73 35 54 61 62 6c 65 20  tx;.  Fts5Table 
b400: 2a 70 54 61 62 20 3d 20 28 46 74 73 35 54 61 62  *pTab = (Fts5Tab
b410: 6c 65 2a 29 28 70 43 73 72 2d 3e 62 61 73 65 2e  le*)(pCsr->base.
b420: 70 56 74 61 62 29 3b 0a 20 20 69 6e 74 20 72 63  pVtab);.  int rc
b430: 3b 0a 20 20 46 74 73 35 43 75 72 73 6f 72 20 2a  ;.  Fts5Cursor *
b440: 70 4e 65 77 20 3d 20 30 3b 0a 0a 20 20 72 63 20  pNew = 0;..  rc 
b450: 3d 20 66 74 73 35 4f 70 65 6e 4d 65 74 68 6f 64  = fts5OpenMethod
b460: 28 70 43 73 72 2d 3e 62 61 73 65 2e 70 56 74 61  (pCsr->base.pVta
b470: 62 2c 20 28 73 71 6c 69 74 65 33 5f 76 74 61 62  b, (sqlite3_vtab
b480: 5f 63 75 72 73 6f 72 2a 2a 29 26 70 4e 65 77 29  _cursor**)&pNew)
b490: 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  ;.  if( rc==SQLI
b4a0: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 46 74 73  TE_OK ){.    Fts
b4b0: 35 43 6f 6e 66 69 67 20 2a 70 43 6f 6e 66 20 3d  5Config *pConf =
b4c0: 20 70 54 61 62 2d 3e 70 43 6f 6e 66 69 67 3b 0a   pTab->pConfig;.
b4d0: 20 20 20 20 70 4e 65 77 2d 3e 69 64 78 4e 75 6d      pNew->idxNum
b4e0: 20 3d 20 46 54 53 35 5f 50 4c 41 4e 5f 4d 41 54   = FTS5_PLAN_MAT
b4f0: 43 48 3b 0a 20 20 20 20 70 4e 65 77 2d 3e 62 61  CH;.    pNew->ba
b500: 73 65 2e 70 56 74 61 62 20 3d 20 28 73 71 6c 69  se.pVtab = (sqli
b510: 74 65 33 5f 76 74 61 62 2a 29 70 54 61 62 3b 0a  te3_vtab*)pTab;.
b520: 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
b530: 46 74 73 35 45 78 70 72 50 68 72 61 73 65 45 78  Fts5ExprPhraseEx
b540: 70 72 28 70 43 6f 6e 66 2c 20 70 43 73 72 2d 3e  pr(pConf, pCsr->
b550: 70 45 78 70 72 2c 20 69 50 68 72 61 73 65 2c 20  pExpr, iPhrase, 
b560: 26 70 4e 65 77 2d 3e 70 45 78 70 72 29 3b 0a 20  &pNew->pExpr);. 
b570: 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51   }..  if( rc==SQ
b580: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 66  LITE_OK ){.    f
b590: 6f 72 28 72 63 20 3d 20 66 74 73 35 43 75 72 73  or(rc = fts5Curs
b5a0: 6f 72 46 69 72 73 74 28 70 54 61 62 2c 20 70 4e  orFirst(pTab, pN
b5b0: 65 77 2c 20 30 29 3b 0a 20 20 20 20 20 20 20 20  ew, 0);.        
b5c0: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26  rc==SQLITE_OK &&
b5d0: 20 43 73 72 46 6c 61 67 54 65 73 74 28 70 4e 65   CsrFlagTest(pNe
b5e0: 77 2c 20 46 54 53 35 43 53 52 5f 45 4f 46 29 3d  w, FTS5CSR_EOF)=
b5f0: 3d 30 3b 0a 20 20 20 20 20 20 20 20 72 63 20 3d  =0;.        rc =
b600: 20 66 74 73 35 4e 65 78 74 4d 65 74 68 6f 64 28   fts5NextMethod(
b610: 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75  (sqlite3_vtab_cu
b620: 72 73 6f 72 2a 29 70 4e 65 77 29 0a 20 20 20 20  rsor*)pNew).    
b630: 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 78 43  ){.      rc = xC
b640: 61 6c 6c 62 61 63 6b 28 26 73 46 74 73 35 41 70  allback(&sFts5Ap
b650: 69 2c 20 28 46 74 73 35 43 6f 6e 74 65 78 74 2a  i, (Fts5Context*
b660: 29 70 4e 65 77 2c 20 70 55 73 65 72 44 61 74 61  )pNew, pUserData
b670: 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 21  );.      if( rc!
b680: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
b690: 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51        if( rc==SQ
b6a0: 4c 49 54 45 5f 44 4f 4e 45 20 29 20 72 63 20 3d  LITE_DONE ) rc =
b6b0: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 20 20   SQLITE_OK;.    
b6c0: 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20      break;.     
b6d0: 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20   }.    }.  }..  
b6e0: 66 74 73 35 43 6c 6f 73 65 4d 65 74 68 6f 64 28  fts5CloseMethod(
b6f0: 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75  (sqlite3_vtab_cu
b700: 72 73 6f 72 2a 29 70 4e 65 77 29 3b 0a 20 20 72  rsor*)pNew);.  r
b710: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61  eturn rc;.}..sta
b720: 74 69 63 20 76 6f 69 64 20 66 74 73 35 41 70 69  tic void fts5Api
b730: 49 6e 76 6f 6b 65 28 0a 20 20 46 74 73 35 41 75  Invoke(.  Fts5Au
b740: 78 69 6c 69 61 72 79 20 2a 70 41 75 78 2c 0a 20  xiliary *pAux,. 
b750: 20 46 74 73 35 43 75 72 73 6f 72 20 2a 70 43 73   Fts5Cursor *pCs
b760: 72 2c 0a 20 20 73 71 6c 69 74 65 33 5f 63 6f 6e  r,.  sqlite3_con
b770: 74 65 78 74 20 2a 63 6f 6e 74 65 78 74 2c 0a 20  text *context,. 
b780: 20 69 6e 74 20 61 72 67 63 2c 0a 20 20 73 71 6c   int argc,.  sql
b790: 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a 61 72 67  ite3_value **arg
b7a0: 76 0a 29 7b 0a 20 20 61 73 73 65 72 74 28 20 70  v.){.  assert( p
b7b0: 43 73 72 2d 3e 70 41 75 78 3d 3d 30 20 29 3b 0a  Csr->pAux==0 );.
b7c0: 20 20 70 43 73 72 2d 3e 70 41 75 78 20 3d 20 70    pCsr->pAux = p
b7d0: 41 75 78 3b 0a 20 20 70 41 75 78 2d 3e 78 46 75  Aux;.  pAux->xFu
b7e0: 6e 63 28 26 73 46 74 73 35 41 70 69 2c 20 28 46  nc(&sFts5Api, (F
b7f0: 74 73 35 43 6f 6e 74 65 78 74 2a 29 70 43 73 72  ts5Context*)pCsr
b800: 2c 20 63 6f 6e 74 65 78 74 2c 20 61 72 67 63 2c  , context, argc,
b810: 20 61 72 67 76 29 3b 0a 20 20 70 43 73 72 2d 3e   argv);.  pCsr->
b820: 70 41 75 78 20 3d 20 30 3b 0a 7d 0a 0a 73 74 61  pAux = 0;.}..sta
b830: 74 69 63 20 76 6f 69 64 20 66 74 73 35 41 70 69  tic void fts5Api
b840: 43 61 6c 6c 62 61 63 6b 28 0a 20 20 73 71 6c 69  Callback(.  sqli
b850: 74 65 33 5f 63 6f 6e 74 65 78 74 20 2a 63 6f 6e  te3_context *con
b860: 74 65 78 74 2c 0a 20 20 69 6e 74 20 61 72 67 63  text,.  int argc
b870: 2c 0a 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75  ,.  sqlite3_valu
b880: 65 20 2a 2a 61 72 67 76 0a 29 7b 0a 0a 20 20 46  e **argv.){..  F
b890: 74 73 35 41 75 78 69 6c 69 61 72 79 20 2a 70 41  ts5Auxiliary *pA
b8a0: 75 78 3b 0a 20 20 46 74 73 35 43 75 72 73 6f 72  ux;.  Fts5Cursor
b8b0: 20 2a 70 43 73 72 3b 0a 20 20 69 36 34 20 69 43   *pCsr;.  i64 iC
b8c0: 73 72 49 64 3b 0a 0a 20 20 61 73 73 65 72 74 28  srId;..  assert(
b8d0: 20 61 72 67 63 3e 3d 31 20 29 3b 0a 20 20 70 41   argc>=1 );.  pA
b8e0: 75 78 20 3d 20 28 46 74 73 35 41 75 78 69 6c 69  ux = (Fts5Auxili
b8f0: 61 72 79 2a 29 73 71 6c 69 74 65 33 5f 75 73 65  ary*)sqlite3_use
b900: 72 5f 64 61 74 61 28 63 6f 6e 74 65 78 74 29 3b  r_data(context);
b910: 0a 20 20 69 43 73 72 49 64 20 3d 20 73 71 6c 69  .  iCsrId = sqli
b920: 74 65 33 5f 76 61 6c 75 65 5f 69 6e 74 36 34 28  te3_value_int64(
b930: 61 72 67 76 5b 30 5d 29 3b 0a 0a 20 20 66 6f 72  argv[0]);..  for
b940: 28 70 43 73 72 3d 70 41 75 78 2d 3e 70 47 6c 6f  (pCsr=pAux->pGlo
b950: 62 61 6c 2d 3e 70 43 73 72 3b 20 70 43 73 72 3b  bal->pCsr; pCsr;
b960: 20 70 43 73 72 3d 70 43 73 72 2d 3e 70 4e 65 78   pCsr=pCsr->pNex
b970: 74 29 7b 0a 20 20 20 20 69 66 28 20 70 43 73 72  t){.    if( pCsr
b980: 2d 3e 69 43 73 72 49 64 3d 3d 69 43 73 72 49 64  ->iCsrId==iCsrId
b990: 20 29 20 62 72 65 61 6b 3b 0a 20 20 7d 0a 20 20   ) break;.  }.  
b9a0: 69 66 28 20 70 43 73 72 3d 3d 30 20 29 7b 0a 20  if( pCsr==0 ){. 
b9b0: 20 20 20 63 68 61 72 20 2a 7a 45 72 72 20 3d 20     char *zErr = 
b9c0: 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28  sqlite3_mprintf(
b9d0: 22 6e 6f 20 73 75 63 68 20 63 75 72 73 6f 72 3a  "no such cursor:
b9e0: 20 25 6c 6c 64 22 2c 20 69 43 73 72 49 64 29 3b   %lld", iCsrId);
b9f0: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73  .    sqlite3_res
ba00: 75 6c 74 5f 65 72 72 6f 72 28 63 6f 6e 74 65 78  ult_error(contex
ba10: 74 2c 20 7a 45 72 72 2c 20 2d 31 29 3b 0a 20 20  t, zErr, -1);.  
ba20: 7d 65 6c 73 65 7b 0a 20 20 20 20 66 74 73 35 41  }else{.    fts5A
ba30: 70 69 49 6e 76 6f 6b 65 28 70 41 75 78 2c 20 70  piInvoke(pAux, p
ba40: 43 73 72 2c 20 63 6f 6e 74 65 78 74 2c 20 61 72  Csr, context, ar
ba50: 67 63 2d 31 2c 20 26 61 72 67 76 5b 31 5d 29 3b  gc-1, &argv[1]);
ba60: 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65  .  }.}../*.** Re
ba70: 74 75 72 6e 20 61 20 22 70 6f 73 69 74 69 6f 6e  turn a "position
ba80: 2d 6c 69 73 74 20 62 6c 6f 62 22 20 63 6f 72 72  -list blob" corr
ba90: 65 73 70 6f 6e 64 69 6e 67 20 74 6f 20 74 68 65  esponding to the
baa0: 20 63 75 72 72 65 6e 74 20 70 6f 73 69 74 69 6f   current positio
bab0: 6e 20 6f 66 0a 2a 2a 20 63 75 72 73 6f 72 20 70  n of.** cursor p
bac0: 43 73 72 20 76 69 61 20 73 71 6c 69 74 65 33 5f  Csr via sqlite3_
bad0: 72 65 73 75 6c 74 5f 62 6c 6f 62 28 29 2e 20 41  result_blob(). A
bae0: 20 70 6f 73 69 74 69 6f 6e 2d 6c 69 73 74 20 62   position-list b
baf0: 6c 6f 62 20 63 6f 6e 74 61 69 6e 73 0a 2a 2a 20  lob contains.** 
bb00: 74 68 65 20 63 75 72 72 65 6e 74 20 70 6f 73 69  the current posi
bb10: 74 69 6f 6e 2d 6c 69 73 74 20 66 6f 72 20 65 61  tion-list for ea
bb20: 63 68 20 70 68 72 61 73 65 20 69 6e 20 74 68 65  ch phrase in the
bb30: 20 71 75 65 72 79 20 61 73 73 6f 63 69 61 74 65   query associate
bb40: 64 20 77 69 74 68 0a 2a 2a 20 63 75 72 73 6f 72  d with.** cursor
bb50: 20 70 43 73 72 2e 0a 2a 2a 0a 2a 2a 20 41 20 70   pCsr..**.** A p
bb60: 6f 73 69 74 69 6f 6e 2d 6c 69 73 74 20 62 6c 6f  osition-list blo
bb70: 62 20 62 65 67 69 6e 73 20 77 69 74 68 20 28 6e  b begins with (n
bb80: 50 68 72 61 73 65 2d 31 29 20 76 61 72 69 6e 74  Phrase-1) varint
bb90: 73 2c 20 77 68 65 72 65 20 6e 50 68 72 61 73 65  s, where nPhrase
bba0: 20 69 73 0a 2a 2a 20 74 68 65 20 6e 75 6d 62 65   is.** the numbe
bbb0: 72 20 6f 66 20 70 68 72 61 73 65 73 20 69 6e 20  r of phrases in 
bbc0: 74 68 65 20 71 75 65 72 79 2e 20 46 6f 6c 6c 6f  the query. Follo
bbd0: 77 69 6e 67 20 74 68 65 20 76 61 72 69 6e 74 73  wing the varints
bbe0: 20 61 72 65 20 74 68 65 0a 2a 2a 20 63 6f 6e 63   are the.** conc
bbf0: 61 74 65 6e 61 74 65 64 20 70 6f 73 69 74 69 6f  atenated positio
bc00: 6e 20 6c 69 73 74 73 20 66 6f 72 20 65 61 63 68  n lists for each
bc10: 20 70 68 72 61 73 65 2c 20 69 6e 20 6f 72 64 65   phrase, in orde
bc20: 72 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 66 69 72  r..**.** The fir
bc30: 73 74 20 76 61 72 69 6e 74 20 28 69 66 20 69 74  st varint (if it
bc40: 20 65 78 69 73 74 73 29 20 63 6f 6e 74 61 69 6e   exists) contain
bc50: 73 20 74 68 65 20 73 69 7a 65 20 6f 66 20 74 68  s the size of th
bc60: 65 20 70 6f 73 69 74 69 6f 6e 20 6c 69 73 74 0a  e position list.
bc70: 2a 2a 20 66 6f 72 20 70 68 72 61 73 65 20 30 2e  ** for phrase 0.
bc80: 20 54 68 65 20 73 65 63 6f 6e 64 20 28 73 61 6d   The second (sam
bc90: 65 20 64 69 73 63 6c 61 69 6d 65 72 29 20 63 6f  e disclaimer) co
bca0: 6e 74 61 69 6e 73 20 74 68 65 20 73 69 7a 65 20  ntains the size 
bcb0: 6f 66 20 70 6f 73 69 74 69 6f 6e 0a 2a 2a 20 6c  of position.** l
bcc0: 69 73 74 20 31 2e 20 41 6e 64 20 73 6f 20 6f 6e  ist 1. And so on
bcd0: 2e 20 54 68 65 72 65 20 69 73 20 6e 6f 20 73 69  . There is no si
bce0: 7a 65 20 66 69 65 6c 64 20 66 6f 72 20 74 68 65  ze field for the
bcf0: 20 66 69 6e 61 6c 20 70 6f 73 69 74 69 6f 6e 20   final position 
bd00: 6c 69 73 74 2c 0a 2a 2a 20 61 73 20 69 74 20 63  list,.** as it c
bd10: 61 6e 20 62 65 20 64 65 72 69 76 65 64 20 66 72  an be derived fr
bd20: 6f 6d 20 74 68 65 20 74 6f 74 61 6c 20 73 69 7a  om the total siz
bd30: 65 20 6f 66 20 74 68 65 20 62 6c 6f 62 2e 0a 2a  e of the blob..*
bd40: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73  /.static int fts
bd50: 35 50 6f 73 6c 69 73 74 42 6c 6f 62 28 73 71 6c  5PoslistBlob(sql
bd60: 69 74 65 33 5f 63 6f 6e 74 65 78 74 20 2a 70 43  ite3_context *pC
bd70: 74 78 2c 20 46 74 73 35 43 75 72 73 6f 72 20 2a  tx, Fts5Cursor *
bd80: 70 43 73 72 29 7b 0a 20 20 69 6e 74 20 69 3b 0a  pCsr){.  int i;.
bd90: 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
bda0: 45 5f 4f 4b 3b 0a 20 20 69 6e 74 20 6e 50 68 72  E_OK;.  int nPhr
bdb0: 61 73 65 20 3d 20 73 71 6c 69 74 65 33 46 74 73  ase = sqlite3Fts
bdc0: 35 45 78 70 72 50 68 72 61 73 65 43 6f 75 6e 74  5ExprPhraseCount
bdd0: 28 70 43 73 72 2d 3e 70 45 78 70 72 29 3b 0a 20  (pCsr->pExpr);. 
bde0: 20 46 74 73 35 42 75 66 66 65 72 20 76 61 6c 3b   Fts5Buffer val;
bdf0: 0a 0a 20 20 6d 65 6d 73 65 74 28 26 76 61 6c 2c  ..  memset(&val,
be00: 20 30 2c 20 73 69 7a 65 6f 66 28 46 74 73 35 42   0, sizeof(Fts5B
be10: 75 66 66 65 72 29 29 3b 0a 0a 20 20 2f 2a 20 41  uffer));..  /* A
be20: 70 70 65 6e 64 20 74 68 65 20 76 61 72 69 6e 74  ppend the varint
be30: 73 20 2a 2f 0a 20 20 66 6f 72 28 69 3d 30 3b 20  s */.  for(i=0; 
be40: 69 3c 28 6e 50 68 72 61 73 65 2d 31 29 3b 20 69  i<(nPhrase-1); i
be50: 2b 2b 29 7b 0a 20 20 20 20 63 6f 6e 73 74 20 75  ++){.    const u
be60: 38 20 2a 64 75 6d 6d 79 3b 0a 20 20 20 20 69 6e  8 *dummy;.    in
be70: 74 20 6e 42 79 74 65 20 3d 20 73 71 6c 69 74 65  t nByte = sqlite
be80: 33 46 74 73 35 45 78 70 72 50 6f 73 6c 69 73 74  3Fts5ExprPoslist
be90: 28 70 43 73 72 2d 3e 70 45 78 70 72 2c 20 69 2c  (pCsr->pExpr, i,
bea0: 20 26 64 75 6d 6d 79 29 3b 0a 20 20 20 20 73 71   &dummy);.    sq
beb0: 6c 69 74 65 33 46 74 73 35 42 75 66 66 65 72 41  lite3Fts5BufferA
bec0: 70 70 65 6e 64 56 61 72 69 6e 74 28 26 72 63 2c  ppendVarint(&rc,
bed0: 20 26 76 61 6c 2c 20 6e 42 79 74 65 29 3b 0a 20   &val, nByte);. 
bee0: 20 7d 0a 0a 20 20 2f 2a 20 41 70 70 65 6e 64 20   }..  /* Append 
bef0: 74 68 65 20 70 6f 73 69 74 69 6f 6e 20 6c 69 73  the position lis
bf00: 74 73 20 2a 2f 0a 20 20 66 6f 72 28 69 3d 30 3b  ts */.  for(i=0;
bf10: 20 69 3c 6e 50 68 72 61 73 65 3b 20 69 2b 2b 29   i<nPhrase; i++)
bf20: 7b 0a 20 20 20 20 63 6f 6e 73 74 20 75 38 20 2a  {.    const u8 *
bf30: 70 50 6f 73 6c 69 73 74 3b 0a 20 20 20 20 69 6e  pPoslist;.    in
bf40: 74 20 6e 50 6f 73 6c 69 73 74 3b 0a 20 20 20 20  t nPoslist;.    
bf50: 6e 50 6f 73 6c 69 73 74 20 3d 20 73 71 6c 69 74  nPoslist = sqlit
bf60: 65 33 46 74 73 35 45 78 70 72 50 6f 73 6c 69 73  e3Fts5ExprPoslis
bf70: 74 28 70 43 73 72 2d 3e 70 45 78 70 72 2c 20 69  t(pCsr->pExpr, i
bf80: 2c 20 26 70 50 6f 73 6c 69 73 74 29 3b 0a 20 20  , &pPoslist);.  
bf90: 20 20 73 71 6c 69 74 65 33 46 74 73 35 42 75 66    sqlite3Fts5Buf
bfa0: 66 65 72 41 70 70 65 6e 64 42 6c 6f 62 28 26 72  ferAppendBlob(&r
bfb0: 63 2c 20 26 76 61 6c 2c 20 6e 50 6f 73 6c 69 73  c, &val, nPoslis
bfc0: 74 2c 20 70 50 6f 73 6c 69 73 74 29 3b 0a 20 20  t, pPoslist);.  
bfd0: 7d 0a 0a 20 20 73 71 6c 69 74 65 33 5f 72 65 73  }..  sqlite3_res
bfe0: 75 6c 74 5f 62 6c 6f 62 28 70 43 74 78 2c 20 76  ult_blob(pCtx, v
bff0: 61 6c 2e 70 2c 20 76 61 6c 2e 6e 2c 20 73 71 6c  al.p, val.n, sql
c000: 69 74 65 33 5f 66 72 65 65 29 3b 0a 20 20 72 65  ite3_free);.  re
c010: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 0a  turn rc;.}../* .
c020: 2a 2a 20 54 68 69 73 20 69 73 20 74 68 65 20 78  ** This is the x
c030: 43 6f 6c 75 6d 6e 20 6d 65 74 68 6f 64 2c 20 63  Column method, c
c040: 61 6c 6c 65 64 20 62 79 20 53 51 4c 69 74 65 20  alled by SQLite 
c050: 74 6f 20 72 65 71 75 65 73 74 20 61 20 76 61 6c  to request a val
c060: 75 65 20 66 72 6f 6d 0a 2a 2a 20 74 68 65 20 72  ue from.** the r
c070: 6f 77 20 74 68 61 74 20 74 68 65 20 73 75 70 70  ow that the supp
c080: 6c 69 65 64 20 63 75 72 73 6f 72 20 63 75 72 72  lied cursor curr
c090: 65 6e 74 6c 79 20 70 6f 69 6e 74 73 20 74 6f 2e  ently points to.
c0a0: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66  .*/.static int f
c0b0: 74 73 35 43 6f 6c 75 6d 6e 4d 65 74 68 6f 64 28  ts5ColumnMethod(
c0c0: 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62 5f  .  sqlite3_vtab_
c0d0: 63 75 72 73 6f 72 20 2a 70 43 75 72 73 6f 72 2c  cursor *pCursor,
c0e0: 20 20 20 2f 2a 20 43 75 72 73 6f 72 20 74 6f 20     /* Cursor to 
c0f0: 72 65 74 72 69 65 76 65 20 76 61 6c 75 65 20 66  retrieve value f
c100: 72 6f 6d 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33  rom */.  sqlite3
c110: 5f 63 6f 6e 74 65 78 74 20 2a 70 43 74 78 2c 20  _context *pCtx, 
c120: 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 6e 74           /* Cont
c130: 65 78 74 20 66 6f 72 20 73 71 6c 69 74 65 33 5f  ext for sqlite3_
c140: 72 65 73 75 6c 74 5f 78 78 78 28 29 20 63 61 6c  result_xxx() cal
c150: 6c 73 20 2a 2f 0a 20 20 69 6e 74 20 69 43 6f 6c  ls */.  int iCol
c160: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c170: 20 20 20 20 20 20 20 20 2f 2a 20 49 6e 64 65 78          /* Index
c180: 20 6f 66 20 63 6f 6c 75 6d 6e 20 74 6f 20 72 65   of column to re
c190: 61 64 20 76 61 6c 75 65 20 66 72 6f 6d 20 2a 2f  ad value from */
c1a0: 0a 29 7b 0a 20 20 46 74 73 35 54 61 62 6c 65 20  .){.  Fts5Table 
c1b0: 2a 70 54 61 62 20 3d 20 28 46 74 73 35 54 61 62  *pTab = (Fts5Tab
c1c0: 6c 65 2a 29 28 70 43 75 72 73 6f 72 2d 3e 70 56  le*)(pCursor->pV
c1d0: 74 61 62 29 3b 0a 20 20 46 74 73 35 43 6f 6e 66  tab);.  Fts5Conf
c1e0: 69 67 20 2a 70 43 6f 6e 66 69 67 20 3d 20 70 54  ig *pConfig = pT
c1f0: 61 62 2d 3e 70 43 6f 6e 66 69 67 3b 0a 20 20 46  ab->pConfig;.  F
c200: 74 73 35 43 75 72 73 6f 72 20 2a 70 43 73 72 20  ts5Cursor *pCsr 
c210: 3d 20 28 46 74 73 35 43 75 72 73 6f 72 2a 29 70  = (Fts5Cursor*)p
c220: 43 75 72 73 6f 72 3b 0a 20 20 69 6e 74 20 72 63  Cursor;.  int rc
c230: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20   = SQLITE_OK;.  
c240: 0a 20 20 61 73 73 65 72 74 28 20 43 73 72 46 6c  .  assert( CsrFl
c250: 61 67 54 65 73 74 28 70 43 73 72 2c 20 46 54 53  agTest(pCsr, FTS
c260: 35 43 53 52 5f 45 4f 46 29 3d 3d 30 20 29 3b 0a  5CSR_EOF)==0 );.
c270: 0a 20 20 69 66 28 20 70 43 73 72 2d 3e 69 64 78  .  if( pCsr->idx
c280: 4e 75 6d 3d 3d 46 54 53 35 5f 50 4c 41 4e 5f 53  Num==FTS5_PLAN_S
c290: 50 45 43 49 41 4c 20 29 7b 0a 20 20 20 20 69 66  PECIAL ){.    if
c2a0: 28 20 69 43 6f 6c 3d 3d 70 43 6f 6e 66 69 67 2d  ( iCol==pConfig-
c2b0: 3e 6e 43 6f 6c 20 29 7b 0a 20 20 20 20 20 20 73  >nCol ){.      s
c2c0: 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 74 65  qlite3_result_te
c2d0: 78 74 28 70 43 74 78 2c 20 70 43 73 72 2d 3e 7a  xt(pCtx, pCsr->z
c2e0: 53 70 65 63 69 61 6c 2c 20 2d 31 2c 20 53 51 4c  Special, -1, SQL
c2f0: 49 54 45 5f 54 52 41 4e 53 49 45 4e 54 29 3b 0a  ITE_TRANSIENT);.
c300: 20 20 20 20 7d 0a 20 20 7d 65 6c 73 65 0a 0a 20      }.  }else.. 
c310: 20 69 66 28 20 69 43 6f 6c 3d 3d 70 43 6f 6e 66   if( iCol==pConf
c320: 69 67 2d 3e 6e 43 6f 6c 20 29 7b 0a 20 20 20 20  ig->nCol ){.    
c330: 2f 2a 20 55 73 65 72 20 69 73 20 72 65 71 75 65  /* User is reque
c340: 73 74 69 6e 67 20 74 68 65 20 76 61 6c 75 65 20  sting the value 
c350: 6f 66 20 74 68 65 20 73 70 65 63 69 61 6c 20 63  of the special c
c360: 6f 6c 75 6d 6e 20 77 69 74 68 20 74 68 65 20 73  olumn with the s
c370: 61 6d 65 20 6e 61 6d 65 0a 20 20 20 20 2a 2a 20  ame name.    ** 
c380: 61 73 20 74 68 65 20 74 61 62 6c 65 2e 20 52 65  as the table. Re
c390: 74 75 72 6e 20 74 68 65 20 63 75 72 73 6f 72 20  turn the cursor 
c3a0: 69 6e 74 65 67 65 72 20 69 64 20 6e 75 6d 62 65  integer id numbe
c3b0: 72 2e 20 54 68 69 73 20 76 61 6c 75 65 20 69 73  r. This value is
c3c0: 20 6f 6e 6c 79 0a 20 20 20 20 2a 2a 20 75 73 65   only.    ** use
c3d0: 66 75 6c 20 69 6e 20 74 68 61 74 20 69 74 20 6d  ful in that it m
c3e0: 61 79 20 62 65 20 70 61 73 73 65 64 20 61 73 20  ay be passed as 
c3f0: 74 68 65 20 66 69 72 73 74 20 61 72 67 75 6d 65  the first argume
c400: 6e 74 20 74 6f 20 61 6e 20 46 54 53 35 0a 20 20  nt to an FTS5.  
c410: 20 20 2a 2a 20 61 75 78 69 6c 69 61 72 79 20 66    ** auxiliary f
c420: 75 6e 63 74 69 6f 6e 2e 20 20 2a 2f 0a 20 20 20  unction.  */.   
c430: 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f   sqlite3_result_
c440: 69 6e 74 36 34 28 70 43 74 78 2c 20 70 43 73 72  int64(pCtx, pCsr
c450: 2d 3e 69 43 73 72 49 64 29 3b 0a 20 20 7d 65 6c  ->iCsrId);.  }el
c460: 73 65 20 69 66 28 20 69 43 6f 6c 3d 3d 70 43 6f  se if( iCol==pCo
c470: 6e 66 69 67 2d 3e 6e 43 6f 6c 2b 31 20 29 7b 0a  nfig->nCol+1 ){.
c480: 0a 20 20 20 20 2f 2a 20 54 68 65 20 76 61 6c 75  .    /* The valu
c490: 65 20 6f 66 20 74 68 65 20 22 72 61 6e 6b 22 20  e of the "rank" 
c4a0: 63 6f 6c 75 6d 6e 2e 20 2a 2f 0a 20 20 20 20 69  column. */.    i
c4b0: 66 28 20 46 54 53 35 5f 50 4c 41 4e 28 70 43 73  f( FTS5_PLAN(pCs
c4c0: 72 2d 3e 69 64 78 4e 75 6d 29 3d 3d 46 54 53 35  r->idxNum)==FTS5
c4d0: 5f 50 4c 41 4e 5f 53 4f 55 52 43 45 20 29 7b 0a  _PLAN_SOURCE ){.
c4e0: 20 20 20 20 20 20 66 74 73 35 50 6f 73 6c 69 73        fts5Poslis
c4f0: 74 42 6c 6f 62 28 70 43 74 78 2c 20 70 43 73 72  tBlob(pCtx, pCsr
c500: 29 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28  );.    }else if(
c510: 20 0a 20 20 20 20 20 20 20 20 46 54 53 35 5f 50   .        FTS5_P
c520: 4c 41 4e 28 70 43 73 72 2d 3e 69 64 78 4e 75 6d  LAN(pCsr->idxNum
c530: 29 3d 3d 46 54 53 35 5f 50 4c 41 4e 5f 4d 41 54  )==FTS5_PLAN_MAT
c540: 43 48 0a 20 20 20 20 20 7c 7c 20 46 54 53 35 5f  CH.     || FTS5_
c550: 50 4c 41 4e 28 70 43 73 72 2d 3e 69 64 78 4e 75  PLAN(pCsr->idxNu
c560: 6d 29 3d 3d 46 54 53 35 5f 50 4c 41 4e 5f 53 4f  m)==FTS5_PLAN_SO
c570: 52 54 45 44 5f 4d 41 54 43 48 0a 20 20 20 20 29  RTED_MATCH.    )
c580: 7b 0a 20 20 20 20 20 20 69 66 28 20 70 43 73 72  {.      if( pCsr
c590: 2d 3e 70 52 61 6e 6b 20 7c 7c 20 53 51 4c 49 54  ->pRank || SQLIT
c5a0: 45 5f 4f 4b 3d 3d 28 72 63 20 3d 20 66 74 73 35  E_OK==(rc = fts5
c5b0: 46 69 6e 64 52 61 6e 6b 46 75 6e 63 74 69 6f 6e  FindRankFunction
c5c0: 28 70 43 73 72 29 29 20 29 7b 0a 20 20 20 20 20  (pCsr)) ){.     
c5d0: 20 20 20 66 74 73 35 41 70 69 49 6e 76 6f 6b 65     fts5ApiInvoke
c5e0: 28 70 43 73 72 2d 3e 70 52 61 6e 6b 2c 20 70 43  (pCsr->pRank, pC
c5f0: 73 72 2c 20 70 43 74 78 2c 20 70 43 73 72 2d 3e  sr, pCtx, pCsr->
c600: 6e 52 61 6e 6b 41 72 67 2c 20 70 43 73 72 2d 3e  nRankArg, pCsr->
c610: 61 70 52 61 6e 6b 41 72 67 29 3b 0a 20 20 20 20  apRankArg);.    
c620: 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 65 6c 73    }.    }.  }els
c630: 65 20 69 66 28 20 21 66 74 73 35 49 73 43 6f 6e  e if( !fts5IsCon
c640: 74 65 6e 74 6c 65 73 73 28 70 54 61 62 29 20 29  tentless(pTab) )
c650: 7b 0a 20 20 20 20 72 63 20 3d 20 66 74 73 35 53  {.    rc = fts5S
c660: 65 65 6b 43 75 72 73 6f 72 28 70 43 73 72 29 3b  eekCursor(pCsr);
c670: 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  .    if( rc==SQL
c680: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20  ITE_OK ){.      
c690: 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 76  sqlite3_result_v
c6a0: 61 6c 75 65 28 70 43 74 78 2c 20 73 71 6c 69 74  alue(pCtx, sqlit
c6b0: 65 33 5f 63 6f 6c 75 6d 6e 5f 76 61 6c 75 65 28  e3_column_value(
c6c0: 70 43 73 72 2d 3e 70 53 74 6d 74 2c 20 69 43 6f  pCsr->pStmt, iCo
c6d0: 6c 2b 31 29 29 3b 0a 20 20 20 20 7d 0a 20 20 7d  l+1));.    }.  }
c6e0: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
c6f0: 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75  ../*.** This rou
c700: 74 69 6e 65 20 69 6d 70 6c 65 6d 65 6e 74 73 20  tine implements 
c710: 74 68 65 20 78 46 69 6e 64 46 75 6e 63 74 69 6f  the xFindFunctio
c720: 6e 20 6d 65 74 68 6f 64 20 66 6f 72 20 74 68 65  n method for the
c730: 20 46 54 53 33 0a 2a 2a 20 76 69 72 74 75 61 6c   FTS3.** virtual
c740: 20 74 61 62 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69   table..*/.stati
c750: 63 20 69 6e 74 20 66 74 73 35 46 69 6e 64 46 75  c int fts5FindFu
c760: 6e 63 74 69 6f 6e 4d 65 74 68 6f 64 28 0a 20 20  nctionMethod(.  
c770: 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56  sqlite3_vtab *pV
c780: 74 61 62 2c 20 20 20 20 20 20 20 20 20 20 20 20  tab,            
c790: 2f 2a 20 56 69 72 74 75 61 6c 20 74 61 62 6c 65  /* Virtual table
c7a0: 20 68 61 6e 64 6c 65 20 2a 2f 0a 20 20 69 6e 74   handle */.  int
c7b0: 20 6e 41 72 67 2c 20 20 20 20 20 20 20 20 20 20   nArg,          
c7c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
c7d0: 4e 75 6d 62 65 72 20 6f 66 20 53 51 4c 20 66 75  Number of SQL fu
c7e0: 6e 63 74 69 6f 6e 20 61 72 67 75 6d 65 6e 74 73  nction arguments
c7f0: 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72   */.  const char
c800: 20 2a 7a 4e 61 6d 65 2c 20 20 20 20 20 20 20 20   *zName,        
c810: 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66        /* Name of
c820: 20 53 51 4c 20 66 75 6e 63 74 69 6f 6e 20 2a 2f   SQL function */
c830: 0a 20 20 76 6f 69 64 20 28 2a 2a 70 78 46 75 6e  .  void (**pxFun
c840: 63 29 28 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65  c)(sqlite3_conte
c850: 78 74 2a 2c 69 6e 74 2c 73 71 6c 69 74 65 33 5f  xt*,int,sqlite3_
c860: 76 61 6c 75 65 2a 2a 29 2c 20 2f 2a 20 4f 55 54  value**), /* OUT
c870: 3a 20 52 65 73 75 6c 74 20 2a 2f 0a 20 20 76 6f  : Result */.  vo
c880: 69 64 20 2a 2a 70 70 41 72 67 20 20 20 20 20 20  id **ppArg      
c890: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
c8a0: 20 4f 55 54 3a 20 55 73 65 72 20 64 61 74 61 20   OUT: User data 
c8b0: 66 6f 72 20 2a 70 78 46 75 6e 63 20 2a 2f 0a 29  for *pxFunc */.)
c8c0: 7b 0a 20 20 46 74 73 35 54 61 62 6c 65 20 2a 70  {.  Fts5Table *p
c8d0: 54 61 62 20 3d 20 28 46 74 73 35 54 61 62 6c 65  Tab = (Fts5Table
c8e0: 2a 29 70 56 74 61 62 3b 0a 20 20 46 74 73 35 41  *)pVtab;.  Fts5A
c8f0: 75 78 69 6c 69 61 72 79 20 2a 70 41 75 78 3b 0a  uxiliary *pAux;.
c900: 0a 20 20 70 41 75 78 20 3d 20 66 74 73 35 46 69  .  pAux = fts5Fi
c910: 6e 64 41 75 78 69 6c 69 61 72 79 28 70 54 61 62  ndAuxiliary(pTab
c920: 2c 20 7a 4e 61 6d 65 29 3b 0a 20 20 69 66 28 20  , zName);.  if( 
c930: 70 41 75 78 20 29 7b 0a 20 20 20 20 2a 70 78 46  pAux ){.    *pxF
c940: 75 6e 63 20 3d 20 66 74 73 35 41 70 69 43 61 6c  unc = fts5ApiCal
c950: 6c 62 61 63 6b 3b 0a 20 20 20 20 2a 70 70 41 72  lback;.    *ppAr
c960: 67 20 3d 20 28 76 6f 69 64 2a 29 70 41 75 78 3b  g = (void*)pAux;
c970: 0a 20 20 20 20 72 65 74 75 72 6e 20 31 3b 0a 20  .    return 1;. 
c980: 20 7d 0a 0a 20 20 2f 2a 20 4e 6f 20 66 75 6e 63   }..  /* No func
c990: 74 69 6f 6e 20 6f 66 20 74 68 65 20 73 70 65 63  tion of the spec
c9a0: 69 66 69 65 64 20 6e 61 6d 65 20 77 61 73 20 66  ified name was f
c9b0: 6f 75 6e 64 2e 20 52 65 74 75 72 6e 20 30 2e 20  ound. Return 0. 
c9c0: 2a 2f 0a 20 20 72 65 74 75 72 6e 20 30 3b 0a 7d  */.  return 0;.}
c9d0: 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e  ../*.** Implemen
c9e0: 74 61 74 69 6f 6e 20 6f 66 20 46 54 53 33 20 78  tation of FTS3 x
c9f0: 52 65 6e 61 6d 65 20 6d 65 74 68 6f 64 2e 20 52  Rename method. R
ca00: 65 6e 61 6d 65 20 61 6e 20 66 74 73 35 20 74 61  ename an fts5 ta
ca10: 62 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ble..*/.static i
ca20: 6e 74 20 66 74 73 35 52 65 6e 61 6d 65 4d 65 74  nt fts5RenameMet
ca30: 68 6f 64 28 0a 20 20 73 71 6c 69 74 65 33 5f 76  hod(.  sqlite3_v
ca40: 74 61 62 20 2a 70 56 74 61 62 2c 20 20 20 20 20  tab *pVtab,     
ca50: 20 20 20 20 20 20 20 2f 2a 20 56 69 72 74 75 61         /* Virtua
ca60: 6c 20 74 61 62 6c 65 20 68 61 6e 64 6c 65 20 2a  l table handle *
ca70: 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  /.  const char *
ca80: 7a 4e 61 6d 65 20 20 20 20 20 20 20 20 20 20 20  zName           
ca90: 20 20 20 20 2f 2a 20 4e 65 77 20 6e 61 6d 65 20      /* New name 
caa0: 6f 66 20 74 61 62 6c 65 20 2a 2f 0a 29 7b 0a 20  of table */.){. 
cab0: 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
cac0: 5f 4f 4b 3b 0a 20 20 72 65 74 75 72 6e 20 72 63  _OK;.  return rc
cad0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 78  ;.}../*.** The x
cae0: 53 61 76 65 70 6f 69 6e 74 28 29 20 6d 65 74 68  Savepoint() meth
caf0: 6f 64 2e 0a 2a 2a 0a 2a 2a 20 46 6c 75 73 68 20  od..**.** Flush 
cb00: 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20  the contents of 
cb10: 74 68 65 20 70 65 6e 64 69 6e 67 2d 74 65 72 6d  the pending-term
cb20: 73 20 74 61 62 6c 65 20 74 6f 20 64 69 73 6b 2e  s table to disk.
cb30: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66  .*/.static int f
cb40: 74 73 35 53 61 76 65 70 6f 69 6e 74 4d 65 74 68  ts5SavepointMeth
cb50: 6f 64 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20  od(sqlite3_vtab 
cb60: 2a 70 56 74 61 62 2c 20 69 6e 74 20 69 53 61 76  *pVtab, int iSav
cb70: 65 70 6f 69 6e 74 29 7b 0a 20 20 46 74 73 35 54  epoint){.  Fts5T
cb80: 61 62 6c 65 20 2a 70 54 61 62 20 3d 20 28 46 74  able *pTab = (Ft
cb90: 73 35 54 61 62 6c 65 2a 29 70 56 74 61 62 3b 0a  s5Table*)pVtab;.
cba0: 20 20 66 74 73 35 43 68 65 63 6b 54 72 61 6e 73    fts5CheckTrans
cbb0: 61 63 74 69 6f 6e 53 74 61 74 65 28 70 54 61 62  actionState(pTab
cbc0: 2c 20 46 54 53 35 5f 53 41 56 45 50 4f 49 4e 54  , FTS5_SAVEPOINT
cbd0: 2c 20 69 53 61 76 65 70 6f 69 6e 74 29 3b 0a 20  , iSavepoint);. 
cbe0: 20 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33 46   return sqlite3F
cbf0: 74 73 35 53 74 6f 72 61 67 65 53 79 6e 63 28 70  ts5StorageSync(p
cc00: 54 61 62 2d 3e 70 53 74 6f 72 61 67 65 2c 20 30  Tab->pStorage, 0
cc10: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20  );.}../*.** The 
cc20: 78 52 65 6c 65 61 73 65 28 29 20 6d 65 74 68 6f  xRelease() metho
cc30: 64 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 69 73  d..**.** This is
cc40: 20 61 20 6e 6f 2d 6f 70 2e 0a 2a 2f 0a 73 74 61   a no-op..*/.sta
cc50: 74 69 63 20 69 6e 74 20 66 74 73 35 52 65 6c 65  tic int fts5Rele
cc60: 61 73 65 4d 65 74 68 6f 64 28 73 71 6c 69 74 65  aseMethod(sqlite
cc70: 33 5f 76 74 61 62 20 2a 70 56 74 61 62 2c 20 69  3_vtab *pVtab, i
cc80: 6e 74 20 69 53 61 76 65 70 6f 69 6e 74 29 7b 0a  nt iSavepoint){.
cc90: 20 20 46 74 73 35 54 61 62 6c 65 20 2a 70 54 61    Fts5Table *pTa
cca0: 62 20 3d 20 28 46 74 73 35 54 61 62 6c 65 2a 29  b = (Fts5Table*)
ccb0: 70 56 74 61 62 3b 0a 20 20 66 74 73 35 43 68 65  pVtab;.  fts5Che
ccc0: 63 6b 54 72 61 6e 73 61 63 74 69 6f 6e 53 74 61  ckTransactionSta
ccd0: 74 65 28 70 54 61 62 2c 20 46 54 53 35 5f 52 45  te(pTab, FTS5_RE
cce0: 4c 45 41 53 45 2c 20 69 53 61 76 65 70 6f 69 6e  LEASE, iSavepoin
ccf0: 74 29 3b 0a 20 20 72 65 74 75 72 6e 20 73 71 6c  t);.  return sql
cd00: 69 74 65 33 46 74 73 35 53 74 6f 72 61 67 65 53  ite3Fts5StorageS
cd10: 79 6e 63 28 70 54 61 62 2d 3e 70 53 74 6f 72 61  ync(pTab->pStora
cd20: 67 65 2c 20 30 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  ge, 0);.}../*.**
cd30: 20 54 68 65 20 78 52 6f 6c 6c 62 61 63 6b 54 6f   The xRollbackTo
cd40: 28 29 20 6d 65 74 68 6f 64 2e 0a 2a 2a 0a 2a 2a  () method..**.**
cd50: 20 44 69 73 63 61 72 64 20 74 68 65 20 63 6f 6e   Discard the con
cd60: 74 65 6e 74 73 20 6f 66 20 74 68 65 20 70 65 6e  tents of the pen
cd70: 64 69 6e 67 20 74 65 72 6d 73 20 74 61 62 6c 65  ding terms table
cd80: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
cd90: 66 74 73 35 52 6f 6c 6c 62 61 63 6b 54 6f 4d 65  fts5RollbackToMe
cda0: 74 68 6f 64 28 73 71 6c 69 74 65 33 5f 76 74 61  thod(sqlite3_vta
cdb0: 62 20 2a 70 56 74 61 62 2c 20 69 6e 74 20 69 53  b *pVtab, int iS
cdc0: 61 76 65 70 6f 69 6e 74 29 7b 0a 20 20 46 74 73  avepoint){.  Fts
cdd0: 35 54 61 62 6c 65 20 2a 70 54 61 62 20 3d 20 28  5Table *pTab = (
cde0: 46 74 73 35 54 61 62 6c 65 2a 29 70 56 74 61 62  Fts5Table*)pVtab
cdf0: 3b 0a 20 20 66 74 73 35 43 68 65 63 6b 54 72 61  ;.  fts5CheckTra
ce00: 6e 73 61 63 74 69 6f 6e 53 74 61 74 65 28 70 54  nsactionState(pT
ce10: 61 62 2c 20 46 54 53 35 5f 52 4f 4c 4c 42 41 43  ab, FTS5_ROLLBAC
ce20: 4b 54 4f 2c 20 69 53 61 76 65 70 6f 69 6e 74 29  KTO, iSavepoint)
ce30: 3b 0a 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74  ;.  return sqlit
ce40: 65 33 46 74 73 35 53 74 6f 72 61 67 65 52 6f 6c  e3Fts5StorageRol
ce50: 6c 62 61 63 6b 28 70 54 61 62 2d 3e 70 53 74 6f  lback(pTab->pSto
ce60: 72 61 67 65 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  rage);.}../*.** 
ce70: 52 65 67 69 73 74 65 72 20 61 20 6e 65 77 20 61  Register a new a
ce80: 75 78 69 6c 69 61 72 79 20 66 75 6e 63 74 69 6f  uxiliary functio
ce90: 6e 20 77 69 74 68 20 67 6c 6f 62 61 6c 20 63 6f  n with global co
cea0: 6e 74 65 78 74 20 70 47 6c 6f 62 61 6c 2e 0a 2a  ntext pGlobal..*
ceb0: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73  /.static int fts
cec0: 35 43 72 65 61 74 65 41 75 78 28 0a 20 20 66 74  5CreateAux(.  ft
ced0: 73 35 5f 61 70 69 20 2a 70 41 70 69 2c 20 20 20  s5_api *pApi,   
cee0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
cef0: 20 47 6c 6f 62 61 6c 20 63 6f 6e 74 65 78 74 20   Global context 
cf00: 28 6f 6e 65 20 70 65 72 20 64 62 20 68 61 6e 64  (one per db hand
cf10: 6c 65 29 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63  le) */.  const c
cf20: 68 61 72 20 2a 7a 4e 61 6d 65 2c 20 20 20 20 20  har *zName,     
cf30: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65           /* Name
cf40: 20 6f 66 20 6e 65 77 20 66 75 6e 63 74 69 6f 6e   of new function
cf50: 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 55 73 65   */.  void *pUse
cf60: 72 44 61 74 61 2c 20 20 20 20 20 20 20 20 20 20  rData,          
cf70: 20 20 20 20 20 20 2f 2a 20 55 73 65 72 20 64 61        /* User da
cf80: 74 61 20 66 6f 72 20 61 75 78 2e 20 66 75 6e 63  ta for aux. func
cf90: 74 69 6f 6e 20 2a 2f 0a 20 20 66 74 73 35 5f 65  tion */.  fts5_e
cfa0: 78 74 65 6e 73 69 6f 6e 5f 66 75 6e 63 74 69 6f  xtension_functio
cfb0: 6e 20 78 46 75 6e 63 2c 20 20 2f 2a 20 41 75 78  n xFunc,  /* Aux
cfc0: 2e 20 66 75 6e 63 74 69 6f 6e 20 69 6d 70 6c 65  . function imple
cfd0: 6d 65 6e 74 61 74 69 6f 6e 20 2a 2f 0a 20 20 76  mentation */.  v
cfe0: 6f 69 64 28 2a 78 44 65 73 74 72 6f 79 29 28 76  oid(*xDestroy)(v
cff0: 6f 69 64 2a 29 20 20 20 20 20 20 20 20 20 20 2f  oid*)          /
d000: 2a 20 44 65 73 74 72 75 63 74 6f 72 20 66 6f 72  * Destructor for
d010: 20 70 55 73 65 72 44 61 74 61 20 2a 2f 0a 29 7b   pUserData */.){
d020: 0a 20 20 46 74 73 35 47 6c 6f 62 61 6c 20 2a 70  .  Fts5Global *p
d030: 47 6c 6f 62 61 6c 20 3d 20 28 46 74 73 35 47 6c  Global = (Fts5Gl
d040: 6f 62 61 6c 2a 29 70 41 70 69 3b 0a 20 20 69 6e  obal*)pApi;.  in
d050: 74 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 6f  t rc = sqlite3_o
d060: 76 65 72 6c 6f 61 64 5f 66 75 6e 63 74 69 6f 6e  verload_function
d070: 28 70 47 6c 6f 62 61 6c 2d 3e 64 62 2c 20 7a 4e  (pGlobal->db, zN
d080: 61 6d 65 2c 20 2d 31 29 3b 0a 20 20 69 66 28 20  ame, -1);.  if( 
d090: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
d0a0: 0a 20 20 20 20 46 74 73 35 41 75 78 69 6c 69 61  .    Fts5Auxilia
d0b0: 72 79 20 2a 70 41 75 78 3b 0a 20 20 20 20 69 6e  ry *pAux;.    in
d0c0: 74 20 6e 42 79 74 65 3b 20 20 20 20 20 20 20 20  t nByte;        
d0d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
d0e0: 20 42 79 74 65 73 20 6f 66 20 73 70 61 63 65 20   Bytes of space 
d0f0: 74 6f 20 61 6c 6c 6f 63 61 74 65 20 2a 2f 0a 0a  to allocate */..
d100: 20 20 20 20 6e 42 79 74 65 20 3d 20 73 69 7a 65      nByte = size
d110: 6f 66 28 46 74 73 35 41 75 78 69 6c 69 61 72 79  of(Fts5Auxiliary
d120: 29 20 2b 20 73 74 72 6c 65 6e 28 7a 4e 61 6d 65  ) + strlen(zName
d130: 29 20 2b 20 31 3b 0a 20 20 20 20 70 41 75 78 20  ) + 1;.    pAux 
d140: 3d 20 28 46 74 73 35 41 75 78 69 6c 69 61 72 79  = (Fts5Auxiliary
d150: 2a 29 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63  *)sqlite3_malloc
d160: 28 6e 42 79 74 65 29 3b 0a 20 20 20 20 69 66 28  (nByte);.    if(
d170: 20 70 41 75 78 20 29 7b 0a 20 20 20 20 20 20 6d   pAux ){.      m
d180: 65 6d 73 65 74 28 70 41 75 78 2c 20 30 2c 20 6e  emset(pAux, 0, n
d190: 42 79 74 65 29 3b 0a 20 20 20 20 20 20 70 41 75  Byte);.      pAu
d1a0: 78 2d 3e 7a 46 75 6e 63 20 3d 20 28 63 68 61 72  x->zFunc = (char
d1b0: 2a 29 26 70 41 75 78 5b 31 5d 3b 0a 20 20 20 20  *)&pAux[1];.    
d1c0: 20 20 73 74 72 63 70 79 28 70 41 75 78 2d 3e 7a    strcpy(pAux->z
d1d0: 46 75 6e 63 2c 20 7a 4e 61 6d 65 29 3b 0a 20 20  Func, zName);.  
d1e0: 20 20 20 20 70 41 75 78 2d 3e 70 47 6c 6f 62 61      pAux->pGloba
d1f0: 6c 20 3d 20 70 47 6c 6f 62 61 6c 3b 0a 20 20 20  l = pGlobal;.   
d200: 20 20 20 70 41 75 78 2d 3e 70 55 73 65 72 44 61     pAux->pUserDa
d210: 74 61 20 3d 20 70 55 73 65 72 44 61 74 61 3b 0a  ta = pUserData;.
d220: 20 20 20 20 20 20 70 41 75 78 2d 3e 78 46 75 6e        pAux->xFun
d230: 63 20 3d 20 78 46 75 6e 63 3b 0a 20 20 20 20 20  c = xFunc;.     
d240: 20 70 41 75 78 2d 3e 78 44 65 73 74 72 6f 79 20   pAux->xDestroy 
d250: 3d 20 78 44 65 73 74 72 6f 79 3b 0a 20 20 20 20  = xDestroy;.    
d260: 20 20 70 41 75 78 2d 3e 70 4e 65 78 74 20 3d 20    pAux->pNext = 
d270: 70 47 6c 6f 62 61 6c 2d 3e 70 41 75 78 3b 0a 20  pGlobal->pAux;. 
d280: 20 20 20 20 20 70 47 6c 6f 62 61 6c 2d 3e 70 41       pGlobal->pA
d290: 75 78 20 3d 20 70 41 75 78 3b 0a 20 20 20 20 7d  ux = pAux;.    }
d2a0: 65 6c 73 65 7b 0a 20 20 20 20 20 20 72 63 20 3d  else{.      rc =
d2b0: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
d2c0: 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75     }.  }..  retu
d2d0: 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  rn rc;.}../*.** 
d2e0: 52 65 67 69 73 74 65 72 20 61 20 6e 65 77 20 74  Register a new t
d2f0: 6f 6b 65 6e 69 7a 65 72 2e 20 54 68 69 73 20 69  okenizer. This i
d300: 73 20 74 68 65 20 69 6d 70 6c 65 6d 65 6e 74 61  s the implementa
d310: 74 69 6f 6e 20 6f 66 20 74 68 65 20 0a 2a 2a 20  tion of the .** 
d320: 66 74 73 35 5f 61 70 69 2e 78 43 72 65 61 74 65  fts5_api.xCreate
d330: 54 6f 6b 65 6e 69 7a 65 72 28 29 20 6d 65 74 68  Tokenizer() meth
d340: 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  od..*/.static in
d350: 74 20 66 74 73 35 43 72 65 61 74 65 54 6f 6b 65  t fts5CreateToke
d360: 6e 69 7a 65 72 28 0a 20 20 66 74 73 35 5f 61 70  nizer(.  fts5_ap
d370: 69 20 2a 70 41 70 69 2c 20 20 20 20 20 20 20 20  i *pApi,        
d380: 20 20 20 20 20 20 20 20 20 2f 2a 20 47 6c 6f 62           /* Glob
d390: 61 6c 20 63 6f 6e 74 65 78 74 20 28 6f 6e 65 20  al context (one 
d3a0: 70 65 72 20 64 62 20 68 61 6e 64 6c 65 29 20 2a  per db handle) *
d3b0: 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  /.  const char *
d3c0: 7a 4e 61 6d 65 2c 20 20 20 20 20 20 20 20 20 20  zName,          
d3d0: 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 6e      /* Name of n
d3e0: 65 77 20 66 75 6e 63 74 69 6f 6e 20 2a 2f 0a 20  ew function */. 
d3f0: 20 76 6f 69 64 20 2a 70 55 73 65 72 44 61 74 61   void *pUserData
d400: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
d410: 20 2f 2a 20 55 73 65 72 20 64 61 74 61 20 66 6f   /* User data fo
d420: 72 20 61 75 78 2e 20 66 75 6e 63 74 69 6f 6e 20  r aux. function 
d430: 2a 2f 0a 20 20 66 74 73 35 5f 74 6f 6b 65 6e 69  */.  fts5_tokeni
d440: 7a 65 72 20 2a 70 54 6f 6b 65 6e 69 7a 65 72 2c  zer *pTokenizer,
d450: 20 20 20 20 20 2f 2a 20 54 6f 6b 65 6e 69 7a 65       /* Tokenize
d460: 72 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e  r implementation
d470: 20 2a 2f 0a 20 20 76 6f 69 64 28 2a 78 44 65 73   */.  void(*xDes
d480: 74 72 6f 79 29 28 76 6f 69 64 2a 29 20 20 20 20  troy)(void*)    
d490: 20 20 20 20 20 20 2f 2a 20 44 65 73 74 72 75 63        /* Destruc
d4a0: 74 6f 72 20 66 6f 72 20 70 55 73 65 72 44 61 74  tor for pUserDat
d4b0: 61 20 2a 2f 0a 29 7b 0a 20 20 46 74 73 35 47 6c  a */.){.  Fts5Gl
d4c0: 6f 62 61 6c 20 2a 70 47 6c 6f 62 61 6c 20 3d 20  obal *pGlobal = 
d4d0: 28 46 74 73 35 47 6c 6f 62 61 6c 2a 29 70 41 70  (Fts5Global*)pAp
d4e0: 69 3b 0a 20 20 46 74 73 35 54 6f 6b 65 6e 69 7a  i;.  Fts5Tokeniz
d4f0: 65 72 4d 6f 64 75 6c 65 20 2a 70 4e 65 77 3b 0a  erModule *pNew;.
d500: 20 20 69 6e 74 20 6e 42 79 74 65 3b 20 20 20 20    int nByte;    
d510: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d520: 20 20 2f 2a 20 42 79 74 65 73 20 6f 66 20 73 70    /* Bytes of sp
d530: 61 63 65 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20  ace to allocate 
d540: 2a 2f 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51  */.  int rc = SQ
d550: 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20 6e 42 79 74  LITE_OK;..  nByt
d560: 65 20 3d 20 73 69 7a 65 6f 66 28 46 74 73 35 54  e = sizeof(Fts5T
d570: 6f 6b 65 6e 69 7a 65 72 4d 6f 64 75 6c 65 29 20  okenizerModule) 
d580: 2b 20 73 74 72 6c 65 6e 28 7a 4e 61 6d 65 29 20  + strlen(zName) 
d590: 2b 20 31 3b 0a 20 20 70 4e 65 77 20 3d 20 28 46  + 1;.  pNew = (F
d5a0: 74 73 35 54 6f 6b 65 6e 69 7a 65 72 4d 6f 64 75  ts5TokenizerModu
d5b0: 6c 65 2a 29 73 71 6c 69 74 65 33 5f 6d 61 6c 6c  le*)sqlite3_mall
d5c0: 6f 63 28 6e 42 79 74 65 29 3b 0a 20 20 69 66 28  oc(nByte);.  if(
d5d0: 20 70 4e 65 77 20 29 7b 0a 20 20 20 20 6d 65 6d   pNew ){.    mem
d5e0: 73 65 74 28 70 4e 65 77 2c 20 30 2c 20 6e 42 79  set(pNew, 0, nBy
d5f0: 74 65 29 3b 0a 20 20 20 20 70 4e 65 77 2d 3e 7a  te);.    pNew->z
d600: 4e 61 6d 65 20 3d 20 28 63 68 61 72 2a 29 26 70  Name = (char*)&p
d610: 4e 65 77 5b 31 5d 3b 0a 20 20 20 20 73 74 72 63  New[1];.    strc
d620: 70 79 28 70 4e 65 77 2d 3e 7a 4e 61 6d 65 2c 20  py(pNew->zName, 
d630: 7a 4e 61 6d 65 29 3b 0a 20 20 20 20 70 4e 65 77  zName);.    pNew
d640: 2d 3e 70 55 73 65 72 44 61 74 61 20 3d 20 70 55  ->pUserData = pU
d650: 73 65 72 44 61 74 61 3b 0a 20 20 20 20 70 4e 65  serData;.    pNe
d660: 77 2d 3e 78 20 3d 20 2a 70 54 6f 6b 65 6e 69 7a  w->x = *pTokeniz
d670: 65 72 3b 0a 20 20 20 20 70 4e 65 77 2d 3e 78 44  er;.    pNew->xD
d680: 65 73 74 72 6f 79 20 3d 20 78 44 65 73 74 72 6f  estroy = xDestro
d690: 79 3b 0a 20 20 20 20 70 4e 65 77 2d 3e 70 4e 65  y;.    pNew->pNe
d6a0: 78 74 20 3d 20 70 47 6c 6f 62 61 6c 2d 3e 70 54  xt = pGlobal->pT
d6b0: 6f 6b 3b 0a 20 20 20 20 70 47 6c 6f 62 61 6c 2d  ok;.    pGlobal-
d6c0: 3e 70 54 6f 6b 20 3d 20 70 4e 65 77 3b 0a 20 20  >pTok = pNew;.  
d6d0: 20 20 69 66 28 20 70 4e 65 77 2d 3e 70 4e 65 78    if( pNew->pNex
d6e0: 74 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 70 47  t==0 ){.      pG
d6f0: 6c 6f 62 61 6c 2d 3e 70 44 66 6c 74 54 6f 6b 20  lobal->pDfltTok 
d700: 3d 20 70 4e 65 77 3b 0a 20 20 20 20 7d 0a 20 20  = pNew;.    }.  
d710: 7d 65 6c 73 65 7b 0a 20 20 20 20 72 63 20 3d 20  }else{.    rc = 
d720: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20  SQLITE_NOMEM;.  
d730: 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  }..  return rc;.
d740: 7d 0a 0a 2f 2a 0a 2a 2a 20 46 69 6e 64 20 61 20  }../*.** Find a 
d750: 74 6f 6b 65 6e 69 7a 65 72 2e 20 54 68 69 73 20  tokenizer. This 
d760: 69 73 20 74 68 65 20 69 6d 70 6c 65 6d 65 6e 74  is the implement
d770: 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 0a 2a 2a  ation of the .**
d780: 20 66 74 73 35 5f 61 70 69 2e 78 46 69 6e 64 54   fts5_api.xFindT
d790: 6f 6b 65 6e 69 7a 65 72 28 29 20 6d 65 74 68 6f  okenizer() metho
d7a0: 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  d..*/.static int
d7b0: 20 66 74 73 35 46 69 6e 64 54 6f 6b 65 6e 69 7a   fts5FindTokeniz
d7c0: 65 72 28 0a 20 20 66 74 73 35 5f 61 70 69 20 2a  er(.  fts5_api *
d7d0: 70 41 70 69 2c 20 20 20 20 20 20 20 20 20 20 20  pApi,           
d7e0: 20 20 20 20 20 20 2f 2a 20 47 6c 6f 62 61 6c 20        /* Global 
d7f0: 63 6f 6e 74 65 78 74 20 28 6f 6e 65 20 70 65 72  context (one per
d800: 20 64 62 20 68 61 6e 64 6c 65 29 20 2a 2f 0a 20   db handle) */. 
d810: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61   const char *zNa
d820: 6d 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  me,             
d830: 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 6e 65 77 20   /* Name of new 
d840: 66 75 6e 63 74 69 6f 6e 20 2a 2f 0a 20 20 76 6f  function */.  vo
d850: 69 64 20 2a 2a 70 70 55 73 65 72 44 61 74 61 2c  id **ppUserData,
d860: 0a 20 20 66 74 73 35 5f 74 6f 6b 65 6e 69 7a 65  .  fts5_tokenize
d870: 72 20 2a 70 54 6f 6b 65 6e 69 7a 65 72 20 20 20  r *pTokenizer   
d880: 20 20 20 2f 2a 20 50 6f 70 75 6c 61 74 65 20 74     /* Populate t
d890: 68 69 73 20 6f 62 6a 65 63 74 20 2a 2f 0a 29 7b  his object */.){
d8a0: 0a 20 20 46 74 73 35 47 6c 6f 62 61 6c 20 2a 70  .  Fts5Global *p
d8b0: 47 6c 6f 62 61 6c 20 3d 20 28 46 74 73 35 47 6c  Global = (Fts5Gl
d8c0: 6f 62 61 6c 2a 29 70 41 70 69 3b 0a 20 20 69 6e  obal*)pApi;.  in
d8d0: 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b  t rc = SQLITE_OK
d8e0: 3b 0a 20 20 46 74 73 35 54 6f 6b 65 6e 69 7a 65  ;.  Fts5Tokenize
d8f0: 72 4d 6f 64 75 6c 65 20 2a 70 54 6f 6b 3b 0a 0a  rModule *pTok;..
d900: 20 20 69 66 28 20 7a 4e 61 6d 65 3d 3d 30 20 29    if( zName==0 )
d910: 7b 0a 20 20 20 20 70 54 6f 6b 20 3d 20 70 47 6c  {.    pTok = pGl
d920: 6f 62 61 6c 2d 3e 70 44 66 6c 74 54 6f 6b 3b 0a  obal->pDfltTok;.
d930: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 66 6f 72    }else{.    for
d940: 28 70 54 6f 6b 3d 70 47 6c 6f 62 61 6c 2d 3e 70  (pTok=pGlobal->p
d950: 54 6f 6b 3b 20 70 54 6f 6b 3b 20 70 54 6f 6b 3d  Tok; pTok; pTok=
d960: 70 54 6f 6b 2d 3e 70 4e 65 78 74 29 7b 0a 20 20  pTok->pNext){.  
d970: 20 20 20 20 69 66 28 20 73 71 6c 69 74 65 33 5f      if( sqlite3_
d980: 73 74 72 69 63 6d 70 28 7a 4e 61 6d 65 2c 20 70  stricmp(zName, p
d990: 54 6f 6b 2d 3e 7a 4e 61 6d 65 29 3d 3d 30 20 29  Tok->zName)==0 )
d9a0: 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 20 20   break;.    }.  
d9b0: 7d 0a 0a 20 20 69 66 28 20 70 54 6f 6b 20 29 7b  }..  if( pTok ){
d9c0: 0a 20 20 20 20 2a 70 54 6f 6b 65 6e 69 7a 65 72  .    *pTokenizer
d9d0: 20 3d 20 70 54 6f 6b 2d 3e 78 3b 0a 20 20 20 20   = pTok->x;.    
d9e0: 2a 70 70 55 73 65 72 44 61 74 61 20 3d 20 70 54  *ppUserData = pT
d9f0: 6f 6b 2d 3e 70 55 73 65 72 44 61 74 61 3b 0a 20  ok->pUserData;. 
da00: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 6d 65 6d 73   }else{.    mems
da10: 65 74 28 70 54 6f 6b 65 6e 69 7a 65 72 2c 20 30  et(pTokenizer, 0
da20: 2c 20 73 69 7a 65 6f 66 28 66 74 73 35 5f 74 6f  , sizeof(fts5_to
da30: 6b 65 6e 69 7a 65 72 29 29 3b 0a 20 20 20 20 72  kenizer));.    r
da40: 63 20 3d 20 53 51 4c 49 54 45 5f 45 52 52 4f 52  c = SQLITE_ERROR
da50: 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20  ;.  }..  return 
da60: 72 63 3b 0a 7d 0a 0a 69 6e 74 20 73 71 6c 69 74  rc;.}..int sqlit
da70: 65 33 46 74 73 35 47 65 74 54 6f 6b 65 6e 69 7a  e3Fts5GetTokeniz
da80: 65 72 28 0a 20 20 46 74 73 35 47 6c 6f 62 61 6c  er(.  Fts5Global
da90: 20 2a 70 47 6c 6f 62 61 6c 2c 20 0a 20 20 63 6f   *pGlobal, .  co
daa0: 6e 73 74 20 63 68 61 72 20 2a 2a 61 7a 41 72 67  nst char **azArg
dab0: 2c 0a 20 20 69 6e 74 20 6e 41 72 67 2c 0a 20 20  ,.  int nArg,.  
dac0: 46 74 73 35 54 6f 6b 65 6e 69 7a 65 72 20 2a 2a  Fts5Tokenizer **
dad0: 70 70 54 6f 6b 2c 0a 20 20 66 74 73 35 5f 74 6f  ppTok,.  fts5_to
dae0: 6b 65 6e 69 7a 65 72 20 2a 2a 70 70 54 6f 6b 41  kenizer **ppTokA
daf0: 70 69 0a 29 7b 0a 20 20 46 74 73 35 54 6f 6b 65  pi.){.  Fts5Toke
db00: 6e 69 7a 65 72 4d 6f 64 75 6c 65 20 2a 70 4d 6f  nizerModule *pMo
db10: 64 20 3d 20 30 3b 0a 20 20 69 6e 74 20 72 63 20  d = 0;.  int rc 
db20: 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20  = SQLITE_OK;..  
db30: 69 66 28 20 6e 41 72 67 3d 3d 30 20 29 7b 0a 20  if( nArg==0 ){. 
db40: 20 20 20 70 4d 6f 64 20 3d 20 70 47 6c 6f 62 61     pMod = pGloba
db50: 6c 2d 3e 70 44 66 6c 74 54 6f 6b 3b 0a 20 20 7d  l->pDfltTok;.  }
db60: 65 6c 73 65 7b 0a 20 20 20 20 66 6f 72 28 70 4d  else{.    for(pM
db70: 6f 64 3d 70 47 6c 6f 62 61 6c 2d 3e 70 54 6f 6b  od=pGlobal->pTok
db80: 3b 20 70 4d 6f 64 3b 20 70 4d 6f 64 3d 70 4d 6f  ; pMod; pMod=pMo
db90: 64 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20 20  d->pNext){.     
dba0: 20 69 66 28 20 73 71 6c 69 74 65 33 5f 73 74 72   if( sqlite3_str
dbb0: 69 63 6d 70 28 61 7a 41 72 67 5b 30 5d 2c 20 70  icmp(azArg[0], p
dbc0: 4d 6f 64 2d 3e 7a 4e 61 6d 65 29 3d 3d 30 20 29  Mod->zName)==0 )
dbd0: 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 20 20   break;.    }.  
dbe0: 7d 0a 0a 20 20 69 66 28 20 70 4d 6f 64 3d 3d 30  }..  if( pMod==0
dbf0: 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 53 51 4c   ){.    rc = SQL
dc00: 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 7d 65 6c  ITE_ERROR;.  }el
dc10: 73 65 7b 0a 20 20 20 20 72 63 20 3d 20 70 4d 6f  se{.    rc = pMo
dc20: 64 2d 3e 78 2e 78 43 72 65 61 74 65 28 70 4d 6f  d->x.xCreate(pMo
dc30: 64 2d 3e 70 55 73 65 72 44 61 74 61 2c 20 26 61  d->pUserData, &a
dc40: 7a 41 72 67 5b 31 5d 2c 20 28 6e 41 72 67 3f 6e  zArg[1], (nArg?n
dc50: 41 72 67 2d 31 3a 30 29 2c 20 70 70 54 6f 6b 29  Arg-1:0), ppTok)
dc60: 3b 0a 20 20 20 20 2a 70 70 54 6f 6b 41 70 69 20  ;.    *ppTokApi 
dc70: 3d 20 26 70 4d 6f 64 2d 3e 78 3b 0a 20 20 7d 0a  = &pMod->x;.  }.
dc80: 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54  .  if( rc!=SQLIT
dc90: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 2a 70 70 54  E_OK ){.    *ppT
dca0: 6f 6b 41 70 69 20 3d 20 30 3b 0a 20 20 20 20 2a  okApi = 0;.    *
dcb0: 70 70 54 6f 6b 20 3d 20 30 3b 0a 20 20 7d 0a 0a  ppTok = 0;.  }..
dcc0: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
dcd0: 73 74 61 74 69 63 20 76 6f 69 64 20 66 74 73 35  static void fts5
dce0: 4d 6f 64 75 6c 65 44 65 73 74 72 6f 79 28 76 6f  ModuleDestroy(vo
dcf0: 69 64 20 2a 70 43 74 78 29 7b 0a 20 20 46 74 73  id *pCtx){.  Fts
dd00: 35 54 6f 6b 65 6e 69 7a 65 72 4d 6f 64 75 6c 65  5TokenizerModule
dd10: 20 2a 70 54 6f 6b 2c 20 2a 70 4e 65 78 74 54 6f   *pTok, *pNextTo
dd20: 6b 3b 0a 20 20 46 74 73 35 41 75 78 69 6c 69 61  k;.  Fts5Auxilia
dd30: 72 79 20 2a 70 41 75 78 2c 20 2a 70 4e 65 78 74  ry *pAux, *pNext
dd40: 41 75 78 3b 0a 20 20 46 74 73 35 47 6c 6f 62 61  Aux;.  Fts5Globa
dd50: 6c 20 2a 70 47 6c 6f 62 61 6c 20 3d 20 28 46 74  l *pGlobal = (Ft
dd60: 73 35 47 6c 6f 62 61 6c 2a 29 70 43 74 78 3b 0a  s5Global*)pCtx;.
dd70: 0a 20 20 66 6f 72 28 70 41 75 78 3d 70 47 6c 6f  .  for(pAux=pGlo
dd80: 62 61 6c 2d 3e 70 41 75 78 3b 20 70 41 75 78 3b  bal->pAux; pAux;
dd90: 20 70 41 75 78 3d 70 4e 65 78 74 41 75 78 29 7b   pAux=pNextAux){
dda0: 0a 20 20 20 20 70 4e 65 78 74 41 75 78 20 3d 20  .    pNextAux = 
ddb0: 70 41 75 78 2d 3e 70 4e 65 78 74 3b 0a 20 20 20  pAux->pNext;.   
ddc0: 20 69 66 28 20 70 41 75 78 2d 3e 78 44 65 73 74   if( pAux->xDest
ddd0: 72 6f 79 20 29 20 70 41 75 78 2d 3e 78 44 65 73  roy ) pAux->xDes
dde0: 74 72 6f 79 28 70 41 75 78 2d 3e 70 55 73 65 72  troy(pAux->pUser
ddf0: 44 61 74 61 29 3b 0a 20 20 20 20 73 71 6c 69 74  Data);.    sqlit
de00: 65 33 5f 66 72 65 65 28 70 41 75 78 29 3b 0a 20  e3_free(pAux);. 
de10: 20 7d 0a 0a 20 20 66 6f 72 28 70 54 6f 6b 3d 70   }..  for(pTok=p
de20: 47 6c 6f 62 61 6c 2d 3e 70 54 6f 6b 3b 20 70 54  Global->pTok; pT
de30: 6f 6b 3b 20 70 54 6f 6b 3d 70 4e 65 78 74 54 6f  ok; pTok=pNextTo
de40: 6b 29 7b 0a 20 20 20 20 70 4e 65 78 74 54 6f 6b  k){.    pNextTok
de50: 20 3d 20 70 54 6f 6b 2d 3e 70 4e 65 78 74 3b 0a   = pTok->pNext;.
de60: 20 20 20 20 69 66 28 20 70 54 6f 6b 2d 3e 78 44      if( pTok->xD
de70: 65 73 74 72 6f 79 20 29 20 70 54 6f 6b 2d 3e 78  estroy ) pTok->x
de80: 44 65 73 74 72 6f 79 28 70 54 6f 6b 2d 3e 70 55  Destroy(pTok->pU
de90: 73 65 72 44 61 74 61 29 3b 0a 20 20 20 20 73 71  serData);.    sq
dea0: 6c 69 74 65 33 5f 66 72 65 65 28 70 54 6f 6b 29  lite3_free(pTok)
deb0: 3b 0a 20 20 7d 0a 0a 20 20 73 71 6c 69 74 65 33  ;.  }..  sqlite3
dec0: 5f 66 72 65 65 28 70 47 6c 6f 62 61 6c 29 3b 0a  _free(pGlobal);.
ded0: 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 66  }..static void f
dee0: 74 73 35 46 74 73 35 46 75 6e 63 28 0a 20 20 73  ts5Fts5Func(.  s
def0: 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74 20 2a  qlite3_context *
df00: 70 43 74 78 2c 20 20 20 20 20 20 20 20 20 20 2f  pCtx,          /
df10: 2a 20 46 75 6e 63 74 69 6f 6e 20 63 61 6c 6c 20  * Function call 
df20: 63 6f 6e 74 65 78 74 20 2a 2f 0a 20 20 69 6e 74  context */.  int
df30: 20 6e 41 72 67 2c 20 20 20 20 20 20 20 20 20 20   nArg,          
df40: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
df50: 4e 75 6d 62 65 72 20 6f 66 20 61 72 67 73 20 2a  Number of args *
df60: 2f 0a 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75  /.  sqlite3_valu
df70: 65 20 2a 2a 61 70 56 61 6c 20 20 20 20 20 20 20  e **apVal       
df80: 20 20 20 20 2f 2a 20 46 75 6e 63 74 69 6f 6e 20      /* Function 
df90: 61 72 67 75 6d 65 6e 74 73 20 2a 2f 0a 29 7b 0a  arguments */.){.
dfa0: 20 20 46 74 73 35 47 6c 6f 62 61 6c 20 2a 70 47    Fts5Global *pG
dfb0: 6c 6f 62 61 6c 20 3d 20 28 46 74 73 35 47 6c 6f  lobal = (Fts5Glo
dfc0: 62 61 6c 2a 29 73 71 6c 69 74 65 33 5f 75 73 65  bal*)sqlite3_use
dfd0: 72 5f 64 61 74 61 28 70 43 74 78 29 3b 0a 20 20  r_data(pCtx);.  
dfe0: 63 68 61 72 20 62 75 66 5b 38 5d 3b 0a 20 20 61  char buf[8];.  a
dff0: 73 73 65 72 74 28 20 6e 41 72 67 3d 3d 30 20 29  ssert( nArg==0 )
e000: 3b 0a 20 20 61 73 73 65 72 74 28 20 73 69 7a 65  ;.  assert( size
e010: 6f 66 28 62 75 66 29 3e 3d 73 69 7a 65 6f 66 28  of(buf)>=sizeof(
e020: 70 47 6c 6f 62 61 6c 29 20 29 3b 0a 20 20 6d 65  pGlobal) );.  me
e030: 6d 63 70 79 28 62 75 66 2c 20 28 76 6f 69 64 2a  mcpy(buf, (void*
e040: 29 26 70 47 6c 6f 62 61 6c 2c 20 73 69 7a 65 6f  )&pGlobal, sizeo
e050: 66 28 70 47 6c 6f 62 61 6c 29 29 3b 0a 20 20 73  f(pGlobal));.  s
e060: 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 62 6c  qlite3_result_bl
e070: 6f 62 28 70 43 74 78 2c 20 62 75 66 2c 20 73 69  ob(pCtx, buf, si
e080: 7a 65 6f 66 28 70 47 6c 6f 62 61 6c 29 2c 20 53  zeof(pGlobal), S
e090: 51 4c 49 54 45 5f 54 52 41 4e 53 49 45 4e 54 29  QLITE_TRANSIENT)
e0a0: 3b 0a 7d 0a 0a 69 6e 74 20 73 71 6c 69 74 65 33  ;.}..int sqlite3
e0b0: 46 74 73 35 49 6e 69 74 28 73 71 6c 69 74 65 33  Fts5Init(sqlite3
e0c0: 20 2a 64 62 29 7b 0a 20 20 73 74 61 74 69 63 20   *db){.  static 
e0d0: 63 6f 6e 73 74 20 73 71 6c 69 74 65 33 5f 6d 6f  const sqlite3_mo
e0e0: 64 75 6c 65 20 66 74 73 35 4d 6f 64 20 3d 20 7b  dule fts5Mod = {
e0f0: 0a 20 20 20 20 2f 2a 20 69 56 65 72 73 69 6f 6e  .    /* iVersion
e100: 20 20 20 20 20 20 2a 2f 20 32 2c 0a 20 20 20 20        */ 2,.    
e110: 2f 2a 20 78 43 72 65 61 74 65 20 20 20 20 20 20  /* xCreate      
e120: 20 2a 2f 20 66 74 73 35 43 72 65 61 74 65 4d 65   */ fts5CreateMe
e130: 74 68 6f 64 2c 0a 20 20 20 20 2f 2a 20 78 43 6f  thod,.    /* xCo
e140: 6e 6e 65 63 74 20 20 20 20 20 20 2a 2f 20 66 74  nnect      */ ft
e150: 73 35 43 6f 6e 6e 65 63 74 4d 65 74 68 6f 64 2c  s5ConnectMethod,
e160: 0a 20 20 20 20 2f 2a 20 78 42 65 73 74 49 6e 64  .    /* xBestInd
e170: 65 78 20 20 20 20 2a 2f 20 66 74 73 35 42 65 73  ex    */ fts5Bes
e180: 74 49 6e 64 65 78 4d 65 74 68 6f 64 2c 0a 20 20  tIndexMethod,.  
e190: 20 20 2f 2a 20 78 44 69 73 63 6f 6e 6e 65 63 74    /* xDisconnect
e1a0: 20 20 20 2a 2f 20 66 74 73 35 44 69 73 63 6f 6e     */ fts5Discon
e1b0: 6e 65 63 74 4d 65 74 68 6f 64 2c 0a 20 20 20 20  nectMethod,.    
e1c0: 2f 2a 20 78 44 65 73 74 72 6f 79 20 20 20 20 20  /* xDestroy     
e1d0: 20 2a 2f 20 66 74 73 35 44 65 73 74 72 6f 79 4d   */ fts5DestroyM
e1e0: 65 74 68 6f 64 2c 0a 20 20 20 20 2f 2a 20 78 4f  ethod,.    /* xO
e1f0: 70 65 6e 20 20 20 20 20 20 20 20 20 2a 2f 20 66  pen         */ f
e200: 74 73 35 4f 70 65 6e 4d 65 74 68 6f 64 2c 0a 20  ts5OpenMethod,. 
e210: 20 20 20 2f 2a 20 78 43 6c 6f 73 65 20 20 20 20     /* xClose    
e220: 20 20 20 20 2a 2f 20 66 74 73 35 43 6c 6f 73 65      */ fts5Close
e230: 4d 65 74 68 6f 64 2c 0a 20 20 20 20 2f 2a 20 78  Method,.    /* x
e240: 46 69 6c 74 65 72 20 20 20 20 20 20 20 2a 2f 20  Filter       */ 
e250: 66 74 73 35 46 69 6c 74 65 72 4d 65 74 68 6f 64  fts5FilterMethod
e260: 2c 0a 20 20 20 20 2f 2a 20 78 4e 65 78 74 20 20  ,.    /* xNext  
e270: 20 20 20 20 20 20 20 2a 2f 20 66 74 73 35 4e 65         */ fts5Ne
e280: 78 74 4d 65 74 68 6f 64 2c 0a 20 20 20 20 2f 2a  xtMethod,.    /*
e290: 20 78 45 6f 66 20 20 20 20 20 20 20 20 20 20 2a   xEof          *
e2a0: 2f 20 66 74 73 35 45 6f 66 4d 65 74 68 6f 64 2c  / fts5EofMethod,
e2b0: 0a 20 20 20 20 2f 2a 20 78 43 6f 6c 75 6d 6e 20  .    /* xColumn 
e2c0: 20 20 20 20 20 20 2a 2f 20 66 74 73 35 43 6f 6c        */ fts5Col
e2d0: 75 6d 6e 4d 65 74 68 6f 64 2c 0a 20 20 20 20 2f  umnMethod,.    /
e2e0: 2a 20 78 52 6f 77 69 64 20 20 20 20 20 20 20 20  * xRowid        
e2f0: 2a 2f 20 66 74 73 35 52 6f 77 69 64 4d 65 74 68  */ fts5RowidMeth
e300: 6f 64 2c 0a 20 20 20 20 2f 2a 20 78 55 70 64 61  od,.    /* xUpda
e310: 74 65 20 20 20 20 20 20 20 2a 2f 20 66 74 73 35  te       */ fts5
e320: 55 70 64 61 74 65 4d 65 74 68 6f 64 2c 0a 20 20  UpdateMethod,.  
e330: 20 20 2f 2a 20 78 42 65 67 69 6e 20 20 20 20 20    /* xBegin     
e340: 20 20 20 2a 2f 20 66 74 73 35 42 65 67 69 6e 4d     */ fts5BeginM
e350: 65 74 68 6f 64 2c 0a 20 20 20 20 2f 2a 20 78 53  ethod,.    /* xS
e360: 79 6e 63 20 20 20 20 20 20 20 20 20 2a 2f 20 66  ync         */ f
e370: 74 73 35 53 79 6e 63 4d 65 74 68 6f 64 2c 0a 20  ts5SyncMethod,. 
e380: 20 20 20 2f 2a 20 78 43 6f 6d 6d 69 74 20 20 20     /* xCommit   
e390: 20 20 20 20 2a 2f 20 66 74 73 35 43 6f 6d 6d 69      */ fts5Commi
e3a0: 74 4d 65 74 68 6f 64 2c 0a 20 20 20 20 2f 2a 20  tMethod,.    /* 
e3b0: 78 52 6f 6c 6c 62 61 63 6b 20 20 20 20 20 2a 2f  xRollback     */
e3c0: 20 66 74 73 35 52 6f 6c 6c 62 61 63 6b 4d 65 74   fts5RollbackMet
e3d0: 68 6f 64 2c 0a 20 20 20 20 2f 2a 20 78 46 69 6e  hod,.    /* xFin
e3e0: 64 46 75 6e 63 74 69 6f 6e 20 2a 2f 20 66 74 73  dFunction */ fts
e3f0: 35 46 69 6e 64 46 75 6e 63 74 69 6f 6e 4d 65 74  5FindFunctionMet
e400: 68 6f 64 2c 0a 20 20 20 20 2f 2a 20 78 52 65 6e  hod,.    /* xRen
e410: 61 6d 65 20 20 20 20 20 20 20 2a 2f 20 66 74 73  ame       */ fts
e420: 35 52 65 6e 61 6d 65 4d 65 74 68 6f 64 2c 0a 20  5RenameMethod,. 
e430: 20 20 20 2f 2a 20 78 53 61 76 65 70 6f 69 6e 74     /* xSavepoint
e440: 20 20 20 20 2a 2f 20 66 74 73 35 53 61 76 65 70      */ fts5Savep
e450: 6f 69 6e 74 4d 65 74 68 6f 64 2c 0a 20 20 20 20  ointMethod,.    
e460: 2f 2a 20 78 52 65 6c 65 61 73 65 20 20 20 20 20  /* xRelease     
e470: 20 2a 2f 20 66 74 73 35 52 65 6c 65 61 73 65 4d   */ fts5ReleaseM
e480: 65 74 68 6f 64 2c 0a 20 20 20 20 2f 2a 20 78 52  ethod,.    /* xR
e490: 6f 6c 6c 62 61 63 6b 54 6f 20 20 20 2a 2f 20 66  ollbackTo   */ f
e4a0: 74 73 35 52 6f 6c 6c 62 61 63 6b 54 6f 4d 65 74  ts5RollbackToMet
e4b0: 68 6f 64 2c 0a 20 20 7d 3b 0a 0a 20 20 69 6e 74  hod,.  };..  int
e4c0: 20 72 63 3b 0a 20 20 46 74 73 35 47 6c 6f 62 61   rc;.  Fts5Globa
e4d0: 6c 20 2a 70 47 6c 6f 62 61 6c 20 3d 20 30 3b 0a  l *pGlobal = 0;.
e4e0: 20 20 70 47 6c 6f 62 61 6c 20 3d 20 28 46 74 73    pGlobal = (Fts
e4f0: 35 47 6c 6f 62 61 6c 2a 29 73 71 6c 69 74 65 33  5Global*)sqlite3
e500: 5f 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 46  _malloc(sizeof(F
e510: 74 73 35 47 6c 6f 62 61 6c 29 29 3b 0a 0a 20 20  ts5Global));..  
e520: 69 66 28 20 70 47 6c 6f 62 61 6c 3d 3d 30 20 29  if( pGlobal==0 )
e530: 7b 0a 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54  {.    rc = SQLIT
e540: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 65 6c 73 65  E_NOMEM;.  }else
e550: 7b 0a 20 20 20 20 76 6f 69 64 20 2a 70 20 3d 20  {.    void *p = 
e560: 28 76 6f 69 64 2a 29 70 47 6c 6f 62 61 6c 3b 0a  (void*)pGlobal;.
e570: 20 20 20 20 6d 65 6d 73 65 74 28 70 47 6c 6f 62      memset(pGlob
e580: 61 6c 2c 20 30 2c 20 73 69 7a 65 6f 66 28 46 74  al, 0, sizeof(Ft
e590: 73 35 47 6c 6f 62 61 6c 29 29 3b 0a 20 20 20 20  s5Global));.    
e5a0: 70 47 6c 6f 62 61 6c 2d 3e 64 62 20 3d 20 64 62  pGlobal->db = db
e5b0: 3b 0a 20 20 20 20 70 47 6c 6f 62 61 6c 2d 3e 61  ;.    pGlobal->a
e5c0: 70 69 2e 69 56 65 72 73 69 6f 6e 20 3d 20 31 3b  pi.iVersion = 1;
e5d0: 0a 20 20 20 20 70 47 6c 6f 62 61 6c 2d 3e 61 70  .    pGlobal->ap
e5e0: 69 2e 78 43 72 65 61 74 65 46 75 6e 63 74 69 6f  i.xCreateFunctio
e5f0: 6e 20 3d 20 66 74 73 35 43 72 65 61 74 65 41 75  n = fts5CreateAu
e600: 78 3b 0a 20 20 20 20 70 47 6c 6f 62 61 6c 2d 3e  x;.    pGlobal->
e610: 61 70 69 2e 78 43 72 65 61 74 65 54 6f 6b 65 6e  api.xCreateToken
e620: 69 7a 65 72 20 3d 20 66 74 73 35 43 72 65 61 74  izer = fts5Creat
e630: 65 54 6f 6b 65 6e 69 7a 65 72 3b 0a 20 20 20 20  eTokenizer;.    
e640: 70 47 6c 6f 62 61 6c 2d 3e 61 70 69 2e 78 46 69  pGlobal->api.xFi
e650: 6e 64 54 6f 6b 65 6e 69 7a 65 72 20 3d 20 66 74  ndTokenizer = ft
e660: 73 35 46 69 6e 64 54 6f 6b 65 6e 69 7a 65 72 3b  s5FindTokenizer;
e670: 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65  .    rc = sqlite
e680: 33 5f 63 72 65 61 74 65 5f 6d 6f 64 75 6c 65 5f  3_create_module_
e690: 76 32 28 64 62 2c 20 22 66 74 73 35 22 2c 20 26  v2(db, "fts5", &
e6a0: 66 74 73 35 4d 6f 64 2c 20 70 2c 20 66 74 73 35  fts5Mod, p, fts5
e6b0: 4d 6f 64 75 6c 65 44 65 73 74 72 6f 79 29 3b 0a  ModuleDestroy);.
e6c0: 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49      if( rc==SQLI
e6d0: 54 45 5f 4f 4b 20 29 20 72 63 20 3d 20 73 71 6c  TE_OK ) rc = sql
e6e0: 69 74 65 33 46 74 73 35 49 6e 64 65 78 49 6e 69  ite3Fts5IndexIni
e6f0: 74 28 64 62 29 3b 0a 20 20 20 20 69 66 28 20 72  t(db);.    if( r
e700: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72  c==SQLITE_OK ) r
e710: 63 20 3d 20 73 71 6c 69 74 65 33 46 74 73 35 45  c = sqlite3Fts5E
e720: 78 70 72 49 6e 69 74 28 70 47 6c 6f 62 61 6c 2c  xprInit(pGlobal,
e730: 20 64 62 29 3b 0a 20 20 20 20 69 66 28 20 72 63   db);.    if( rc
e740: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 63  ==SQLITE_OK ) rc
e750: 20 3d 20 73 71 6c 69 74 65 33 46 74 73 35 41 75   = sqlite3Fts5Au
e760: 78 49 6e 69 74 28 26 70 47 6c 6f 62 61 6c 2d 3e  xInit(&pGlobal->
e770: 61 70 69 29 3b 0a 20 20 20 20 69 66 28 20 72 63  api);.    if( rc
e780: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 63  ==SQLITE_OK ) rc
e790: 20 3d 20 73 71 6c 69 74 65 33 46 74 73 35 54 6f   = sqlite3Fts5To
e7a0: 6b 65 6e 69 7a 65 72 49 6e 69 74 28 26 70 47 6c  kenizerInit(&pGl
e7b0: 6f 62 61 6c 2d 3e 61 70 69 29 3b 0a 20 20 20 20  obal->api);.    
e7c0: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
e7d0: 4b 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20  K ){.      rc = 
e7e0: 73 71 6c 69 74 65 33 5f 63 72 65 61 74 65 5f 66  sqlite3_create_f
e7f0: 75 6e 63 74 69 6f 6e 28 0a 20 20 20 20 20 20 20  unction(.       
e800: 20 20 20 64 62 2c 20 22 66 74 73 35 22 2c 20 30     db, "fts5", 0
e810: 2c 20 53 51 4c 49 54 45 5f 55 54 46 38 2c 20 70  , SQLITE_UTF8, p
e820: 2c 20 66 74 73 35 46 74 73 35 46 75 6e 63 2c 20  , fts5Fts5Func, 
e830: 30 2c 20 30 0a 20 20 20 20 20 20 29 3b 0a 20 20  0, 0.      );.  
e840: 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e    }.  }.  return
e850: 20 72 63 3b 0a 7d 0a 0a 0a                        rc;.}...